Yao 折腾手记:如何快速创建一套管理系统

文章首发于个人公号:阿拉平平

有开发经验的小伙伴肯定知道,要独立开发一套管理系统并非易事。从设计数据库,到开发接口,再到编写前端页面,想想就让人头大。如果需求不是很复杂,我们可以借助低代码应用引擎来快速开发。

项目介绍

Yao[1] 是一款 Go 语言驱动的低代码应用引擎,通过编写 JSON 文件即可快速制作 API 接口,数据管理系统 ,命令行工具等应用程序,应用可以运行在本地、云端和物联网设备上。

快速安装

Yao 可以通过脚本或容器来安装,官方推荐后者,所以这里我们使用 Docker 来部署。

运行以下命令创建容器:

# 注意修改挂载的目录
docker run -d --name yao -v :/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://: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

版权声明:
作者:zhangchen
链接:https://www.techfm.club/p/46092.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>