@cpzxrobot/sdk 1.3.116 → 1.3.118

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/AIFORM_GATEWAY.md CHANGED
@@ -1,449 +1,399 @@
1
- # AI报表模板接口使用说明
1
+ # AI报表 接口文档
2
2
 
3
- ## 概述
3
+ ---
4
4
 
5
- AI报表模板接口用于管理工厂的AI报表模板,包括查询模板列表、新增和修改模板等功能。
6
-
7
- ## 接口基础信息
8
-
9
- **Base URL**: `/api/v2/aiform/template`
10
-
11
- ## 如何使用
12
-
13
- 通过 `cpzxrobot().aiform.template` 访问AI报表模板相关功能。
14
-
15
- 通过 `cpzxrobot().aiform.record` 访问文件上传和记录相关功能。
16
-
17
- ## 可用方法
18
-
19
- ### 1. 查询模板列表
20
-
21
- **方法**: `list(factoryId: number): Promise<AiformTemplateListResponse>`
5
+ ## 1. 按 factoryId 查询模板列表
22
6
 
23
7
  **接口路径**: `GET /api/v2/aiform/template/list/{factoryId}`
24
8
 
25
- **功能**: 根据工厂ID查询该工厂下的所有AI报表模板
9
+ **接口描述**: 根据工厂ID查询该工厂下的所有AI报表模板
26
10
 
27
- **参数**:
28
- - `factoryId` (number): 工厂ID,必填
11
+ **请求参数**:
29
12
 
30
- **返回值**:
31
- ```typescript
32
- interface AiformTemplateListResponse {
33
- code: number; // 状态码
34
- message: string; // 提示信息
35
- data: AiformTemplate[]; // 模板列表
36
- }
13
+ | 参数名 | 位置 | 类型 | 必填 | 说明 |
14
+ |--------|------|------|------|------|
15
+ | factoryId | path | Long | 是 | 工厂ID |
16
+
17
+ **请求示例**:
37
18
 
38
- interface AiformTemplate {
39
- id: number; // 模板ID
40
- factoryId: number; // 工厂ID
41
- name: string; // 模板名称
42
- content: string; // 模板内容
43
- attention?: string; // 注意事项
44
- }
19
+ ```
20
+ GET /api/v2/aiform/template/list/17231604990917
45
21
  ```
46
22
 
47
- **使用示例**:
48
-
49
- ```javascript
50
- // 查询工厂1001的模板列表
51
- const response = await cpzxrobot().aiform.template.list(1001);
52
-
53
- if (response.code === 200) {
54
- const templates = response.data;
55
- console.log(`找到 ${templates.length} 个模板:`);
56
-
57
- templates.forEach(template => {
58
- console.log(`ID: ${template.id}, 名称: ${template.name}`);
59
- console.log(`内容: ${template.content.substring(0, 100)}...`);
60
- if (template.attention) {
61
- console.log(`注意事项: ${template.attention}`);
23
+ **响应参数**:
24
+
25
+ | 参数名 | 类型 | 说明 |
26
+ |--------|------|------|
27
+ | code | int | 状态码 |
28
+ | message | String | 提示信息 |
29
+ | data | Array\<AiformTemplateVO\> | 模板列表 |
30
+
31
+ **data 数组元素字段(AiformTemplateVO)**:
32
+
33
+ | 参数名 | 类型 | 说明 |
34
+ |--------|------|------|
35
+ | id | Long | 模板ID |
36
+ | factoryId | Long | 工厂ID |
37
+ | name | String | 模板名称 |
38
+ | content | String | 模板内容 |
39
+ | attention | TemplateAttention | 注意事项(对象) |
40
+
41
+ **attention 字段(TemplateAttention)**:
42
+
43
+ | 参数名 | 类型 | 说明 |
44
+ |--------|------|------|
45
+ | hasFixedContent | Boolean | 是否有固定内容 |
46
+ | fixedContentList | Array\<String\> | 固定内容列表 |
47
+ | hasFixedRowContent | Boolean | 是否有固定行内容 |
48
+ | rowContent | String | 行内容 |
49
+ | hasFixedColumnContent | Boolean | 是否有固定列内容 |
50
+ | columnContent | String | 列内容 |
51
+ | otherNotes | String | 其他备注 |
52
+
53
+ **响应示例**:
54
+
55
+ ```json
56
+ {
57
+ "code": 200,
58
+ "message": "SUCCESS",
59
+ "data": [
60
+ {
61
+ "id": 1,
62
+ "factoryId": 17231604990917,
63
+ "name": "栋舍巡检报表",
64
+ "content": "进行分娩舍的巡检记录",
65
+ "attention": {
66
+ "hasFixedContent": false,
67
+ "fixedContentList": [],
68
+ "hasFixedRowContent": true,
69
+ "rowContent": "每头母猪和仔猪的日常记录情况",
70
+ "hasFixedColumnContent": false,
71
+ "columnContent": "",
72
+ "otherNotes": ""
73
+ }
62
74
  }
63
- });
64
- } else {
65
- console.error('获取模板列表失败:', response.message);
75
+ ]
66
76
  }
67
77
  ```
68
78
 
69
- ### 2. 新增或修改模板
79
+ ---
70
80
 
71
- **方法**: `save(request: AiformTemplateSaveRequest): Promise<AiformTemplateSaveResponse>`
81
+ ## 2. 新增或修改模板
72
82
 
73
83
  **接口路径**: `POST /api/v2/aiform/template/save`
74
84
 
75
- **功能**: 新增或修改AI报表模板。当请求体中包含 `id` 时执行修改操作,不包含 `id` 时执行新增操作。
76
-
77
- **请求参数**:
78
- ```typescript
79
- interface AiformTemplateSaveRequest {
80
- id?: number; // 模板ID(传则修改,不传则新增)
81
- factoryId: number; // 工厂ID,必填
82
- name: string; // 模板名称,必填
83
- content: string; // 模板内容,必填
84
- attention?: string; // 注意事项,可选
85
+ **接口描述**: 新增或修改AI报表模板。当请求体中包含 `id` 时执行修改操作,不包含 `id` 时执行新增操作。
86
+
87
+ **请求头**:
88
+
89
+ | Header | 值 |
90
+ |--------|----|
91
+ | Content-Type | application/json |
92
+
93
+ **请求体参数(AiformTemplateVO)**:
94
+
95
+ | 参数名 | 类型 | 必填 | 说明 |
96
+ |--------|------|------|------|
97
+ | id | Long | 否 | 模板ID(传则修改,不传则新增) |
98
+ | factoryId | Long | 是 | 工厂ID |
99
+ | name | String | 是 | 模板名称 |
100
+ | content | String | 是 | 模板内容 |
101
+ | attention | TemplateAttention | 否 | 注意事项(对象) |
102
+
103
+ **attention 字段(TemplateAttention)**:
104
+
105
+ | 参数名 | 类型 | 必填 | 说明 |
106
+ |--------|------|------|------|
107
+ | hasFixedContent | Boolean | 否 | 是否有固定内容 |
108
+ | fixedContentList | Array\<String\> | 否 | 固定内容列表 |
109
+ | hasFixedRowContent | Boolean | 否 | 是否有固定行内容 |
110
+ | rowContent | String | 否 | 行内容 |
111
+ | hasFixedColumnContent | Boolean | 否 | 是否有固定列内容 |
112
+ | columnContent | String | 否 | 列内容 |
113
+ | otherNotes | String | 否 | 其他备注 |
114
+
115
+ **新增请求示例**:
116
+
117
+ ```json
118
+ {
119
+ "factoryId": 17231604990917,
120
+ "name": "栋舍巡检报表",
121
+ "content": "进行分娩舍的巡检记录",
122
+ "attention": {
123
+ "hasFixedContent": false,
124
+ "fixedContentList": [],
125
+ "hasFixedRowContent": true,
126
+ "rowContent": "每头母猪和仔猪的日常记录情况",
127
+ "hasFixedColumnContent": false,
128
+ "columnContent": "",
129
+ "otherNotes": ""
130
+ }
85
131
  }
86
132
  ```
87
133
 
88
- **返回值**:
89
- ```typescript
90
- interface AiformTemplateSaveResponse {
91
- code: number; // 状态码
92
- message: string; // 提示信息
134
+ **修改请求示例**:
135
+
136
+ ```json
137
+ {
138
+ "id": 1,
139
+ "factoryId": 17231604990917,
140
+ "name": "栋舍巡检报表(修改)",
141
+ "content": "修改后的巡检记录内容",
142
+ "attention": {
143
+ "hasFixedContent": true,
144
+ "fixedContentList": ["温度", "湿度"],
145
+ "hasFixedRowContent": true,
146
+ "rowContent": "每头母猪和仔猪的日常记录情况",
147
+ "hasFixedColumnContent": false,
148
+ "columnContent": "",
149
+ "otherNotes": "需关注异常情况"
150
+ }
93
151
  }
94
152
  ```
95
153
 
96
- **使用示例**:
154
+ **响应参数**:
97
155
 
98
- #### 新增模板
156
+ | 参数名 | 类型 | 说明 |
157
+ |--------|------|------|
158
+ | code | int | 状态码 |
159
+ | message | String | 提示信息 |
99
160
 
100
- ```javascript
101
- // 新增模板
102
- const response = await cpzxrobot().aiform.template.save({
103
- factoryId: 1001,
104
- name: "生产日报模板",
105
- content: "## 生产日报\n\n日期: {{date}}\n\n产量: {{production}}\n\n质量: {{quality}}",
106
- attention: "请确保填写真实数据"
107
- });
161
+ **响应示例**:
108
162
 
109
- if (response.code === 200) {
110
- console.log('模板创建成功');
111
- } else {
112
- console.error('模板创建失败:', response.message);
163
+ ```json
164
+ {
165
+ "code": 200,
166
+ "message": "SUCCESS"
113
167
  }
114
168
  ```
115
169
 
116
- #### 修改模板
117
-
118
- ```javascript
119
- // 修改模板
120
- const response = await cpzxrobot().aiform.template.save({
121
- id: 1, // 模板ID
122
- factoryId: 1001,
123
- name: "生产日报模板(更新版)",
124
- content: "## 生产日报\n\n日期: {{date}}\n\n产量: {{production}}\n\n质量: {{quality}}\n\n备注: {{remark}}",
125
- attention: "请确保填写真实数据,新增加了备注字段"
126
- });
127
-
128
- if (response.code === 200) {
129
- console.log('模板更新成功');
130
- } else {
131
- console.error('模板更新失败:', response.message);
132
- }
133
- ```
170
+ ---
171
+
172
+ ---
173
+
174
+ # AI报表文件 接口
175
+
176
+ **Base URL**: `/api/v2/aiform/file`
134
177
 
135
- ### 3. 上传表格图片
178
+ ---
136
179
 
137
- **方法**: `upload(file: File, templateId: number): Promise<AiformFileUploadResponse>`
180
+ ## 3. 上传表格图片
138
181
 
139
182
  **接口路径**: `POST /api/v2/aiform/file/upload`
140
183
 
141
- **功能**: 上传表格图片到 MinIO,并关联到指定的模板。上传成功后自动异步触发大模型解析。
184
+ **接口描述**: 上传表格图片到 MinIO,并关联到指定的模板。上传成功后自动触发大模型解析。返回文件记录(含 code),可通过接口4轮询文件状态,通过接口5根据 code 获取解析结果和预签名访问链接。
142
185
 
143
- **参数**:
144
- - `file` (File): 表格图片文件,必填
145
- - `templateId` (number): 关联的模板ID,必填
186
+ **请求头**:
146
187
 
147
- **返回值**:
148
- ```typescript
149
- interface AiformFileUploadResponse {
150
- code: number; // 状态码
151
- message: string; // 提示信息
152
- data: File; // 文件记录
153
- }
188
+ | Header | 值 |
189
+ |--------|----|
190
+ | Content-Type | multipart/form-data |
154
191
 
155
- interface File {
156
- id: number; // 文件记录ID
157
- code?: string; // 业务编码
158
- tableKey: number; // 关联业务ID(模板ID)
159
- tableName: string; // 关联业务表名(固定值 aiform_template)
160
- fileName: string; // 原始文件名
161
- storageName: string; // 存储文件名
162
- fileUrl: string; // MinIO存储路径
163
- accessUrl: string; // 预签名访问链接
164
- fileExt: string; // 文件扩展名
165
- server: string; // 存储服务(minio)
166
- type: string; // 文件类型(image)
167
- status: number; // 状态:0-已上传 1-解析中 2-已解析
168
- createTime: string; // 创建时间
169
- updateTime: string; // 更新时间
170
- }
171
- ```
192
+ **请求参数**:
172
193
 
173
- **使用示例**:
174
-
175
- ```javascript
176
- // HTML文件输入示例
177
- <input type="file" id="fileInput" accept="image/*">
178
-
179
- // 上传文件
180
- async function uploadFile() {
181
- const fileInput = document.getElementById('fileInput');
182
- const file = fileInput.files[0];
183
- const templateId = 1; // 模板ID
184
-
185
- if (!file) {
186
- alert('请选择文件');
187
- return;
194
+ | 参数名 | 位置 | 类型 | 必填 | 说明 |
195
+ |--------|------|------|------|------|
196
+ | file | form-data | MultipartFile | 是 | 表格图片文件 |
197
+ | templateId | form-data | Long | 是 | 关联的模板ID |
198
+
199
+ **响应参数**:
200
+
201
+ | 参数名 | 类型 | 说明 |
202
+ |--------|------|------|
203
+ | code | int | 状态码 |
204
+ | message | String | 提示信息 |
205
+ | data | File | 文件记录 |
206
+
207
+ **data 字段(File,通用文件表 `app_v2_file`)**:
208
+
209
+ | 参数名 | 类型 | 说明 |
210
+ |--------|------|------|
211
+ | id | Long | 文件记录ID |
212
+ | code | String | 业务编码(用于调用详情接口) |
213
+ | tableKey | Long | 关联业务ID(此处为模板ID) |
214
+ | tableName | String | 关联业务表名(固定值 `aiform_template`) |
215
+ | fileName | String | 原始文件名 |
216
+ | storageName | String | 存储文件名(系统统一生成) |
217
+ | fileUrl | String | MinIO存储路径 |
218
+ | fileExt | String | 文件扩展名 |
219
+ | server | String | 存储服务(minio) |
220
+ | type | String | 文件类型(image) |
221
+ | status | Integer | 状态:0-已上传 1-解析中 2-已解析 |
222
+ | createUserId | Long | 创建用户ID |
223
+ | createTime | String | 创建时间 |
224
+ | updateTime | String | 更新时间 |
225
+
226
+ **响应示例**:
227
+
228
+ ```json
229
+ {
230
+ "code": 200,
231
+ "message": "SUCCESS",
232
+ "data": {
233
+ "id": 1,
234
+ "code": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
235
+ "tableKey": 1,
236
+ "tableName": "aiform_template",
237
+ "fileName": "巡检报表20260301.png",
238
+ "storageName": "20260301120000000123.png",
239
+ "fileUrl": "aiform/1/20260301120000000123.png",
240
+ "fileExt": "png",
241
+ "server": "minio",
242
+ "type": "image",
243
+ "status": 0,
244
+ "createUserId": 100,
245
+ "createTime": "2026-03-01 12:00:00",
246
+ "updateTime": "2026-03-01 12:00:00"
188
247
  }
189
-
190
- try {
191
- const response = await cpzxrobot().aiform.record.upload(file, templateId);
192
- console.log('上传成功:', response.data);
193
- console.log('文件状态:', getFileStatusText(response.data.status));
194
- console.log('访问链接:', response.data.accessUrl);
195
-
196
- // 可以开始轮询状态
197
- trackFileStatus(templateId, response.data.id);
198
- } catch (error) {
199
- console.error('上传失败:', error.message);
200
- }
201
- }
202
-
203
- function getFileStatusText(status) {
204
- const statusMap = {
205
- 0: '已上传',
206
- 1: '解析中',
207
- 2: '已解析'
208
- };
209
- return statusMap[status] || '未知';
210
248
  }
211
-
212
- // 绑定事件
213
- document.getElementById('fileInput').addEventListener('change', uploadFile);
214
249
  ```
215
250
 
216
- ### 4. 根据模板ID查询上传记录
251
+ ---
217
252
 
218
- **方法**: `list(templateId: number): Promise<AiformFileListResponse>`
253
+ ## 4. 根据模板ID查询上传记录
219
254
 
220
255
  **接口路径**: `GET /api/v2/aiform/file/list/{templateId}`
221
256
 
222
- **功能**: 根据模板ID查询该模板下所有上传的文件记录,按创建时间倒序排列。
257
+ **接口描述**: 根据模板ID查询该模板下所有上传的文件记录,按创建时间倒序排列。返回精简的文件列表(FileVO),如需解析结果或预签名访问链接请调用接口5。
223
258
 
224
- **参数**:
225
- - `templateId` (number): 模板ID,必填
259
+ **请求参数**:
226
260
 
227
- **返回值**:
228
- ```typescript
229
- interface AiformFileListResponse {
230
- code: number; // 状态码
231
- message: string; // 提示信息
232
- data: File[]; // 文件记录列表
233
- }
234
- ```
261
+ | 参数名 | 位置 | 类型 | 必填 | 说明 |
262
+ |--------|------|------|------|------|
263
+ | templateId | path | Long | 是 | 模板ID |
235
264
 
236
- **使用示例**:
237
-
238
- ```javascript
239
- // 获取模板的上传记录
240
- async function getTemplateRecords(templateId) {
241
- try {
242
- const response = await cpzxrobot().aiform.record.list(templateId);
243
-
244
- if (response.code === 200) {
245
- const records = response.data;
246
- console.log(`找到 ${records.length} 条上传记录:`);
247
-
248
- records.forEach((record, index) => {
249
- console.log(`\n记录 ${index + 1}:`);
250
- console.log(`文件名: ${record.fileName}`);
251
- console.log(`状态: ${getFileStatusText(record.status)}`);
252
- console.log(`创建时间: ${record.createTime}`);
253
- console.log(`访问链接: ${record.accessUrl}`);
254
- });
255
- }
256
- } catch (error) {
257
- console.error('获取记录失败:', error.message);
258
- }
259
- }
265
+ **请求示例**:
260
266
 
261
- // 调用示例
262
- getTemplateRecords(1); // 查询模板ID为1的上传记录
267
+ ```
268
+ GET /api/v2/aiform/file/list/1
263
269
  ```
264
270
 
265
- ### 5. 轮询文件解析状态
266
-
267
- **功能**: 上传文件后,需要轮询文件状态以确认解析进度。
268
-
269
- **使用示例**:
270
-
271
- ```javascript
272
- async function trackFileStatus(templateId, fileId) {
273
- let status = 0; // 初始状态
274
- let attempts = 0;
275
- const maxAttempts = 30; // 最多轮询30次
276
-
277
- console.log('开始跟踪文件解析状态...');
278
-
279
- while (status !== 2 && attempts < maxAttempts) {
280
- try {
281
- const response = await cpzxrobot().aiform.record.list(templateId);
282
- const fileRecord = response.data.find(record => record.id === fileId);
283
-
284
- if (fileRecord) {
285
- status = fileRecord.status;
286
- console.log(`当前状态: ${getFileStatusText(status)}`);
287
-
288
- if (status === 2) {
289
- console.log('文件已成功解析!');
290
- return;
291
- }
292
- }
293
-
294
- await new Promise(resolve => setTimeout(resolve, 5000)); // 每5秒轮询一次
295
- attempts++;
296
- } catch (error) {
297
- console.error('轮询失败:', error.message);
298
- await new Promise(resolve => setTimeout(resolve, 5000));
299
- attempts++;
271
+ **响应参数**:
272
+
273
+ | 参数名 | 类型 | 说明 |
274
+ |--------|------|------|
275
+ | code | int | 状态码 |
276
+ | message | String | 提示信息 |
277
+ | data | Array\<FileVO\> | 文件记录列表 |
278
+
279
+ **data 数组元素字段(FileVO)**:
280
+
281
+ | 参数名 | 类型 | 说明 |
282
+ |--------|------|------|
283
+ | code | String | 业务编码(用于调用详情接口) |
284
+ | storageName | String | 存储文件名 |
285
+ | status | Integer | 状态:0-已上传 1-解析中 2-已解析 |
286
+ | createUserId | Long | 创建用户ID |
287
+ | createTime | String | 创建时间(RFC 3339 格式,如 `2026-03-02T10:00:00+08:00`) |
288
+ | updateTime | String | 更新时间(RFC 3339 格式,如 `2026-03-02T10:05:00+08:00`) |
289
+
290
+ **status 状态说明**:
291
+
292
+ | 值 | 含义 |
293
+ |----|------|
294
+ | 0 | 已上传 |
295
+ | 1 | 解析中 |
296
+ | 2 | 已解析 |
297
+
298
+ **响应示例**:
299
+
300
+ ```json
301
+ {
302
+ "code": 200,
303
+ "message": "SUCCESS",
304
+ "data": [
305
+ {
306
+ "code": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
307
+ "storageName": "20260302100000000456.png",
308
+ "status": 2,
309
+ "createUserId": 100,
310
+ "createTime": "2026-03-02T10:00:00+08:00",
311
+ "updateTime": "2026-03-02T10:05:00+08:00"
312
+ },
313
+ {
314
+ "code": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
315
+ "storageName": "20260301120000000123.png",
316
+ "status": 0,
317
+ "createUserId": 100,
318
+ "createTime": "2026-03-01T12:00:00+08:00",
319
+ "updateTime": "2026-03-01T12:00:00+08:00"
300
320
  }
301
- }
302
-
303
- if (attempts >= maxAttempts) {
304
- console.log('解析超时,请稍后手动检查状态');
305
- }
321
+ ]
306
322
  }
307
323
  ```
308
324
 
309
- ## 错误处理
325
+ ---
310
326
 
311
- ### 常见错误
327
+ ## 5. 根据文件code获取详情
312
328
 
313
- 1. **参数验证错误**:
314
- - `工厂ID不能为空` - 未提供factoryId参数
315
- - `模板名称不能为空` - 未提供name参数
316
- - `模板内容不能为空` - 未提供content参数
317
- - `文件不能为空` - 未提供file参数
318
- - `模板ID不能为空` - 未提供templateId参数
329
+ **接口路径**: `GET /api/v2/aiform/file/detail/{code}`
319
330
 
320
- 2. **API错误**:
321
- - 当API返回非200状态码时,会抛出包含错误信息的异常
331
+ **接口描述**: 根据文件业务编码(code)获取解析结果和预签名访问链接。需在列表接口中获取 code 后调用。
322
332
 
323
- ### 错误处理示例
333
+ **请求参数**:
324
334
 
325
- ```javascript
326
- try {
327
- // 尝试获取模板列表
328
- const response = await cpzxrobot().aiform.template.list(1001);
329
- console.log('模板列表:', response.data);
330
- } catch (error) {
331
- console.error('操作失败:', error.message);
332
- }
335
+ | 参数名 | 位置 | 类型 | 必填 | 说明 |
336
+ |--------|------|------|------|------|
337
+ | code | path | String | 是 | 文件业务编码(上传或列表接口返回) |
333
338
 
334
- try {
335
- // 尝试保存模板
336
- const response = await cpzxrobot().aiform.template.save({
337
- factoryId: 1001,
338
- name: "测试模板",
339
- content: "模板内容"
340
- });
341
- console.log('保存成功:', response.message);
342
- } catch (error) {
343
- console.error('保存失败:', error.message);
344
- }
339
+ **请求示例**:
345
340
 
346
- try {
347
- // 尝试上传文件
348
- const file = document.getElementById('fileInput').files[0];
349
- const response = await cpzxrobot().aiform.record.upload(file, 1);
350
- console.log('上传成功:', response.data);
351
- } catch (error) {
352
- console.error('上传失败:', error.message);
353
- }
354
-
355
- try {
356
- // 尝试获取上传记录
357
- const response = await cpzxrobot().aiform.record.list(1);
358
- console.log('上传记录:', response.data);
359
- } catch (error) {
360
- console.error('获取记录失败:', error.message);
361
- }
341
+ ```
342
+ GET /api/v2/aiform/file/detail/a1b2c3d4-e5f6-7890-abcd-ef1234567890
362
343
  ```
363
344
 
364
- ## 完整使用示例
365
-
366
- ```javascript
367
- async function manageAITemplates() {
368
- try {
369
- const aiform = cpzxrobot().aiform.template;
370
- const factoryId = 1001;
371
-
372
- console.log('=== 管理AI报表模板 ===');
373
-
374
- // 1. 获取模板列表
375
- console.log('\n1. 获取模板列表:');
376
- const listResponse = await aiform.list(factoryId);
377
- if (listResponse.code === 200) {
378
- console.log(`找到 ${listResponse.data.length} 个模板:`);
379
- listResponse.data.forEach((template, index) => {
380
- console.log(` ${index + 1}. ${template.name} (ID: ${template.id})`);
381
- });
382
- }
383
-
384
- // 2. 新增模板
385
- console.log('\n2. 新增模板:');
386
- const createResponse = await aiform.save({
387
- factoryId: factoryId,
388
- name: "新增测试模板",
389
- content: "## 测试模板\n\n这是一个测试模板",
390
- attention: "测试用模板"
391
- });
392
- console.log(`新增结果: ${createResponse.message}`);
393
-
394
- // 3. 再次获取模板列表
395
- console.log('\n3. 再次获取模板列表:');
396
- const updatedListResponse = await aiform.list(factoryId);
397
- if (updatedListResponse.code === 200) {
398
- console.log(`现在有 ${updatedListResponse.data.length} 个模板:`);
399
- updatedListResponse.data.forEach((template, index) => {
400
- console.log(` ${index + 1}. ${template.name} (ID: ${template.id})`);
401
- });
402
- }
403
-
404
- // 4. 修改最后一个模板
405
- if (updatedListResponse.data.length > 0) {
406
- const lastTemplate = updatedListResponse.data[updatedListResponse.data.length - 1];
407
- console.log(`\n4. 修改模板: ${lastTemplate.name}`);
408
-
409
- const updateResponse = await aiform.save({
410
- id: lastTemplate.id,
411
- factoryId: factoryId,
412
- name: `${lastTemplate.name} (已更新)`,
413
- content: lastTemplate.content + '\n\n更新时间: ' + new Date().toLocaleString(),
414
- attention: lastTemplate.attention + ' - 已更新'
415
- });
416
- console.log(`修改结果: ${updateResponse.message}`);
417
- }
418
-
419
- // 5. 最终模板列表
420
- console.log('\n5. 最终模板列表:');
421
- const finalListResponse = await aiform.list(factoryId);
422
- if (finalListResponse.code === 200) {
423
- console.log(`最终有 ${finalListResponse.data.length} 个模板:`);
424
- finalListResponse.data.forEach((template, index) => {
425
- console.log(` ${index + 1}. ${template.name} (ID: ${template.id})`);
426
- });
427
- }
428
-
429
- } catch (error) {
430
- console.error('操作失败:', error.message);
345
+ **响应参数**:
346
+
347
+ | 参数名 | 类型 | 说明 |
348
+ |--------|------|------|
349
+ | code | int | 状态码 |
350
+ | message | String | 提示信息 |
351
+ | data | AiformParseResultVO | 解析结果详情 |
352
+
353
+ **data 字段(AiformParseResultVO)**:
354
+
355
+ | 参数名 | 类型 | 说明 |
356
+ |--------|------|------|
357
+ | content | String | markdown 解析的表格内容 |
358
+ | unclears | Array\<String\> | 疑似不清晰处的描述说明 |
359
+ | description | String | 整体解析说明 |
360
+ | parseResult | String | 解析结果(兼容旧数据或解析失败时的原始结果) |
361
+ | accessUrl | String | 预签名访问链接(有效期7天) |
362
+
363
+ **响应示例**:
364
+
365
+ ```json
366
+ {
367
+ "code": 200,
368
+ "message": "SUCCESS",
369
+ "data": {
370
+ "content": "| 列1 | 列2 |\n|-----|-----|\n| 值1 | 值2 |",
371
+ "unclears": ["第3行第2列字迹模糊"],
372
+ "description": "表格共3行2列,已完整解析",
373
+ "parseResult": null,
374
+ "accessUrl": "https://minio.cpzxrobot.com/app/aiform/1/20260302100000000456.png?X-Amz-..."
431
375
  }
432
376
  }
433
-
434
- // 执行操作
435
- manageAITemplates();
436
377
  ```
437
378
 
438
- ## 注意事项
379
+ ---
380
+
381
+ **文件状态流转说明**:
382
+
383
+ 上传成功后系统自动异步调用大模型(Qwen3-VL-235B)解析图片,文件状态流转如下:
384
+
385
+ - `0`(已上传)→ `1`(解析中)→ `2`(已解析)
386
+ - 解析失败时回退为 `0`(已上传)
439
387
 
440
- 1. **权限要求**: 使用这些接口需要具有相应的工厂管理权限
441
- 2. **模板内容**: 模板内容支持使用模板变量(如 `{{date}}`),具体变量格式请参考AI报表系统的相关文档
442
- 3. **参数验证**: 所有必填参数必须提供,否则会抛出错误
443
- 4. **错误处理**: 建议使用 try-catch 捕获可能的错误
444
- 5. **网络请求**: 这些接口是异步网络请求,需要使用 `async/await` 或 Promise 处理
388
+ 解析结果持久化到 `aiform_parse_result` 表,按 `content`(表格内容)、`unclears`(疑似不清晰处)、`description`(整体说明)三个字段存储,可通过接口5根据文件 code 获取。
445
389
 
446
- ## 版本信息
390
+ ---
447
391
 
448
- - **SDK版本**: 1.3.114+
449
- - **接口版本**: v2
392
+ ## 公共错误响应
393
+
394
+ ```json
395
+ {
396
+ "code": 400,
397
+ "message": "FAIL"
398
+ }
399
+ ```
package/aiform_gateway.ts CHANGED
@@ -5,6 +5,7 @@ import type {
5
5
  AiformTemplateSaveResponse,
6
6
  AiformFileUploadResponse,
7
7
  AiformFileListResponse,
8
+ AiformFileDetailResponse,
8
9
  } from ".";
9
10
 
10
11
  export class AiformGateway extends Object {
@@ -73,7 +74,6 @@ export class AiformGateway extends Object {
73
74
  return {
74
75
  /**
75
76
  * 上传表格图片
76
- * @param file 表格图片文件
77
77
  * @param templateId 关联的模板ID
78
78
  * @returns Promise 包含文件记录信息
79
79
  */
@@ -100,7 +100,7 @@ export class AiformGateway extends Object {
100
100
  /**
101
101
  * 根据模板ID查询上传记录
102
102
  * @param templateId 模板ID
103
- * @returns Promise 包含文件记录列表
103
+ * @returns Promise 包含文件记录列表(精简版)
104
104
  */
105
105
  list: async (templateId: number): Promise<AiformFileListResponse> => {
106
106
  const axios = await this.context.ready;
@@ -117,6 +117,27 @@ export class AiformGateway extends Object {
117
117
  return res.data;
118
118
  });
119
119
  },
120
+
121
+ /**
122
+ * 根据文件业务编码获取详情
123
+ * @param code 文件业务编码
124
+ * @returns Promise 包含解析结果详情
125
+ */
126
+ detail: async (code: string): Promise<AiformFileDetailResponse> => {
127
+ const axios = await this.context.ready;
128
+
129
+ // 参数验证
130
+ if (!code) {
131
+ throw new Error('文件业务编码不能为空');
132
+ }
133
+
134
+ return axios.get(`/api/v2/aiform/file/detail/${code}`).then((res) => {
135
+ if (res.data.code !== 200) {
136
+ throw new Error(res.data.message || '获取文件详情失败');
137
+ }
138
+ return res.data;
139
+ });
140
+ },
120
141
  };
121
142
  }
122
143
  }
@@ -67,7 +67,6 @@ class AiformGateway extends Object {
67
67
  return {
68
68
  /**
69
69
  * 上传表格图片
70
- * @param file 表格图片文件
71
70
  * @param templateId 关联的模板ID
72
71
  * @returns Promise 包含文件记录信息
73
72
  */
@@ -91,7 +90,7 @@ class AiformGateway extends Object {
91
90
  /**
92
91
  * 根据模板ID查询上传记录
93
92
  * @param templateId 模板ID
94
- * @returns Promise 包含文件记录列表
93
+ * @returns Promise 包含文件记录列表(精简版)
95
94
  */
96
95
  list: (templateId) => __awaiter(this, void 0, void 0, function* () {
97
96
  const axios = yield this.context.ready;
@@ -106,6 +105,24 @@ class AiformGateway extends Object {
106
105
  return res.data;
107
106
  });
108
107
  }),
108
+ /**
109
+ * 根据文件业务编码获取详情
110
+ * @param code 文件业务编码
111
+ * @returns Promise 包含解析结果详情
112
+ */
113
+ detail: (code) => __awaiter(this, void 0, void 0, function* () {
114
+ const axios = yield this.context.ready;
115
+ // 参数验证
116
+ if (!code) {
117
+ throw new Error('文件业务编码不能为空');
118
+ }
119
+ return axios.get(`/api/v2/aiform/file/detail/${code}`).then((res) => {
120
+ if (res.data.code !== 200) {
121
+ throw new Error(res.data.message || '获取文件详情失败');
122
+ }
123
+ return res.data;
124
+ });
125
+ }),
109
126
  };
110
127
  }
111
128
  }
@@ -131,6 +131,11 @@ class MobilePlatform {
131
131
  return this.platform.callHandler("app.scanQrcode");
132
132
  });
133
133
  }
134
+ getUserFromCache(userId) {
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ return this.platform.callHandler("app.getUserFromCache", userId);
137
+ });
138
+ }
134
139
  setTitle(title) {
135
140
  this.platform.callHandler("app.setTitle", title);
136
141
  }
@@ -313,6 +313,10 @@ class UserGateway extends Object {
313
313
  var factory = yield this.context.user.getSelectedFarm();
314
314
  var url = '/api/v1/user/info';
315
315
  if (userId) {
316
+ var userInCache = yield this.context.platform.getUserFromCache(userId);
317
+ if (userInCache) {
318
+ return userInCache;
319
+ }
316
320
  url += `/${userId}`;
317
321
  }
318
322
  return axios.get(url, {
@@ -395,6 +395,23 @@ class WebPlatform {
395
395
  }
396
396
  return Promise.resolve(this._selectedUnit);
397
397
  }
398
+ getUserFromCache(userId) {
399
+ return __awaiter(this, void 0, void 0, function* () {
400
+ // 从本地缓存中获取用户数据
401
+ const userKey = `user_${userId}`;
402
+ const userData = localStorage.getItem(userKey);
403
+ if (userData) {
404
+ try {
405
+ return JSON.parse(userData);
406
+ }
407
+ catch (error) {
408
+ console.error('Failed to parse user data from cache:', error);
409
+ return null;
410
+ }
411
+ }
412
+ return null;
413
+ });
414
+ }
398
415
  jumpToMiniApp(url) {
399
416
  window.location.href = url;
400
417
  return Promise.resolve();
@@ -148,5 +148,12 @@ class WindwosMiniAppPlatform {
148
148
  // @ts-ignore
149
149
  (_a = window.miniapp) === null || _a === void 0 ? void 0 : _a.aiAssist(args);
150
150
  }
151
+ getUserFromCache(userId) {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ var _a;
154
+ // @ts-ignore
155
+ return yield ((_a = window.miniapp) === null || _a === void 0 ? void 0 : _a.getUserFromCache(userId));
156
+ });
157
+ }
151
158
  }
152
159
  exports.WindwosMiniAppPlatform = WindwosMiniAppPlatform;
@@ -130,6 +130,10 @@ export class MobilePlatform implements PlatformInterface {
130
130
  return this.platform.callHandler("app.scanQrcode");
131
131
  }
132
132
 
133
+ async getUserFromCache(userId: number): Promise<any> {
134
+ return this.platform.callHandler("app.getUserFromCache", userId);
135
+ }
136
+
133
137
  setTitle(title: string): void {
134
138
  this.platform.callHandler("app.setTitle", title);
135
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cpzxrobot/sdk",
3
- "version": "1.3.116",
3
+ "version": "1.3.118",
4
4
  "description": "提供给上海正芯数智APP第三方H5应用使用的SDK",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -34,4 +34,5 @@ export abstract class PlatformInterface {
34
34
  //change factory
35
35
  abstract openFactorySelector():void;
36
36
  abstract aiAssist(args:AiAssistRequest):void;
37
+ abstract getUserFromCache(userId: number): Promise<any>;
37
38
  }
package/types.d.ts CHANGED
@@ -866,7 +866,7 @@ interface File {
866
866
  /** 文件记录ID */
867
867
  id: number;
868
868
  /** 业务编码 */
869
- code?: string;
869
+ code: string;
870
870
  /** 关联业务ID(此处为模板ID) */
871
871
  tableKey: number;
872
872
  /** 关联业务表名(固定值 aiform_template) */
@@ -877,8 +877,6 @@ interface File {
877
877
  storageName: string;
878
878
  /** MinIO存储路径 */
879
879
  fileUrl: string;
880
- /** 预签名访问链接(动态生成,有效期7天,不存数据库) */
881
- accessUrl: string;
882
880
  /** 文件扩展名 */
883
881
  fileExt: string;
884
882
  /** 存储服务(minio) */
@@ -887,12 +885,48 @@ interface File {
887
885
  type: string;
888
886
  /** 状态:0-已上传 1-解析中 2-已解析 */
889
887
  status: number;
888
+ /** 创建用户ID */
889
+ createUserId: number;
890
890
  /** 创建时间 */
891
891
  createTime: string;
892
892
  /** 更新时间 */
893
893
  updateTime: string;
894
894
  }
895
895
 
896
+ /**
897
+ * 文件列表项接口(FileVO)
898
+ */
899
+ interface FileVO {
900
+ /** 业务编码(用于调用详情接口) */
901
+ code: string;
902
+ /** 存储文件名 */
903
+ storageName: string;
904
+ /** 状态:0-已上传 1-解析中 2-已解析 */
905
+ status: number;
906
+ /** 创建用户ID */
907
+ createUserId: number;
908
+ /** 创建时间(RFC 3339 格式) */
909
+ createTime: string;
910
+ /** 更新时间(RFC 3339 格式) */
911
+ updateTime: string;
912
+ }
913
+
914
+ /**
915
+ * 解析结果详情接口(AiformParseResultVO)
916
+ */
917
+ interface AiformParseResultVO {
918
+ /** markdown 解析的表格内容 */
919
+ content: string;
920
+ /** 疑似不清晰处的描述说明 */
921
+ unclears: string[];
922
+ /** 整体解析说明 */
923
+ description: string;
924
+ /** 解析结果(兼容旧数据或解析失败时的原始结果) */
925
+ parseResult: string | null;
926
+ /** 预签名访问链接(有效期7天) */
927
+ accessUrl: string;
928
+ }
929
+
896
930
  /**
897
931
  * 文件上传响应接口
898
932
  */
@@ -914,7 +948,19 @@ interface AiformFileListResponse {
914
948
  /** 提示信息 */
915
949
  message: string;
916
950
  /** 文件记录列表 */
917
- data: File[];
951
+ data: FileVO[];
952
+ }
953
+
954
+ /**
955
+ * 文件详情响应接口
956
+ */
957
+ interface AiformFileDetailResponse {
958
+ /** 响应码 */
959
+ code: number;
960
+ /** 提示信息 */
961
+ message: string;
962
+ /** 解析结果详情 */
963
+ data: AiformParseResultVO;
918
964
  }
919
965
 
920
966
  declare class Cpzxrobot {
@@ -1025,8 +1071,11 @@ declare module "@cpzxrobot/sdk" {
1025
1071
  AiformTemplateSaveRequest,
1026
1072
  AiformTemplateSaveResponse,
1027
1073
  File,
1074
+ FileVO,
1075
+ AiformParseResultVO,
1028
1076
  AiformFileUploadResponse,
1029
1077
  AiformFileListResponse,
1078
+ AiformFileDetailResponse,
1030
1079
  AlarmRuleDetail,
1031
1080
  AlarmRuleListResponse,
1032
1081
  AlarmRuleDetailResponse,
package/user_gateway.ts CHANGED
@@ -342,6 +342,11 @@ export class UserGateway extends Object {
342
342
  var factory = await this.context.user.getSelectedFarm()
343
343
  var url = '/api/v1/user/info'
344
344
  if (userId) {
345
+ var userInCache = await this.context.platform.getUserFromCache(userId);
346
+ if (userInCache) {
347
+ return userInCache
348
+ }
349
+
345
350
  url += `/${userId}`
346
351
  }
347
352
  return axios.get(url, {
package/web_platform.ts CHANGED
@@ -399,6 +399,21 @@ export class WebPlatform implements PlatformInterface {
399
399
  return Promise.resolve(this._selectedUnit);
400
400
  }
401
401
 
402
+ async getUserFromCache(userId: number): Promise<any> {
403
+ // 从本地缓存中获取用户数据
404
+ const userKey = `user_${userId}`;
405
+ const userData = localStorage.getItem(userKey);
406
+ if (userData) {
407
+ try {
408
+ return JSON.parse(userData);
409
+ } catch (error) {
410
+ console.error('Failed to parse user data from cache:', error);
411
+ return null;
412
+ }
413
+ }
414
+ return null;
415
+ }
416
+
402
417
  jumpToMiniApp(url: string): Promise<void> {
403
418
  window.location.href = url;
404
419
  return Promise.resolve();
@@ -139,4 +139,9 @@ export class WindwosMiniAppPlatform implements PlatformInterface {
139
139
  // @ts-ignore
140
140
  window.miniapp?.aiAssist(args);
141
141
  }
142
+
143
+ async getUserFromCache(userId: number): Promise<any> {
144
+ // @ts-ignore
145
+ return await window.miniapp?.getUserFromCache(userId);
146
+ }
142
147
  }