adspecs 0.1.18 → 0.1.19

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.
Files changed (29) hide show
  1. package/.adspecs/extensions/git/commands/adspecs.git.initialize.md +4 -4
  2. package/.adspecs/extensions/git/extension.yml +1 -1
  3. package/.adspecs/extensions/git/git-config.yml +17 -2
  4. package/.adspecs/extensions.yml +32 -0
  5. package/.adspecs/paths.json +17 -0
  6. 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
  7. package/.adspecs/workflows/adspecs/workflow.yml +5 -4
  8. package/.claude-plugin/marketplace.json +1 -1
  9. package/.claude-plugin/plugin.json +1 -1
  10. package/.qoder-plugin/plugin.json +1 -1
  11. package/package.json +1 -1
  12. package/references/antd-front-demo/.env +4 -4
  13. package/references/antd-front-demo/.env.develop +12 -0
  14. package/references/antd-front-demo/.env.production +5 -0
  15. package/references/antd-front-demo/package-lock.json +2 -2
  16. package/references/antd-front-demo/package.json +1 -1
  17. package/skills/adspecs-front-prototype/SKILL.md +405 -0
  18. package/skills/adspecs-git-commit/SKILL.md +23 -8
  19. package/skills/adspecs-git-initialize/SKILL.md +54 -0
  20. package/src/lib/prompts.js +23 -21
  21. package/references/antd-front-demo/src/pages/aps/coil/components/CoilDrawer.tsx +0 -141
  22. package/references/antd-front-demo/src/pages/aps/coil/index.tsx +0 -209
  23. package/references/antd-front-demo/src/pages/aps/optimization/index.tsx +0 -192
  24. package/references/antd-front-demo/src/pages/aps/order/components/OrderDrawer.tsx +0 -251
  25. package/references/antd-front-demo/src/pages/aps/order/index.tsx +0 -273
  26. package/references/antd-front-demo/src/pages/aps/param/index.tsx +0 -153
  27. package/references/antd-front-demo/src/pages/aps/plan/components/CuttingPlanVisualization.tsx +0 -821
  28. package/references/antd-front-demo/src/pages/aps/plan/index.tsx +0 -254
  29. package/references/antd-front-demo/src/pages/aps/task/index.tsx +0 -190
@@ -1,251 +0,0 @@
1
- import { useEffect, useRef, useState } from 'react';
2
- import {
3
- Drawer,
4
- Form,
5
- Input,
6
- InputNumber,
7
- DatePicker,
8
- Select,
9
- Button,
10
- Space,
11
- Row,
12
- Col,
13
- Card,
14
- App,
15
- } from 'antd';
16
- import { useTranslation } from 'react-i18next';
17
- import { getOrder, createOrder, updateOrder } from '@/api/aps/order';
18
- import type { OrderSaveParams, OrderVO } from '@/types/aps/order';
19
- import dayjs from 'dayjs';
20
-
21
- interface OrderDrawerProps {
22
- open: boolean;
23
- id: number | null;
24
- onSuccess: () => void;
25
- onClose: () => void;
26
- }
27
-
28
- const OrderDrawer: React.FC<OrderDrawerProps> = ({ open, id, onSuccess, onClose }) => {
29
- const { t } = useTranslation('aps/order');
30
- const { t: tc } = useTranslation('common');
31
- const { message } = App.useApp();
32
- const [form] = Form.useForm();
33
- const [confirmLoading, setConfirmLoading] = useState(false);
34
- const isEdit = id != null;
35
- // 保留服务端原始字段,避免编辑时丢掉未在表单里出现的字段
36
- const originData = useRef<Partial<OrderVO>>({});
37
-
38
- useEffect(() => {
39
- if (!open) return;
40
- form.resetFields();
41
- originData.current = {};
42
- if (id != null) {
43
- getOrder(id).then(({ data }) => {
44
- originData.current = { ...data };
45
- form.setFieldsValue({
46
- ...data,
47
- deliveryDate: dayjs(data.deliveryDate),
48
- });
49
- });
50
- } else {
51
- form.setFieldsValue({ priority: 3 });
52
- }
53
- }, [open, id, form]);
54
-
55
- const handleOk = async () => {
56
- let values: OrderSaveParams;
57
- try {
58
- values = await form.validateFields();
59
- } catch {
60
- return;
61
- }
62
- setConfirmLoading(true);
63
- try {
64
- const params: OrderSaveParams = {
65
- ...originData.current,
66
- ...values,
67
- id: id ?? undefined,
68
- deliveryDate: dayjs(values.deliveryDate).format('YYYY-MM-DD'),
69
- } as OrderSaveParams;
70
- if (isEdit) {
71
- await updateOrder(params);
72
- message.success(tc('success'));
73
- } else {
74
- await createOrder(params);
75
- message.success(tc('success'));
76
- }
77
- onSuccess();
78
- } catch (err) {
79
- message.error((err as Error).message || tc('fail'));
80
- } finally {
81
- setConfirmLoading(false);
82
- }
83
- };
84
-
85
- return (
86
- <Drawer
87
- title={isEdit ? tc('edit') : tc('create')}
88
- open={open}
89
- onClose={onClose}
90
- destroyOnHidden={true}
91
- size={600}
92
- closable={{ placement: 'end' }}
93
- mask={{ closable: false }}
94
- styles={{ body: { background: '#f5f5f5' } }}
95
- footer={
96
- <Space style={{ float: 'right' }}>
97
- <Button onClick={onClose}>{tc('cancel')}</Button>
98
- <Button type="primary" loading={confirmLoading} onClick={handleOk}>
99
- {tc('confirm')}
100
- </Button>
101
- </Space>
102
- }
103
- >
104
- <Card style={{ border: 'none' }}>
105
- <Form form={form} layout="horizontal" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
106
- <Row gutter={16}>
107
- <Col span={12}>
108
- <Form.Item
109
- name="orderId"
110
- label={t('orderId')}
111
- rules={[{ required: true, message: tc('required') }]}
112
- >
113
- <Input />
114
- </Form.Item>
115
- </Col>
116
- <Col span={12}>
117
- <Form.Item
118
- name="customerName"
119
- label={t('customerName')}
120
- rules={[{ required: true, message: tc('required') }]}
121
- >
122
- <Input />
123
- </Form.Item>
124
- </Col>
125
- </Row>
126
- <Row gutter={16}>
127
- <Col span={12}>
128
- <Form.Item
129
- name="alloy"
130
- label={t('alloy')}
131
- rules={[{ required: true, message: tc('required') }]}
132
- >
133
- <Select
134
- options={[
135
- { value: '3003', label: '3003' },
136
- { value: '5052', label: '5052' },
137
- ]}
138
- />
139
- </Form.Item>
140
- </Col>
141
- <Col span={12}>
142
- <Form.Item
143
- name="temper"
144
- label={t('temper')}
145
- rules={[{ required: true, message: tc('required') }]}
146
- >
147
- <Select
148
- options={[
149
- { value: 'H24', label: 'H24' },
150
- { value: 'H18', label: 'H18' },
151
- { value: 'O', label: 'O' },
152
- ]}
153
- />
154
- </Form.Item>
155
- </Col>
156
- </Row>
157
- <Row gutter={16}>
158
- <Col span={12}>
159
- <Form.Item
160
- name="thickness"
161
- label={t('thickness')}
162
- rules={[{ required: true, message: tc('required') }]}
163
- >
164
- <InputNumber min={0} max={10} step={0.1} style={{ width: '100%' }} />
165
- </Form.Item>
166
- </Col>
167
- <Col span={12}>
168
- <Form.Item
169
- name="width"
170
- label={t('width')}
171
- rules={[{ required: true, message: tc('required') }]}
172
- >
173
- <InputNumber min={0} max={2500} style={{ width: '100%' }} />
174
- </Form.Item>
175
- </Col>
176
- </Row>
177
- <Row gutter={16}>
178
- <Col span={12}>
179
- <Form.Item
180
- name="innerDiameter"
181
- label={t('innerDiameter')}
182
- rules={[{ required: true, message: tc('required') }]}
183
- >
184
- <InputNumber min={0} style={{ width: '100%' }} />
185
- </Form.Item>
186
- </Col>
187
- <Col span={12}>
188
- <Form.Item
189
- name="minOuterDiameter"
190
- label={t('minOuterDiameter')}
191
- rules={[{ required: true, message: tc('required') }]}
192
- >
193
- <InputNumber min={0} style={{ width: '100%' }} />
194
- </Form.Item>
195
- </Col>
196
- </Row>
197
- <Row gutter={16}>
198
- <Col span={12}>
199
- <Form.Item
200
- name="maxOuterDiameter"
201
- label={t('maxOuterDiameter')}
202
- rules={[{ required: true, message: tc('required') }]}
203
- >
204
- <InputNumber min={0} style={{ width: '100%' }} />
205
- </Form.Item>
206
- </Col>
207
- <Col span={12}>
208
- <Form.Item
209
- name="demand"
210
- label={t('demand')}
211
- rules={[{ required: true, message: tc('required') }]}
212
- >
213
- <InputNumber min={0} max={50} step={0.1} style={{ width: '100%' }} />
214
- </Form.Item>
215
- </Col>
216
- </Row>
217
- <Row gutter={16}>
218
- <Col span={12}>
219
- <Form.Item
220
- name="deliveryDate"
221
- label={t('deliveryDate')}
222
- rules={[{ required: true, message: tc('required') }]}
223
- >
224
- <DatePicker style={{ width: '100%' }} />
225
- </Form.Item>
226
- </Col>
227
- <Col span={12}>
228
- <Form.Item
229
- name="priority"
230
- label={t('priority')}
231
- rules={[{ required: true, message: tc('required') }]}
232
- >
233
- <Select
234
- options={[
235
- { value: 1, label: '1 - 低' },
236
- { value: 2, label: '2 - 中低' },
237
- { value: 3, label: '3 - 中' },
238
- { value: 4, label: '4 - 中高' },
239
- { value: 5, label: '5 - 高' },
240
- ]}
241
- />
242
- </Form.Item>
243
- </Col>
244
- </Row>
245
- </Form>
246
- </Card>
247
- </Drawer>
248
- );
249
- };
250
-
251
- export default OrderDrawer;
@@ -1,273 +0,0 @@
1
- import { useRef, useState } from 'react';
2
- import { App, Button, Space, Tag, Upload } from 'antd';
3
- import { PlusOutlined, UploadOutlined, DownloadOutlined, DeleteOutlined } 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 {
9
- getOrderPage,
10
- deleteOrder,
11
- importOrders,
12
- exportOrders,
13
- downloadOrderTemplate,
14
- } from '@/api/aps/order';
15
- import type { OrderVO } from '@/types/aps/order';
16
- import { ORDER_STATUS, ORDER_PRIORITY } from '@/types/aps/order';
17
- import OrderDrawer from './components/OrderDrawer';
18
-
19
- const OrderPage: React.FC = () => {
20
- const { t } = useTranslation('aps/order');
21
- const { t: tc } = useTranslation('common');
22
- const { message, modal } = App.useApp();
23
- const actionRef = useRef<ActionType>(null);
24
- const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
25
- const [drawerOpen, setDrawerOpen] = useState(false);
26
- const [editId, setEditId] = useState<number | null>(null);
27
-
28
- const reload = () => actionRef.current?.reload();
29
-
30
- const handleDelete = (record: OrderVO) => {
31
- modal.confirm({
32
- title: t('deleteConfirm'),
33
- okType: 'danger',
34
- content: t('deleteConfirmContent', { name: record.orderId }),
35
- onOk: async () => {
36
- await deleteOrder(record.id);
37
- message.success(tc('success'));
38
- reload();
39
- },
40
- });
41
- };
42
-
43
- const handleDeleteBatch = () => {
44
- modal.confirm({
45
- title: t('deleteConfirm'),
46
- okType: 'danger',
47
- content: t('deleteBatchConfirmContent', { count: selectedRowKeys.length }),
48
- onOk: async () => {
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- await Promise.all(selectedRowKeys.map((id) => deleteOrder(id as any)));
51
- message.success(tc('success'));
52
- setSelectedRowKeys([]);
53
- reload();
54
- },
55
- });
56
- };
57
-
58
- const handleImport = async (file: File) => {
59
- const result = await importOrders(file);
60
- if (result.data.failCount === 0) {
61
- message.success(t('importSuccess', { count: result.data.successCount }));
62
- } else {
63
- message.warning(t('importFailed', { count: result.data.failCount }));
64
- }
65
- reload();
66
- return false;
67
- };
68
-
69
- const handleExport = async () => {
70
- await exportOrders({});
71
- message.success(tc('success'));
72
- };
73
-
74
- const handleDownloadTemplate = async () => {
75
- await downloadOrderTemplate();
76
- message.success(tc('success'));
77
- };
78
-
79
- const columns: ProColumns<OrderVO>[] = [
80
- {
81
- title: t('orderId'),
82
- dataIndex: 'orderId',
83
- ellipsis: true,
84
- width: 100,
85
- },
86
- {
87
- title: t('customerName'),
88
- dataIndex: 'customerName',
89
- ellipsis: true,
90
- width: 120,
91
- },
92
- {
93
- title: t('alloy'),
94
- dataIndex: 'alloy',
95
- search: false,
96
- width: 80,
97
- },
98
- {
99
- title: t('temper'),
100
- dataIndex: 'temper',
101
- search: false,
102
- width: 80,
103
- },
104
- {
105
- title: t('width'),
106
- dataIndex: 'width',
107
- search: false,
108
- width: 80,
109
- },
110
- {
111
- title: t('thickness'),
112
- dataIndex: 'thickness',
113
- search: false,
114
- width: 80,
115
- },
116
- {
117
- title: t('demand'),
118
- dataIndex: 'demand',
119
- search: false,
120
- width: 100,
121
- },
122
- {
123
- title: t('assigned'),
124
- dataIndex: 'assigned',
125
- search: false,
126
- width: 100,
127
- },
128
- {
129
- title: t('deliveryDate'),
130
- dataIndex: 'deliveryDate',
131
- search: false,
132
- width: 120,
133
- },
134
- {
135
- title: t('priority'),
136
- dataIndex: 'priority',
137
- valueType: 'select',
138
- valueEnum: {
139
- 1: { text: ORDER_PRIORITY[1].label },
140
- 2: { text: ORDER_PRIORITY[2].label },
141
- 3: { text: ORDER_PRIORITY[3].label },
142
- 4: { text: ORDER_PRIORITY[4].label },
143
- 5: { text: ORDER_PRIORITY[5].label },
144
- },
145
- width: 80,
146
- render: (_, record) => {
147
- const item = ORDER_PRIORITY[record.priority as keyof typeof ORDER_PRIORITY];
148
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
149
- },
150
- },
151
- {
152
- title: t('status'),
153
- dataIndex: 'status',
154
- valueType: 'select',
155
- valueEnum: {
156
- 0: { text: ORDER_STATUS[0].label, status: 'Default' },
157
- 1: { text: ORDER_STATUS[1].label, status: 'Processing' },
158
- 2: { text: ORDER_STATUS[2].label, status: 'Success' },
159
- 3: { text: ORDER_STATUS[3].label, status: 'Error' },
160
- },
161
- width: 100,
162
- render: (_, record) => {
163
- const item = ORDER_STATUS[record.status as keyof typeof ORDER_STATUS];
164
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
165
- },
166
- },
167
- {
168
- title: t('createTime'),
169
- dataIndex: 'createTime',
170
- search: false,
171
- width: 180,
172
- },
173
- {
174
- title: tc('operation'),
175
- key: 'action',
176
- fixed: 'right',
177
- search: false,
178
- width: 150,
179
- render: (_, record) => (
180
- <Space>
181
- <Access code="aps:order:update">
182
- <a
183
- onClick={() => {
184
- setEditId(record.id);
185
- setDrawerOpen(true);
186
- }}
187
- >
188
- {tc('edit')}
189
- </a>
190
- </Access>
191
- <Access code="aps:order:delete">
192
- <a style={{ color: '#ff4d4f' }} onClick={() => handleDelete(record)}>
193
- {tc('delete')}
194
- </a>
195
- </Access>
196
- </Space>
197
- ),
198
- },
199
- ];
200
-
201
- return (
202
- <>
203
- <ProTable<OrderVO>
204
- columns={columns}
205
- actionRef={actionRef}
206
- rowKey="id"
207
- headerTitle={t('title')}
208
- scroll={{ x: 1400 }}
209
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
210
- request={async (params: any) => {
211
- const { current, pageSize, ...rest } = params;
212
- const { data } = await getOrderPage({
213
- pageNo: current ?? 1,
214
- pageSize: pageSize ?? 10,
215
- ...rest,
216
- });
217
- return { data: data.list, total: data.total, success: true };
218
- }}
219
- pagination={{ defaultPageSize: 10, showSizeChanger: true }}
220
- rowSelection={{ selectedRowKeys, onChange: setSelectedRowKeys }}
221
- toolBarRender={() => [
222
- <Access code="aps:order:create" key="add">
223
- <Button
224
- type="primary"
225
- icon={<PlusOutlined />}
226
- onClick={() => {
227
- setEditId(null);
228
- setDrawerOpen(true);
229
- }}
230
- >
231
- {tc('create')}
232
- </Button>
233
- </Access>,
234
- <Access code="aps:order:import" key="import">
235
- <Upload accept=".xlsx,.xls" showUploadList={false} beforeUpload={handleImport}>
236
- <Button icon={<UploadOutlined />}>{t('import')}</Button>
237
- </Upload>
238
- </Access>,
239
- <Access code="aps:order:export" key="export">
240
- <Button icon={<DownloadOutlined />} onClick={handleExport}>
241
- {t('export')}
242
- </Button>
243
- </Access>,
244
- <Access code="aps:order:delete" key="batch">
245
- <Button
246
- danger
247
- icon={<DeleteOutlined />}
248
- disabled={selectedRowKeys.length === 0}
249
- onClick={handleDeleteBatch}
250
- >
251
- {t('deleteBatch')}
252
- </Button>
253
- </Access>,
254
- <Button key="template" icon={<DownloadOutlined />} onClick={handleDownloadTemplate}>
255
- {t('downloadTemplate')}
256
- </Button>,
257
- ]}
258
- />
259
-
260
- <OrderDrawer
261
- open={drawerOpen}
262
- id={editId}
263
- onSuccess={() => {
264
- setDrawerOpen(false);
265
- reload();
266
- }}
267
- onClose={() => setDrawerOpen(false)}
268
- />
269
- </>
270
- );
271
- };
272
-
273
- export default OrderPage;
@@ -1,153 +0,0 @@
1
- import { useEffect, useState, useCallback } from 'react';
2
- import { Card, Form, InputNumber, Button, Space, Popconfirm, message, Divider } from 'antd';
3
- import { useTranslation } from 'react-i18next';
4
- import { Access } from '@/components/Access';
5
- import { getParamList, saveParams, resetParams } from '@/api/aps/param';
6
- import type { ProcessParamVO } from '@/types/aps/param';
7
- import { PARAM_NAMES } from '@/types/aps/param';
8
-
9
- const ParamPage: React.FC = () => {
10
- const { t } = useTranslation('aps/param');
11
- const { t: tc } = useTranslation('common');
12
- const [form] = Form.useForm();
13
- const [loading, setLoading] = useState(false);
14
- const [params, setParams] = useState<ProcessParamVO[]>([]);
15
-
16
- const loadParams = useCallback(async () => {
17
- setLoading(true);
18
- try {
19
- const res = await getParamList();
20
- setParams(res.data);
21
- const formValues: Record<string, string> = {};
22
- res.data.forEach((p) => {
23
- formValues[p.paramName] = p.paramValue;
24
- });
25
- form.setFieldsValue(formValues);
26
- } finally {
27
- setLoading(false);
28
- }
29
- }, [form]);
30
-
31
- useEffect(() => {
32
- // eslint-disable-next-line react-hooks/set-state-in-effect
33
- loadParams();
34
- }, [loadParams]);
35
-
36
- const handleSave = async () => {
37
- try {
38
- const values = form.getFieldsValue();
39
-
40
- // Validate weight sum
41
- const utilWeight = parseFloat(values[PARAM_NAMES.UTILIZATION_WEIGHT] || '0');
42
- const priorityWeight = parseFloat(values[PARAM_NAMES.PRIORITY_WEIGHT] || '0');
43
- const cutsWeight = parseFloat(values[PARAM_NAMES.CUTS_WEIGHT] || '0');
44
- const weightSum = utilWeight + priorityWeight + cutsWeight;
45
-
46
- if (Math.abs(weightSum - 1.0) > 0.001) {
47
- message.error(t('weightSumError', { sum: weightSum.toFixed(2) }));
48
- return;
49
- }
50
-
51
- const paramsToSave = Object.entries(values).map(([paramName, paramValue]) => {
52
- const existingParam = params.find(p => p.paramName === paramName);
53
- return {
54
- paramName,
55
- paramValue: String(paramValue),
56
- paramUnit: existingParam?.paramUnit || '',
57
- description: existingParam?.description || '',
58
- };
59
- });
60
-
61
- await saveParams(paramsToSave);
62
- message.success(t('saveSuccess'));
63
- loadParams();
64
- } catch {
65
- // Error handling
66
- }
67
- };
68
-
69
- const handleReset = async () => {
70
- await resetParams();
71
- message.success(t('resetSuccess'));
72
- loadParams();
73
- };
74
-
75
- const basicParams = [
76
- PARAM_NAMES.EDGE_WASTE_WIDTH,
77
- PARAM_NAMES.HEAD_TAIL_WASTE,
78
- PARAM_NAMES.CUT_HEAD_LENGTH,
79
- PARAM_NAMES.MAX_VERTICAL_CUTS,
80
- PARAM_NAMES.MAX_HORIZONTAL_CUTS,
81
- PARAM_NAMES.MIN_ORDER_WIDTH,
82
- ];
83
-
84
- const weightParams: string[] = [
85
- PARAM_NAMES.UTILIZATION_WEIGHT,
86
- PARAM_NAMES.PRIORITY_WEIGHT,
87
- PARAM_NAMES.CUTS_WEIGHT,
88
- ];
89
-
90
- const otherParams = [
91
- PARAM_NAMES.MIN_REGION_LENGTH,
92
- PARAM_NAMES.MAX_ORDER_SPLIT,
93
- ];
94
-
95
- const getParamUnit = (paramName: string) => {
96
- const param = params.find((p) => p.paramName === paramName);
97
- return param?.paramUnit || '';
98
- };
99
-
100
- const renderParamInput = (paramName: string) => {
101
- const unit = getParamUnit(paramName);
102
- const isWeight = weightParams.includes(paramName);
103
-
104
- return (
105
- <Form.Item
106
- key={paramName}
107
- name={paramName}
108
- label={t(`paramNames.${paramName}`)}
109
- rules={[{ required: true, message: tc('required') }]}
110
- >
111
- <InputNumber
112
- min={0}
113
- step={isWeight ? 0.1 : 1}
114
- style={{ width: '100%' }}
115
- addonAfter={unit || undefined}
116
- />
117
- </Form.Item>
118
- );
119
- };
120
-
121
- return (
122
- <Form form={form} layout="vertical">
123
- <Card title={t('paramGroups.basic')} style={{ marginBottom: 16 }}>
124
- {basicParams.map(renderParamInput)}
125
- </Card>
126
-
127
- <Card title={t('paramGroups.weight')} style={{ marginBottom: 16 }}>
128
- {weightParams.map(renderParamInput)}
129
- </Card>
130
-
131
- <Card title={t('paramGroups.other')} style={{ marginBottom: 16 }}>
132
- {otherParams.map(renderParamInput)}
133
- </Card>
134
-
135
- <Divider />
136
-
137
- <Space>
138
- <Access code="aps:param:update">
139
- <Button type="primary" onClick={handleSave} loading={loading}>
140
- {t('save')}
141
- </Button>
142
- </Access>
143
- <Access code="aps:param:update">
144
- <Popconfirm title={t('resetConfirm')} onConfirm={handleReset}>
145
- <Button loading={loading}>{t('reset')}</Button>
146
- </Popconfirm>
147
- </Access>
148
- </Space>
149
- </Form>
150
- );
151
- };
152
-
153
- export default ParamPage;