befly 3.21.0 → 3.21.2

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.
@@ -4,25 +4,44 @@ import { dirname } from "node:path";
4
4
  import { Logger } from "../../lib/logger.js";
5
5
  import { isNonEmptyString } from "../../utils/is.js";
6
6
  import { camelCase } from "../../utils/util.js";
7
- import { countSyncDbMissingFields } from "./diff.js";
8
7
  import { toSyncDbFieldDef } from "./transform.js";
9
8
 
10
9
  export function printSyncDbProcessLog(message) {
11
10
  process.stdout.write(`[syncDb] ${message}\n`);
12
11
  }
13
12
 
14
- export function printSyncDbDiffSummary(mode, diff) {
13
+ export function printSyncDbDiffSummary(diff) {
15
14
  const tableNames = diff.missingTables.map((item) => item.tableName);
15
+ const extraTableFileNames = diff.extraTables.map((item) => item.tableFileName);
16
16
  const missingFieldGroups = Object.values(diff.missingFieldsByTable);
17
- const missingFieldCount = countSyncDbMissingFields(diff);
17
+ const missingFieldCount = resolveSyncDbFieldCount(diff.missingFieldsByTable, diff.missingFieldCount);
18
+ const extraFieldGroups = Object.values(diff.extraFieldsByTable);
19
+ const extraFieldCount = resolveSyncDbFieldCount(diff.extraFieldsByTable, diff.extraFieldCount);
18
20
 
19
- Logger.info("DB 与项目根目录 tables 差异检查完成", {
20
- mode: mode,
21
+ Logger.info("数据库与项目根目录表定义差异检查完成", {
21
22
  missingTableCount: diff.missingTables.length,
22
23
  missingFieldCount: missingFieldCount,
23
- missingTables: tableNames
24
+ extraTableCount: diff.extraTables.length,
25
+ extraFieldCount: extraFieldCount,
26
+ missingTables: tableNames,
27
+ extraTables: extraTableFileNames
24
28
  });
25
29
 
30
+ for (const item of diff.missingTables) {
31
+ Logger.info("发现缺失表", {
32
+ tableName: item.tableName,
33
+ tableFileName: item.tableFileName,
34
+ columnNames: item.columns.map((column) => column.columnName)
35
+ });
36
+ }
37
+
38
+ for (const item of diff.extraTables) {
39
+ Logger.info("发现多余表", {
40
+ tableFileName: item.tableFileName,
41
+ filePath: item.filePath
42
+ });
43
+ }
44
+
26
45
  for (const item of missingFieldGroups) {
27
46
  Logger.info("发现缺失字段", {
28
47
  tableName: item.tableName,
@@ -30,6 +49,14 @@ export function printSyncDbDiffSummary(mode, diff) {
30
49
  fieldNames: item.fields.map((field) => field.fieldName)
31
50
  });
32
51
  }
52
+
53
+ for (const item of extraFieldGroups) {
54
+ Logger.info("发现多余字段", {
55
+ tableName: item.tableName,
56
+ tableFileName: item.tableFileName,
57
+ fieldNames: item.fields.map((field) => field.fieldName)
58
+ });
59
+ }
33
60
  }
34
61
 
35
62
  function escapeSyncDbMdCell(value) {
@@ -47,144 +74,116 @@ function formatSyncDbValue(value) {
47
74
  return String(value);
48
75
  }
49
76
 
50
- function buildSyncDbCheckRows(diff) {
51
- const rows = [];
52
-
53
- for (const missingTable of diff.missingTables) {
54
- for (const columnMeta of missingTable.columns) {
55
- const fieldInfo = toSyncDbFieldDef(columnMeta);
56
- rows.push({
57
- diffType: "缺少表",
58
- tableName: missingTable.tableName,
59
- tableFileName: `${missingTable.tableFileName}.json`,
60
- dbColumnName: columnMeta.columnName,
61
- fieldName: fieldInfo.fieldName,
62
- dbDataType: columnMeta.dataType,
63
- dbColumnType: columnMeta.columnType,
64
- dbCharLength: columnMeta.charLength,
65
- fieldInput: fieldInfo.fieldDef.input,
66
- fieldMax: fieldInfo.fieldDef.max,
67
- fieldDisplayName: fieldInfo.fieldDef.name
68
- });
69
- }
77
+ function resolveSyncDbFieldCount(groups, fieldCount) {
78
+ if (Number.isInteger(fieldCount) && fieldCount >= 0) {
79
+ return fieldCount;
70
80
  }
71
81
 
72
- for (const tableInfo of Object.values(diff.missingFieldsByTable)) {
73
- for (const fieldItem of tableInfo.fields) {
74
- rows.push({
75
- diffType: "缺少字段",
76
- tableName: tableInfo.tableName,
77
- tableFileName: `${tableInfo.tableFileName}.json`,
78
- dbColumnName: fieldItem.dbColumnName,
79
- fieldName: fieldItem.fieldName,
80
- dbDataType: fieldItem.dbDataType,
81
- dbColumnType: fieldItem.dbColumnType,
82
- dbCharLength: fieldItem.dbCharLength,
83
- fieldInput: fieldItem.fieldDef.input,
84
- fieldMax: fieldItem.fieldDef.max,
85
- fieldDisplayName: fieldItem.fieldDef.name
86
- });
87
- }
82
+ let resolvedFieldCount = 0;
83
+ for (const item of Object.values(groups || {})) {
84
+ resolvedFieldCount = resolvedFieldCount + item.fields.length;
88
85
  }
89
86
 
90
- return rows;
87
+ return resolvedFieldCount;
91
88
  }
92
89
 
93
- function groupSyncDbDiffRowsByTable(rows) {
94
- const grouped = new Map();
95
-
96
- for (const row of rows) {
97
- const tableName = String(row.tableName || "-");
98
- const tableFileName = String(row.tableFileName || "-");
99
- const groupKey = `${tableName}@@${tableFileName}`;
100
- if (!grouped.has(groupKey)) {
101
- grouped.set(groupKey, {
102
- tableName: tableName,
103
- tableFileName: tableFileName,
104
- rows: []
105
- });
106
- }
107
-
108
- grouped.get(groupKey).rows.push(row);
109
- }
110
-
111
- return Array.from(grouped.values());
90
+ function appendSyncDbMarkdownRow(lines, values) {
91
+ lines.push(`| ${values.map((item) => escapeSyncDbMdCell(formatSyncDbValue(item))).join(" | ")} |`);
112
92
  }
113
93
 
114
- function buildSyncDbAllTableRows(groupedDbColumns, existingTableMap) {
115
- const rows = [];
116
-
117
- for (const [tableName, columns] of groupedDbColumns.entries()) {
118
- const hasTableDef = existingTableMap.has(String(camelCase(tableName)).toLowerCase()) ? "" : "否";
119
- const tableComment = isNonEmptyString(columns[0]?.tableComment) ? String(columns[0].tableComment).trim() : "-";
120
- rows.push({
121
- tableName: tableName,
122
- tableComment: tableComment,
123
- columnCount: columns.length,
124
- hasTableDef: hasTableDef
125
- });
94
+ function appendSyncDbDiffGroup(lines, tableName, tableFileName, rows) {
95
+ lines.push(`### ${escapeSyncDbMdCell(formatSyncDbValue(tableName))}(${escapeSyncDbMdCell(formatSyncDbValue(tableFileName))})`);
96
+ lines.push("");
97
+ lines.push("| 差异类型 | 数据库字段名 | 字段标识 | 字段名称 | 字段类型 | 列类型 | 字符串长度 | 推断input | 推断max |");
98
+ lines.push("|---|---|---|---|---|---|---:|---|---:|");
99
+ for (const row of rows) {
100
+ appendSyncDbMarkdownRow(lines, row);
126
101
  }
127
-
128
- return rows;
102
+ lines.push("");
129
103
  }
130
104
 
131
- function buildSyncDbCheckMarkdown(diff, groupedDbColumns, existingTableMap) {
132
- const allTableRows = buildSyncDbAllTableRows(groupedDbColumns, existingTableMap);
133
- const rows = buildSyncDbCheckRows(diff);
134
- const diffGroups = groupSyncDbDiffRowsByTable(rows);
135
- const missingFieldCount = countSyncDbMissingFields(diff);
105
+ function buildSyncDbReportMarkdown(diff, groupedDbColumns, existingTableMap) {
106
+ const missingFieldCount = resolveSyncDbFieldCount(diff.missingFieldsByTable, diff.missingFieldCount);
107
+ const extraFieldCount = resolveSyncDbFieldCount(diff.extraFieldsByTable, diff.extraFieldCount);
108
+ const hasDiff = diff.missingTables.length > 0 || missingFieldCount > 0 || diff.extraTables.length > 0 || extraFieldCount > 0;
136
109
 
137
110
  const lines = [];
138
- lines.push("# DB 与项目根目录 tables 差异报告");
111
+ lines.push("# 数据库与项目根目录表定义差异报告");
139
112
  lines.push("");
140
113
  lines.push(`- 生成时间戳: ${String(Date.now())}`);
141
- lines.push(`- 扫描数据库表数量: ${String(allTableRows.length)}`);
114
+ lines.push(`- 扫描数据库表数量: ${String(groupedDbColumns.size)}`);
142
115
  lines.push(`- 缺少表数量: ${String(diff.missingTables.length)}`);
143
116
  lines.push(`- 缺少字段数量: ${String(missingFieldCount)}`);
117
+ lines.push(`- 多余表数量: ${String(diff.extraTables.length)}`);
118
+ lines.push(`- 多余字段数量: ${String(extraFieldCount)}`);
119
+ if (diff.missingTables.length > 0) {
120
+ lines.push(`- 缺少表列表: ${diff.missingTables.map((item) => item.tableName).join(", ")}`);
121
+ }
122
+ if (diff.extraTables.length > 0) {
123
+ lines.push(`- 多余表列表: ${diff.extraTables.map((item) => item.tableFileName).join(", ")}`);
124
+ }
144
125
  lines.push("");
145
126
  lines.push("## 全部数据库表信息");
146
127
  lines.push("");
147
- lines.push("| 数据库表 | 表说明 | 列数量 | tables中是否存在 |\n|---|---|---:|---|");
128
+ lines.push("| 数据库表 | 表说明 | 列数量 | 表定义中是否存在 |\n|---|---|---:|---|");
148
129
 
149
- if (allTableRows.length === 0) {
130
+ if (groupedDbColumns.size === 0) {
150
131
  lines.push("| - | - | - | 未扫描到可对比表(可能全部被过滤) |");
151
132
  } else {
152
- for (const row of allTableRows) {
153
- lines.push(`| ${escapeSyncDbMdCell(formatSyncDbValue(row.tableName))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.tableComment))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.columnCount))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.hasTableDef))} |`);
133
+ for (const [tableName, columns] of groupedDbColumns.entries()) {
134
+ appendSyncDbMarkdownRow(lines, [tableName, isNonEmptyString(columns[0]?.tableComment) ? String(columns[0].tableComment).trim() : "-", columns.length, existingTableMap.has(String(camelCase(tableName)).toLowerCase()) ? "是" : "否"]);
154
135
  }
155
136
  }
156
137
 
157
138
  lines.push("");
158
139
  lines.push("## 全部差异信息");
159
140
  lines.push("");
160
- if (rows.length === 0) {
141
+ if (!hasDiff) {
161
142
  lines.push("- 未发现差异");
162
143
  lines.push("");
163
144
  return lines.join("\n");
164
145
  }
165
146
 
166
- for (const group of diffGroups) {
167
- lines.push(`### ${escapeSyncDbMdCell(formatSyncDbValue(group.tableName))}(${escapeSyncDbMdCell(formatSyncDbValue(group.tableFileName))})`);
168
- lines.push("");
169
- lines.push("| 差异类型 | 数据库字段名 | 字段标识 | 字段名称 | 字段类型 | 列类型 | 字符串长度 | 推断input | 推断max |");
170
- lines.push("|---|---|---|---|---|---|---:|---|---:|");
171
- for (const row of group.rows) {
172
- lines.push(`| ${escapeSyncDbMdCell(formatSyncDbValue(row.diffType))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.dbColumnName))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.fieldName))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.fieldDisplayName))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.dbDataType))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.dbColumnType))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.dbCharLength))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.fieldInput))} | ${escapeSyncDbMdCell(formatSyncDbValue(row.fieldMax))} |`);
147
+ for (const missingTable of diff.missingTables) {
148
+ const groupRows = [];
149
+ for (const columnMeta of missingTable.columns) {
150
+ const fieldInfo = toSyncDbFieldDef(columnMeta);
151
+ groupRows.push(["缺少表", columnMeta.columnName, fieldInfo.fieldName, fieldInfo.fieldDef.name, columnMeta.dataType, columnMeta.columnType, columnMeta.charLength, fieldInfo.fieldDef.input, fieldInfo.fieldDef.max]);
173
152
  }
174
- lines.push("");
153
+ appendSyncDbDiffGroup(lines, missingTable.tableName, `${missingTable.tableFileName}.json`, groupRows);
154
+ }
155
+
156
+ for (const tableInfo of Object.values(diff.missingFieldsByTable)) {
157
+ const groupRows = [];
158
+ for (const fieldItem of tableInfo.fields) {
159
+ groupRows.push(["缺少字段", fieldItem.dbColumnName, fieldItem.fieldName, fieldItem.fieldDef.name, fieldItem.dbDataType, fieldItem.dbColumnType, fieldItem.dbCharLength, fieldItem.fieldDef.input, fieldItem.fieldDef.max]);
160
+ }
161
+ appendSyncDbDiffGroup(lines, tableInfo.tableName, `${tableInfo.tableFileName}.json`, groupRows);
162
+ }
163
+
164
+ for (const extraTable of diff.extraTables) {
165
+ appendSyncDbDiffGroup(lines, "-", `${extraTable.tableFileName}.json`, [["多余表", "-", "-", extraTable.filePath || "-", "-", "-", null, "-", null]]);
166
+ }
167
+
168
+ for (const tableInfo of Object.values(diff.extraFieldsByTable)) {
169
+ const groupRows = [];
170
+ for (const fieldItem of tableInfo.fields) {
171
+ groupRows.push(["多余字段", "-", fieldItem.fieldName, fieldItem.fieldDef?.name, "-", "-", null, fieldItem.fieldDef?.input, fieldItem.fieldDef?.max]);
172
+ }
173
+ appendSyncDbDiffGroup(lines, tableInfo.tableName, `${tableInfo.tableFileName}.json`, groupRows);
175
174
  }
176
175
 
177
176
  lines.push("");
178
177
  return lines.join("\n");
179
178
  }
180
179
 
181
- export async function writeSyncDbCheckReport(reportPath, diff, groupedDbColumns, existingTableMap) {
180
+ export async function writeSyncDbReport(reportPath, diff, groupedDbColumns, existingTableMap) {
182
181
  if (!isNonEmptyString(reportPath)) {
183
182
  return "";
184
183
  }
185
184
 
186
185
  await mkdir(dirname(reportPath), { recursive: true });
187
- const markdown = buildSyncDbCheckMarkdown(diff, groupedDbColumns, existingTableMap);
186
+ const markdown = buildSyncDbReportMarkdown(diff, groupedDbColumns, existingTableMap);
188
187
  await Bun.write(reportPath, markdown);
189
188
  printSyncDbProcessLog(`差异报告已写入 ${reportPath}`);
190
189
  Logger.info("差异报告写入完成", {
package/sync/dev.js CHANGED
@@ -23,11 +23,13 @@ export async function syncDev(ctx) {
23
23
 
24
24
  const devRole = await ctx.mysql.getOne({
25
25
  table: ROLE_TABLE_NAME,
26
+ fields: ["id"],
26
27
  where: { code: "dev", state$gte: 0 }
27
28
  });
28
29
 
29
30
  const devAdmin = await ctx.mysql.getOne({
30
31
  table: ADMIN_TABLE_NAME,
32
+ fields: ["id"],
31
33
  where: { username: "dev", state$gte: 0 }
32
34
  });
33
35
 
@@ -133,6 +135,7 @@ export async function syncDev(ctx) {
133
135
  for (const roleConfig of roles) {
134
136
  const existingRole = await ctx.mysql.getOne({
135
137
  table: ROLE_TABLE_NAME,
138
+ fields: ["id", "apis"],
136
139
  where: {
137
140
  code: roleConfig.code,
138
141
  state$gte: 0
package/tables/admin.json CHANGED
@@ -1,4 +1,10 @@
1
1
  {
2
+ "id": {
3
+ "name": "ID",
4
+ "input": "integer",
5
+ "min": 1,
6
+ "max": null
7
+ },
2
8
  "nickname": {
3
9
  "name": "昵称",
4
10
  "input": "string",
@@ -57,5 +63,23 @@
57
63
  "name": "最后登录IP",
58
64
  "input": "string",
59
65
  "max": 50
66
+ },
67
+ "state": {
68
+ "name": "状态",
69
+ "input": "integer",
70
+ "min": 0,
71
+ "max": 2
72
+ },
73
+ "createdAt": {
74
+ "name": "创建时间",
75
+ "input": "number"
76
+ },
77
+ "updatedAt": {
78
+ "name": "更新时间",
79
+ "input": "number"
80
+ },
81
+ "deletedAt": {
82
+ "name": "删除时间",
83
+ "input": "number"
60
84
  }
61
85
  }
package/tables/api.json CHANGED
@@ -1,4 +1,10 @@
1
1
  {
2
+ "id": {
3
+ "name": "ID",
4
+ "input": "integer",
5
+ "min": 1,
6
+ "max": null
7
+ },
2
8
  "name": {
3
9
  "name": "接口名称",
4
10
  "input": "string",
@@ -28,5 +34,23 @@
28
34
  "input": "string",
29
35
  "min": 1,
30
36
  "max": 200
37
+ },
38
+ "state": {
39
+ "name": "状态",
40
+ "input": "integer",
41
+ "min": 0,
42
+ "max": 2
43
+ },
44
+ "createdAt": {
45
+ "name": "创建时间",
46
+ "input": "number"
47
+ },
48
+ "updatedAt": {
49
+ "name": "更新时间",
50
+ "input": "number"
51
+ },
52
+ "deletedAt": {
53
+ "name": "删除时间",
54
+ "input": "number"
31
55
  }
32
56
  }
package/tables/dict.json CHANGED
@@ -1,4 +1,10 @@
1
1
  {
2
+ "id": {
3
+ "name": "ID",
4
+ "input": "integer",
5
+ "min": 1,
6
+ "max": null
7
+ },
2
8
  "typeCode": {
3
9
  "name": "字典类型代码",
4
10
  "input": "regexp",
@@ -28,5 +34,23 @@
28
34
  "name": "备注",
29
35
  "input": "string",
30
36
  "max": 200
37
+ },
38
+ "state": {
39
+ "name": "状态",
40
+ "input": "integer",
41
+ "min": 0,
42
+ "max": 2
43
+ },
44
+ "createdAt": {
45
+ "name": "创建时间",
46
+ "input": "number"
47
+ },
48
+ "updatedAt": {
49
+ "name": "更新时间",
50
+ "input": "number"
51
+ },
52
+ "deletedAt": {
53
+ "name": "删除时间",
54
+ "input": "number"
31
55
  }
32
56
  }
@@ -1,4 +1,10 @@
1
1
  {
2
+ "id": {
3
+ "name": "ID",
4
+ "input": "integer",
5
+ "min": 1,
6
+ "max": null
7
+ },
2
8
  "code": {
3
9
  "name": "类型代码",
4
10
  "input": "regexp",
@@ -21,5 +27,23 @@
21
27
  "name": "排序",
22
28
  "input": "number",
23
29
  "max": 9999
30
+ },
31
+ "state": {
32
+ "name": "状态",
33
+ "input": "integer",
34
+ "min": 0,
35
+ "max": 2
36
+ },
37
+ "createdAt": {
38
+ "name": "创建时间",
39
+ "input": "number"
40
+ },
41
+ "updatedAt": {
42
+ "name": "更新时间",
43
+ "input": "number"
44
+ },
45
+ "deletedAt": {
46
+ "name": "删除时间",
47
+ "input": "number"
24
48
  }
25
49
  }
@@ -1,4 +1,10 @@
1
1
  {
2
+ "id": {
3
+ "name": "ID",
4
+ "input": "integer",
5
+ "min": 1,
6
+ "max": null
7
+ },
2
8
  "adminId": {
3
9
  "name": "发送人ID",
4
10
  "input": "number"
@@ -58,5 +64,23 @@
58
64
  "name": "失败原因",
59
65
  "input": "string",
60
66
  "max": 500
67
+ },
68
+ "state": {
69
+ "name": "状态",
70
+ "input": "integer",
71
+ "min": 0,
72
+ "max": 2
73
+ },
74
+ "createdAt": {
75
+ "name": "创建时间",
76
+ "input": "number"
77
+ },
78
+ "updatedAt": {
79
+ "name": "更新时间",
80
+ "input": "number"
81
+ },
82
+ "deletedAt": {
83
+ "name": "删除时间",
84
+ "input": "number"
61
85
  }
62
86
  }
@@ -0,0 +1,140 @@
1
+ {
2
+ "id": {
3
+ "name": "ID",
4
+ "input": "integer",
5
+ "min": 1,
6
+ "max": null
7
+ },
8
+ "reportTime": {
9
+ "name": "上报时间",
10
+ "input": "number"
11
+ },
12
+ "firstReportTime": {
13
+ "name": "首次上报时间",
14
+ "input": "number"
15
+ },
16
+ "bucketTime": {
17
+ "name": "时间桶时间",
18
+ "input": "number"
19
+ },
20
+ "bucketDate": {
21
+ "name": "时间桶日期",
22
+ "input": "number"
23
+ },
24
+ "hitCount": {
25
+ "name": "命中次数",
26
+ "input": "number"
27
+ },
28
+ "source": {
29
+ "name": "来源",
30
+ "input": "string",
31
+ "max": 50
32
+ },
33
+ "productName": {
34
+ "name": "产品名称",
35
+ "input": "string",
36
+ "max": 100
37
+ },
38
+ "productCode": {
39
+ "name": "产品代号",
40
+ "input": "string",
41
+ "max": 100
42
+ },
43
+ "productVersion": {
44
+ "name": "产品版本",
45
+ "input": "string",
46
+ "max": 100
47
+ },
48
+ "pagePath": {
49
+ "name": "页面路径",
50
+ "input": "string",
51
+ "max": 200
52
+ },
53
+ "pageName": {
54
+ "name": "页面名称",
55
+ "input": "string",
56
+ "max": 100
57
+ },
58
+ "errorType": {
59
+ "name": "错误类型",
60
+ "input": "string",
61
+ "max": 50
62
+ },
63
+ "message": {
64
+ "name": "错误信息",
65
+ "input": "string",
66
+ "max": 500
67
+ },
68
+ "detail": {
69
+ "name": "错误详情",
70
+ "input": "string"
71
+ },
72
+ "userAgent": {
73
+ "name": "用户代理",
74
+ "input": "string",
75
+ "max": 500
76
+ },
77
+ "browserName": {
78
+ "name": "浏览器名称",
79
+ "input": "string",
80
+ "max": 100
81
+ },
82
+ "browserVersion": {
83
+ "name": "浏览器版本",
84
+ "input": "string",
85
+ "max": 100
86
+ },
87
+ "osName": {
88
+ "name": "操作系统名称",
89
+ "input": "string",
90
+ "max": 100
91
+ },
92
+ "osVersion": {
93
+ "name": "操作系统版本",
94
+ "input": "string",
95
+ "max": 100
96
+ },
97
+ "deviceType": {
98
+ "name": "设备类型",
99
+ "input": "string",
100
+ "max": 50
101
+ },
102
+ "deviceVendor": {
103
+ "name": "设备厂商",
104
+ "input": "string",
105
+ "max": 100
106
+ },
107
+ "deviceModel": {
108
+ "name": "设备型号",
109
+ "input": "string",
110
+ "max": 100
111
+ },
112
+ "engineName": {
113
+ "name": "引擎名称",
114
+ "input": "string",
115
+ "max": 100
116
+ },
117
+ "cpuArchitecture": {
118
+ "name": "CPU架构",
119
+ "input": "string",
120
+ "max": 100
121
+ },
122
+ "state": {
123
+ "name": "状态",
124
+ "input": "integer",
125
+ "min": 0,
126
+ "max": 2
127
+ },
128
+ "createdAt": {
129
+ "name": "创建时间",
130
+ "input": "number"
131
+ },
132
+ "updatedAt": {
133
+ "name": "更新时间",
134
+ "input": "number"
135
+ },
136
+ "deletedAt": {
137
+ "name": "删除时间",
138
+ "input": "number"
139
+ }
140
+ }