官方文档

封装思想

  • 直接复制官网json数据即可开发
  • 每个json中的接口由fastapi 转发(透传)使其开发模式与前端思维一致

基础组件

from amis import Page, Service, App
from pydantic import BaseModel, Field
from fastapi import FastAPI, Request, Response, APIRouter
from starlette.responses import HTMLResponse


class JsonRegister(BaseModel):
    page_json_url: str = "/demo.json"

    def __init__(self, **kwargs):
        super(JsonRegister, self).__init__(**kwargs)

    def register(self, router: APIRouter):
        router.add_api_route(self.page_json_url, endpoint=self.json)

    def json(self) -> {}:
        """amis json格式数据"""
        return {}


class HtmlRegister(BaseModel):
    page_url = "/"

    def __init__(self, **kwargs):
        super(HtmlRegister, self).__init__(**kwargs)

    def register(self, router: APIRouter):
        router.add_api_route(self.page_url, endpoint=self.html)

    def html(self):
        """渲染html页面"""
        return HTMLResponse(content=Page().render())


class TableRegister(JsonRegister):
    base_url = "/crud/"
    primary_key = "id"
    page_json_url = "/curd/model.json"

    primary_key_url = ""

    def __init__(self, **kwargs):
        super(TableRegister, self).__init__(**kwargs)

    def register(self, router: APIRouter):
        super(TableRegister, self).register(router=router)
        self.primary_key_url = self.base_url + "{" + self.primary_key + "}"
        router.add_api_route(self.primary_key_url, endpoint=self.get_item, methods=["GET"])
        router.add_api_route(self.primary_key_url, endpoint=self.delete_item, methods=["DELETE"])
        router.add_api_route(self.primary_key_url, endpoint=self.put_item, methods=["PUT"])
        router.add_api_route(self.primary_key_url, endpoint=self.options_item, methods=["OPTIONS"])
        router.add_api_route(self.base_url, endpoint=self.get_items, methods=["GET"])
        router.add_api_route(self.base_url, endpoint=self.post_item, methods=["POST"])

    def get_item(self, request: Request):
        return {}

    def delete_item(self, request: Request):
        return {}

    def put_item(self, request: Request):
        return {}

    def options_item(self, request: Request):
        return {}

    def get_items(self, request: Request):
        return []

    def post_item(self, request: Request):
        return {}
  • 上诉组件中定义
  • json格式注册器
  • html页面注册器
  • 表格增删改查注册器

常见业务功能组件封装

class RouterJson(JsonRegister):
    page_json_url = "/router.json"
    children_pages = [
        {
            "label": "父页面",
            "url": "/parent",
            "redirect": "/parent/pageA",
            "children": [
                {
                    "label": "子页面",
                    "url": "pageA",
                    "schemaApi": "get:/pages/crud-list.json"
                },
                {
                    "label": "子页面",
                    "url": "pageB",
                    "schemaApi": "get:/pages/crud-list.json"
                }
            ]
        }
    ]

    def json(self) -> {}:
        return {
            "status": 0,
            "msg": "",
            "data": {
                "pages": {
                    "children": self.children_pages
                }
            }
        }


class AppAdminHtml(HtmlRegister):
    web_url: str = "/"
    """获取静态页面地址"""
    app_brandName = "测试Demo"
    router_json: RouterJson = RouterJson()

    def html(self):
        app_ = App()
        app_.brandName = "测试Demo"
        app_.api = f"get:{self.router_json.page_json_url}"
        return HTMLResponse(app_.render())


class ModelAdminJson(TableRegister):
    base_url = "/crud/"
    primary_key = "id"
    page_json_url = "/curd/model.json"

    def get_item(self, request: Request):
        id_ = request.get(self.primary_key)
        return {"name": "mock data", "id": id_}

    def delete_item(self, request: Request):
        id_ = request.get(self.primary_key)
        return {"name": "mock data", "id": id_}

    def put_item(self, request: Request):
        id_ = request.get(self.primary_key)
        return {"name": "mock data", "id": id_}

    def options_item(self, request: Request):
        id_ = request.get(self.primary_key)
        return {"name": "mock data", "id": id_}

    def get_items(self, request: Request):
        return [{"name": f"mock data {id_}", "id": id_} for id_ in range(10)]

    def post_item(self, request: Request):
        return {"name": "mock data", "id": 0}


class LoginJson(JsonRegister):
    page_json_url: str = "/login.json"
    """获取json配置接口地址"""
    title: str = ""
    """标题"""
    success_redirect_url = "/"
    """成功登陆后的重定向地址"""
    login_params = {
        "url": "${serverUrl}/login/",
        "method": "post",
        "dataType": "form-data"
    }

    def register(self, router: APIRouter):
        super(LoginJson, self).register(router=router)
        router.add_api_route("/login/", endpoint=self.post_item, methods=["POST"])

    def post_item(self, request: Request):
        return {"name": "mock data", "id": 0}

    def json(self):
        return Page(**{
            "type": "page",
            "title": "",
            "style": {
                "backgroundImage": "linear-gradient(180deg, #86a4e9, transparent)"
            },
            "cssVars": {
                "--Form-input-onFocused-borderColor": "#e8e9eb",
                "--Form-input-onHover-borderColor": "#e8e9eb"
            },
            "body": {
                "type": "grid-2d",
                "cols": 12,
                "grids": [
                    {
                        "x": 5,
                        "y": 5,
                        "h": 1,
                        "w": 4,
                        "width": 200,
                        "type": "form",
                        "mode": "horizontal",
                        "title": "",
                        "api": self.login_params,
                        "panelClassName": "p-r p-l p-b-md",
                        "redirect": self.success_redirect_url,
                        "body": [
                            {
                                "type": "tpl",
                                "tpl": f"<div style='text-align: center; font-weight: bold;'><p>{self.title}</p></div>"
                            },
                            {
                                "type": "input-text",
                                "label": False,
                                "name": "userName",
                                "size": "full",
                                "placeholder": "登陆名",
                                "addOn": {
                                    "label": "",
                                    "type": "text",
                                    "position": "left",
                                    "icon": "fa fa-user"
                                }
                            },
                            {
                                "type": "input-password",
                                "label": False,
                                "name": "password",
                                "size": "full",
                                "placeholder": "密码",
                                "addOn": {
                                    "label": "",
                                    "type": "text",
                                    "position": "left",
                                    "icon": "fa fa-lock"
                                }
                            },
                            {
                                "type": "checkbox",
                                "label": False,
                                "name": "record",
                                "option": "记住密码"
                            },
                            {
                                "type": "control",
                                "label": False,
                                "body": {
                                    "type": "button",
                                    "level": "primary",
                                    "actionType": "submit",
                                    "block": True,
                                    "label": "登陆",
                                    "size": "lg"
                                }
                            }
                        ]
                    }
                ]
            }
        }).to_dict()


class LoginHtml(HtmlRegister):
    page_url: str = "/login"
    """获取静态页面地址"""
    login_json: LoginJson = LoginJson()

    def html(self):
        return HTMLResponse(Page(body=Service(schemaApi=f"get:{self.login_json.page_json_url}")).render())

启动运行

import json
import re

from fastapi import FastAPI, Request, APIRouter
from default_template import *

app = FastAPI()


def main_router():
    router = APIRouter()

    login_json = LoginJson()
    login_json.title = "欢迎登录"
    login_json.success_redirect_url = "/#/home"
    login_json.register(router=router)
    """登录json"""
    router_json = RouterJson()
    router_json.children_pages = [
        {
            "label": "首页",
            "url": "/home",
            "schema": {
                "type": "markdown",
                "value": "# title\n markdown **text**"
            }
        },
        {
            "label": "测试页面",
            "url": "/parent",
            "redirect": "/parent/pageA",
            "children": [
                {
                    "label": "测试页面1",
                    "url": "pageA",
                    "schemaApi": "get:/pages/crud-list.json"
                },
                {
                    "label": "测试页面2",
                    "url": "pageB",
                    "schemaApi": "get:/pages/crud-list.json"
                }
            ]
        }
    ]
    router_json.register(router=router)
    """路由json"""

    login_html = LoginHtml()
    login_html.login_json = login_json
    login_html.register(router=router)
    """登录页面"""
    app_admin_html = AppAdminHtml()
    app_admin_html.app_brandName = "测试应用"
    app_admin_html.router_json = router_json
    app_admin_html.register(router=router)
    """后台页面"""
    return router


app.include_router(main_router())

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=9000)

  • 可以知道当下页面中有登录界面,后台页面
  • 业务中的所有json 页面接口都可以先行注册,再注册静态页面

在这里插入图片描述

在这里插入图片描述

更多推荐