yindie-erp-mcp 1.0.2 → 2.0.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.
- package/dist/client.js +54 -3
- package/dist/craft/guide.js +35 -10
- package/dist/craft/normalize-self-check.js +24 -0
- package/dist/craft/template.js +477 -94
- package/dist/index.js +42 -7
- package/dist/tool-helpers.js +32 -0
- package/dist/tool-meta.js +468 -54
- package/dist/tools-merged.js +451 -0
- package/dist/tools-write.js +36 -3
- package/dist/tools.js +131 -0
- package/package.json +5 -4
package/dist/client.js
CHANGED
|
@@ -8,16 +8,40 @@ export class YindieClient {
|
|
|
8
8
|
clientId;
|
|
9
9
|
/** token 过期时重新登录 */
|
|
10
10
|
relogin;
|
|
11
|
+
/** 当前登录用户 */
|
|
12
|
+
currentUser = null;
|
|
11
13
|
constructor(config) {
|
|
12
14
|
this.baseUrl = config.baseUrl;
|
|
13
15
|
this.token = config.token;
|
|
14
16
|
this.clientId = config.clientId;
|
|
15
17
|
this.relogin = config.relogin;
|
|
16
18
|
}
|
|
17
|
-
/**
|
|
18
|
-
async
|
|
19
|
+
/** 拉取当前用户与菜单权限 */
|
|
20
|
+
async loadSession() {
|
|
19
21
|
const info = await this.get('/system/user/getInfo');
|
|
20
|
-
|
|
22
|
+
const user = info.user;
|
|
23
|
+
if (!user?.userId || !user.userName) {
|
|
24
|
+
throw new Error('登录失败:未返回用户信息');
|
|
25
|
+
}
|
|
26
|
+
this.currentUser = {
|
|
27
|
+
userId: String(user.userId),
|
|
28
|
+
userName: user.userName,
|
|
29
|
+
nickName: user.nickName ?? user.userName,
|
|
30
|
+
deptId: user.deptId == null ? '' : String(user.deptId),
|
|
31
|
+
deptName: user.deptName ?? '',
|
|
32
|
+
roles: info.roles ?? []
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
permissions: info.permissions ?? [],
|
|
36
|
+
currentUser: this.currentUser
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** 返回当前登录用户 */
|
|
40
|
+
getCurrentUser() {
|
|
41
|
+
if (!this.currentUser) {
|
|
42
|
+
throw new Error('当前用户未初始化');
|
|
43
|
+
}
|
|
44
|
+
return this.currentUser;
|
|
21
45
|
}
|
|
22
46
|
/** GET 请求 */
|
|
23
47
|
async get(path, params) {
|
|
@@ -35,6 +59,10 @@ export class YindieClient {
|
|
|
35
59
|
async delete(path) {
|
|
36
60
|
return this.request('DELETE', path);
|
|
37
61
|
}
|
|
62
|
+
/** multipart 上传(factory 便于 401 重试重建 body;勿设 Content-Type) */
|
|
63
|
+
async postForm(path, formFactory) {
|
|
64
|
+
return this.requestForm(path, formFactory);
|
|
65
|
+
}
|
|
38
66
|
/** 统一 HTTP 请求 */
|
|
39
67
|
async request(method, path, body, params, retried = false) {
|
|
40
68
|
const url = new URL(path, this.baseUrl);
|
|
@@ -72,4 +100,27 @@ export class YindieClient {
|
|
|
72
100
|
data: result.data
|
|
73
101
|
};
|
|
74
102
|
}
|
|
103
|
+
/** multipart POST */
|
|
104
|
+
async requestForm(path, formFactory, retried = false) {
|
|
105
|
+
const url = new URL(path, this.baseUrl);
|
|
106
|
+
const headers = {
|
|
107
|
+
Authorization: `Bearer ${this.token}`,
|
|
108
|
+
clientid: this.clientId
|
|
109
|
+
};
|
|
110
|
+
const form = await formFactory();
|
|
111
|
+
const response = await fetch(url, { method: 'POST', headers, body: form });
|
|
112
|
+
const result = (await response.json());
|
|
113
|
+
if (result.code === 401 && !retried) {
|
|
114
|
+
this.token = await this.relogin();
|
|
115
|
+
return this.requestForm(path, formFactory, true);
|
|
116
|
+
}
|
|
117
|
+
if (result.code !== 200) {
|
|
118
|
+
throw new Error(result.msg || `请求失败: ${path}`);
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
success: true,
|
|
122
|
+
msg: result.msg || '操作成功',
|
|
123
|
+
data: result.data
|
|
124
|
+
};
|
|
125
|
+
}
|
|
75
126
|
}
|
package/dist/craft/guide.js
CHANGED
|
@@ -6,19 +6,24 @@ function buildExample(item) {
|
|
|
6
6
|
}
|
|
7
7
|
if (item.control === 'radio') {
|
|
8
8
|
const first = item.options?.[0] || '选项';
|
|
9
|
-
if (item.
|
|
10
|
-
return JSON.stringify({ radio:
|
|
9
|
+
if (item.alwaysInput || item.inputWhen?.includes(first)) {
|
|
10
|
+
return JSON.stringify({ radio: first, note: '备注' });
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const withNote = item.inputWhen?.[0];
|
|
13
|
+
if (withNote) {
|
|
14
|
+
return JSON.stringify({ radio: withNote, note: '备注' });
|
|
14
15
|
}
|
|
15
16
|
return JSON.stringify({ radio: first });
|
|
16
17
|
}
|
|
17
18
|
if (item.control === 'checkbox' && item.perItemSize) {
|
|
18
|
-
const opt = item.options?.[0] || '领';
|
|
19
|
+
const opt = (item.options || []).find((o) => o !== (item.noneLabel || '无')) || item.options?.[0] || '领';
|
|
19
20
|
const size = item.sizeOptions?.[0] || '0.15';
|
|
20
21
|
return JSON.stringify({ checkbox: [opt], combineMap: { [opt]: size } });
|
|
21
22
|
}
|
|
23
|
+
if (item.control === 'checkbox' && item.perItemInput) {
|
|
24
|
+
const opt = (item.options || []).find((o) => o !== (item.noneLabel || '无')) || item.options?.[0] || '选项';
|
|
25
|
+
return JSON.stringify({ checkbox: [opt], combineMap: { [opt]: '值' } });
|
|
26
|
+
}
|
|
22
27
|
if (item.control === 'checkbox') {
|
|
23
28
|
return JSON.stringify({ checkbox: item.options?.slice(0, 2) || [] });
|
|
24
29
|
}
|
|
@@ -56,22 +61,42 @@ function buildHowTo(item) {
|
|
|
56
61
|
if (item.allowAdd) {
|
|
57
62
|
text += ';可+新增自定义(写入 customOptions)';
|
|
58
63
|
}
|
|
59
|
-
if (item.
|
|
60
|
-
text += '
|
|
64
|
+
if (item.alwaysInput) {
|
|
65
|
+
text += ';选中后可填 note';
|
|
61
66
|
}
|
|
62
|
-
if (item.
|
|
63
|
-
text += '
|
|
67
|
+
else if (item.inputWhen?.length) {
|
|
68
|
+
text += `;选「${item.inputWhen.join('/')}」时再填 note`;
|
|
64
69
|
}
|
|
65
70
|
return text;
|
|
66
71
|
}
|
|
67
72
|
if (item.control === 'checkbox' && item.perItemSize) {
|
|
68
|
-
|
|
73
|
+
let text = `可多选部位:${(item.options || []).join('/')};勾选后每项再选尺寸 ${(item.sizeOptions || []).join('/')}`;
|
|
74
|
+
if (item.allowCustomSize) {
|
|
75
|
+
text += '或手填';
|
|
76
|
+
}
|
|
77
|
+
if (item.syncSizeOptions?.length) {
|
|
78
|
+
text += `;${item.syncSizeOptions.join('/')} 尺寸联动`;
|
|
79
|
+
}
|
|
80
|
+
if (item.mutexNone) {
|
|
81
|
+
text += ';「无」与其它互斥';
|
|
82
|
+
}
|
|
83
|
+
return text;
|
|
84
|
+
}
|
|
85
|
+
if (item.control === 'checkbox' && item.perItemInput) {
|
|
86
|
+
let text = `可多选:${(item.options || []).join('/')};勾选后每项可填值`;
|
|
87
|
+
if (item.mutexNone) {
|
|
88
|
+
text += ';「无」与其它互斥';
|
|
89
|
+
}
|
|
90
|
+
return text;
|
|
69
91
|
}
|
|
70
92
|
if (item.control === 'checkbox') {
|
|
71
93
|
let text = `可多选:${(item.options || []).join('/')}`;
|
|
72
94
|
if (item.allowAdd) {
|
|
73
95
|
text += ';可+新增';
|
|
74
96
|
}
|
|
97
|
+
if (item.mutexNone) {
|
|
98
|
+
text += ';「无」与其它互斥';
|
|
99
|
+
}
|
|
75
100
|
return text;
|
|
76
101
|
}
|
|
77
102
|
if (item.control === 'input') {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { normalizeCraftSavePayload } from '../tool-helpers.js';
|
|
2
|
+
/** 工艺入参规整自检 */
|
|
3
|
+
function main() {
|
|
4
|
+
const normalized = normalizeCraftSavePayload({
|
|
5
|
+
styleId: '1',
|
|
6
|
+
garmentPart: 'jacket',
|
|
7
|
+
craft: [{ module: 'style', fieldKey: 'description', fieldValue: '{"radio":"单排2扣"}' }]
|
|
8
|
+
});
|
|
9
|
+
const crafts = normalized.crafts;
|
|
10
|
+
if (!Array.isArray(crafts) || crafts.length !== 1) {
|
|
11
|
+
throw new Error('craft 应转为 crafts');
|
|
12
|
+
}
|
|
13
|
+
if (crafts[0].craftModule !== 'style' || crafts[0].module !== undefined) {
|
|
14
|
+
throw new Error('module 应转为 craftModule');
|
|
15
|
+
}
|
|
16
|
+
if (crafts[0].garmentPart !== 'jacket') {
|
|
17
|
+
throw new Error('顶层 garmentPart 应落入行内');
|
|
18
|
+
}
|
|
19
|
+
if (normalized.garmentPart !== undefined || normalized.craft !== undefined) {
|
|
20
|
+
throw new Error('兼容键应删除');
|
|
21
|
+
}
|
|
22
|
+
console.log('normalizeCraftSavePayload self-check ok');
|
|
23
|
+
}
|
|
24
|
+
main();
|