intention-coding 0.3.8 → 0.4.1
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/package.json +1 -1
- package/dist/db/file-storage.js +0 -638
- package/dist/index.js +0 -26
- package/dist/server/index.js +0 -88
- package/dist/services/bug-fix-agent/index.js +0 -320
- package/dist/services/change-summarizer/index.js +0 -123
- package/dist/services/change-summarizer/prompt/change-analysis.js +0 -56
- package/dist/services/code-generator/index.js +0 -403
- package/dist/services/code-generator/stages/execution-stage.js +0 -549
- package/dist/services/code-generator/stages/ideation-stage.js +0 -267
- package/dist/services/code-generator/stages/optimization-stage.js +0 -334
- package/dist/services/code-generator/stages/planning-stage.js +0 -295
- package/dist/services/code-generator/stages/research-stage.js +0 -283
- package/dist/services/code-generator/stages/review-stage.js +0 -270
- package/dist/services/code-generator/types.js +0 -37
- package/dist/services/code-generator/utils/instruction-executor.js +0 -207
- package/dist/services/code-generator/workflow-manager.js +0 -252
- package/dist/services/image-analysis/analyzer.js +0 -530
- package/dist/services/image-analysis/index.js +0 -406
- package/dist/services/image-analysis/types.js +0 -46
- package/dist/services/image-converter/converter.js +0 -310
- package/dist/services/image-converter/index.js +0 -262
- package/dist/services/image-converter/types.js +0 -31
- package/dist/services/integrated-generator/index.js +0 -1297
- package/dist/services/pdf2md/index.js +0 -180
- package/dist/services/project-template/index.js +0 -83
- package/dist/services/project-template/prompt/project-rules.js +0 -98
- package/dist/services/requirement-analyzer/chunk-reader.js +0 -218
- package/dist/services/requirement-analyzer/core/document-generator.js +0 -254
- package/dist/services/requirement-analyzer/core/intelligent-analyzer.js +0 -169
- package/dist/services/requirement-analyzer/core/project-analyzer.js +0 -199
- package/dist/services/requirement-analyzer/core/requirement-analyzer-service.js +0 -191
- package/dist/services/requirement-analyzer/core/template-selector.js +0 -124
- package/dist/services/requirement-analyzer/core/types.js +0 -23
- package/dist/services/requirement-analyzer/index.js +0 -177
- package/dist/services/requirement-analyzer/prompt/api-template.js +0 -302
- package/dist/services/requirement-analyzer/prompt/app-template.js +0 -455
- package/dist/services/requirement-analyzer/prompt/intelligent-requirement-analysis.js +0 -92
- package/dist/services/requirement-analyzer/prompt/pc-page-template.js +0 -582
- package/dist/services/requirement-analyzer/prompt/requirement-analysis.js +0 -664
- package/dist/services/requirement-analyzer/prompt/sdk-template.js +0 -582
- package/dist/services/requirement-analyzer/utils/file-reader.js +0 -169
- package/dist/services/world2md/index.js +0 -157
- package/dist/types/index.js +0 -2
- package/dist/utils/common.js +0 -72
- package/dist/utils/config.js +0 -163
- package/dist/utils/context-manager.js +0 -114
- package/dist/utils/dify.js +0 -243
- package/dist/utils/logger.js +0 -129
- package/dist/utils/openai.js +0 -225
- package/dist/utils/pack.js +0 -75
|
@@ -1,530 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
-
};
|
|
47
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.ImageAnalyzer = void 0;
|
|
49
|
-
const fs = __importStar(require("fs/promises"));
|
|
50
|
-
const path = __importStar(require("path"));
|
|
51
|
-
const sharp_1 = __importDefault(require("sharp"));
|
|
52
|
-
const openai_1 = require("../../utils/openai");
|
|
53
|
-
const logger_1 = require("../../utils/logger");
|
|
54
|
-
const types_1 = require("./types");
|
|
55
|
-
/**
|
|
56
|
-
* 图片内容理解核心服务
|
|
57
|
-
* 职责:分析图片内容并提供智能理解
|
|
58
|
-
*/
|
|
59
|
-
class ImageAnalyzer {
|
|
60
|
-
/**
|
|
61
|
-
* 分析图片内容
|
|
62
|
-
*/
|
|
63
|
-
analyzeImage(params) {
|
|
64
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
const startTime = Date.now();
|
|
66
|
-
try {
|
|
67
|
-
logger_1.logger.info('开始图片内容分析', {
|
|
68
|
-
imagePath: params.image_path,
|
|
69
|
-
analysisType: params.analysis_type,
|
|
70
|
-
detailLevel: params.detail_level
|
|
71
|
-
});
|
|
72
|
-
// 验证参数和文件
|
|
73
|
-
yield this.validateParams(params);
|
|
74
|
-
// 获取图片基本信息
|
|
75
|
-
const basicInfo = yield this.getImageBasicInfo(params.image_path);
|
|
76
|
-
// 执行AI分析
|
|
77
|
-
const analysisContent = yield this.performAIAnalysis(params, basicInfo);
|
|
78
|
-
const processingTime = Date.now() - startTime;
|
|
79
|
-
const result = {
|
|
80
|
-
basic_info: basicInfo,
|
|
81
|
-
analysis_type: params.analysis_type,
|
|
82
|
-
detail_level: params.detail_level || types_1.DetailLevel.DETAILED,
|
|
83
|
-
content: analysisContent,
|
|
84
|
-
processing_time_ms: processingTime,
|
|
85
|
-
confidence_score: this.calculateConfidenceScore(analysisContent)
|
|
86
|
-
};
|
|
87
|
-
logger_1.logger.info('图片内容分析完成', {
|
|
88
|
-
imagePath: params.image_path,
|
|
89
|
-
processingTimeMs: processingTime,
|
|
90
|
-
confidenceScore: result.confidence_score
|
|
91
|
-
});
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
logger_1.logger.error('图片内容分析失败', { error, params });
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* 执行AI分析
|
|
102
|
-
*/
|
|
103
|
-
performAIAnalysis(params, basicInfo) {
|
|
104
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
try {
|
|
106
|
-
// 将图片转换为base64
|
|
107
|
-
const imageBase64 = yield this.imageToBase64(params.image_path);
|
|
108
|
-
// 构建分析prompt
|
|
109
|
-
const prompt = this.buildAnalysisPrompt(params, basicInfo);
|
|
110
|
-
// 调用AI服务
|
|
111
|
-
const aiResponse = yield openai_1.openAIService.analyzeImage({
|
|
112
|
-
image_base64: imageBase64,
|
|
113
|
-
prompt: prompt
|
|
114
|
-
});
|
|
115
|
-
// 解析AI响应
|
|
116
|
-
const analysisContent = this.parseAIResponse(aiResponse, params.analysis_type);
|
|
117
|
-
return analysisContent;
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
logger_1.logger.error('AI分析失败', { error, params });
|
|
121
|
-
throw new types_1.ImageAnalysisError('AI图片分析服务调用失败', types_1.AnalysisErrorCodes.AI_SERVICE_ERROR, { originalError: error });
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* 构建分析prompt
|
|
127
|
-
*/
|
|
128
|
-
buildAnalysisPrompt(params, basicInfo) {
|
|
129
|
-
const basePrompt = `请分析这张图片,图片信息:
|
|
130
|
-
- 格式:${basicInfo.format}
|
|
131
|
-
- 尺寸:${basicInfo.dimensions.width} × ${basicInfo.dimensions.height}
|
|
132
|
-
- 文件大小:${this.formatFileSize(basicInfo.file_size)}`;
|
|
133
|
-
let specificPrompt = '';
|
|
134
|
-
switch (params.analysis_type) {
|
|
135
|
-
case types_1.AnalysisType.GENERAL:
|
|
136
|
-
specificPrompt = '请提供图片的全面描述,包括主要内容、场景、物体、颜色、构图等。';
|
|
137
|
-
break;
|
|
138
|
-
case types_1.AnalysisType.OBJECTS:
|
|
139
|
-
specificPrompt = '请识别图片中的所有物体,包括物体名称、位置、大小、特征等详细信息。';
|
|
140
|
-
break;
|
|
141
|
-
case types_1.AnalysisType.TEXT:
|
|
142
|
-
specificPrompt = '请提取图片中的所有文字内容,包括文字位置、字体、语言等信息。';
|
|
143
|
-
break;
|
|
144
|
-
case types_1.AnalysisType.SCENE:
|
|
145
|
-
specificPrompt = '请分析图片的场景信息,包括地点类型、环境、光照、天气、时间、氛围等。';
|
|
146
|
-
break;
|
|
147
|
-
case types_1.AnalysisType.PEOPLE:
|
|
148
|
-
specificPrompt = '请分析图片中的人物信息,包括人数、年龄、性别、表情、动作、服装等。';
|
|
149
|
-
break;
|
|
150
|
-
case types_1.AnalysisType.TECHNICAL:
|
|
151
|
-
specificPrompt = '请从技术角度分析图片,包括色彩分析、构图分析、质量评估等专业信息。';
|
|
152
|
-
break;
|
|
153
|
-
case types_1.AnalysisType.UI_DESIGN:
|
|
154
|
-
specificPrompt = `请分析这张UI设计稿,重点关注以下方面:
|
|
155
|
-
1. 页面布局结构和组件层次
|
|
156
|
-
2. 导航设计和信息架构
|
|
157
|
-
3. 色彩搭配和视觉风格
|
|
158
|
-
4. 交互元素和用户体验设计
|
|
159
|
-
5. 响应式设计考虑
|
|
160
|
-
6. 可访问性特征
|
|
161
|
-
7. 设计模式和最佳实践
|
|
162
|
-
请提供详细的UI结构图和页面结构分析。`;
|
|
163
|
-
break;
|
|
164
|
-
case types_1.AnalysisType.REQUIREMENT:
|
|
165
|
-
specificPrompt = `请从需求分析角度分析这张图片,识别和提取以下信息:
|
|
166
|
-
1. 功能需求:识别图片中体现的功能点和业务逻辑
|
|
167
|
-
2. 用户故事:基于图片内容推导用户需求和使用场景
|
|
168
|
-
3. 非功能需求:性能、安全、可用性等方面的要求
|
|
169
|
-
4. 业务规则:从图片中识别的业务约束和规则
|
|
170
|
-
5. 系统边界:确定系统范围和外部接口
|
|
171
|
-
6. 数据需求:识别需要处理的数据类型和结构
|
|
172
|
-
请提供结构化的需求分析报告。`;
|
|
173
|
-
break;
|
|
174
|
-
case types_1.AnalysisType.CUSTOM:
|
|
175
|
-
specificPrompt = params.custom_prompt || '请分析这张图片的内容。';
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
const detailInstruction = this.getDetailInstruction(params.detail_level);
|
|
179
|
-
const languageInstruction = params.language ? `请用${params.language}回答。` : '';
|
|
180
|
-
return `${basePrompt}\n\n${specificPrompt}\n\n${detailInstruction}\n\n${languageInstruction}`.trim();
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* 获取详细程度指令
|
|
184
|
-
*/
|
|
185
|
-
getDetailInstruction(detailLevel) {
|
|
186
|
-
switch (detailLevel) {
|
|
187
|
-
case types_1.DetailLevel.BRIEF:
|
|
188
|
-
return '请提供简要的分析结果,重点突出最重要的信息。';
|
|
189
|
-
case types_1.DetailLevel.COMPREHENSIVE:
|
|
190
|
-
return '请提供全面详细的分析结果,包含所有可能的细节和专业见解。';
|
|
191
|
-
case types_1.DetailLevel.DETAILED:
|
|
192
|
-
default:
|
|
193
|
-
return '请提供详细的分析结果,包含主要特征和重要细节。';
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* 解析AI响应
|
|
198
|
-
*/
|
|
199
|
-
parseAIResponse(aiResponse, analysisType) {
|
|
200
|
-
// 基础内容结构
|
|
201
|
-
const content = {
|
|
202
|
-
summary: aiResponse,
|
|
203
|
-
details: {},
|
|
204
|
-
tags: this.extractTags(aiResponse)
|
|
205
|
-
};
|
|
206
|
-
// 根据分析类型解析特定内容
|
|
207
|
-
switch (analysisType) {
|
|
208
|
-
case types_1.AnalysisType.OBJECTS:
|
|
209
|
-
content.objects = this.extractObjects(aiResponse);
|
|
210
|
-
break;
|
|
211
|
-
case types_1.AnalysisType.TEXT:
|
|
212
|
-
content.text_content = this.extractTextContent(aiResponse);
|
|
213
|
-
break;
|
|
214
|
-
case types_1.AnalysisType.SCENE:
|
|
215
|
-
content.scene_info = this.extractSceneInfo(aiResponse);
|
|
216
|
-
break;
|
|
217
|
-
case types_1.AnalysisType.PEOPLE:
|
|
218
|
-
content.people_info = this.extractPeopleInfo(aiResponse);
|
|
219
|
-
break;
|
|
220
|
-
case types_1.AnalysisType.TECHNICAL:
|
|
221
|
-
content.technical_info = this.extractTechnicalInfo(aiResponse);
|
|
222
|
-
break;
|
|
223
|
-
case types_1.AnalysisType.UI_DESIGN:
|
|
224
|
-
content.ui_design_info = this.extractUIDesignInfo(aiResponse);
|
|
225
|
-
break;
|
|
226
|
-
case types_1.AnalysisType.REQUIREMENT:
|
|
227
|
-
content.requirement_info = this.extractRequirementInfo(aiResponse);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
return content;
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* 获取图片基本信息
|
|
234
|
-
*/
|
|
235
|
-
getImageBasicInfo(imagePath) {
|
|
236
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
-
try {
|
|
238
|
-
const metadata = yield (0, sharp_1.default)(imagePath).metadata();
|
|
239
|
-
const stats = yield fs.stat(imagePath);
|
|
240
|
-
return {
|
|
241
|
-
path: imagePath,
|
|
242
|
-
format: metadata.format || 'unknown',
|
|
243
|
-
dimensions: {
|
|
244
|
-
width: metadata.width || 0,
|
|
245
|
-
height: metadata.height || 0
|
|
246
|
-
},
|
|
247
|
-
file_size: stats.size,
|
|
248
|
-
color_space: metadata.space,
|
|
249
|
-
has_alpha: metadata.hasAlpha
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
catch (error) {
|
|
253
|
-
throw new types_1.ImageAnalysisError(`无法读取图片信息: ${imagePath}`, types_1.AnalysisErrorCodes.IMAGE_CORRUPTED, { imagePath, originalError: error });
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* 将图片转换为base64 data URL
|
|
259
|
-
*/
|
|
260
|
-
imageToBase64(imagePath) {
|
|
261
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
262
|
-
try {
|
|
263
|
-
const imageBuffer = yield fs.readFile(imagePath);
|
|
264
|
-
const base64 = imageBuffer.toString('base64');
|
|
265
|
-
// 获取文件扩展名来确定 MIME 类型
|
|
266
|
-
const ext = path.extname(imagePath).toLowerCase();
|
|
267
|
-
let mimeType = 'image/jpeg'; // 默认
|
|
268
|
-
switch (ext) {
|
|
269
|
-
case '.png':
|
|
270
|
-
mimeType = 'image/png';
|
|
271
|
-
break;
|
|
272
|
-
case '.gif':
|
|
273
|
-
mimeType = 'image/gif';
|
|
274
|
-
break;
|
|
275
|
-
case '.webp':
|
|
276
|
-
mimeType = 'image/webp';
|
|
277
|
-
break;
|
|
278
|
-
case '.jpg':
|
|
279
|
-
case '.jpeg':
|
|
280
|
-
mimeType = 'image/jpeg';
|
|
281
|
-
break;
|
|
282
|
-
default:
|
|
283
|
-
mimeType = 'image/jpeg';
|
|
284
|
-
}
|
|
285
|
-
// 返回完整的 data URL 格式
|
|
286
|
-
return `data:${mimeType};base64,${base64}`;
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
throw new types_1.ImageAnalysisError(`无法读取图片文件: ${imagePath}`, types_1.AnalysisErrorCodes.FILE_NOT_FOUND, { imagePath, originalError: error });
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* 验证参数
|
|
295
|
-
*/
|
|
296
|
-
validateParams(params) {
|
|
297
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
-
// 验证文件存在
|
|
299
|
-
try {
|
|
300
|
-
yield fs.access(params.image_path);
|
|
301
|
-
}
|
|
302
|
-
catch (_a) {
|
|
303
|
-
throw new types_1.ImageAnalysisError(`图片文件不存在: ${params.image_path}`, types_1.AnalysisErrorCodes.FILE_NOT_FOUND, { imagePath: params.image_path });
|
|
304
|
-
}
|
|
305
|
-
// 验证文件格式
|
|
306
|
-
const ext = path.extname(params.image_path).slice(1).toLowerCase();
|
|
307
|
-
if (!types_1.SUPPORTED_IMAGE_FORMATS.includes(ext)) {
|
|
308
|
-
throw new types_1.ImageAnalysisError(`不支持的图片格式: ${ext}`, types_1.AnalysisErrorCodes.UNSUPPORTED_FORMAT, {
|
|
309
|
-
format: ext,
|
|
310
|
-
supportedFormats: types_1.SUPPORTED_IMAGE_FORMATS
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
// 验证分析类型
|
|
314
|
-
if (!Object.values(types_1.AnalysisType).includes(params.analysis_type)) {
|
|
315
|
-
throw new types_1.ImageAnalysisError(`无效的分析类型: ${params.analysis_type}`, types_1.AnalysisErrorCodes.INVALID_ANALYSIS_TYPE, { analysisType: params.analysis_type });
|
|
316
|
-
}
|
|
317
|
-
// 验证自定义分析的prompt
|
|
318
|
-
if (params.analysis_type === types_1.AnalysisType.CUSTOM && !params.custom_prompt) {
|
|
319
|
-
throw new types_1.ImageAnalysisError('自定义分析类型需要提供custom_prompt参数', types_1.AnalysisErrorCodes.INVALID_ANALYSIS_TYPE, { analysisType: params.analysis_type });
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* 计算置信度分数
|
|
325
|
-
*/
|
|
326
|
-
calculateConfidenceScore(content) {
|
|
327
|
-
// 基于内容长度和结构化程度计算置信度
|
|
328
|
-
let score = 0.5; // 基础分数
|
|
329
|
-
if (content.summary.length > 100)
|
|
330
|
-
score += 0.2;
|
|
331
|
-
if (content.tags && content.tags.length > 0)
|
|
332
|
-
score += 0.1;
|
|
333
|
-
if (content.objects && content.objects.length > 0)
|
|
334
|
-
score += 0.1;
|
|
335
|
-
if (content.text_content && content.text_content.length > 0)
|
|
336
|
-
score += 0.1;
|
|
337
|
-
return Math.min(score, 1.0);
|
|
338
|
-
}
|
|
339
|
-
// 内容提取辅助方法
|
|
340
|
-
extractTags(text) {
|
|
341
|
-
// 简单的标签提取逻辑
|
|
342
|
-
const tagPatterns = [
|
|
343
|
-
/标签[::]\s*([^\n]+)/i,
|
|
344
|
-
/关键词[::]\s*([^\n]+)/i,
|
|
345
|
-
/tags[::]\s*([^\n]+)/i
|
|
346
|
-
];
|
|
347
|
-
for (const pattern of tagPatterns) {
|
|
348
|
-
const match = text.match(pattern);
|
|
349
|
-
if (match) {
|
|
350
|
-
return match[1].split(/[,,、]/).map(tag => tag.trim()).filter(Boolean);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return [];
|
|
354
|
-
}
|
|
355
|
-
extractObjects(text) {
|
|
356
|
-
// 简化的物体提取逻辑
|
|
357
|
-
return [];
|
|
358
|
-
}
|
|
359
|
-
extractTextContent(text) {
|
|
360
|
-
// 简化的文字提取逻辑
|
|
361
|
-
return [];
|
|
362
|
-
}
|
|
363
|
-
extractSceneInfo(text) {
|
|
364
|
-
// 简化的场景信息提取逻辑
|
|
365
|
-
return {};
|
|
366
|
-
}
|
|
367
|
-
extractPeopleInfo(text) {
|
|
368
|
-
// 简化的人物信息提取逻辑
|
|
369
|
-
return [];
|
|
370
|
-
}
|
|
371
|
-
extractTechnicalInfo(text) {
|
|
372
|
-
// 简化的技术信息提取逻辑
|
|
373
|
-
return {};
|
|
374
|
-
}
|
|
375
|
-
extractUIDesignInfo(text) {
|
|
376
|
-
// UI设计信息提取逻辑
|
|
377
|
-
const uiInfo = {
|
|
378
|
-
layout_type: this.extractValue(text, /布局类型[::]\s*([^\n]+)/i) || '未识别',
|
|
379
|
-
components: this.extractUIComponents(text),
|
|
380
|
-
color_scheme: this.extractColorScheme(text),
|
|
381
|
-
typography: this.extractTypography(text),
|
|
382
|
-
navigation: this.extractNavigation(text),
|
|
383
|
-
responsive_design: this.extractBoolean(text, /响应式|自适应/i),
|
|
384
|
-
design_patterns: this.extractList(text, /设计模式[::]\s*([^\n]+)/i),
|
|
385
|
-
accessibility_features: this.extractList(text, /可访问性[::]\s*([^\n]+)/i)
|
|
386
|
-
};
|
|
387
|
-
return uiInfo;
|
|
388
|
-
}
|
|
389
|
-
extractRequirementInfo(text) {
|
|
390
|
-
// 需求信息提取逻辑
|
|
391
|
-
const reqInfo = {
|
|
392
|
-
functional_requirements: this.extractFunctionalRequirements(text),
|
|
393
|
-
non_functional_requirements: this.extractNonFunctionalRequirements(text),
|
|
394
|
-
user_stories: this.extractUserStories(text),
|
|
395
|
-
business_rules: this.extractList(text, /业务规则[::]\s*([^\n]+)/i),
|
|
396
|
-
constraints: this.extractList(text, /约束条件[::]\s*([^\n]+)/i),
|
|
397
|
-
assumptions: this.extractList(text, /假设条件[::]\s*([^\n]+)/i)
|
|
398
|
-
};
|
|
399
|
-
return reqInfo;
|
|
400
|
-
}
|
|
401
|
-
// 辅助提取方法
|
|
402
|
-
extractValue(text, pattern) {
|
|
403
|
-
const match = text.match(pattern);
|
|
404
|
-
return match ? match[1].trim() : null;
|
|
405
|
-
}
|
|
406
|
-
extractBoolean(text, pattern) {
|
|
407
|
-
return pattern.test(text);
|
|
408
|
-
}
|
|
409
|
-
extractList(text, pattern) {
|
|
410
|
-
const match = text.match(pattern);
|
|
411
|
-
if (match) {
|
|
412
|
-
return match[1].split(/[,,、]/).map(item => item.trim()).filter(Boolean);
|
|
413
|
-
}
|
|
414
|
-
return [];
|
|
415
|
-
}
|
|
416
|
-
extractUIComponents(text) {
|
|
417
|
-
// 简化的UI组件提取逻辑
|
|
418
|
-
const components = [];
|
|
419
|
-
const componentPatterns = [
|
|
420
|
-
/按钮|button/gi,
|
|
421
|
-
/输入框|input|文本框/gi,
|
|
422
|
-
/导航|navigation|nav/gi,
|
|
423
|
-
/卡片|card/gi,
|
|
424
|
-
/列表|list/gi,
|
|
425
|
-
/表格|table/gi
|
|
426
|
-
];
|
|
427
|
-
componentPatterns.forEach((pattern, index) => {
|
|
428
|
-
const matches = text.match(pattern);
|
|
429
|
-
if (matches) {
|
|
430
|
-
components.push({
|
|
431
|
-
type: ['button', 'input', 'navigation', 'card', 'list', 'table'][index],
|
|
432
|
-
name: matches[0],
|
|
433
|
-
position: { x: 0, y: 0, width: 0, height: 0 },
|
|
434
|
-
properties: {}
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
return components;
|
|
439
|
-
}
|
|
440
|
-
extractColorScheme(text) {
|
|
441
|
-
return {
|
|
442
|
-
primary_colors: this.extractList(text, /主色调[::]\s*([^\n]+)/i),
|
|
443
|
-
secondary_colors: this.extractList(text, /辅助色[::]\s*([^\n]+)/i),
|
|
444
|
-
background_colors: this.extractList(text, /背景色[::]\s*([^\n]+)/i)
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
extractTypography(text) {
|
|
448
|
-
return {
|
|
449
|
-
fonts: this.extractList(text, /字体[::]\s*([^\n]+)/i),
|
|
450
|
-
text_hierarchy: this.extractList(text, /文字层次[::]\s*([^\n]+)/i)
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
extractNavigation(text) {
|
|
454
|
-
return {
|
|
455
|
-
type: this.extractValue(text, /导航类型[::]\s*([^\n]+)/i) || '未识别',
|
|
456
|
-
elements: this.extractList(text, /导航元素[::]\s*([^\n]+)/i)
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
extractFunctionalRequirements(text) {
|
|
460
|
-
// 简化的功能需求提取逻辑
|
|
461
|
-
const requirements = [];
|
|
462
|
-
const funcReqPattern = /功能需求[::][\s\S]*?(?=非功能需求|用户故事|$)/i;
|
|
463
|
-
const match = text.match(funcReqPattern);
|
|
464
|
-
if (match) {
|
|
465
|
-
const reqText = match[0];
|
|
466
|
-
const reqItems = reqText.split(/\d+\./).filter(item => item.trim());
|
|
467
|
-
reqItems.forEach((item, index) => {
|
|
468
|
-
if (item.trim()) {
|
|
469
|
-
requirements.push({
|
|
470
|
-
id: `FR-${index + 1}`,
|
|
471
|
-
title: item.split('\n')[0].trim(),
|
|
472
|
-
description: item.trim(),
|
|
473
|
-
priority: 'medium',
|
|
474
|
-
category: '功能需求',
|
|
475
|
-
acceptance_criteria: []
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
return requirements;
|
|
481
|
-
}
|
|
482
|
-
extractNonFunctionalRequirements(text) {
|
|
483
|
-
// 简化的非功能需求提取逻辑
|
|
484
|
-
const requirements = [];
|
|
485
|
-
const nfrTypes = ['性能', '安全', '可用性', '可维护性', '可扩展性'];
|
|
486
|
-
nfrTypes.forEach(type => {
|
|
487
|
-
const pattern = new RegExp(`${type}[::]\\s*([^\\n]+)`, 'i');
|
|
488
|
-
const match = text.match(pattern);
|
|
489
|
-
if (match) {
|
|
490
|
-
requirements.push({
|
|
491
|
-
type: type,
|
|
492
|
-
description: match[1].trim(),
|
|
493
|
-
metric: '',
|
|
494
|
-
target_value: ''
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
});
|
|
498
|
-
return requirements;
|
|
499
|
-
}
|
|
500
|
-
extractUserStories(text) {
|
|
501
|
-
// 简化的用户故事提取逻辑
|
|
502
|
-
const stories = [];
|
|
503
|
-
const storyPattern = /作为.*?我希望.*?以便.*?/g;
|
|
504
|
-
const matches = text.match(storyPattern);
|
|
505
|
-
if (matches) {
|
|
506
|
-
matches.forEach((story, index) => {
|
|
507
|
-
const parts = story.split(/我希望|以便/);
|
|
508
|
-
if (parts.length >= 3) {
|
|
509
|
-
stories.push({
|
|
510
|
-
as_a: parts[0].replace('作为', '').trim(),
|
|
511
|
-
i_want: parts[1].trim(),
|
|
512
|
-
so_that: parts[2].trim(),
|
|
513
|
-
acceptance_criteria: [],
|
|
514
|
-
priority: 'medium'
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
return stories;
|
|
520
|
-
}
|
|
521
|
-
formatFileSize(bytes) {
|
|
522
|
-
if (bytes === 0)
|
|
523
|
-
return '0 B';
|
|
524
|
-
const k = 1024;
|
|
525
|
-
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
526
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
527
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
exports.ImageAnalyzer = ImageAnalyzer;
|