Yao 折騰手記:如何快速創建一套管理系統

文章首發於個人公號:阿拉平平

有開發經驗的小夥伴肯定知道,要獨立開發一套管理系統並非易事。從設計數據庫,到開發接口,再到編寫前端頁面,想想就讓人頭大。如果需求不是很複雜,我們可以藉助低代碼應用引擎來快速開發。

項目介紹

Yao[1] 是一款 Go 語言驅動的低代碼應用引擎,通過編寫 JSON 文件即可快速製作 API 接口,數據管理系統 ,命令行工具等應用程序,應用可以運行在本地、雲端和物聯網設備上。

快速安裝

Yao 可以通過腳本或容器來安裝,官方推薦後者,所以這裏我們使用 Docker 來部署。

運行以下命令創建容器:

# 注意修改掛載的目錄
docker run -d --name yao -v <project root>:/data/app -p 5099:5099 yaoapp/yao:0.9.2-amd64-dev

容器啓動後,進入容器:

docker exec -it yao bash

在項目目錄中,運行初始化命令:

yao init

接着創建數據表:

yao migrate

初始化菜單:

yao run flows.setmenu

完成以上步驟後,啓動服務:

yao start

服務啓動後,用瀏覽器訪問 https://<server-ip>:5099/xiang/login/admin,輸入用戶名:[email protected], 密碼: A123456p+ 登錄。

使用說明

接下來,我將介紹 Yao 的用法,其中包含:

  1. 基本用法:藉助測試數據,瞭解 Yao 界面上的功能。
  2. 新建內容:新建新的內容,包括數據、接口和界面。

基本用法

Yao 在初始化後會有些測試數據,在界面中可以看到表單信息:

我們可以查看、編輯數據:

Yao 還有張用戶表,支持增刪改查:

在菜單界面可以配置左側顯示的內容:

新建內容

Yao 界面上的功能大致如此,接下來我們建下自己的內容。這裏我打算實現一個簡單的圖書管理功能。

先從數據開始。我們回到項目目錄,在 models 下新建一個 book.mod.json 文件,內容如下:

{
    "name": "Book",
    "table": {
        "name": "book",
        "comment": "Book"
    },
    "columns": [{
            "label": "ID",
            "name": "id",
            "type": "ID",
            "comment": "ID"
        },
        {
            "label": "SN",
            "name": "sn",
            "type": "string",
            "unique": true
        },
        {
            "label": "Name",
            "name": "name",
            "type": "string",
            "index": true
        },
        {
            "label": "Kind",
            "name": "kind",
            "type": "enum",
            "option": ["科幻", "名著"],
            "default": "科幻",
            "index": true
        },
        {
            "label": "Description",
            "name": "desc",
            "type": "string",
            "comment": "Description"
        },
        {
            "label": "Score",
            "name": "score",
            "type": "integer",
            "comment": "Score"
        }
    ],
    "values": [{
            "sn": "100001",
            "name": "水滸傳",
            "kind": "名著",
            "desc": "三個女人和一百零五個男人的故事",
            "score": 9
        },
        {
            "sn": "100002",
            "name": "三體",
            "kind": "科幻",
            "desc": "不要回答!不要回答!不要回答!",
            "score": 9
        }
    ],
    "option": {
        "timestamps": true,
        "soft_deletes": true
    }
}

然後在項目目錄中運行以下命令:

yao migrate -n book

需要注意的是,該命令的結果不會在前臺顯示,而是寫到 logs/application.log 中。

針對這種情況,我們可以先查詢下數據,如果數據能夠正常顯示,則說明數據表已創建:

yao run models.book.get '::{}'

Run: models.book.get
args[0]: {}
--------------------------------------
models.book.get Response
--------------------------------------
[
    {
        "created_at": "2022-07-27 05:41:32",
        "deleted_at": null,
        "desc": "三個女人和一百零五個男人的故事",
        "id": 1,
        "kind": "名著",
        "name": "水滸傳",
        "score": 9,
        "sn": "100001",
        "updated_at": null
    },
    {
        "created_at": "2022-07-27 05:41:32",
        "deleted_at": null,
        "desc": "不要回答!不要回答!不要回答!",
        "id": 2,
        "kind": "科幻",
        "name": "三體",
        "score": 9,
        "sn": "100002",
        "updated_at": null
    }
]
--------------------------------------
✨DONE✨

再編寫接口。在 apis 下新建一個 book.http.json 文件,內容如下:

{
    "name": "書籍",
    "version": "1.0.0",
    "description": "書籍接口",
    "group": "book",
    "guard": "bearer-jwt",
    "paths": [{
            "path": "/search",
            "method": "GET",
            "guard": "-",
            "process": "models.book.Paginate",
            "in": [":query-param", "$query.page", "$query.pagesize"],
            "out": {
                "status": 200,
                "type": "application/json"
            }
        },
        {
            "path": "/save",
            "method": "POST",
            "guard": "-",
            "process": "models.book.Save",
            "in": [":payload"],
            "out": {
                "status": 200,
                "type": "application/json"
            }
        }
    ]
}

在這個文件中,我定義了兩個接口:/search/save,用於查詢和創建。我們先用接口創建新的數據:

curl -X POST http://127.0.0.1:5099/api/book/save \
   -H 'Content-Type: application/json' \
   -d '{ "sn": "100003", "name": "三國演義", "kind": "名著", "desc": "東漢末年分三國", "score": 9 }'

查詢剛剛創建的數據,如果結果返回正常,說明接口功能無誤。

curl 'http://127.0.0.1:5099/api/book/search?where.name.match=三國演義&page=1&pagesize=1'

最後編寫界面。在 tables 目錄下新建一個 book.tab.json 文件,內容如下:

{
    "name": "Book",
    "version": "1.0.0",
    "decription": "Book",
    "bind": {
        "model": "book"
    },
    "apis": {},
    "columns": {
        "ID": {
            "label": "ID",
            "view": {
                "type": "label",
                "props": {
                    "value": ":id"
                }
            }
        },
        "SN": {
            "label": "SN",
            "view": {
                "type": "label",
                "props": {
                    "value": ":sn"
                }
            },
            "edit": {
                "type": "input",
                "props": {
                    "value": ":sn"
                }
            }
        },
        "Name": {
            "label": "Name",
            "view": {
                "type": "label",
                "props": {
                    "value": ":name"
                }
            },
            "edit": {
                "type": "input",
                "props": {
                    "value": ":name"
                }
            }
        },
        "Kind": {
            "label": "Kind",
            "view": {
                "type": "label",
                "props": {
                    "value": ":kind"
                }
            },
            "edit": {
                "type": "select",
                "props": {
                    "value": ":kind",
                    "options": [{
                            "label": "科幻",
                            "value": "科幻"
                        },
                        {
                            "label": "名著",
                            "value": "名著"
                        }
                    ]
                }
            }
        },
        "Score": {
            "label": "Score",
            "view": {
                "type": "label",
                "props": {
                    "value": ":score"
                }
            },
            "edit": {
                "type": "input",
                "props": {
                    "value": ":score"
                }
            }
        },
        "Description": {
            "label": "Description",
            "view": {
                "type": "label",
                "props": {
                    "value": ":desc"
                }
            },
            "edit": {
                "type": "textArea",
                "props": {
                    "value": ":desc",
                    "rows": 4
                }
            }
        }
    },
    "filters": {
        "Keywords": {
            "@": "f.Keywords",
            "in": ["where.name.match"]
        }
    },
    "list": {
        "primary": "id",
        "layout": {
            "columns": [{
                    "name": "SN",
                    "width": 100
                },
                {
                    "name": "Name",
                    "width": 200
                },
                {
                    "name": "Score",
                    "width": 300
                },
                {
                    "name": "Kind"
                }
            ],
            "filters": [{
                "name": "Keywords"
            }]
        },
        "actions": {
            "create": {
                "type": "button",
                "props": {
                    "label": "添加書籍",
                    "icon": "fas fa-plus"
                }
            },
            "pagination": {
                "props": {
                    "showTotal": true
                }
            }
        },
        "option": {
            "operation": {
                "unfold": true
            }
        }
    },
    "edit": {
        "primary": "id",
        "layout": {
            "fieldset": [{
                "columns": [{
                        "name": "SN",
                        "width": 6
                    },
                    {
                        "name": "Name",
                        "width": 6
                    },
                    {
                        "name": "Kind",
                        "width": 6
                    },
                    {
                        "name": "Score",
                        "width": 6
                    },
                    {
                        "name": "Description",
                        "width": 24
                    }
                ]
            }]
        },
        "actions": {
            "cancel": {},
            "save": {
                "type": "button",
                "props": {
                    "label": "Save"
                }
            },
            "delete": {
                "type": "button",
                "props": {
                    "label": "Delete"
                }
            }
        }
    }
}

回到菜單界面,把建好的書籍界面添加進去:

重新登錄系統,可以看到書籍界面:

寫在最後

可以看到,我們用 Yao 添加新內容時,基本都是在和 JSON 打交道,沒有涉及到代碼。所以對於需求不復雜的系統,使用低代碼引擎來開發或許是個不錯的選擇。

References

[1] Yao: https://github.com/YaoApp/yao

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章