ciyon_ai/aiskill/ciyon-数据字典设计.md
2026-04-15 17:28:46 +08:00

428 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ciyon 数据字典设计 Skill 文档
参考zc_cata表未指定新字典表则复用该表。
## 数据库表结构
### zc_cata 表定义
```sql
CREATE TABLE `zc_cata` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`upid` int(11) NOT NULL COMMENT '上级,DB,zc_cata',
`csort` int(11) NOT NULL DEFAULT 10 COMMENT '排序',
`isuse` int(11) NOT NULL DEFAULT 1 COMMENT '|行为|,BOOL',
`cbid` int(11) NOT NULL DEFAULT 0 COMMENT '库,DB,zc_cata',
`codeid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '值',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称',
`clas` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '样式类',
`extdata` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '使用表',
PRIMARY KEY (`id`) USING BTREE,
INDEX `cbid`(`cbid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12001701 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典表' ROW_FORMAT = Dynamic;
```
### 字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int(11) | 主键ID |
| upid | int(11) | 上级ID支持树形结构多级字典使用 |
| csort | int(11) | 排序字段 |
| isuse | int(11) | 是否启用1=启用2=禁用。是否使用开关。已被使用不能被删除,可操作关闭。关闭后前端组件不可选该字典项。|
| cbid | int(11) | cbid=0为字典集合cbid>0为某个字典的字典项集合 |
| codeid | varchar(20) | 字典集合的codeid为字典代码通常英文命名一般与列名相同。字典项集合的codeid一般为数字。 |
| name | varchar(30) | 显示名称 |
| clas | varchar(20) | 一般用于给前端元素标记class名**仅在前端页面需用不同颜色显示的情况设置样式类,其余不设置** |
| extdata | varchar(180) | 使用表列表,一行一个 |
### 字典项编号
一般从10开始编号
- 进行中过程一般设置10/20/30
- 失败一般设置90/91等
- 成功一般设置100
- 归档/完成等一般设置110/120等。
**重要规范**在前端选项卡筛选等场景中字典项标识应从1开始编号避免使用0。例如
- 变动类型10=类型120=类型230=类型3
- 数据状态1=公开2=订阅
### 数据组织结构
字典采用双层结构:
- **库层级**`cbid=0` 的记录为字典库
- **值层级**`cbid>0` 的记录为字典值,`cbid` 指向所属库的 `id`
示例数据:
```
id=10, cbid=0, codeid='sex', name='性别' → 字典库
id=1000, cbid=10, codeid='10', name='男' → 字典值
id=1001, cbid=10, codeid='20', name='女' → 字典值
```
## 字典类型
### 固定字典small data
**特点**
- 库和值都存储在 zc_cata 表中
- 支持多级树形结构(通过 upid
- 登录时自动加载到前端缓存
**适用场景**
- 数据量小(< 1000条
- 需要频繁修改
- 需要多级树形结构
**管理方式**
- 使用 `/web/admin/rigger/cataindex.php` 管理字典库
- 使用 `/web/admin/rigger/cata.php` 管理字典值
### 大数据量静态字典large data
**特点**
- 数据存储为独立的 JS 文件
- 按需加载减少初始加载时间
- PC端和移动端均可使用
**适用场景**
- 数据量大> 1000条
- 数据相对固定
- 不需要频繁修改
**文件格式**
```javascript
var ciy_arearpc=[
{"id":"110000","upid":"0","name":"北京市"},
{"id":"110100","upid":"110000","name":"市辖区"},
{"id":"110101","upid":"110100","name":"东城区"}
];
```
**文件位置**
- PC端`/web/ud/dict/`
- 移动端通过远程URL加载
## PC端实现
### 登录时加载字典
**后端接口**`/web/admin/login.php` 中的 `json_login()` 方法
```php
static function getsync($userrow, $oid = 0, $sid = '') {
// ... 认证代码 ...
$ret['storage'] = array();
$csql = new \ciy\sql('zc_cata');
$csql->order('csort,id');
$ret['storage']['cata'] = $db->get($csql); // 加载所有字典
// ... 其他数据 ...
return succjson($ret);
}
```
### 前端缓存字典
**前端函数**`/web/jscss/ciy.js` 中的 `savedict()` 函数
**存储格式**
- 键名:`cata_{codeid}`,例如:`cata_sex`
- 值格式:数组,每个元素包含 `id`, `name`, `upid`, `clas`, `isuse`
### 查询字典
**ccode** - 单值查询:
```javascript
// 根据id查询name
var name = ciyfn.ccode('sex', '10'); // 返回 '男'
// 查询其他字段
var item = ciyfn.ccode('sex', '10', '_obj'); // 返回完整对象
var clas = ciyfn.ccode('sex', '10', 'clas'); // 返回样式类
```
**scode** - 多值查询:
```javascript
var names = ciyfn.scode(sexArray, '10,20'); // 返回 ['男', '女']
```
**mcode** - 多级查询:
```javascript
// 查询从当前节点到根节点的所有名称
var path = ciyfn.mcode(areaArray, '110101'); // 返回 ['东城区', '市辖区', '北京市']
```
**bcode** - 位标记查询:
```javascript
// 假设使用位标记存储多个状态
var flags = ciyfn.bcode(statusArray, 5); // 5 = 1 + 4返回对应的状态数组
```
## 移动端实现
### 字典加载
**登录时加载**
```javascript
// /fapp/ciyon_ap/util/ciy.js
ciyfn.pageload(function () {
this.me = this.getme();
// 字典存储在 this.g 中
this.g = this.getstorage('g', {});
});
```
**设置字典**
```javascript
// 登录成功后
ciyfn.setstorage(ciy_vars.tokenfield, json.me);
if (json.storage)
ciyfn.savedict(json.storage);
```
### 字典查询
**在页面中使用**
```
<view>{{ccode(g.sex, sexcode)}}</view>
<ciy-select :range="g.sex" ></ciy-select>
```
```javascript
export default {
methods: {
getSexName(code) {
return this.ccode(this.g.sex, code);
}
}
}
```
**核心函数**
ccode(arr, value, field, nonestr) - 单值查询
scode(arr, ids, field) - 多值查询
mcode(arr, value, field) - 多级查询
### 按需加载静态字典
**加载函数**
```javascript
async load_ciydict(url) {}
```
**使用示例**
```javascript
// 按需加载地区字典
var [err, res] = await this.go(this.load_ciydict('/dict/ciy_arearpc.js'));
if (!err) {
this.g.arearpc = res.arr; // 存储到全局变量
}
```
## 字典管理
### 创建新字典库
**方式一:通过管理界面**
1. 访问 `/web/admin/rigger/cataindex.html`
2. 点击"批量添加"
3. 填写格式:
```
性别,sex
男,10
女,20
其他,90
```
**方式二直接SQL插入**
```sql
-- 插入库
INSERT INTO zc_cata (upid, csort, isuse, cbid, codeid, name)
VALUES (0, 10, 1, 0, 'education', '学历');
-- 获取库ID假设为102
-- 插入库值
INSERT INTO zc_cata (upid, csort, isuse, cbid, codeid, name, clas)
VALUES
(0, 10, 1, 102, '10', '小学', ''),
(0, 20, 1, 102, '20', '初中', ''),
(0, 30, 1, 102, '30', '高中', '');
```
### 管理字典值
**访问字典管理页面**
```
/web/admin/rigger/cata.html?cbid=10
```
**支持的URL参数**
- `cbid`: 字典库ID
- `issub=yes`: 支持子码
- `ismulti=yes`: 支持批量添加
- `ext=扩展名`: 显示扩展字段
### 字典刷新
当字典数据变更后,需要刷新前端缓存:
**方式一:管理界面刷新**
- 访问字典管理页面,点击"刷新缓存"按钮
**方式二API刷新**
```
POST /web/admin/login.php
参数: action=restorage
```
## AI生成字典和代码的指导原则
### 生成固定字典的步骤
**步骤一:定义库**
```sql
INSERT INTO zc_cata (upid, csort, isuse, cbid, codeid, name, extdata)
VALUES (0, 10, 1, 0, 'orderstatus', '订单状态', 'ap_order');
```
**步骤二:定义值**
```sql
INSERT INTO zc_cata (upid, csort, isuse, cbid, codeid, name, clas)
VALUES
(0, 10, 1, [ID], '10', '待支付', 'def'),
(0, 20, 1, [ID], '20', '已支付', 'warn'),
(0, 30, 1, [ID], '30', '已发货', 'man'),
(0, 100, 1, [ID], '100', '已完成', 'succ');
```
- **开关类字段**:如是否启用、是否公开等,直接使用数据库字段存储,不需要定义为字典
**步骤三:定义哪些表使用了该字典**
extdata表名1.不相同的字段名\n表名2\n表名3
删除字典项时,检索每个表的字段是否已引用。已引用的禁止删除。
**步骤四:前端使用**
```javascript
// 查询单个值
var name = ciyfn.ccode('orderstatus', '10'); // '待支付'
// 查询带样式
var item = ciyfn.ccode('orderstatus', '10', '_obj'); // {id:'10', name:'待支付', clas:'def'}
```
### 生成业务代码的规范
**表字段设计**
```sql
CREATE TABLE ap_order (
id INT PRIMARY KEY,
orderstatus INT COMMENT '订单状态,CATA,orderstatus',
-- ...
);
```
**前端展示**
```vue
<template>
<view>
<text>{{ ccode(g.orderstatus, order.orderstatus) }}</text>
</view>
</template>
<script>
export default {
data() {
return {
order: { orderstatus: '10' }
}
}
}
</script>
```
### 代码生成检查清单
生成字典相关代码时,必须检查:
- [ ] 字典库是否已创建cbid=0 的记录)
- [ ] 字典值是否已插入cbid 指向库ID
- [ ] extdata 是否定义了引用表(如需要)
- [ ] clas 字段是否根据字典类型合理设置(前端需用不同颜色显示时设置样式,其余不设置)
- [ ] isuse 字段是否设置为1启用
- [ ] 前端是否正确调用 ccode/scode/mcode/bcode
- [ ] 修改字典后是否刷新了缓存
## 常见问题
**问题一:哪些场景不适合使用字典?**
**答案**:
- 需要用户自主设置的类型/状态,不适合
- 开关类字段(如是否启用、是否公开等),直接使用数据库字段存储,不需要定义为字典
**问题二:字典修改后为什么前端没有更新?**
**答案**: 需要刷新缓存:
控制台右上角 点击"刷新缓存"按钮
**问题三:如何支持多级字典?**
**答案**: 使用 `upid` 字段:
```sql
-- 一级:省
INSERT INTO zc_cata VALUES (..., 0, ..., '110000', '北京市');
-- 二级:市
INSERT INTO zc_cata VALUES (..., [ID], ..., '110100', '市辖区');
-- 三级:区
INSERT INTO zc_cata VALUES (..., [ID], ..., '110101', '东城区');
```
查询多级路径:
```javascript
var path = ciyfn.mcode('area', '110101'); // ['东城区', '市辖区', '北京市']
```
**问题四:如何在移动端使用字典?**
**答案**:
1. 登录后字典自动加载到 `this.g`
2. 在页面中直接使用 `this.ccode()`
3. 大数据量字典使用 `this.load_ciydict()` 按需加载
## 附录
### 样式类说明
| clas | 说明 | 颜色 |
|------|------|------|
| dag | 失败 | 红色 |
| warn | 警告 | 橙色 |
| succ | 成功 | 绿色 |
| def | 灰色 | 灰色 |
| man | 主色 | 蓝色 |
### 核心函数速查
| 函数 | 平台 | 说明 |
|------|------|------|
| ccode(arr, value, field, nonestr) | 全 | 单值查询 |
| scode(arr, ids, field) | 全 | 多值查询 |
| mcode(arr, value, field) | 全 | 多级查询 |
| bcode(arr, value, field) | 全 | 位标记查询 |
---
**文档版本**: v1.0
**更新日期**: 2026-03-20
**维护者**: ciyon开发团队