@befly-addon/admin 1.1.29 → 1.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/apis/admin/cacheRefresh.ts +1 -4
  2. package/apis/admin/del.ts +4 -4
  3. package/apis/admin/detail.ts +8 -40
  4. package/apis/admin/ins.ts +21 -14
  5. package/apis/admin/list.ts +3 -3
  6. package/apis/admin/upd.ts +43 -8
  7. package/apis/api/all.ts +7 -3
  8. package/apis/api/list.ts +8 -17
  9. package/apis/auth/login.ts +19 -16
  10. package/apis/dict/all.ts +21 -4
  11. package/apis/dict/del.ts +7 -15
  12. package/apis/dict/detail.ts +28 -14
  13. package/apis/dict/ins.ts +34 -16
  14. package/apis/dict/items.ts +27 -0
  15. package/apis/dict/list.ts +30 -5
  16. package/apis/dict/upd.ts +51 -17
  17. package/apis/dictType/all.ts +11 -0
  18. package/apis/dictType/del.ts +32 -0
  19. package/apis/dictType/detail.ts +17 -0
  20. package/apis/dictType/ins.ts +30 -0
  21. package/apis/dictType/list.ts +24 -0
  22. package/apis/dictType/upd.ts +42 -0
  23. package/apis/email/logList.ts +2 -2
  24. package/apis/loginLog/list.ts +2 -2
  25. package/apis/menu/all.ts +1 -2
  26. package/apis/menu/list.ts +0 -1
  27. package/apis/operateLog/list.ts +2 -2
  28. package/apis/role/apiSave.ts +4 -3
  29. package/apis/role/{apiDetail.ts → apis.ts} +8 -3
  30. package/apis/role/del.ts +18 -10
  31. package/apis/role/detail.ts +0 -1
  32. package/apis/role/menuSave.ts +4 -3
  33. package/apis/role/{menuDetail.ts → menus.ts} +8 -3
  34. package/apis/role/save.ts +2 -3
  35. package/apis/sysConfig/all.ts +0 -1
  36. package/apis/sysConfig/del.ts +1 -1
  37. package/apis/sysConfig/get.ts +1 -2
  38. package/apis/sysConfig/upd.ts +1 -1
  39. package/package.json +3 -3
  40. package/tables/admin.json +0 -6
  41. package/tables/dict.json +13 -19
  42. package/tables/dictType.json +28 -0
  43. package/views/config/dict/components/edit.vue +76 -122
  44. package/views/config/dict/index.vue +76 -54
  45. package/views/config/dict/meta.json +1 -1
  46. package/views/config/dictType/components/edit.vue +106 -0
  47. package/views/config/dictType/index.vue +206 -0
  48. package/views/config/dictType/meta.json +4 -0
  49. package/views/login_1/index.vue +184 -2
  50. package/views/people/admin/components/edit.vue +5 -5
  51. package/views/permission/role/components/api.vue +3 -3
  52. package/views/permission/role/components/menu.vue +4 -4
  53. package/apis/admin/roleDetail.ts +0 -29
  54. package/apis/admin/roleSave.ts +0 -39
  55. package/apis/auth/logout.ts +0 -17
  56. package/apis/auth/register.ts +0 -43
  57. package/apis/dashboard/changelog.ts +0 -31
  58. package/views/login_1/components/emailLoginForm.vue +0 -174
  59. package/views/login_1/components/registerForm.vue +0 -175
  60. package/views/login_1/components/welcomePanel.vue +0 -61
package/apis/dict/upd.ts CHANGED
@@ -2,29 +2,63 @@
2
2
 
3
3
  export default {
4
4
  name: '更新字典',
5
- fields: adminDictTable,
5
+ fields: {
6
+ ...adminDictTable,
7
+ '@id': true
8
+ },
9
+ required: ['id'],
6
10
  handler: async (befly, ctx) => {
7
- try {
8
- await befly.db.updData({
11
+ const { id, typeCode, key, label, sort, remark } = ctx.body;
12
+
13
+ // 如果更新了 typeCode,验证其是否存在
14
+ if (typeCode) {
15
+ const dictType = await befly.db.getOne({
16
+ table: 'addon_admin_dict_type',
17
+ where: { code: typeCode }
18
+ });
19
+
20
+ if (!dictType?.id) {
21
+ return befly.tool.No('字典类型不存在');
22
+ }
23
+ }
24
+
25
+ // 如果更新了 typeCode 或 key,检查唯一性
26
+ if (typeCode || key) {
27
+ const current = await befly.db.getOne({
28
+ table: 'addon_admin_dict',
29
+ where: { id: id }
30
+ });
31
+
32
+ const checkTypeCode = typeCode || current?.typeCode;
33
+ const checkKey = key || current?.key;
34
+
35
+ const existing = await befly.db.getOne({
9
36
  table: 'addon_admin_dict',
10
- data: {
11
- name: ctx.body.name,
12
- code: ctx.body.code,
13
- value: ctx.body.value,
14
- sort: ctx.body.sort,
15
- pid: ctx.body.pid,
16
- description: ctx.body.description,
17
- state: ctx.body.state
18
- },
19
37
  where: {
20
- id: ctx.body.id
38
+ typeCode: checkTypeCode,
39
+ key: checkKey,
40
+ id$ne: id
21
41
  }
22
42
  });
23
43
 
24
- return befly.tool.Yes('操作成功');
25
- } catch (error) {
26
- befly.logger.error({ err: error }, '更新字典失败');
27
- return befly.tool.No('操作失败');
44
+ if (existing?.id) {
45
+ return befly.tool.No('该类型下已存在相同的键名');
46
+ }
28
47
  }
48
+
49
+ const updateData: Record<string, any> = {};
50
+ if (typeCode !== undefined) updateData.typeCode = typeCode;
51
+ if (key !== undefined) updateData.key = key;
52
+ if (label !== undefined) updateData.label = label;
53
+ if (sort !== undefined) updateData.sort = sort;
54
+ if (remark !== undefined) updateData.remark = remark;
55
+
56
+ await befly.db.updData({
57
+ table: 'addon_admin_dict',
58
+ data: updateData,
59
+ where: { id: id }
60
+ });
61
+
62
+ return befly.tool.Yes('更新成功');
29
63
  }
30
64
  };
@@ -0,0 +1,11 @@
1
+ export default {
2
+ name: '获取所有字典类型',
3
+ handler: async (befly, ctx) => {
4
+ const result = await befly.db.getAll({
5
+ table: 'addon_admin_dict_type',
6
+ orderBy: ['sort#ASC', 'id#ASC']
7
+ });
8
+
9
+ return befly.tool.Yes('操作成功', { lists: result.lists });
10
+ }
11
+ };
@@ -0,0 +1,32 @@
1
+ export default {
2
+ name: '删除字典类型',
3
+ fields: { '@id': true },
4
+ required: ['id'],
5
+ handler: async (befly, ctx) => {
6
+ const { id } = ctx.body;
7
+
8
+ // 检查是否有字典项引用此类型
9
+ const dictItems = await befly.db.getOne({
10
+ table: 'addon_admin_dict',
11
+ where: {
12
+ typeCode: (
13
+ await befly.db.getOne({
14
+ table: 'addon_admin_dict_type',
15
+ where: { id: id }
16
+ })
17
+ )?.code
18
+ }
19
+ });
20
+
21
+ if (dictItems?.id) {
22
+ return befly.tool.No('该类型下存在字典项,无法删除');
23
+ }
24
+
25
+ await befly.db.delData({
26
+ table: 'addon_admin_dict_type',
27
+ where: { id: id }
28
+ });
29
+
30
+ return befly.tool.Yes('删除成功');
31
+ }
32
+ };
@@ -0,0 +1,17 @@
1
+ export default {
2
+ name: '字典类型详情',
3
+ fields: { '@id': true },
4
+ required: ['id'],
5
+ handler: async (befly, ctx) => {
6
+ const detail = await befly.db.getDetail({
7
+ table: 'addon_admin_dict_type',
8
+ where: { id: ctx.body.id }
9
+ });
10
+
11
+ if (!detail?.id) {
12
+ return befly.tool.No('字典类型不存在');
13
+ }
14
+
15
+ return befly.tool.Yes('获取成功', detail);
16
+ }
17
+ };
@@ -0,0 +1,30 @@
1
+ import dictTypeTable from '../../tables/dictType.json';
2
+
3
+ export default {
4
+ name: '添加字典类型',
5
+ fields: dictTypeTable,
6
+ required: ['code', 'name'],
7
+ handler: async (befly, ctx) => {
8
+ // 检查代码是否已存在
9
+ const existing = await befly.db.getOne({
10
+ table: 'addon_admin_dict_type',
11
+ where: { code: ctx.body.code }
12
+ });
13
+
14
+ if (existing?.id) {
15
+ return befly.tool.No('类型代码已存在');
16
+ }
17
+
18
+ const typeId = await befly.db.insData({
19
+ table: 'addon_admin_dict_type',
20
+ data: {
21
+ code: ctx.body.code,
22
+ name: ctx.body.name,
23
+ description: ctx.body.description,
24
+ sort: ctx.body.sort
25
+ }
26
+ });
27
+
28
+ return befly.tool.Yes('添加成功', { id: typeId });
29
+ }
30
+ };
@@ -0,0 +1,24 @@
1
+ import dictTypeTable from '../../tables/dictType.json';
2
+
3
+ export default {
4
+ name: '获取字典类型列表',
5
+ fields: {
6
+ page: '@page',
7
+ limit: '@limit',
8
+ keyword: '@keyword',
9
+ state: '@state'
10
+ },
11
+ handler: async (befly, ctx) => {
12
+ const result = await befly.db.getList({
13
+ table: 'addon_admin_dict_type',
14
+ where: {
15
+ name$like: ctx.body.keyword ? `%${ctx.body.keyword}%` : undefined
16
+ },
17
+ orderBy: ['sort#ASC', 'id#ASC'],
18
+ page: ctx.body.page,
19
+ limit: ctx.body.limit
20
+ });
21
+
22
+ return befly.tool.Yes('操作成功', result);
23
+ }
24
+ };
@@ -0,0 +1,42 @@
1
+ import dictTypeTable from '../../tables/dictType.json';
2
+
3
+ export default {
4
+ name: '更新字典类型',
5
+ fields: {
6
+ ...dictTypeTable,
7
+ '@id': true
8
+ },
9
+ required: ['id'],
10
+ handler: async (befly, ctx) => {
11
+ const { id, code, name, description, sort } = ctx.body;
12
+
13
+ // 如果更新了 code,需要检查是否已被使用
14
+ if (code) {
15
+ const existing = await befly.db.getOne({
16
+ table: 'addon_admin_dict_type',
17
+ where: {
18
+ code: code,
19
+ id$ne: id
20
+ }
21
+ });
22
+
23
+ if (existing?.id) {
24
+ return befly.tool.No('类型代码已被使用');
25
+ }
26
+ }
27
+
28
+ const updateData: Record<string, any> = {};
29
+ if (code !== undefined) updateData.code = code;
30
+ if (name !== undefined) updateData.name = name;
31
+ if (description !== undefined) updateData.description = description;
32
+ if (sort !== undefined) updateData.sort = sort;
33
+
34
+ await befly.db.updData({
35
+ table: 'addon_admin_dict_type',
36
+ data: updateData,
37
+ where: { id: id }
38
+ });
39
+
40
+ return befly.tool.Yes('更新成功');
41
+ }
42
+ };
@@ -9,8 +9,8 @@ export default {
9
9
  handler: async (befly, ctx) => {
10
10
  const result = await befly.db.getList({
11
11
  table: 'addon_admin_email_log',
12
- page: ctx.body.page || 1,
13
- limit: ctx.body.limit || 30,
12
+ page: ctx.body.page,
13
+ limit: ctx.body.limit,
14
14
  orderBy: ['sendTime#DESC']
15
15
  });
16
16
 
@@ -9,8 +9,8 @@ export default {
9
9
  handler: async (befly, ctx) => {
10
10
  const result = await befly.db.getList({
11
11
  table: 'addon_admin_login_log',
12
- page: ctx.body.page || 1,
13
- limit: ctx.body.limit || 30,
12
+ page: ctx.body.page,
13
+ limit: ctx.body.limit,
14
14
  orderBy: ['loginTime#DESC']
15
15
  });
16
16
 
package/apis/menu/all.ts CHANGED
@@ -17,7 +17,7 @@ export default {
17
17
  where: { code: ctx.user.roleCode }
18
18
  });
19
19
 
20
- if (!role) {
20
+ if (!role?.id) {
21
21
  return befly.tool.No('角色不存在', { lists: [] });
22
22
  }
23
23
 
@@ -38,7 +38,6 @@ export default {
38
38
  if (allMenus.length === 0) {
39
39
  const result = await befly.db.getAll({
40
40
  table: 'addon_admin_menu',
41
- fields: ['id', 'pid', 'name', 'path', 'sort'],
42
41
  orderBy: ['sort#ASC', 'id#ASC']
43
42
  });
44
43
  allMenus = result.lists;
package/apis/menu/list.ts CHANGED
@@ -10,7 +10,6 @@
10
10
  try {
11
11
  const menus = await befly.db.getAll({
12
12
  table: 'addon_admin_menu',
13
- fields: ['*'],
14
13
  orderBy: ['sort#ASC', 'id#ASC']
15
14
  });
16
15
 
@@ -9,8 +9,8 @@ export default {
9
9
  handler: async (befly, ctx) => {
10
10
  const result = await befly.db.getList({
11
11
  table: 'addon_admin_operate_log',
12
- page: ctx.body.page || 1,
13
- limit: ctx.body.limit || 30,
12
+ page: ctx.body.page,
13
+ limit: ctx.body.limit,
14
14
  orderBy: ['operateTime#DESC']
15
15
  });
16
16
 
@@ -3,16 +3,17 @@
3
3
  export default {
4
4
  name: '保存角色接口权限',
5
5
  fields: {
6
+ roleCode: adminRoleTable.code,
6
7
  apiIds: adminRoleTable.apis
7
8
  },
8
9
  handler: async (befly, ctx) => {
9
10
  // 查询角色是否存在
10
11
  const role = await befly.db.getOne({
11
12
  table: 'addon_admin_role',
12
- where: { id: ctx.body.roleId }
13
+ where: { code: ctx.body.roleCode }
13
14
  });
14
15
 
15
- if (!role) {
16
+ if (!role?.id) {
16
17
  return befly.tool.No('角色不存在');
17
18
  }
18
19
 
@@ -22,7 +23,7 @@ export default {
22
23
  // 更新角色的接口权限
23
24
  await befly.db.updData({
24
25
  table: 'addon_admin_role',
25
- where: { id: ctx.body.roleId },
26
+ where: { code: ctx.body.roleCode },
26
27
  data: {
27
28
  apis: apiIdsStr
28
29
  }
@@ -1,13 +1,18 @@
1
- export default {
1
+ import adminRoleTable from '../../tables/role.json';
2
+
3
+ export default {
2
4
  name: '获取角色接口权限',
5
+ fields: {
6
+ roleCode: adminRoleTable.code
7
+ },
3
8
  handler: async (befly, ctx) => {
4
9
  // 查询角色信息
5
10
  const role = await befly.db.getOne({
6
11
  table: 'addon_admin_role',
7
- where: { id: ctx.body.roleId }
12
+ where: { code: ctx.body.roleCode }
8
13
  });
9
14
 
10
- if (!role) {
15
+ if (!role?.id) {
11
16
  return befly.tool.No('角色不存在');
12
17
  }
13
18
 
package/apis/role/del.ts CHANGED
@@ -6,21 +6,31 @@
6
6
  handler: async (befly, ctx) => {
7
7
  try {
8
8
  // 检查是否有用户使用此角色(使用 getList 代替 getAll)
9
+ const role = await befly.db.getOne({
10
+ table: 'addon_admin_role',
11
+ where: { id: ctx.body.id },
12
+ fields: ['code']
13
+ });
14
+
15
+ if (!role?.code) {
16
+ return befly.tool.No('角色不存在');
17
+ }
18
+
19
+ // 禁止删除系统角色
20
+ const systemRoles = ['dev', 'user', 'admin', 'guest'];
21
+ if (systemRoles.includes(role.code)) {
22
+ return befly.tool.No(`系统角色 [${role.code}] 不允许删除`);
23
+ }
24
+
9
25
  const adminList = await befly.db.getList({
10
26
  table: 'addon_admin_admin',
11
- where: { roleId: ctx.body.id }
27
+ where: { roleCode: role.code }
12
28
  });
13
29
 
14
30
  if (adminList.total > 0) {
15
31
  return befly.tool.No('该角色已分配给用户,无法删除');
16
32
  }
17
33
 
18
- // 获取角色信息(用于删除缓存)
19
- const role = await befly.db.getDetail({
20
- table: 'addon_admin_role',
21
- where: { id: ctx.body.id }
22
- });
23
-
24
34
  // 删除角色
25
35
  await befly.db.delData({
26
36
  table: 'addon_admin_role',
@@ -28,9 +38,7 @@
28
38
  });
29
39
 
30
40
  // 删除角色权限缓存
31
- if (role?.code) {
32
- await befly.cache.deleteRolePermissions(befly, role.code);
33
- }
41
+ await befly.cache.deleteRolePermissions(befly, role.code);
34
42
 
35
43
  return befly.tool.Yes('操作成功');
36
44
  } catch (error: any) {
@@ -13,7 +13,6 @@
13
13
  }
14
14
 
15
15
  return befly.tool.Yes('操作成功', {
16
- roleId: ctx.body.id,
17
16
  roleCode: ctx.body.id,
18
17
  role: roleInfo
19
18
  });
@@ -3,16 +3,17 @@
3
3
  export default {
4
4
  name: '保存角色菜单权限',
5
5
  fields: {
6
+ roleCode: adminRoleTable.code,
6
7
  menuIds: adminRoleTable.menus
7
8
  },
8
9
  handler: async (befly, ctx) => {
9
10
  // 查询角色是否存在
10
11
  const role = await befly.db.getOne({
11
12
  table: 'addon_admin_role',
12
- where: { id: ctx.body.roleId }
13
+ where: { code: ctx.body.roleCode }
13
14
  });
14
15
 
15
- if (!role) {
16
+ if (!role?.id) {
16
17
  return befly.tool.No('角色不存在');
17
18
  }
18
19
 
@@ -22,7 +23,7 @@ export default {
22
23
  // 更新角色的菜单权限
23
24
  await befly.db.updData({
24
25
  table: 'addon_admin_role',
25
- where: { id: ctx.body.roleId },
26
+ where: { code: ctx.body.roleCode },
26
27
  data: {
27
28
  menus: menuIdsStr
28
29
  }
@@ -1,13 +1,18 @@
1
- export default {
1
+ import adminRoleTable from '../../tables/role.json';
2
+
3
+ export default {
2
4
  name: '获取角色菜单权限',
5
+ fields: {
6
+ roleCode: adminRoleTable.code
7
+ },
3
8
  handler: async (befly, ctx) => {
4
9
  // 查询角色信息
5
10
  const role = await befly.db.getOne({
6
11
  table: 'addon_admin_role',
7
- where: { id: ctx.body.roleId }
12
+ where: { code: ctx.body.roleCode }
8
13
  });
9
14
 
10
- if (!role) {
15
+ if (!role?.id) {
11
16
  return befly.tool.No('角色不存在');
12
17
  }
13
18
 
package/apis/role/save.ts CHANGED
@@ -17,19 +17,18 @@
17
17
  where: { code: ctx.body.roleCode }
18
18
  });
19
19
 
20
- if (!role) {
20
+ if (!role?.id) {
21
21
  return befly.tool.No('角色不存在');
22
22
  }
23
23
 
24
24
  // 根据角色编码判断角色类型(硬编码规则)
25
25
  const roleType = role.code === 'dev' || role.code === 'admin' ? 'admin' : 'user';
26
26
 
27
- // 更新管理员的角色ID、角色编码和角色类型
27
+ // 更新管理员的角色编码和角色类型
28
28
  await befly.db.updData({
29
29
  table: 'addon_admin_admin',
30
30
  where: { id: ctx.body.adminId },
31
31
  data: {
32
- roleId: role.id,
33
32
  roleCode: role.code,
34
33
  roleType: roleType
35
34
  }
@@ -3,7 +3,6 @@ export default {
3
3
  handler: async (befly, ctx) => {
4
4
  const result = await befly.db.getAll({
5
5
  table: 'addon_admin_sys_config',
6
- fields: ['*'],
7
6
  orderBy: ['id#ASC']
8
7
  });
9
8
 
@@ -11,7 +11,7 @@ export default {
11
11
  where: { id: ctx.body.id }
12
12
  });
13
13
 
14
- if (!config) {
14
+ if (!config?.id) {
15
15
  return befly.tool.No('配置不存在');
16
16
  }
17
17
 
@@ -7,11 +7,10 @@ export default {
7
7
  handler: async (befly, ctx) => {
8
8
  const config = await befly.db.getDetail({
9
9
  table: 'addon_admin_sys_config',
10
- fields: ['code', 'value', 'valueType'],
11
10
  where: { code: ctx.body.code }
12
11
  });
13
12
 
14
- if (!config) {
13
+ if (!config?.id) {
15
14
  return befly.tool.No('配置不存在');
16
15
  }
17
16
 
@@ -14,7 +14,7 @@ export default {
14
14
  where: { id: ctx.body.id }
15
15
  });
16
16
 
17
- if (!config) {
17
+ if (!config?.id) {
18
18
  return befly.tool.No('配置不存在');
19
19
  }
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@befly-addon/admin",
3
- "version": "1.1.29",
3
+ "version": "1.1.30",
4
4
  "title": "管理后台",
5
5
  "description": "Befly - 管理后台功能组件",
6
6
  "type": "module",
@@ -44,9 +44,9 @@
44
44
  "url": "https://github.com/chenbimo/befly.git",
45
45
  "directory": "packages/addon-admin"
46
46
  },
47
- "gitHead": "e078b94f087ddf21f289b55ab86c0b8dce105807",
47
+ "gitHead": "8cb371928961c63d6c3c416c6dd667f8fe285376",
48
48
  "dependencies": {
49
- "befly": "^3.9.37",
49
+ "befly": "^3.9.38",
50
50
  "befly-shared": "^1.2.8",
51
51
  "nodemailer": "^7.0.11",
52
52
  "ua-parser-js": "^2.0.7"
package/tables/admin.json CHANGED
@@ -35,12 +35,6 @@
35
35
  "type": "string",
36
36
  "max": 500
37
37
  },
38
- "roleId": {
39
- "name": "角色ID",
40
- "type": "number",
41
- "min": 1,
42
- "index": true
43
- },
44
38
  "roleCode": {
45
39
  "name": "角色编码",
46
40
  "type": "string",
package/tables/dict.json CHANGED
@@ -1,24 +1,25 @@
1
1
  {
2
- "name": {
3
- "name": "字典名称",
2
+ "typeCode": {
3
+ "name": "字典类型代码",
4
4
  "type": "string",
5
5
  "min": 2,
6
6
  "max": 50,
7
- "index": true
7
+ "index": true,
8
+ "regexp": "@alphanumeric_"
8
9
  },
9
- "code": {
10
- "name": "字典代码",
10
+ "key": {
11
+ "name": "字典键",
11
12
  "type": "string",
12
- "min": 2,
13
+ "min": 1,
13
14
  "max": 50,
14
15
  "index": true,
15
16
  "regexp": "@alphanumeric_"
16
17
  },
17
- "value": {
18
- "name": "字典值",
18
+ "label": {
19
+ "name": "字典标签",
19
20
  "type": "string",
20
- "max": 200,
21
- "index": true
21
+ "min": 1,
22
+ "max": 100
22
23
  },
23
24
  "sort": {
24
25
  "name": "排序",
@@ -27,15 +28,8 @@
27
28
  "max": 9999,
28
29
  "default": 0
29
30
  },
30
- "pid": {
31
- "name": "父级ID",
32
- "type": "number",
33
- "min": 0,
34
- "default": 0,
35
- "index": true
36
- },
37
- "description": {
38
- "name": "描述",
31
+ "remark": {
32
+ "name": "备注",
39
33
  "type": "string",
40
34
  "max": 200
41
35
  }
@@ -0,0 +1,28 @@
1
+ {
2
+ "code": {
3
+ "name": "类型代码",
4
+ "type": "string",
5
+ "min": 2,
6
+ "max": 50,
7
+ "unique": true,
8
+ "regexp": "@alphanumeric_"
9
+ },
10
+ "name": {
11
+ "name": "类型名称",
12
+ "type": "string",
13
+ "min": 2,
14
+ "max": 50
15
+ },
16
+ "description": {
17
+ "name": "描述",
18
+ "type": "string",
19
+ "max": 200
20
+ },
21
+ "sort": {
22
+ "name": "排序",
23
+ "type": "number",
24
+ "min": 0,
25
+ "max": 9999,
26
+ "default": 0
27
+ }
28
+ }