官方文档
封装思想
- 直接复制官网
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 页面接口都可以先行注册,再注册静态页面