adspecs 0.1.18 → 0.1.20
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/.adspecs/extensions/git/commands/adspecs.git.initialize.md +4 -4
- package/.adspecs/extensions/git/extension.yml +1 -1
- package/.adspecs/extensions/git/git-config.yml +17 -2
- package/.adspecs/extensions.yml +32 -0
- package/.adspecs/feature.json +16 -16
- package/.adspecs/feature.yml +28 -28
- package/.adspecs/paths.json +17 -0
- package/.adspecs/templates/02-/344/272/247/345/223/201/351/234/200/346/261/202/350/257/264/346/230/216/344/271/246/346/250/241/346/235/277.md +4 -0
- package/.adspecs/workflows/adspecs/workflow.yml +5 -4
- package/.claude-plugin/marketplace.json +23 -23
- package/.claude-plugin/plugin.json +18 -18
- package/.qoder-plugin/plugin.json +31 -31
- package/CLAUDE.md +1 -5
- package/README.md +395 -395
- package/bin/adspecs.js +129 -129
- package/hooks/commit-queue.js +245 -245
- package/hooks/hooks.json +63 -63
- package/hooks/session-start.js +44 -44
- package/hooks/wiki-queue.js +127 -127
- package/package.json +61 -61
- package/references/ant6-front-standard/index.md +99 -99
- package/references/antd-front-demo/.env.develop +12 -0
- package/references/antd-front-demo/.env.production +5 -0
- package/references/antd-front-demo/package-lock.json +2 -2
- package/references/antd-front-demo/package.json +1 -1
- package/references/antd-front-demo/public/mockServiceWorker.js +361 -361
- package/references/ecp-end-standard/index.md +63 -63
- package/references/python-end-standard/01-Python/345/220/216/347/253/257/347/274/226/347/240/201/350/247/204/350/214/203.md +372 -372
- package/references/python-end-standard/02-/346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/344/270/216/344/275/277/347/224/250/350/247/204/350/214/203.md +226 -226
- package/references/python-end-standard/03-Celery/345/274/202/346/255/245/344/273/273/345/212/241/350/247/204/350/214/203.md +237 -237
- package/references/python-end-standard/04-Redis/344/275/277/347/224/250/350/247/204/350/214/203.md +231 -231
- package/scripts/postinstall.js +107 -107
- package/scripts/sync-version.js +105 -105
- package/skills/.claude/.wiki-update-queue +26 -26
- package/skills/adspecs-constitution/SKILL.md +157 -0
- package/skills/adspecs-export-word/SKILL.md +498 -498
- package/skills/adspecs-export-word/references/md-to-docx.js +862 -862
- package/skills/adspecs-export-word/references/package-lock.json +220 -220
- package/skills/adspecs-export-word/references/package.json +10 -10
- package/skills/adspecs-front-prototype/SKILL.md +405 -0
- package/skills/adspecs-git-commit/SKILL.md +23 -8
- package/skills/adspecs-git-initialize/SKILL.md +54 -0
- package/skills/adspecs-plan/SKILL.md +59 -69
- package/skills/adspecs-prd/SKILL.md +13 -5
- package/skills/adspecs-prd-to-demo/SKILL.md +532 -0
- package/skills/adspecs-tasks/SKILL.md +175 -204
- package/skills/adspecs-update-status/SKILL.md +382 -382
- package/skills/adspecs-utest/SKILL.md +107 -116
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/grill-me/agents/openai.yaml +5 -0
- package/skills/playwright-cli/SKILL.md +420 -0
- package/skills/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright-cli/references/test-generation.md +433 -0
- package/skills/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright-cli/references/video-recording.md +143 -0
- package/skills/playwright-trace/SKILL.md +171 -0
- package/skills/project-init/references/front-demo/.claude/settings.local.json +9 -0
- package/skills/wiki-update/SKILL.md +232 -232
- package/src/commands/doctor.js +197 -197
- package/src/commands/init.js +83 -83
- package/src/commands/plugin.js +165 -165
- package/src/commands/update.js +87 -87
- package/src/lib/area-scanner.js +129 -129
- package/src/lib/copier.js +104 -104
- package/src/lib/dir-utils.js +133 -133
- package/src/lib/json-merge.js +114 -114
- package/src/lib/paths-defaults.js +37 -37
- package/src/lib/prompts.js +347 -345
- package/src/lib/readme-gen.js +143 -143
- package/src/lib/report.js +327 -327
- package/src/lib/scaffolder.js +518 -518
- package/src/lib/short-name.js +36 -36
- package/src/utils.js +80 -80
- package/references/antd-front-demo/.env +0 -15
- package/references/antd-front-demo/src/pages/aps/coil/components/CoilDrawer.tsx +0 -141
- package/references/antd-front-demo/src/pages/aps/coil/index.tsx +0 -209
- package/references/antd-front-demo/src/pages/aps/optimization/index.tsx +0 -192
- package/references/antd-front-demo/src/pages/aps/order/components/OrderDrawer.tsx +0 -251
- package/references/antd-front-demo/src/pages/aps/order/index.tsx +0 -273
- package/references/antd-front-demo/src/pages/aps/param/index.tsx +0 -153
- package/references/antd-front-demo/src/pages/aps/plan/components/CuttingPlanVisualization.tsx +0 -821
- package/references/antd-front-demo/src/pages/aps/plan/index.tsx +0 -254
- package/references/antd-front-demo/src/pages/aps/task/index.tsx +0 -190
package/src/lib/short-name.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* project_short_name 自动推导
|
|
5
|
-
*
|
|
6
|
-
* 规则(与 project-init SKILL.md 保持一致):
|
|
7
|
-
* 1. 从 project_name 中提取所有英文字母和数字(去除中文、空格、连字符、下划线等)
|
|
8
|
-
* 2. 转为小写
|
|
9
|
-
* 3. 如果结果为空(项目名称全中文),则从 project_dir 推导(去除连字符和下划线)
|
|
10
|
-
* 4. 如果仍为空,使用 'project' 作为默认值
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 推导 project_short_name
|
|
15
|
-
* @param {string} projectName - 项目完整名称
|
|
16
|
-
* @param {string} projectDir - 项目目录名(可选)
|
|
17
|
-
* @returns {string} 仅包含英文字母和数字的小写短名称
|
|
18
|
-
*/
|
|
19
|
-
function deriveShortName(projectName, projectDir) {
|
|
20
|
-
// 1. 从 project_name 提取英文字母和数字
|
|
21
|
-
if (projectName) {
|
|
22
|
-
const fromName = projectName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
23
|
-
if (fromName) return fromName;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// 2. 从 project_dir 推导(去除连字符和下划线)
|
|
27
|
-
if (projectDir) {
|
|
28
|
-
const fromDir = projectDir.replace(/[-_\s]/g, '').toLowerCase();
|
|
29
|
-
if (fromDir) return fromDir;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 3. 默认值
|
|
33
|
-
return 'project';
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
module.exports = { deriveShortName };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* project_short_name 自动推导
|
|
5
|
+
*
|
|
6
|
+
* 规则(与 project-init SKILL.md 保持一致):
|
|
7
|
+
* 1. 从 project_name 中提取所有英文字母和数字(去除中文、空格、连字符、下划线等)
|
|
8
|
+
* 2. 转为小写
|
|
9
|
+
* 3. 如果结果为空(项目名称全中文),则从 project_dir 推导(去除连字符和下划线)
|
|
10
|
+
* 4. 如果仍为空,使用 'project' 作为默认值
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 推导 project_short_name
|
|
15
|
+
* @param {string} projectName - 项目完整名称
|
|
16
|
+
* @param {string} projectDir - 项目目录名(可选)
|
|
17
|
+
* @returns {string} 仅包含英文字母和数字的小写短名称
|
|
18
|
+
*/
|
|
19
|
+
function deriveShortName(projectName, projectDir) {
|
|
20
|
+
// 1. 从 project_name 提取英文字母和数字
|
|
21
|
+
if (projectName) {
|
|
22
|
+
const fromName = projectName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
23
|
+
if (fromName) return fromName;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 2. 从 project_dir 推导(去除连字符和下划线)
|
|
27
|
+
if (projectDir) {
|
|
28
|
+
const fromDir = projectDir.replace(/[-_\s]/g, '').toLowerCase();
|
|
29
|
+
if (fromDir) return fromDir;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 3. 默认值
|
|
33
|
+
return 'project';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { deriveShortName };
|
package/src/utils.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* adspecs CLI 通用工具
|
|
5
|
-
*
|
|
6
|
-
* 此模块作为 package.json 的 "main" 入口,
|
|
7
|
-
* 供其他 Node.js 脚本 require('adspecs') 时使用。
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 获取插件根目录(即 adspecs/ 目录)
|
|
15
|
-
* @returns {string}
|
|
16
|
-
*/
|
|
17
|
-
function getPluginDir() {
|
|
18
|
-
return path.resolve(__dirname, '..');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 获取 package.json 内容
|
|
23
|
-
* @returns {object}
|
|
24
|
-
*/
|
|
25
|
-
function getPkg() {
|
|
26
|
-
const pkgPath = path.join(getPluginDir(), 'package.json');
|
|
27
|
-
return JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 获取版本号
|
|
32
|
-
* @returns {string}
|
|
33
|
-
*/
|
|
34
|
-
function getVersion() {
|
|
35
|
-
return getPkg().version;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 判断目标路径是否在 adspecs 插件目录内
|
|
40
|
-
* @param {string} targetPath
|
|
41
|
-
* @returns {boolean}
|
|
42
|
-
*/
|
|
43
|
-
function isInsidePlugin(targetPath) {
|
|
44
|
-
const pluginDir = getPluginDir();
|
|
45
|
-
const resolved = path.resolve(targetPath);
|
|
46
|
-
return resolved.startsWith(pluginDir);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 安全读取 JSON 文件
|
|
51
|
-
* @param {string} filePath
|
|
52
|
-
* @param {object} [fallback]
|
|
53
|
-
* @returns {object|null}
|
|
54
|
-
*/
|
|
55
|
-
function safeReadJson(filePath, fallback = null) {
|
|
56
|
-
try {
|
|
57
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
58
|
-
} catch {
|
|
59
|
-
return fallback;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 安全写入 JSON 文件(带 2 空格缩进 + 尾部换行)
|
|
65
|
-
* @param {string} filePath
|
|
66
|
-
* @param {object} data
|
|
67
|
-
*/
|
|
68
|
-
function safeWriteJson(filePath, data) {
|
|
69
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
70
|
-
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
module.exports = {
|
|
74
|
-
getPluginDir,
|
|
75
|
-
getPkg,
|
|
76
|
-
getVersion,
|
|
77
|
-
isInsidePlugin,
|
|
78
|
-
safeReadJson,
|
|
79
|
-
safeWriteJson,
|
|
80
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* adspecs CLI 通用工具
|
|
5
|
+
*
|
|
6
|
+
* 此模块作为 package.json 的 "main" 入口,
|
|
7
|
+
* 供其他 Node.js 脚本 require('adspecs') 时使用。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 获取插件根目录(即 adspecs/ 目录)
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
function getPluginDir() {
|
|
18
|
+
return path.resolve(__dirname, '..');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 获取 package.json 内容
|
|
23
|
+
* @returns {object}
|
|
24
|
+
*/
|
|
25
|
+
function getPkg() {
|
|
26
|
+
const pkgPath = path.join(getPluginDir(), 'package.json');
|
|
27
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 获取版本号
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
function getVersion() {
|
|
35
|
+
return getPkg().version;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 判断目标路径是否在 adspecs 插件目录内
|
|
40
|
+
* @param {string} targetPath
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
*/
|
|
43
|
+
function isInsidePlugin(targetPath) {
|
|
44
|
+
const pluginDir = getPluginDir();
|
|
45
|
+
const resolved = path.resolve(targetPath);
|
|
46
|
+
return resolved.startsWith(pluginDir);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 安全读取 JSON 文件
|
|
51
|
+
* @param {string} filePath
|
|
52
|
+
* @param {object} [fallback]
|
|
53
|
+
* @returns {object|null}
|
|
54
|
+
*/
|
|
55
|
+
function safeReadJson(filePath, fallback = null) {
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
58
|
+
} catch {
|
|
59
|
+
return fallback;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 安全写入 JSON 文件(带 2 空格缩进 + 尾部换行)
|
|
65
|
+
* @param {string} filePath
|
|
66
|
+
* @param {object} data
|
|
67
|
+
*/
|
|
68
|
+
function safeWriteJson(filePath, data) {
|
|
69
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
70
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
getPluginDir,
|
|
75
|
+
getPkg,
|
|
76
|
+
getVersion,
|
|
77
|
+
isInsidePlugin,
|
|
78
|
+
safeReadJson,
|
|
79
|
+
safeWriteJson,
|
|
80
|
+
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# 应用标题
|
|
2
|
-
VITE_APP_TITLE=Sie Front Demo
|
|
3
|
-
VITE_APP_SIDEBAR_TITLE=Sie Demo
|
|
4
|
-
VITE_APP_BRAND_TITLE=Sie Front Demo
|
|
5
|
-
|
|
6
|
-
# 应用命名空间
|
|
7
|
-
VITE_APP_NAMESPACE=sie-demo
|
|
8
|
-
|
|
9
|
-
# 请求路径
|
|
10
|
-
VITE_BASE_URL=
|
|
11
|
-
# 接口地址
|
|
12
|
-
VITE_API_BASE_URL=/admin-api
|
|
13
|
-
|
|
14
|
-
# 是否开启模拟数据(Demo 项目默认开启)
|
|
15
|
-
VITE_MOCK_ENABLED=true
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { Drawer, Form, Input, InputNumber, DatePicker, Select, Button, Space, Card, message } from 'antd';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import { getCoil, createCoil, updateCoil } from '@/api/aps/coil';
|
|
5
|
-
import type { CoilSaveParams } from '@/types/aps/coil';
|
|
6
|
-
import dayjs from 'dayjs';
|
|
7
|
-
|
|
8
|
-
interface CoilDrawerProps {
|
|
9
|
-
open: boolean;
|
|
10
|
-
id: number | null;
|
|
11
|
-
onSuccess: () => void;
|
|
12
|
-
onClose: () => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const CoilDrawer: React.FC<CoilDrawerProps> = ({ open, id, onSuccess, onClose }) => {
|
|
16
|
-
const { t } = useTranslation('aps/coil');
|
|
17
|
-
const { t: tc } = useTranslation('common');
|
|
18
|
-
const [form] = Form.useForm();
|
|
19
|
-
const isEdit = id !== null;
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
if (open && id) {
|
|
23
|
-
getCoil(id).then((res) => {
|
|
24
|
-
form.setFieldsValue({
|
|
25
|
-
...res.data,
|
|
26
|
-
inDate: dayjs(res.data.inDate),
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
} else {
|
|
30
|
-
form.resetFields();
|
|
31
|
-
}
|
|
32
|
-
}, [open, id, form]);
|
|
33
|
-
|
|
34
|
-
const handleOk = async () => {
|
|
35
|
-
try {
|
|
36
|
-
const values = await form.validateFields();
|
|
37
|
-
const params: CoilSaveParams = {
|
|
38
|
-
...values,
|
|
39
|
-
id: id || undefined,
|
|
40
|
-
inDate: values.inDate.format('YYYY-MM-DD'),
|
|
41
|
-
};
|
|
42
|
-
if (isEdit) {
|
|
43
|
-
await updateCoil(params);
|
|
44
|
-
} else {
|
|
45
|
-
await createCoil(params);
|
|
46
|
-
}
|
|
47
|
-
message.success(tc('success'));
|
|
48
|
-
onSuccess();
|
|
49
|
-
} catch {
|
|
50
|
-
// Validation failed
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<Drawer
|
|
56
|
-
title={isEdit ? tc('edit') : tc('create')}
|
|
57
|
-
open={open}
|
|
58
|
-
onClose={onClose}
|
|
59
|
-
size={256}
|
|
60
|
-
closable={{ placement: 'end' }}
|
|
61
|
-
destroyOnHidden={true}
|
|
62
|
-
mask={{ closable: false }}
|
|
63
|
-
styles={{ body: { background: '#f5f5f5' } }}
|
|
64
|
-
footer={
|
|
65
|
-
<Space style={{ float: 'right' }}>
|
|
66
|
-
<Button onClick={onClose}>{tc('cancel')}</Button>
|
|
67
|
-
<Button type="primary" onClick={handleOk}>
|
|
68
|
-
{tc('confirm')}
|
|
69
|
-
</Button>
|
|
70
|
-
</Space>
|
|
71
|
-
}
|
|
72
|
-
>
|
|
73
|
-
<Card style={{ border: 'none' }}>
|
|
74
|
-
<Form form={form} layout="vertical">
|
|
75
|
-
<Form.Item
|
|
76
|
-
name="coilId"
|
|
77
|
-
label={t('coilId')}
|
|
78
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
79
|
-
>
|
|
80
|
-
<Input />
|
|
81
|
-
</Form.Item>
|
|
82
|
-
<Form.Item
|
|
83
|
-
name="alloy"
|
|
84
|
-
label={t('alloy')}
|
|
85
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
86
|
-
>
|
|
87
|
-
<Select
|
|
88
|
-
options={[
|
|
89
|
-
{ value: '3003', label: '3003' },
|
|
90
|
-
{ value: '5052', label: '5052' },
|
|
91
|
-
]}
|
|
92
|
-
/>
|
|
93
|
-
</Form.Item>
|
|
94
|
-
<Form.Item
|
|
95
|
-
name="temper"
|
|
96
|
-
label={t('temper')}
|
|
97
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
98
|
-
>
|
|
99
|
-
<Select
|
|
100
|
-
options={[
|
|
101
|
-
{ value: 'H24', label: 'H24' },
|
|
102
|
-
{ value: 'H18', label: 'H18' },
|
|
103
|
-
{ value: 'O', label: 'O' },
|
|
104
|
-
]}
|
|
105
|
-
/>
|
|
106
|
-
</Form.Item>
|
|
107
|
-
<Form.Item
|
|
108
|
-
name="width"
|
|
109
|
-
label={t('width')}
|
|
110
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
111
|
-
>
|
|
112
|
-
<InputNumber min={0} max={2500} style={{ width: '100%' }} />
|
|
113
|
-
</Form.Item>
|
|
114
|
-
<Form.Item
|
|
115
|
-
name="thickness"
|
|
116
|
-
label={t('thickness')}
|
|
117
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
118
|
-
>
|
|
119
|
-
<InputNumber min={0} max={10} step={0.1} style={{ width: '100%' }} />
|
|
120
|
-
</Form.Item>
|
|
121
|
-
<Form.Item
|
|
122
|
-
name="weight"
|
|
123
|
-
label={t('weight')}
|
|
124
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
125
|
-
>
|
|
126
|
-
<InputNumber min={0} max={30} step={0.1} style={{ width: '100%' }} />
|
|
127
|
-
</Form.Item>
|
|
128
|
-
<Form.Item
|
|
129
|
-
name="inDate"
|
|
130
|
-
label={t('inDate')}
|
|
131
|
-
rules={[{ required: true, message: tc('required') }]}
|
|
132
|
-
>
|
|
133
|
-
<DatePicker style={{ width: '100%' }} />
|
|
134
|
-
</Form.Item>
|
|
135
|
-
</Form>
|
|
136
|
-
</Card>
|
|
137
|
-
</Drawer>
|
|
138
|
-
);
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
export default CoilDrawer;
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { useRef, useState } from 'react';
|
|
2
|
-
import { Button, Space, Tag, Popconfirm, Upload, message } from 'antd';
|
|
3
|
-
import { PlusOutlined, UploadOutlined, DownloadOutlined } from '@ant-design/icons';
|
|
4
|
-
import { ProTable } from '@ant-design/pro-components';
|
|
5
|
-
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import { Access } from '@/components/Access';
|
|
8
|
-
import { getCoilPage, deleteCoil, importCoils, exportCoils, downloadCoilTemplate } from '@/api/aps/coil';
|
|
9
|
-
import type { CoilVO } from '@/types/aps/coil';
|
|
10
|
-
import { COIL_STATUS } from '@/types/aps/coil';
|
|
11
|
-
import CoilDrawer from './components/CoilDrawer';
|
|
12
|
-
|
|
13
|
-
const CoilPage: React.FC = () => {
|
|
14
|
-
const { t } = useTranslation('aps/coil');
|
|
15
|
-
const { t: tc } = useTranslation('common');
|
|
16
|
-
const actionRef = useRef<ActionType>(null);
|
|
17
|
-
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
18
|
-
const [editId, setEditId] = useState<number | null>(null);
|
|
19
|
-
|
|
20
|
-
const handleDelete = (id: number) => async () => {
|
|
21
|
-
await deleteCoil(id);
|
|
22
|
-
message.success(tc('success'));
|
|
23
|
-
actionRef.current?.reload();
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const handleImport = async (file: File) => {
|
|
27
|
-
const result = await importCoils(file);
|
|
28
|
-
if (result.data.failCount === 0) {
|
|
29
|
-
message.success(t('importSuccess', { count: result.data.successCount }));
|
|
30
|
-
} else {
|
|
31
|
-
message.warning(t('importFailed', { count: result.data.failCount }));
|
|
32
|
-
}
|
|
33
|
-
actionRef.current?.reload();
|
|
34
|
-
return false;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const handleExport = async () => {
|
|
38
|
-
await exportCoils({});
|
|
39
|
-
message.success(tc('success'));
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const handleDownloadTemplate = async () => {
|
|
43
|
-
await downloadCoilTemplate();
|
|
44
|
-
message.success(tc('success'));
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const columns: ProColumns<CoilVO>[] = [
|
|
48
|
-
{
|
|
49
|
-
title: t('coilId'),
|
|
50
|
-
dataIndex: 'coilId',
|
|
51
|
-
ellipsis: true,
|
|
52
|
-
width: 120,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
title: t('alloy'),
|
|
56
|
-
dataIndex: 'alloy',
|
|
57
|
-
valueType: 'select',
|
|
58
|
-
valueEnum: {
|
|
59
|
-
'3003': { text: '3003' },
|
|
60
|
-
'5052': { text: '5052' },
|
|
61
|
-
},
|
|
62
|
-
width: 100,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
title: t('temper'),
|
|
66
|
-
dataIndex: 'temper',
|
|
67
|
-
search: false,
|
|
68
|
-
width: 80,
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
title: t('width'),
|
|
72
|
-
dataIndex: 'width',
|
|
73
|
-
search: false,
|
|
74
|
-
width: 100,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
title: t('thickness'),
|
|
78
|
-
dataIndex: 'thickness',
|
|
79
|
-
search: false,
|
|
80
|
-
width: 100,
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
title: t('weight'),
|
|
84
|
-
dataIndex: 'weight',
|
|
85
|
-
search: false,
|
|
86
|
-
width: 100,
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
title: t('inDate'),
|
|
90
|
-
dataIndex: 'inDate',
|
|
91
|
-
search: false,
|
|
92
|
-
width: 120,
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
title: t('status'),
|
|
96
|
-
dataIndex: 'status',
|
|
97
|
-
valueType: 'select',
|
|
98
|
-
valueEnum: {
|
|
99
|
-
0: { text: COIL_STATUS[0].label, status: 'Default' },
|
|
100
|
-
1: { text: COIL_STATUS[1].label, status: 'Processing' },
|
|
101
|
-
2: { text: COIL_STATUS[2].label, status: 'Success' },
|
|
102
|
-
3: { text: COIL_STATUS[3].label, status: 'Error' },
|
|
103
|
-
},
|
|
104
|
-
width: 100,
|
|
105
|
-
render: (_, record) => {
|
|
106
|
-
const item = COIL_STATUS[record.status as keyof typeof COIL_STATUS];
|
|
107
|
-
return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
title: t('createTime'),
|
|
112
|
-
dataIndex: 'createTime',
|
|
113
|
-
search: false,
|
|
114
|
-
width: 180,
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
title: tc('operation'),
|
|
118
|
-
key: 'action',
|
|
119
|
-
fixed: 'right',
|
|
120
|
-
search: false,
|
|
121
|
-
width: 150,
|
|
122
|
-
render: (_, record) => (
|
|
123
|
-
<Space>
|
|
124
|
-
<Access code="aps:coil:update">
|
|
125
|
-
<a
|
|
126
|
-
onClick={() => {
|
|
127
|
-
setEditId(record.id);
|
|
128
|
-
setDrawerOpen(true);
|
|
129
|
-
}}
|
|
130
|
-
>
|
|
131
|
-
{tc('edit')}
|
|
132
|
-
</a>
|
|
133
|
-
</Access>
|
|
134
|
-
<Access code="aps:coil:delete">
|
|
135
|
-
<Popconfirm title={t('deleteConfirm')} onConfirm={handleDelete(record.id)}>
|
|
136
|
-
<a style={{ color: '#ff4d4f' }}>{tc('delete')}</a>
|
|
137
|
-
</Popconfirm>
|
|
138
|
-
</Access>
|
|
139
|
-
</Space>
|
|
140
|
-
),
|
|
141
|
-
},
|
|
142
|
-
];
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<>
|
|
146
|
-
<ProTable<CoilVO>
|
|
147
|
-
columns={columns}
|
|
148
|
-
actionRef={actionRef}
|
|
149
|
-
rowKey="id"
|
|
150
|
-
headerTitle={t('title')}
|
|
151
|
-
request={async (params) => {
|
|
152
|
-
const { current, pageSize, ...rest } = params;
|
|
153
|
-
const { data } = await getCoilPage({
|
|
154
|
-
pageNo: current!,
|
|
155
|
-
pageSize: pageSize!,
|
|
156
|
-
...rest,
|
|
157
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
158
|
-
} as any);
|
|
159
|
-
return { data: data.list, total: data.total, success: true };
|
|
160
|
-
}}
|
|
161
|
-
pagination={{ defaultPageSize: 10, showSizeChanger: true }}
|
|
162
|
-
scroll={{ x: 1200 }}
|
|
163
|
-
toolBarRender={() => [
|
|
164
|
-
<Access code="aps:coil:create" key="add">
|
|
165
|
-
<Button
|
|
166
|
-
type="primary"
|
|
167
|
-
icon={<PlusOutlined />}
|
|
168
|
-
onClick={() => {
|
|
169
|
-
setEditId(null);
|
|
170
|
-
setDrawerOpen(true);
|
|
171
|
-
}}
|
|
172
|
-
>
|
|
173
|
-
{tc('create')}
|
|
174
|
-
</Button>
|
|
175
|
-
</Access>,
|
|
176
|
-
<Access code="aps:coil:import" key="import">
|
|
177
|
-
<Upload
|
|
178
|
-
accept=".xlsx,.xls"
|
|
179
|
-
showUploadList={false}
|
|
180
|
-
beforeUpload={handleImport}
|
|
181
|
-
>
|
|
182
|
-
<Button icon={<UploadOutlined />}>{t('import')}</Button>
|
|
183
|
-
</Upload>
|
|
184
|
-
</Access>,
|
|
185
|
-
<Access code="aps:coil:export" key="export">
|
|
186
|
-
<Button icon={<DownloadOutlined />} onClick={handleExport}>
|
|
187
|
-
{t('export')}
|
|
188
|
-
</Button>
|
|
189
|
-
</Access>,
|
|
190
|
-
<Button key="template" icon={<DownloadOutlined />} onClick={handleDownloadTemplate}>
|
|
191
|
-
{t('downloadTemplate')}
|
|
192
|
-
</Button>,
|
|
193
|
-
]}
|
|
194
|
-
/>
|
|
195
|
-
|
|
196
|
-
<CoilDrawer
|
|
197
|
-
open={drawerOpen}
|
|
198
|
-
id={editId}
|
|
199
|
-
onSuccess={() => {
|
|
200
|
-
setDrawerOpen(false);
|
|
201
|
-
actionRef.current?.reload();
|
|
202
|
-
}}
|
|
203
|
-
onClose={() => setDrawerOpen(false)}
|
|
204
|
-
/>
|
|
205
|
-
</>
|
|
206
|
-
);
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
export default CoilPage;
|