@yorha2b-lab/autodev 3.5.3 → 4.0.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.
- package/CONTRIBUTING.md +10 -0
- package/bin/autodev.js +5 -2
- package/config.js +4 -1
- package/example/example.json +7 -2
- package/package.json +3 -2
- package/src/core/context.js +2 -1
- package/src/core/react-compiler.js +1 -1
- package/src/prompts/react/api-linker.js +18 -0
- package/src/prompts/react/watch-page.js +2 -2
- package/src/prompts/react/watch-part.js +1 -1
- package/src/schema/page.json +9 -2
- package/src/services/api-linker.js +162 -0
- package/src/services/llm.js +12 -0
- package/templates/react/handlebars/handleBlock.hbs +4 -3
- package/templates/react/handlebars/hookBlock.hbs +1 -1
package/CONTRIBUTING.md
CHANGED
|
@@ -44,6 +44,16 @@
|
|
|
44
44
|
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
45
45
|
5. 创建一个 Pull Request
|
|
46
46
|
|
|
47
|
+
### 贡献许可
|
|
48
|
+
|
|
49
|
+
提交 Pull Request 即表示您确认:您有权提交该贡献,并同意该贡献在合并后按本项目的 [GNU AGPL v3.0](./LICENSE) 许可证进行授权和分发。
|
|
50
|
+
|
|
51
|
+
贡献者保留其对原创贡献的版权;本条不构成版权转让。
|
|
52
|
+
|
|
53
|
+
By submitting a Pull Request, you confirm that you have the right to submit the contribution and agree that, once merged, it will be licensed and distributed under this project's [GNU AGPL v3.0](./LICENSE).
|
|
54
|
+
|
|
55
|
+
Contributors retain copyright in their original contributions; this does not constitute a copyright assignment.
|
|
56
|
+
|
|
47
57
|
## 📋 开发指南
|
|
48
58
|
|
|
49
59
|
### 环境准备
|
package/bin/autodev.js
CHANGED
|
@@ -57,10 +57,13 @@ program
|
|
|
57
57
|
return
|
|
58
58
|
}
|
|
59
59
|
bootSequence(pkg.version)
|
|
60
|
-
require('../src/commands/watch
|
|
60
|
+
require('../src/commands/watch')()
|
|
61
61
|
const { config } = bunker.get()
|
|
62
|
+
if (config.apiDoc && config.enableAutoAlignment) {
|
|
63
|
+
require('../src/services/api-linker')()
|
|
64
|
+
}
|
|
62
65
|
if (config.proxyTarget && !config.needMock && config.enableAutoAlignment) {
|
|
63
|
-
require('../src/services/proxy-tower
|
|
66
|
+
require('../src/services/proxy-tower')()
|
|
64
67
|
}
|
|
65
68
|
process.on('SIGINT', () => {
|
|
66
69
|
console.log('\n')
|
package/config.js
CHANGED
|
@@ -18,7 +18,10 @@ module.exports = {
|
|
|
18
18
|
utilsDir: 'src/utils',
|
|
19
19
|
componentsDir: 'src/components',
|
|
20
20
|
|
|
21
|
+
// 代理目标
|
|
22
|
+
proxyTarget: 'http://id:port',
|
|
21
23
|
responseSuccess: `response?.code === 200`,
|
|
22
|
-
|
|
24
|
+
// 指向公司的 Swagger JSON 地址
|
|
25
|
+
apiDoc: 'http://api.company.com/v2/api-docs',
|
|
23
26
|
|
|
24
27
|
}
|
package/example/example.json
CHANGED
|
@@ -72,14 +72,17 @@
|
|
|
72
72
|
],
|
|
73
73
|
"operation": [
|
|
74
74
|
{
|
|
75
|
+
"uri": "BUNKER_API_ANCHOR_viewByRecord",
|
|
75
76
|
"label": "查看",
|
|
76
77
|
"action": "viewByRecord"
|
|
77
78
|
},
|
|
78
79
|
{
|
|
80
|
+
"uri": "BUNKER_API_ANCHOR_editByRecord",
|
|
79
81
|
"label": "编辑",
|
|
80
82
|
"action": "editByRecord"
|
|
81
83
|
},
|
|
82
84
|
{
|
|
85
|
+
"uri": "BUNKER_API_ANCHOR_deleteByRecord",
|
|
83
86
|
"label": "删除",
|
|
84
87
|
"action": "deleteByRecord"
|
|
85
88
|
}
|
|
@@ -146,7 +149,7 @@
|
|
|
146
149
|
},
|
|
147
150
|
{
|
|
148
151
|
"label": "魔法",
|
|
149
|
-
"value": "
|
|
152
|
+
"value": "magic"
|
|
150
153
|
}
|
|
151
154
|
]
|
|
152
155
|
}
|
|
@@ -159,11 +162,13 @@
|
|
|
159
162
|
"functionButton": [
|
|
160
163
|
{
|
|
161
164
|
"btn": "批量删除",
|
|
165
|
+
"uri": "BUNKER_API_ANCHOR_batchDeleteBySelected",
|
|
162
166
|
"action": "batchDeleteBySelected"
|
|
163
167
|
},
|
|
164
168
|
{
|
|
165
169
|
"btn": "批量导出",
|
|
166
|
-
"
|
|
170
|
+
"uri": "BUNKER_API_ANCHOR_exportData",
|
|
171
|
+
"action": "exportData"
|
|
167
172
|
}
|
|
168
173
|
]
|
|
169
174
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yorha2b-lab/autodev",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "基于视觉大模型的前端(react+Antd)全自动 CRUD 代码生成器",
|
|
5
5
|
"bin": {
|
|
6
6
|
"autodev": "bin/autodev.js"
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"sharp": "^0.34.5"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"http-proxy": "^1.18.1"
|
|
51
|
+
"http-proxy": "^1.18.1",
|
|
52
|
+
"segmentit": "^2.0.3"
|
|
52
53
|
}
|
|
53
54
|
}
|
package/src/core/context.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
*/
|
|
16
16
|
init: options => {
|
|
17
17
|
|
|
18
|
-
const { recognizePage, generateMock, alignResponseFields } = require('../services/llm')
|
|
18
|
+
const { apiLinker, recognizePage, generateMock, alignResponseFields } = require('../services/llm')
|
|
19
19
|
const { language, getConfig, unwrapSignal, isQuerySignal, getExistingMenus } = require('../utils/utils')
|
|
20
20
|
|
|
21
21
|
const config = getConfig()
|
|
@@ -51,6 +51,7 @@ module.exports = {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const llmCtx = {
|
|
54
|
+
apiLinker,
|
|
54
55
|
generateMock,
|
|
55
56
|
recognizePage,
|
|
56
57
|
alignResponseFields
|
|
@@ -64,7 +64,6 @@ const index = ({ config, fileName, indexTpl, pageConfig }) => {
|
|
|
64
64
|
|
|
65
65
|
const viewData = {
|
|
66
66
|
hasTabs,
|
|
67
|
-
fileName,
|
|
68
67
|
pageStruct,
|
|
69
68
|
hasOperate,
|
|
70
69
|
columnsValue,
|
|
@@ -80,6 +79,7 @@ const index = ({ config, fileName, indexTpl, pageConfig }) => {
|
|
|
80
79
|
staticInfoText: pageConfig.staticInfo?.text,
|
|
81
80
|
operations: pageConfig.table.operation || [],
|
|
82
81
|
hasRowSelection: pageConfig.table.rowSelection,
|
|
82
|
+
uri: config.needMock ? fileName : 'BUNKER_API_ANCHOR_pages',
|
|
83
83
|
formItems: hasFormItems ? (hasTabs ? 'formItems[activeKey]' : 'formItems') : '[]',
|
|
84
84
|
initParams: `{ ${hasTabs ? 'type: tabs[0].key ,' : ''}${hasPagination ? 'pageNo: 1 , pageSize: 10' : ''}}`,
|
|
85
85
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module.exports = (bunkerAnchors, realApis) => `
|
|
2
|
+
# MISSION: Multi-Point API Alignment
|
|
3
|
+
目标:为地堡生成的多个作战动作匹配真实的后端接口。
|
|
4
|
+
|
|
5
|
+
## 1. 待匹配指令清单 (Target Anchors)
|
|
6
|
+
${bunkerAnchors}
|
|
7
|
+
|
|
8
|
+
## 2. 后端情报库 (Swagger Docs)
|
|
9
|
+
${realApis}
|
|
10
|
+
|
|
11
|
+
## 3. 匹配协议
|
|
12
|
+
- 识别后缀(如 edit, delete, add)。
|
|
13
|
+
- 结合 UI 语义,在 API 库中寻找对应路径。
|
|
14
|
+
- **输出格式**:请只输出一个 JSON 映射表。
|
|
15
|
+
- **例如**:{"BUNKER_API_ANCHOR_editByRecord": "[method] /api/v1/update-user"}
|
|
16
|
+
|
|
17
|
+
⚠️ 严禁解释,严禁输出 JSON 之外的内容。
|
|
18
|
+
`.trim()
|
|
@@ -44,10 +44,10 @@ module.exports = `
|
|
|
44
44
|
- text: 普通文本(默认)
|
|
45
45
|
- tag: 标签列(有背景色的文本)
|
|
46
46
|
- badge: 徽标列(文本前有颜色小圆点)
|
|
47
|
-
- **行操作 (operation)**: [{label:'操作名', action:'动词ByRecord'}]。
|
|
47
|
+
- **行操作 (operation)**: [{label:'操作名', action:'动词ByRecord',uri:'BUNKER_API_ANCHOR_动词ByRecord'}]。
|
|
48
48
|
|
|
49
49
|
### 全局功能按钮 (FunctionButton)
|
|
50
|
-
- **格式**: [{btn:'显示文本', action:'操作动词BySelected'}]。
|
|
50
|
+
- **格式**: [{btn:'显示文本', action:'操作动词BySelected',uri:'BUNKER_API_ANCHOR_动词BySelected'}]。
|
|
51
51
|
- **导出数据**: action 设为 'exportData' 或 'export+模块名'。
|
|
52
52
|
- **逻辑锁定**: ⚠️只要页面中出现了非查询、非重置的独立操作按钮,必须识别并存入 [functionButton] 数组。
|
|
53
53
|
- **构筑联动**: ⚠️若 [functionButton] 数组不为空,则在下文的 [pageStruct] 中必须包含 "FunctionButtonsBlock"。
|
|
@@ -12,7 +12,7 @@ module.exports = `
|
|
|
12
12
|
- ⚠️ 字段白名单: [title, dataIndex, sorter, render, filters, onFilter]
|
|
13
13
|
- 禁止输出:
|
|
14
14
|
- 严禁在 columns 中包含“操作”列。
|
|
15
|
-
- ***⚠️⚠️⚠️严禁输出formItems,只允许输出
|
|
15
|
+
- ***⚠️⚠️⚠️严禁输出formItems,只允许输出columns⚠️⚠️⚠️***
|
|
16
16
|
- **标准定义 (Columns)**:
|
|
17
17
|
- ⚠️ **操作锁定**: 严禁在 columns 数组中包含“操作”列。
|
|
18
18
|
- enum: 枚举列
|
package/src/schema/page.json
CHANGED
|
@@ -82,11 +82,15 @@
|
|
|
82
82
|
"items": {
|
|
83
83
|
"type": "object",
|
|
84
84
|
"required": [
|
|
85
|
+
"uri",
|
|
85
86
|
"label",
|
|
86
87
|
"action"
|
|
87
88
|
],
|
|
88
89
|
"additionalProperties": false,
|
|
89
90
|
"properties": {
|
|
91
|
+
"uri": {
|
|
92
|
+
"type": "string"
|
|
93
|
+
},
|
|
90
94
|
"label": {
|
|
91
95
|
"type": "string"
|
|
92
96
|
},
|
|
@@ -113,8 +117,7 @@
|
|
|
113
117
|
"type": "object",
|
|
114
118
|
"required": [
|
|
115
119
|
"label",
|
|
116
|
-
"name"
|
|
117
|
-
"type"
|
|
120
|
+
"name"
|
|
118
121
|
],
|
|
119
122
|
"additionalProperties": false,
|
|
120
123
|
"properties": {
|
|
@@ -210,6 +213,7 @@
|
|
|
210
213
|
"type": "object",
|
|
211
214
|
"required": [
|
|
212
215
|
"btn",
|
|
216
|
+
"uri",
|
|
213
217
|
"action"
|
|
214
218
|
],
|
|
215
219
|
"additionalProperties": false,
|
|
@@ -217,6 +221,9 @@
|
|
|
217
221
|
"btn": {
|
|
218
222
|
"type": "string"
|
|
219
223
|
},
|
|
224
|
+
"uri": {
|
|
225
|
+
"type": "string"
|
|
226
|
+
},
|
|
220
227
|
"action": {
|
|
221
228
|
"type": "string"
|
|
222
229
|
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const chalk = require('chalk')
|
|
4
|
+
const { Segment, useDefault } = require('segmentit')
|
|
5
|
+
const segmentit = useDefault(new Segment())
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @function getSemanticKeywords
|
|
9
|
+
* @description [语义精炼厂 2.0] 使用 segmentit 引擎进行物理切片。
|
|
10
|
+
*/
|
|
11
|
+
const getSemanticKeywords = text => {
|
|
12
|
+
// 💡 物理脱水:确保输入为纯净字符串
|
|
13
|
+
const content = Array.isArray(text) ? text.join(' ') : (text || '')
|
|
14
|
+
// 💡 执行分词
|
|
15
|
+
const result = segmentit.doSegment(content, {
|
|
16
|
+
simple: true, // 开启简易模式,提升吞吐效率
|
|
17
|
+
stripPunctuation: true // 物理过滤掉所有的标点符号
|
|
18
|
+
})
|
|
19
|
+
// 💡 提取词条并执行“基因筛选”
|
|
20
|
+
return Array.from(new Set(result.filter(word => word.length >= 2 && !/^[0-9]+$/.test(word))))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @function getLocalScore
|
|
25
|
+
* @description [战力评估协议] 计算语义重合度。
|
|
26
|
+
*/
|
|
27
|
+
const getLocalScore = (api, pageKeywords, moduleName) => {
|
|
28
|
+
let score = 0
|
|
29
|
+
const path = api.path.toLowerCase()
|
|
30
|
+
const desc = api.desc.toLowerCase()
|
|
31
|
+
const mod = moduleName.toLowerCase()
|
|
32
|
+
|
|
33
|
+
// 💡 权重 A:路径直接包含模块名 (暴击加分 +50)
|
|
34
|
+
if (path.includes(mod)) score += 50
|
|
35
|
+
|
|
36
|
+
// 💡 权重 B:描述包含模块核心词 (中量加分 +10)
|
|
37
|
+
pageKeywords.forEach(word => {
|
|
38
|
+
if (desc.includes(word.toLowerCase())) score += 10
|
|
39
|
+
if (path.includes(word.toLowerCase())) score += 5
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
return score
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @module apiLinker
|
|
47
|
+
* @description [地堡 4.0 核心] 全频道自动寻址协议。
|
|
48
|
+
*/
|
|
49
|
+
module.exports = async () => {
|
|
50
|
+
|
|
51
|
+
const { get } = require('../core/context')
|
|
52
|
+
const { config, options, language, apiLinker } = get()
|
|
53
|
+
if (!config.apiDoc) return
|
|
54
|
+
|
|
55
|
+
console.log(chalk.cyan(language(
|
|
56
|
+
`\n🤖 Pod 153: 启动‘全频道自动寻址协议 [语义扫描版]’...`,
|
|
57
|
+
`\n🤖 Pod 153: Initiating "Full-Channel Autonomous Addressing Protocol [Semantic Scan]"...`
|
|
58
|
+
)))
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
// 1. 抓取情报
|
|
62
|
+
const apiData = await fetch(config.apiDoc).then(res => res.json())
|
|
63
|
+
const refinedApis = Object.entries(apiData.paths).flatMap(([apiUrl, methods]) => {
|
|
64
|
+
// 💡 适配多方法接口:有的路径下可能既有 GET 也有 POST
|
|
65
|
+
return Object.entries(methods).map(([method, info]) => ({
|
|
66
|
+
path: apiUrl,
|
|
67
|
+
method: method.toUpperCase(),
|
|
68
|
+
desc: info.summary || info.description || 'N/A'
|
|
69
|
+
}))
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// 2. 战场侦察
|
|
73
|
+
const pagesDir = path.join(process.cwd(), config.pagesDir)
|
|
74
|
+
const files = fs.readdirSync(pagesDir)
|
|
75
|
+
|
|
76
|
+
for (const fileName of files) {
|
|
77
|
+
const indexPath = path.join(pagesDir, fileName, 'index.js')
|
|
78
|
+
const resourcePath = path.join(pagesDir, fileName, 'resource.js')
|
|
79
|
+
|
|
80
|
+
if (fs.existsSync(indexPath) && fs.existsSync(resourcePath)) {
|
|
81
|
+
let indexCode = fs.readFileSync(indexPath, 'utf-8')
|
|
82
|
+
|
|
83
|
+
// 💡 锁定待通电锚点
|
|
84
|
+
if (indexCode.includes('BUNKER_API_ANCHOR')) {
|
|
85
|
+
const resourceCode = fs.readFileSync(resourcePath, 'utf-8')
|
|
86
|
+
const fileName = path.basename(indexPath, path.extname(indexPath))
|
|
87
|
+
const bunkerAnchors = indexCode.match(/BUNKER_API_ANCHOR_\w+/g).join('\n')
|
|
88
|
+
|
|
89
|
+
// 💡 执行语义提取流程
|
|
90
|
+
const returnMatch = indexCode.match(/return\s*\(([\s\S]*?)\)\s*}/)
|
|
91
|
+
const returnStatement = returnMatch ? returnMatch[0] : ''
|
|
92
|
+
|
|
93
|
+
const moduleSemantics = `${returnStatement}${resourceCode}`.match(/[\u4e00-\u9fa5][\u4e00-\u9fa5A-Za-z0-9?。,、:;!() ]*/g) || []
|
|
94
|
+
const pageKeywords = getSemanticKeywords(moduleSemantics)
|
|
95
|
+
|
|
96
|
+
// 💡 物理扫描:执行“语义雷达”过滤
|
|
97
|
+
const candidates = refinedApis
|
|
98
|
+
.map(api => ({
|
|
99
|
+
...api,
|
|
100
|
+
score: getLocalScore(api, pageKeywords, fileName)
|
|
101
|
+
}))
|
|
102
|
+
.filter(item => item.score > 0)
|
|
103
|
+
.sort((a, b) => b.score - a.score)
|
|
104
|
+
.slice(0, 20) // 💡 拓宽至前 20 名,给 AI 更多的判别空间
|
|
105
|
+
|
|
106
|
+
const finalCandidates = candidates.map(item => `${item.method} ${item.path} ${item.desc}`).join('\n')
|
|
107
|
+
|
|
108
|
+
console.log(chalk.yellow(language(
|
|
109
|
+
` 🛰️ Inactive module: [${fileName}]. Requesting 9S for precise alignment...`,
|
|
110
|
+
` 🛰️ 发现未通电模块 [${fileName}],请求 9S 执行高精度对账...`
|
|
111
|
+
)))
|
|
112
|
+
|
|
113
|
+
// 3. 驱动 9S 最终裁决
|
|
114
|
+
const result = await apiLinker(options, bunkerAnchors, finalCandidates)
|
|
115
|
+
|
|
116
|
+
if (result) {
|
|
117
|
+
// 💡 执行物理更替
|
|
118
|
+
Object.entries(result).forEach(([anchor, fullSignal]) => {
|
|
119
|
+
// 💡 1. 信号解压
|
|
120
|
+
const parts = fullSignal.split(' ')
|
|
121
|
+
const realMethod = parts[0].toUpperCase()
|
|
122
|
+
const realPath = parts[1]
|
|
123
|
+
|
|
124
|
+
// 💡 2. 路径清洗:确保路径拼接时不产生双斜杠 //
|
|
125
|
+
// 逻辑:如果 realPath 以 / 开头,咱们拼接时就得小心
|
|
126
|
+
const cleanPath = realPath.startsWith('/') ? realPath : `/${realPath}`
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 💡 3. 物理定位正则表达式
|
|
130
|
+
* 我们把 (request\(\s*['"])\/api\/ 这一段作为第一个捕获组 $1
|
|
131
|
+
* 这样在替换时,只需在 $1 后面补上新的路径即可,/api/ 会被原样保留!
|
|
132
|
+
*/
|
|
133
|
+
const requestRegex = new RegExp(`(request\\(\\s*['"]\\/api)${anchor}(['"]\\s*,\\s*\\{[^}]*method\\s*:\\s*['"])(.*?)(['"])`, 'g')
|
|
134
|
+
|
|
135
|
+
// 💡 4. 执行“全频道通电”
|
|
136
|
+
// $1 现在包含了 request('/api 这一串
|
|
137
|
+
indexCode = indexCode.replace(requestRegex, `$1${cleanPath}$2${realMethod}$4`)
|
|
138
|
+
// 💡 5. 兜底替换(针对没有 method 配置的简易请求)
|
|
139
|
+
// 同样保留 /api/ 前缀
|
|
140
|
+
indexCode = indexCode.replaceAll(`/api/${anchor}`, `/api${cleanPath}`)
|
|
141
|
+
})
|
|
142
|
+
fs.writeFileSync(indexPath, indexCode)
|
|
143
|
+
console.log(chalk.green(language(
|
|
144
|
+
`✅ 信号同步完成,${Object.keys(result).length} 个节点已通电。`,
|
|
145
|
+
`✅ Signal Synchronized: ${Object.keys(result).length} nodes energized.`
|
|
146
|
+
)))
|
|
147
|
+
// 💡 战术免责补丁:采用橙黄色高亮,提醒指挥官保持警惕
|
|
148
|
+
console.log(chalk.yellow(language(
|
|
149
|
+
`⚠️ 匹配结果仅供参考,不构成最终决策,各机体需根据实际情况进行调整。`,
|
|
150
|
+
`⚠️ Match Result Reference Only. Not Final Decision. Each Unit should adjust based on battlefield conditions.`
|
|
151
|
+
)))
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
} catch (e) {
|
|
157
|
+
console.error(chalk.red(language(
|
|
158
|
+
`\n❌ Pod 153: 信号链路故障: ${e.message}\n`,
|
|
159
|
+
`\n❌ Pod 153: Signal Link Fault: ${e.message}\n`
|
|
160
|
+
)))
|
|
161
|
+
}
|
|
162
|
+
}
|
package/src/services/llm.js
CHANGED
|
@@ -73,6 +73,18 @@ module.exports = {
|
|
|
73
73
|
]
|
|
74
74
|
})
|
|
75
75
|
},
|
|
76
|
+
apiLinker: async (options, bunkerAnchors, realApis) => {
|
|
77
|
+
const config = getConfig()
|
|
78
|
+
const { API_DESIGNER } = require('../prompts/system.js')
|
|
79
|
+
const apiPrompt = require(`../prompts/${options.template}/api-linker.js`)
|
|
80
|
+
return askAI({
|
|
81
|
+
model: config.textModel,
|
|
82
|
+
messages: [
|
|
83
|
+
{ role: 'system', content: API_DESIGNER },
|
|
84
|
+
{ role: 'user', content: apiPrompt(bunkerAnchors, realApis) }
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
},
|
|
76
88
|
recognizePage: async (prompt, filePath, taskType = 'page') => {
|
|
77
89
|
const config = getConfig()
|
|
78
90
|
const { UI_DESIGNER } = require('../prompts/system.js')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{{#each operations}}
|
|
2
2
|
const {{this.action}} = async record => {
|
|
3
|
-
const response = await request('/api')
|
|
3
|
+
const response = await request('/api/{{this.uri}}',{ method: 'POST', body:{} })
|
|
4
4
|
if({{{../responseSuccess}}}){
|
|
5
5
|
refresh()
|
|
6
6
|
}
|
|
@@ -15,7 +15,7 @@ const {{this.action}} = () => {
|
|
|
15
15
|
centered: true,
|
|
16
16
|
content: '确认{{this.btn}}吗?',
|
|
17
17
|
onOk: async () => {
|
|
18
|
-
const response = await request('/api')
|
|
18
|
+
const response = await request('/api/{{this.uri}}',{ method: 'POST', body:{} })
|
|
19
19
|
if({{{../responseSuccess}}}){
|
|
20
20
|
refresh()
|
|
21
21
|
}
|
|
@@ -63,8 +63,9 @@ const showImg = (record, dataIndex) => {
|
|
|
63
63
|
|
|
64
64
|
const modalSubmit = async values => {
|
|
65
65
|
let response
|
|
66
|
+
let body = values
|
|
66
67
|
if(modal.type==='add'){
|
|
67
|
-
response = await request('/api')
|
|
68
|
+
response = await request('/api',{ method: 'POST', body })
|
|
68
69
|
}
|
|
69
70
|
if({{{responseSuccess}}}){
|
|
70
71
|
setModal({ visible: false })
|
|
@@ -3,7 +3,7 @@ const initialParams = {{initParams}}
|
|
|
3
3
|
const query = formatQuery(Object.fromEntries(new URLSearchParams(location.search).entries()), {{formItems}})
|
|
4
4
|
|
|
5
5
|
const { total, columns, loading, dataSource, search, setSearch, setDataSource, refresh } = useTableQuery({
|
|
6
|
-
api: async params => await request('/api/{{
|
|
6
|
+
api: async params => await request('/api/{{uri}}', { method: 'POST', body: params }),
|
|
7
7
|
initialParams: { ...initialParams, ...query },
|
|
8
8
|
cols:tableColumns,
|
|
9
9
|
formatResponse: response => {
|