# 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=类型1,20=类型2,30=类型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);
```
### 字典查询
**在页面中使用**:
```
{{ccode(g.sex, sexcode)}}
```
```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
{{ ccode(g.orderstatus, order.orderstatus) }}
```
### 代码生成检查清单
生成字典相关代码时,必须检查:
- [ ] 字典库是否已创建(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开发团队