@agile-team/wl-skills-kit 2.7.2 → 2.8.0

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.
@@ -1,173 +1,178 @@
1
- 'use strict'
2
-
3
- const { queryDictModules, saveDictModule, saveDictItem } = require('../api/dictApi')
4
-
5
- /**
6
- * 从字典树查询响应中提取模块列表
7
- * 响应结构: { dictionary: { children: DictModule[] } }
8
- *
9
- * @param {any} data - queryDictModules 返回的 result.data
10
- * @returns {object[]}
11
- */
12
- function extractModules(data) {
13
- if (!data) return []
14
- if (data.dictionary && Array.isArray(data.dictionary.children)) {
15
- return data.dictionary.children
16
- }
17
- if (Array.isArray(data)) return data
18
- return []
19
- }
20
-
21
- /**
22
- * wls_dict_query 工具处理器
23
- * 查询当前应用的所有字典模块及字典项
24
- *
25
- * @param {object} config
26
- * @returns {Promise<string>}
27
- */
28
- async function handleDictQuery(config) {
29
- const result = await queryDictModules(config)
30
-
31
- if (!result.ok) {
32
- return `❌ 查询字典失败: ${result.error} (code: ${result.code})`
33
- }
34
-
35
- const modules = extractModules(result.data)
36
-
37
- if (modules.length === 0) {
38
- return '✅ 字典查询成功,当前应用暂无字典数据'
39
- }
40
-
41
- return `✅ 字典查询成功,共 ${modules.length} 个模块\n\n${JSON.stringify(modules, null, 2)}`
42
- }
43
-
44
- /**
45
- * wls_dict_upsert 工具处理器
46
- * 新增或更新字典模块及字典项(完整幂等流程)
47
- *
48
- * 流程:
49
- * ① 查询现有模块,检查 strSn 是否已存在
50
- * ② 若不存在:创建模块(data=null)→ 重新查询 → 用 strSn 定位拿 id
51
- * ③ 若已存在:跳过模块创建,直接取已有 id
52
- * ④ 遍历 items,跳过 strSn 已存在的,其余逐条创建
53
- *
54
- * @param {{ module: object, items?: object[] }} args
55
- * @param {object} config
56
- * @returns {Promise<string>}
57
- */
58
- async function handleDictUpsert(args, config) {
59
- const { module: moduleBody, items = [] } = args
60
-
61
- if (!moduleBody || !moduleBody.strSn) {
62
- return '❌ 参数错误:module.strSn 必填'
63
- }
64
- if (!moduleBody.strName) {
65
- return '❌ 参数错误:module.strName 必填'
66
- }
67
-
68
- // ① 查询现有模块
69
- const queryResult = await queryDictModules(config)
70
- if (!queryResult.ok) {
71
- return `❌ 查询字典失败: ${queryResult.error}`
72
- }
73
-
74
- const existingModules = extractModules(queryResult.data)
75
- let targetModule = existingModules.find((m) => m.strSn === moduleBody.strSn)
76
- let moduleAction
77
-
78
- // ② 模块不存在时创建
79
- if (!targetModule) {
80
- const saveBody = {
81
- strSn: moduleBody.strSn,
82
- strName: moduleBody.strName,
83
- sortPriority: moduleBody.sortPriority != null ? String(moduleBody.sortPriority) : '1',
84
- strLevel: 2,
85
- }
86
-
87
- const createResult = await saveDictModule(saveBody, config)
88
- if (!createResult.ok) {
89
- return `❌ 创建字典模块失败: ${createResult.error}`
90
- }
91
-
92
- // ③ 重新查询(data=null,只能靠 re-query 拿 id)
93
- const reQueryResult = await queryDictModules(config)
94
- if (!reQueryResult.ok) {
95
- return `❌ 重新查询字典失败: ${reQueryResult.error}`
96
- }
97
-
98
- const freshModules = extractModules(reQueryResult.data)
99
- targetModule = freshModules.find((m) => m.strSn === moduleBody.strSn)
100
-
101
- if (!targetModule) {
102
- return `❌ 字典模块创建后未能找到(strSn="${moduleBody.strSn}"),请在字典管理后台确认`
103
- }
104
-
105
- moduleAction = '✅ 已创建'
106
- } else {
107
- moduleAction = '⏭ 已存在(跳过创建)'
108
- }
109
-
110
- const moduleId = targetModule.id
111
-
112
- // ④ 处理字典项
113
- const existingItems = Array.isArray(targetModule.dictionaries)
114
- ? targetModule.dictionaries
115
- : []
116
- const existingSns = new Set(existingItems.map((i) => i.strSn))
117
-
118
- const itemResults = []
119
-
120
- for (const item of items) {
121
- if (existingSns.has(item.strSn)) {
122
- itemResults.push({
123
- strSn: item.strSn,
124
- strName: item.strName || '',
125
- status: '⏭ 已存在(跳过)',
126
- })
127
- continue
128
- }
129
-
130
- const itemBody = {
131
- moduleId,
132
- strSn: item.strSn,
133
- strName: item.strName,
134
- strLevel: 2,
135
- dtlValue: item.dtlValue != null ? item.dtlValue : '',
136
- dtlValueRequired: item.dtlValueRequired || false,
137
- dtlValue2Required: item.dtlValue2Required || false,
138
- dtlValue3Required: item.dtlValue3Required || false,
139
- dtlValue4Required: item.dtlValue4Required || false,
140
- }
141
-
142
- const createResult = await saveDictItem(itemBody, config)
143
- if (createResult.ok) {
144
- itemResults.push({ strSn: item.strSn, strName: item.strName || '', status: '✅ 已创建' })
145
- } else {
146
- itemResults.push({
147
- strSn: item.strSn,
148
- strName: item.strName || '',
149
- status: `❌ 失败: ${createResult.error}`,
150
- })
151
- }
152
- }
153
-
154
- const createdCount = itemResults.filter((r) => r.status.startsWith('✅')).length
155
- const skippedCount = itemResults.filter((r) => r.status.startsWith('⏭')).length
156
- const failedCount = itemResults.filter((r) => r.status.startsWith('❌')).length
157
-
158
- let output = `字典模块 "${moduleBody.strSn}" (${moduleBody.strName}):${moduleAction}\n`
159
- output += `模块 ID:${moduleId}\n`
160
-
161
- if (items.length > 0) {
162
- output += `字典项:创建 ${createdCount},跳过 ${skippedCount},失败 ${failedCount}\n\n`
163
- output += '| strSn | strName | 状态 |\n'
164
- output += '|---|---|---|\n'
165
- for (const r of itemResults) {
166
- output += `| ${r.strSn} | ${r.strName} | ${r.status} |\n`
167
- }
168
- }
169
-
170
- return output
171
- }
172
-
173
- module.exports = { handleDictQuery, handleDictUpsert }
1
+ 'use strict'
2
+
3
+ const { queryDictModules, saveDictModule, saveDictItem } = require('../api/dictApi')
4
+
5
+ /**
6
+ * 从字典树查询响应中提取模块列表
7
+ * 响应结构: { dictionary: { children: DictModule[] } }
8
+ *
9
+ * @param {any} data - queryDictModules 返回的 result.data
10
+ * @returns {object[]}
11
+ */
12
+ function extractModules(data) {
13
+ if (!data) return []
14
+ if (data.dictionary && Array.isArray(data.dictionary.children)) {
15
+ return data.dictionary.children
16
+ }
17
+ if (Array.isArray(data)) return data
18
+ return []
19
+ }
20
+
21
+ /**
22
+ * wls_dict_query 工具处理器
23
+ * 查询当前应用的所有字典模块及字典项
24
+ *
25
+ * @param {object} config
26
+ * @returns {Promise<string>}
27
+ */
28
+ async function handleDictQuery(config) {
29
+ const result = await queryDictModules(config)
30
+
31
+ if (!result.ok) {
32
+ return `❌ 查询字典失败: ${result.error} (code: ${result.code})`
33
+ }
34
+
35
+ const modules = extractModules(result.data)
36
+
37
+ if (modules.length === 0) {
38
+ return '✅ 字典查询成功,当前应用暂无字典数据'
39
+ }
40
+
41
+ return `✅ 字典查询成功,共 ${modules.length} 个模块\n\n${JSON.stringify(modules, null, 2)}`
42
+ }
43
+
44
+ /**
45
+ * wls_dict_upsert 工具处理器
46
+ * 新增或更新字典模块及字典项(完整幂等流程)
47
+ *
48
+ * 流程:
49
+ * ① 查询现有模块,检查 strSn 是否已存在
50
+ * ② 若不存在:创建模块(data=null)→ 重新查询 → 用 strSn 定位拿 id
51
+ * ③ 若已存在:跳过模块创建,直接取已有 id
52
+ * ④ 遍历 items,跳过 strSn 已存在的,其余逐条创建
53
+ *
54
+ * @param {{ module: object, items?: object[] }} args
55
+ * @param {object} config
56
+ * @returns {Promise<string>}
57
+ */
58
+ async function handleDictUpsert(args, config) {
59
+ const { module: moduleBody, items = [] } = args
60
+
61
+ if (!moduleBody || !moduleBody.strSn) {
62
+ return '❌ 参数错误:module.strSn 必填'
63
+ }
64
+ if (!moduleBody.strName) {
65
+ return '❌ 参数错误:module.strName 必填'
66
+ }
67
+
68
+ // ① 查询现有模块
69
+ const queryResult = await queryDictModules(config)
70
+ if (!queryResult.ok) {
71
+ return `❌ 查询字典失败: ${queryResult.error}`
72
+ }
73
+
74
+ const existingModules = extractModules(queryResult.data)
75
+ let targetModule = existingModules.find((m) => m.strSn === moduleBody.strSn)
76
+ let moduleAction
77
+
78
+ // ② 模块不存在时创建
79
+ if (!targetModule) {
80
+ const saveBody = {
81
+ strSn: moduleBody.strSn,
82
+ strName: moduleBody.strName,
83
+ sortPriority: moduleBody.sortPriority != null ? String(moduleBody.sortPriority) : '1',
84
+ strLevel: 2,
85
+ }
86
+
87
+ const createResult = await saveDictModule(saveBody, config)
88
+ if (!createResult.ok) {
89
+ return `❌ 创建字典模块失败: ${createResult.error}`
90
+ }
91
+
92
+ // ③ 重新查询(data=null,只能靠 re-query 拿 id)
93
+ const reQueryResult = await queryDictModules(config)
94
+ if (!reQueryResult.ok) {
95
+ return `❌ 重新查询字典失败: ${reQueryResult.error}`
96
+ }
97
+
98
+ const freshModules = extractModules(reQueryResult.data)
99
+ targetModule = freshModules.find((m) => m.strSn === moduleBody.strSn)
100
+
101
+ if (!targetModule) {
102
+ return `❌ 字典模块创建后未能找到(strSn="${moduleBody.strSn}"),请在字典管理后台确认`
103
+ }
104
+
105
+ moduleAction = '✅ 已创建'
106
+ } else {
107
+ moduleAction = '⏭ 已存在(跳过创建)'
108
+ }
109
+
110
+ const moduleId = targetModule.id
111
+
112
+ // ④ 处理字典项
113
+ const existingItems = Array.isArray(targetModule.dictionaries)
114
+ ? targetModule.dictionaries
115
+ : []
116
+ const existingSns = new Set(existingItems.map((i) => i.strSn))
117
+
118
+ const itemResults = []
119
+
120
+ for (const item of items) {
121
+ if (existingSns.has(item.strSn)) {
122
+ itemResults.push({
123
+ strSn: item.strSn,
124
+ strName: item.strName || '',
125
+ status: '⏭ 已存在(跳过)',
126
+ })
127
+ continue
128
+ }
129
+
130
+ const itemBody = {
131
+ moduleId,
132
+ strSn: item.strSn,
133
+ strName: item.strName,
134
+ strLevel: 2,
135
+ dtlValue: item.dtlValue != null ? item.dtlValue : '',
136
+ dtlValueRequired: item.dtlValueRequired || false,
137
+ dtlValue2Required: item.dtlValue2Required || false,
138
+ dtlValue3Required: item.dtlValue3Required || false,
139
+ dtlValue4Required: item.dtlValue4Required || false,
140
+ }
141
+
142
+ const createResult = await saveDictItem(itemBody, config)
143
+ if (createResult.ok) {
144
+ itemResults.push({ strSn: item.strSn, strName: item.strName || '', status: '✅ 已创建' })
145
+ } else {
146
+ itemResults.push({
147
+ strSn: item.strSn,
148
+ strName: item.strName || '',
149
+ status: `❌ 失败: ${createResult.error}`,
150
+ })
151
+ }
152
+ }
153
+
154
+ const createdCount = itemResults.filter((r) => r.status.startsWith('✅')).length
155
+ const skippedCount = itemResults.filter((r) => r.status.startsWith('⏭')).length
156
+ const failedCount = itemResults.filter((r) => r.status.startsWith('❌')).length
157
+
158
+ let output = `字典模块 "${moduleBody.strSn}" (${moduleBody.strName}):${moduleAction}\n`
159
+ output += `模块 ID:${moduleId}\n`
160
+
161
+ if (items.length > 0) {
162
+ output += `字典项:创建 ${createdCount},跳过 ${skippedCount},失败 ${failedCount}\n\n`
163
+ output += '| strSn | strName | 状态 |\n'
164
+ output += '|---|---|---|\n'
165
+ for (const r of itemResults) {
166
+ output += `| ${r.strSn} | ${r.strName} | ${r.status} |\n`
167
+ }
168
+ }
169
+
170
+ return output
171
+ }
172
+
173
+ module.exports = {
174
+ handleDictQuery,
175
+ handleDictUpsert,
176
+ // 导出纯工具函数供单测覆盖
177
+ _internal: { extractModules },
178
+ }
@@ -413,4 +413,15 @@ module.exports = {
413
413
  handleMenuQuery,
414
414
  handleMenuUpsert,
415
415
  handleMenuSyncFromReport,
416
+ // 导出纯工具函数供单测覆盖
417
+ _internal: {
418
+ cleanCell,
419
+ splitMarkdownRow,
420
+ isDividerRow,
421
+ parseBoolean,
422
+ normalizeTree,
423
+ flattenMenus,
424
+ findExisting,
425
+ parseReport,
426
+ },
416
427
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agile-team/wl-skills-kit",
3
- "version": "2.7.2",
4
- "description": "AI Skill 模板包 v2.7.2 — 13 条编码规范 + 10 个 AI Skill + 17 个 MCP Tool,一条命令导入 Vue 3 项目",
3
+ "version": "2.8.0",
4
+ "description": "AI Skill 模板包 v2.8.0 — 13 条编码规范 + 10 个 AI Skill + 17 个 MCP Tool + Mock 架构体系,一条命令导入 Vue 3 项目",
5
5
  "main": "./bin/wl-skills.js",
6
6
  "bin": {
7
7
  "wl-skills": "bin/wl-skills.js"