This commit is contained in:
yumoqing 2026-01-29 16:05:25 +08:00
parent e73f56ba33
commit 343d3af680
7 changed files with 30 additions and 209 deletions

View File

@ -1,4 +1,3 @@
<<<<<<< HEAD
# 支持CRUD # 支持CRUD
用一个json文件定义一张数据表的增删改查操作框架支持两种显示形式的crud 树形表和列表表的crud 用一个json文件定义一张数据表的增删改查操作框架支持两种显示形式的crud 树形表和列表表的crud

View File

@ -1,39 +0,0 @@
## 模块目录结构
模块名称为“mymodule", 以下为mymodule模块的目录文件结构
```
mymodule
+--mymodule # 存放模块的主要逻辑py代码
+--init.py # 模块初始化脚本需要定义一个load_mymodule()函数此函数将在ui和dspy文件中用到的模块变量通过ServerEnv实例传过去
+--__init__.py #python模块所需
|
| +--其他源码.py # 模块中需要的其他py源码文件
+--wwwroot # 目录,存放以.ui和.dspy结束的文件ui文件支持jinja2模板前端控件文件内容为json格式的控件描述文本 dspy是ahserver支持的受限python脚本可以按照需要设置下级目录
+--models # 存放数据表文件的目录
+--json # 存放CRUD描述文件的目录
+--pyproject.toml # pip打包文件, 其中项目名字与mymodule相同
+--README.md # 模块自说明文件
+--init # 模块初始化目录
+--data.json # 初始化数据一个sheet一个表一行一个记录第一行为字>段名
+--script.py # 初始化脚本
```
data.json内容
{
"tablename": # 数据表名
[ # 初始数据
{
"fieldname": value #字段名和值
......
}
]
}

View File

@ -1,8 +1,8 @@
# 模块开发规范 # 模块开发规范
假设需开发的模块名为“mymodule” 模块包括完成特定功能的前后台代码,符合[ahserver](https://git.opencomputing.cn/yumoqing/ahserver)+[sqlor](https://git.opencomputing.cn/yumoqing/sqlor)+[bricks](https://git.opencomputing.cn/yumoqing/bricks)技术路线的B/S架构
一个模块如果使用数据库存储数据则需要按照数据表规范生成数据表和相应的crud定义 假设需开发的模块名为“mymodule”
## 模块目录结构 ## 模块目录结构
``` ```
@ -14,11 +14,11 @@
| |
| +--其他源码.py # 模块中需要的其他py源码文件 | +--其他源码.py # 模块中需要的其他py源码文件
+--wwwroot目录 # web服务脚本文件以.ui和.dspy结束ui文件支持jinja2模>板前端控件文件内容为json格式的控件描述文本 dspy是ahserver支持的受限python脚本>,可以按照需要设置下级目录 +--wwwroot目录 # 前后台脚本,文件以.ui和.dspy结束ui文件是bricks控件的json文件支持jinja2模板dspy是ahserver支持的受限python脚本,可以按照需要设置下级目录
+--models目录 # 模块使用的数据表以.xlsx后缀存放在此目录中 +--models目录 # 模块使用的数据表以“表名.json”为文件名存放在此目录中
+--json目录 # 存放json文件定义数据表的CRUD逻辑 +--json目录 # CRUD描述文件以“表名或别名.json”为文件名
+--pyproject.toml文件 # pip打包文件, 其中项目名字与mymodule相同 +--pyproject.toml文件 # pip打包文件, 其中项目名字与mymodule相同
@ -31,7 +31,9 @@
+--script.py # 初始化脚本 +--script.py # 初始化脚本
``` ```
## mymodule/init.py的主要内容 ## 核心代码
模块的核心代码保存在mymodule目录下init.py是每个模块都需要的, init.py中定义一个load_`mymodule`函数如pricing模块为load_pricing()accounting模块为load_accounting()在此模块中做初始化模块并把模块的核心代码通过ServerEnv()发布给应用的脚本使用, 以下为例子
``` ```
from ahserver.serverenv import ServerEnv from ahserver.serverenv import ServerEnv
from appPublic.worker import awaitify from appPublic.worker import awaitify
@ -46,25 +48,16 @@ def load_mymodule(): # mymodule需替换为实际的模块名字
env.y = awaitify(y) # 将函数包装为协程 env.y = awaitify(y) # 将函数包装为协程
env.x = awaitify(x) # 将函数包装为协程 env.x = awaitify(x) # 将函数包装为协程
``` ```
注释这里的load_mymodule中的mymodule是模块名字而不是“mymodule”本身 数据库表操作需要符合[sqlor数据库操作规范](sqlor.md)
## mymodule/*.py ## 数据库表设计
[数据库表设计规范](table.md)
模块中的主要逻辑用py源码 ## 数据表的CRUD
## models/*.json
每个数据表一个文件,存放按照数据表定义规范生成的数据表定义
## json/*.json
为数据表定义crud功能 每个表至少一个 为数据表定义crud功能 每个表至少一个
## wwwroot/*.ui ## 初始化数据
模块前端ui代码文件内容遵守json格式要求支持jinja2模板 init/data.json
## wwwroot/*.dspy
模块后端脚本代码
## init/data.json
文件保存需要初始化的数据,格式如下 文件保存需要初始化的数据,格式如下
{ {
"table1":[ "table1":[
@ -80,34 +73,7 @@ def load_mymodule(): # mymodule需替换为实际的模块名字
] ]
} }
## init/script.py ### 模块中使用的编码
脚本主要任务是将init/data.json中的数据导入到数据库中
* 客户端业务功能放在wwwroot目录下以.ui和.dspy后缀结束用.ui文件遵守jinja2规范, 而.dspy文件是一个受控的脚本
* 返回客户端数据的功能放在wwwroot目录下以.dspy后缀结束
## ui, dspy可以直接使用的变量
### request
aiohttp.Request实例每个客户端请求有一个独立的Request实例
request._run_ns可以获得所有在.ui和.dspy源码中可以使用的变量通过ahserver.ServerEnv 传递
### params_kw
DictObjectdict子类, 支持a.b方式获取属性实例接收到客户端传来的数据如果有文件>文件都保存在服务器指定的位置params_kw中属性名保存的是其相对路径可用FileStorage().realPath(params_kw.myfile)来获得文件在服务器中的实际路径。
### get_user()
来自rbac模块协程函数获得当前登录用户如果用户没有登录返回None
### get_userorgid()
来自rbac模块协程函数获得当前登录用户的机构id如果用户没有登录返回None
## pyproject.toml和README.md
编写pyproject.toml文件和README.md文件
## 模块中使用的编码
模块中如果用到编码编码需保存在appbase模块的appcodes表和appcodes_kv两个表中 模块中如果用到编码编码需保存在appbase模块的appcodes表和appcodes_kv两个表中
appcodes(编码表)有如下字段: appcodes(编码表)有如下字段:
[ [
@ -122,3 +88,16 @@ appcodes_kv编码键值表字段如下
“k" # str 32, 编码值 “k" # str 32, 编码值
“v” “ str 255,编码显示文本 “v” “ str 255,编码显示文本
] ]
## 前后台脚本
本模块用到的脚本以及资源都放在这个目录下,以.ui和.dspy后缀结束用.ui文件遵守jinja2规范, 而.dspy文件是一个受控的脚本
脚本中可以直接使用的变量,请看[脚本中可以使用的变量列表](variable.md)
## 工程文件
### pyproject.toml文件
python模块打包控制文件
### README.md文件
模块说明文件

View File

@ -1,71 +0,0 @@
## 要求
* 模块中的主要逻辑用py源码实现放在mymodule目录下
* 客户端业务功能放在wwwroot目录下以.ui和.dspy后缀结束用.ui文件遵守jinja2规范, 而.dspy文件是一个受控的脚本
* .dspy中不允许import模块
* 假设模块名为”mymodule“
## mymodule目录
“mymodule”为模块名称 模块目录下存放以py结束的代码文件其中init.py文件为必须
在此目录下的代码中可以通过ahserver.serverenv模块的ServerEnv来引用其他模块的放进来的变量
### init.py的主要内容
```
from ahserver.serverenv import ServerEnv
from appPublic.worker import awaitify
from .x import a, b, c # 从同目录下的源码x.py中import ab, c是协程
from .y import x, y # 从同目录下源码y.py中import x, y是普通函数
def load_mymodule(): # mymodule需替换为实际的模块名字
env = ServerEnv()
env.a = a # 脚本中用"a" 调用"a"
env.b = b # 脚本中用"b"调用"b"
env.cc = c # 脚本中用"cc"调用"c"
env.y = awaitify(y) # 将函数包装为协程
env.x = awaitify(x) # 将函数包装为协程
```
注释这里的load_mymodule中的mymodule是模块名字而不是“mymodule”本身
模块的其他代码都需要放在这个目录中而模块中所有需要在uidspy脚本中用到的变量均需要通过init.py函数的load_mymodule()函数传递
## ui, dspy可以直接使用的变量
### request
aiohttp.Request实例每个客户端请求有一个独立的Request实例
request._run_ns可以获得所有在.ui和.dspy源码中可以使用的变量通过ahserver.ServerEnv 传递
### params_kw
DictObjectdict子类, 支持a.b方式获取属性实例接收到客户端传来的数据如果有文件>文件都保存在服务器指定的位置params_kw中属性名保存的是其相对路径可用FileStorage().realPath(params_kw.myfile)来获得文件在服务器中的实际路径。
### get_user()
来自rbac模块协程函数获得当前登录用户如果用户没有登录返回None
### get_userorgid()
来自rbac模块协程函数获得当前登录用户的机构id如果用户没有登录返回None
### 各个模块通过load_xxxx()放到ServerEnv()中的变量
XXXX是模块名称
## pyproject.toml和README.md
编写pyproject.toml文件和README.md文件
## 模块中使用的编码
模块中如果用到编码编码需保存在appbase模块的appcodes表和appcodes_kv两个表中
appcodes(编码表)有如下字段:
[
"id" # str 32 主键,可设置为数据表字段名称
"name" # 编码名称
"hierarchy_flg", # str 1, '0':单级编码“1”:多级编码
]
appcodes_kv编码键值表字段如下
[
"id", # str, 32,主键,唯一值
"parentid" # str, 32, 一级编码为appcodes表的id, 否则为上级编码键值记录的id
“k" # str 32, 编码值
“v” “ str 255,编码显示文本
]

View File

@ -58,3 +58,5 @@ id字段全部使用str 32类型
* 文件名:"xxxx.json", 其中"xxxx"为数据表名 * 文件名:"xxxx.json", 其中"xxxx"为数据表名
## 数据库表文件保存
每个表一个json文件保存在模块目录的models目录下命名规则为"表名.json"

View File

@ -1,49 +0,0 @@
## 数据库表定义规范
模块中需要定义数据表要遵守一下规范
数据库表用一个json格式文件或数据来定义具体规范如下
{
"summary":[ # 仅一条记录
{
"name" # 表名
"title" # 表标题
"primary" # 主键=“id”, 所有表均以id为主键
"catelog" # 可选项entity relation dimession indication
}
],
"fields":[ # 字段
{
"name"
"title"
"type" #可选项有str char short long llong date time timestamp float double ddouble decimal text
"length"
"dec"
"nullable" # 可选项yes no
"default"
"comments" # 注释
}
]
"indexes":[
{
"name" # 每个索引一个idxname不能重复一个表中
"idxtype" # unique or index
"idxfields" # 字段名或字段名数组[f1,f1]
}
]
“codes":[ # 如果一个字段数据可以从其他表中获得,可以通过下面的模式定义选择输入逻
{
"field" # 字段的名字
"table" # 数据来源表
"valuefield" # 数据来源表值字段
"textfield" # 数据来源表显示字段
"cond" # 检索条件
}
]
]
说明:
id字段全部使用str 32类型
字典中的length如果type是str char float double ddouble decimal中的一个则必为>0的>数字
字典中的dec: 如果type是float double ddouble decimal中的一个则必须是>0的数字