Commit 23aac100fa2a7139d1cf3b13319a2d41ab31e50e
Merge remote-tracking branch 'origin/master' into personMove
Showing
9 changed files
with
174 additions
and
42 deletions
.nvmrc
0 → 100644
1 | +lts/hydrogen | ... | ... |
build.txt
src/pages/cas/afterSaleConfiguration/maintainConfig/components/OilDetailModal/index.tsx
1 | 1 | import React, { useEffect, useMemo, useState } from 'react'; |
2 | -import { Modal, Button, Spin, message, Row, Radio, Table, Empty } from 'antd'; | |
3 | -import { DetailParams, EnergyType, detailApi, energyListApi, getSpecListApi } from '../../subpages/MaintainEdit/api'; | |
2 | +import { Button, Empty, message, Modal, Radio, Row, Spin, Table } from 'antd'; | |
3 | +import { detailApi, DetailParams, energyListApi, EnergyType, getSpecListApi } from '../../subpages/MaintainEdit/api'; | |
4 | 4 | import { ApplyScopeEnum, EnergyTypeEnum, InhaleCodeEnum } from '../../entity'; |
5 | 5 | import st from './style.less'; |
6 | 6 | import useInitial from '@/hooks/useInitail'; |
... | ... | @@ -19,6 +19,7 @@ interface Props { |
19 | 19 | applyScope: number; |
20 | 20 | onCancel: () => void; |
21 | 21 | } |
22 | + | |
22 | 23 | export default function OilDetailModal({ visible, brandId, seriesId, applyScope, onCancel }: Props) { |
23 | 24 | const [energyIndex, setEnergyIndex] = useState(0); |
24 | 25 | const [energyTypes, setEnergyTypes] = useState<EnergyType[]>([]); |
... | ... | @@ -259,7 +260,17 @@ export default function OilDetailModal({ visible, brandId, seriesId, applyScope, |
259 | 260 | <Table dataSource={currGroup.partFilters} pagination={false} scroll={{ y: 200 }}> |
260 | 261 | <Column title="配件名称" dataIndex="partName" /> |
261 | 262 | <Column title="配件编码" width={300} dataIndex="partCode" /> |
262 | - <Column title="数量" width={200} dataIndex="partCnt" /> | |
263 | + <Column | |
264 | + title="数量" | |
265 | + width={200} | |
266 | + dataIndex="partCnt" | |
267 | + render={(partCnt: number, record: Maintain.ListVO) => ( | |
268 | + <span> | |
269 | + {partCnt} | |
270 | + {record.decimal ? record.oilUnit || '' : ''} | |
271 | + </span> | |
272 | + )} | |
273 | + /> | |
263 | 274 | </Table> |
264 | 275 | </> |
265 | 276 | )} |
... | ... | @@ -279,7 +290,17 @@ export default function OilDetailModal({ visible, brandId, seriesId, applyScope, |
279 | 290 | <Table dataSource={item.parts} pagination={false} scroll={{ y: 200 }}> |
280 | 291 | <Column title="配件名称" dataIndex="partName" /> |
281 | 292 | <Column title="配件编码" width={300} dataIndex="partCode" /> |
282 | - <Column title="数量" width={200} dataIndex="partCnt" /> | |
293 | + <Column | |
294 | + title="数量" | |
295 | + width={200} | |
296 | + dataIndex="partCnt" | |
297 | + render={(partCnt: number, record: Maintain.ListVO) => ( | |
298 | + <span> | |
299 | + {partCnt} | |
300 | + {record.decimal ? record.oilUnit || '' : ''} | |
301 | + </span> | |
302 | + )} | |
303 | + /> | |
283 | 304 | </Table> |
284 | 305 | </div> |
285 | 306 | ))} | ... | ... |
src/pages/cas/afterSaleConfiguration/maintainConfig/interface.d.ts
... | ... | @@ -16,6 +16,10 @@ declare namespace Maintain { |
16 | 16 | inhaleType: number; // 进气方式 |
17 | 17 | exhaust: number; // 排量 |
18 | 18 | applyScope: number; // 保养类型 |
19 | + decimal?: boolean; // 是否可以是小数 | |
20 | + capacity?: number; // 容量 | |
21 | + oilUnit?: string; // 容量单位 | |
22 | + unit?: string; // 单位 | |
19 | 23 | } |
20 | 24 | |
21 | 25 | interface DetailVO { |
... | ... | @@ -104,8 +108,12 @@ declare namespace Maintain { |
104 | 108 | partNumber?: number; |
105 | 109 | /**价格 */ |
106 | 110 | price?: number; |
111 | + /** 容量 */ | |
112 | + capacity?: number; | |
107 | 113 | /** 单位 */ |
108 | 114 | unit?: string; |
115 | + /** 容量单位 */ | |
116 | + oilUnit?: string; | |
109 | 117 | /** 油液标号 */ |
110 | 118 | oilGrade?: string; |
111 | 119 | /** 配件品牌 */ | ... | ... |
src/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/GroupConfig/index.tsx
... | ... | @@ -126,25 +126,26 @@ export default function ConfigItem({ configType, base, groupData, energyItem, on |
126 | 126 | > |
127 | 127 | 添加作业项 |
128 | 128 | </Button> |
129 | - <AddItemModal | |
130 | - value={currItem} | |
131 | - visible={itemVisible} | |
132 | - brand={base.brandId} | |
133 | - onCancel={() => setItemVisible(false)} | |
134 | - onChange={(value: Maintain.WorkItem) => { | |
135 | - const idx = groupData.workItems.findIndex((item) => item.id === value.id); | |
136 | - if (idx === -1 && !currItem) { | |
137 | - groupData.workItems.push(value); | |
138 | - } else { | |
139 | - groupData.workItems.splice(idx, 1, value); | |
140 | - } | |
141 | - onUpdate({ ...groupData }); | |
142 | - setItemVisible(false); | |
143 | - }} | |
144 | - /> | |
145 | 129 | </> |
146 | 130 | )} |
147 | 131 | </Card> |
132 | + | |
133 | + <AddItemModal | |
134 | + value={currItem} | |
135 | + visible={itemVisible} | |
136 | + brand={base.brandId} | |
137 | + onCancel={() => setItemVisible(false)} | |
138 | + onChange={(value: Maintain.WorkItem) => { | |
139 | + const idx = groupData.workItems.findIndex((item) => item.id === value.id); | |
140 | + if (idx === -1 && !currItem) { | |
141 | + groupData.workItems.push(value); | |
142 | + } else { | |
143 | + groupData.workItems.splice(idx, 1, value); | |
144 | + } | |
145 | + onUpdate({ ...groupData }); | |
146 | + setItemVisible(false); | |
147 | + }} | |
148 | + /> | |
148 | 149 | </> |
149 | 150 | ); |
150 | 151 | } | ... | ... |
src/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/api.ts
... | ... | @@ -153,3 +153,15 @@ export interface OilList { |
153 | 153 | export function getOilListApi(params: OilParams): http.PromisePageResp<OilList> { |
154 | 154 | return request.get(`${PMS_HOST}/erp/part/oil/parts`, { params }); |
155 | 155 | } |
156 | + | |
157 | +export interface OtherPartInfo { | |
158 | + partId: number; // 配件 id | |
159 | + decimal: boolean; // 是否支持小数 | |
160 | + capacity: number; // 容量 | |
161 | + oilUnit: string; // 容量单位 | |
162 | + unit: string; // 单位 | |
163 | +} | |
164 | + | |
165 | +export function getOtherPartInfo(partIds: number[]): http.PromiseResp<OtherPartInfo[]> { | |
166 | + return request.post(`${CAS_HOST}/erp/basic/maintenance/config/other/part/info`, { partIds }); | |
167 | +} | ... | ... |
src/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/components/PartFilter/index.tsx
1 | 1 | import React, { useEffect, useState } from 'react'; |
2 | -import { Button, Form, InputNumber, Popconfirm, Row, Table } from 'antd'; | |
2 | +import { Button, Form, InputNumber, Modal, Popconfirm, Row, Table } from 'antd'; | |
3 | + | |
4 | +import { getOtherPartInfo } from '@/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/api'; | |
3 | 5 | |
4 | 6 | import EngineFilterModal from '../MachineFilter/components/EngineFilterModal'; |
5 | 7 | |
... | ... | @@ -22,7 +24,7 @@ export default function PartFilter({ partFilters, brandId, onChange }: Props) { |
22 | 24 | setDataSource([...partFilters]); |
23 | 25 | }, [partFilters]); |
24 | 26 | |
25 | - function _onElseOk(data: Maintain.PartItem[]) { | |
27 | + async function _onElseOk(data: Maintain.PartItem[]) { | |
26 | 28 | const newData: any[] = []; |
27 | 29 | data.forEach((item, _index) => { |
28 | 30 | const index = newData.findIndex((i) => `${item.partCode}_${item.partNo}` == `${i.partCode}_${i.partNo}`); |
... | ... | @@ -39,8 +41,30 @@ export default function PartFilter({ partFilters, brandId, onChange }: Props) { |
39 | 41 | }); |
40 | 42 | } |
41 | 43 | }); |
42 | - onChange && onChange(newData); | |
43 | - setElseVisible(false); | |
44 | + // 获取配件是否可配置为小数信息 | |
45 | + try { | |
46 | + const res = await getOtherPartInfo(newData.map((item) => item.partId)); | |
47 | + const partInfoList = res.data || []; | |
48 | + newData.forEach((item, index) => { | |
49 | + const pIdx = partInfoList.findIndex((i) => i.partId == item.partId); | |
50 | + // 配件是可配置为小数 | |
51 | + if (pIdx > -1 && partInfoList[pIdx].decimal) { | |
52 | + // 设置对应参数,提交时需要传 | |
53 | + newData[index].decimal = partInfoList[pIdx].decimal; | |
54 | + newData[index].capacity = partInfoList[pIdx].capacity; | |
55 | + newData[index].oilUnit = partInfoList[pIdx].oilUnit; | |
56 | + newData[index].unit = partInfoList[pIdx].unit; | |
57 | + } | |
58 | + }); | |
59 | + | |
60 | + onChange && onChange(newData); | |
61 | + setElseVisible(false); | |
62 | + } catch (err) { | |
63 | + Modal.error({ | |
64 | + title: '获取配件信息失败', | |
65 | + content: `${String(err)}`, | |
66 | + }); | |
67 | + } | |
44 | 68 | } |
45 | 69 | |
46 | 70 | function onDelete(record: Maintain.PartItem) { |
... | ... | @@ -92,6 +116,9 @@ export default function PartFilter({ partFilters, brandId, onChange }: Props) { |
92 | 116 | partCode: string; |
93 | 117 | partNumber: number; |
94 | 118 | recommend: boolean; |
119 | + decimal?: boolean; | |
120 | + capacity?: number; | |
121 | + unit?: string; | |
95 | 122 | } |
96 | 123 | |
97 | 124 | interface EditableCellProps extends React.HTMLAttributes<HTMLElement> { |
... | ... | @@ -105,8 +132,8 @@ export default function PartFilter({ partFilters, brandId, onChange }: Props) { |
105 | 132 | } |
106 | 133 | |
107 | 134 | const EditableCell: React.FC<EditableCellProps> = ({ editing, dataIndex, title, inputType, record, index, children, ...restProps }) => { |
108 | - // todo 液态配件可以输入小数 | |
109 | - const inputNode = <InputNumber precision={0} />; | |
135 | + // 液态配件可以输入小数 | |
136 | + const inputNode = <InputNumber precision={record?.decimal ? 2 : 0} />; | |
110 | 137 | |
111 | 138 | return ( |
112 | 139 | <td {...restProps}> |
... | ... | @@ -158,6 +185,7 @@ export default function PartFilter({ partFilters, brandId, onChange }: Props) { |
158 | 185 | width={150} |
159 | 186 | title="数量" |
160 | 187 | dataIndex="partCnt" |
188 | + render={(cnt: number, record) => `${cnt}${record.oilUnit ?? ''}`} | |
161 | 189 | onCell={(record: Maintain.PartItem) => ({ |
162 | 190 | record, |
163 | 191 | inputType: 'number', | ... | ... |
src/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/components/WorkItemSelector/PartEditTable/index.tsx
1 | 1 | import React, { useState, useEffect } from 'react'; |
2 | 2 | import { PlusOutlined } from '@ant-design/icons'; |
3 | -import { Button, Card, Form, InputNumber, Popconfirm, Table } from 'antd'; | |
3 | +import { Button, Card, Form, InputNumber, Modal, Popconfirm, Table } from 'antd'; | |
4 | 4 | import AddPartsModal from '../AddPartsModal'; |
5 | 5 | |
6 | +import { getOtherPartInfo } from '@/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/api'; | |
7 | + | |
6 | 8 | const { Column } = Table; |
7 | 9 | |
8 | 10 | interface Props { |
... | ... | @@ -17,6 +19,9 @@ interface Item { |
17 | 19 | partCode: string; |
18 | 20 | partNumber: number; |
19 | 21 | recommend: boolean; |
22 | + decimal?: boolean; | |
23 | + capacity?: number; | |
24 | + unit?: string; | |
20 | 25 | } |
21 | 26 | |
22 | 27 | interface EditableCellProps extends React.HTMLAttributes<HTMLElement> { |
... | ... | @@ -43,7 +48,7 @@ export default function PartTable({ value, _onChange, specGroupCode }: Props) { |
43 | 48 | _onChange && _onChange(selected); |
44 | 49 | }, [selected]); |
45 | 50 | |
46 | - const handleSelect = (params: any) => { | |
51 | + const handleSelect = async (params: any) => { | |
47 | 52 | const newdatas = params.map((item: Maintain.PartListVO) => ({ |
48 | 53 | partId: item.partId, |
49 | 54 | partName: item.partName, |
... | ... | @@ -51,7 +56,26 @@ export default function PartTable({ value, _onChange, specGroupCode }: Props) { |
51 | 56 | partNo: item.partNo, |
52 | 57 | partCnt: 1, |
53 | 58 | })); |
54 | - setSelected([...newdatas]); | |
59 | + | |
60 | + // 获取配件信息 | |
61 | + try { | |
62 | + const res = await getOtherPartInfo(newdatas.map((item: any) => item.partId)); | |
63 | + const partInfoList = res.data || []; | |
64 | + newdatas.forEach((part: any) => { | |
65 | + const _index = partInfoList.findIndex((i) => i.partId == part.partId); | |
66 | + part.decimal = partInfoList[_index].decimal; | |
67 | + part.capacity = partInfoList[_index].capacity; | |
68 | + part.oilUnit = partInfoList[_index].oilUnit; | |
69 | + part.unit = partInfoList[_index].unit; | |
70 | + }) | |
71 | + | |
72 | + setSelected([...newdatas]); | |
73 | + } catch (err) { | |
74 | + Modal.error({ | |
75 | + title: '获取配件信息失败', | |
76 | + content: `${String(err)}`, | |
77 | + }); | |
78 | + } | |
55 | 79 | }; |
56 | 80 | |
57 | 81 | const handleSavePart = async (key: React.Key) => { |
... | ... | @@ -91,7 +115,7 @@ export default function PartTable({ value, _onChange, specGroupCode }: Props) { |
91 | 115 | }; |
92 | 116 | |
93 | 117 | const EditableCell: React.FC<EditableCellProps> = ({ editing, dataIndex, title, inputType, record, index, children, ...restProps }) => { |
94 | - const inputNode = <InputNumber />; | |
118 | + const inputNode = <InputNumber precision={record?.decimal ? 2 : 0} />; | |
95 | 119 | |
96 | 120 | return ( |
97 | 121 | <td {...restProps}> |
... | ... | @@ -151,6 +175,7 @@ export default function PartTable({ value, _onChange, specGroupCode }: Props) { |
151 | 175 | width={150} |
152 | 176 | title="数量" |
153 | 177 | dataIndex="partCnt" |
178 | + render={(cnt: number, record) => `${cnt}${record.oilUnit ?? ''}`} | |
154 | 179 | onCell={(record: Maintain.PartItem) => ({ |
155 | 180 | record, |
156 | 181 | inputType: 'number', | ... | ... |
src/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/components/WorkItemSelector/index.tsx
1 | 1 | import React, { useState } from 'react'; |
2 | -import { Button, Form, InputNumber, Popconfirm, Row, Table } from 'antd'; | |
2 | +import { Button, Form, InputNumber, Modal, Popconfirm, Row, Table } from 'antd'; | |
3 | 3 | import { EditOutlined, DeleteOutlined } from '@ant-design/icons'; |
4 | 4 | |
5 | +import { getOtherPartInfo } from '@/pages/cas/afterSaleConfiguration/maintainConfig/subpages/MaintainEdit/api'; | |
6 | + | |
5 | 7 | import AddPartsModal from './AddPartsModal'; |
6 | 8 | |
7 | 9 | const { Column } = Table; |
... | ... | @@ -12,6 +14,9 @@ interface Item { |
12 | 14 | partCode: string; |
13 | 15 | partNumber: number; |
14 | 16 | recommend: boolean; |
17 | + decimal?: boolean; | |
18 | + capacity?: number; | |
19 | + unit?: string; | |
15 | 20 | } |
16 | 21 | |
17 | 22 | interface EditableCellProps extends React.HTMLAttributes<HTMLElement> { |
... | ... | @@ -65,7 +70,7 @@ export default function WorkItemSelector({ index, currItem, onEdit, onDelete, on |
65 | 70 | }; |
66 | 71 | |
67 | 72 | // 选择配件 |
68 | - const handleSelectParts = (params: any) => { | |
73 | + const handleSelectParts = async (params: any) => { | |
69 | 74 | const allSelectedParts: Maintain.PartItem[] = params.map((item: Maintain.PartListVO) => ({ |
70 | 75 | partId: item.partId, |
71 | 76 | partName: item.partName, |
... | ... | @@ -73,14 +78,44 @@ export default function WorkItemSelector({ index, currItem, onEdit, onDelete, on |
73 | 78 | partNo: item.partNo, |
74 | 79 | partCnt: 1, |
75 | 80 | })); |
76 | - allSelectedParts.forEach((item) => { | |
77 | - const partIdx = currItem.parts.findIndex((i) => i.partCode === item.partCode); | |
78 | - // 避免上次已选配件已编辑数据被覆盖 | |
79 | - if (partIdx === -1) { | |
80 | - currItem.parts.push(item); | |
81 | - } | |
82 | - }); | |
83 | - onChange({ ...currItem }); | |
81 | + | |
82 | + // 原有逻辑 | |
83 | + // allSelectedParts.forEach((item) => { | |
84 | + // const partIdx = currItem.parts.findIndex((i) => i.partCode === item.partCode); | |
85 | + // // 避免上次已选配件已编辑数据被覆盖 | |
86 | + // if (partIdx === -1) { | |
87 | + // currItem.parts.push(item); | |
88 | + // } | |
89 | + // }); | |
90 | + // 获取配件是否可配置为小数信息 | |
91 | + | |
92 | + try { | |
93 | + const res = await getOtherPartInfo(allSelectedParts.map((item) => item.partId)); | |
94 | + const partInfoList = res.data || []; | |
95 | + | |
96 | + allSelectedParts.forEach((item) => { | |
97 | + const _index = partInfoList.findIndex((i) => i.partId == item.partId); | |
98 | + const partIdx = currItem.parts.findIndex((i) => i.partCode === item.partCode); | |
99 | + // 避免上次已选配件已编辑数据被覆盖 | |
100 | + if (partIdx === -1) { | |
101 | + // 新增 | |
102 | + currItem.parts.push(item); | |
103 | + } else { | |
104 | + // 编辑,保留编辑数据,替换规格信息 | |
105 | + currItem.parts[partIdx].decimal = partInfoList[_index].decimal; | |
106 | + currItem.parts[partIdx].capacity = partInfoList[_index].capacity; | |
107 | + currItem.parts[partIdx].oilUnit = partInfoList[_index].oilUnit; | |
108 | + currItem.parts[partIdx].unit = partInfoList[_index].unit; | |
109 | + } | |
110 | + }); | |
111 | + | |
112 | + onChange({ ...currItem }); | |
113 | + } catch (err) { | |
114 | + Modal.error({ | |
115 | + title: '获取配件信息失败', | |
116 | + content: `${String(err)}`, | |
117 | + }); | |
118 | + } | |
84 | 119 | }; |
85 | 120 | |
86 | 121 | const isEditing = (record: Maintain.PartItem) => record.partCode === editingKey; |
... | ... | @@ -95,7 +130,7 @@ export default function WorkItemSelector({ index, currItem, onEdit, onDelete, on |
95 | 130 | }; |
96 | 131 | |
97 | 132 | const EditableCell: React.FC<EditableCellProps> = ({ editing, dataIndex, title, inputType, record, index, children, ...restProps }) => { |
98 | - const inputNode = <InputNumber />; | |
133 | + const inputNode = <InputNumber precision={record?.decimal ? 2 : 0} />; | |
99 | 134 | |
100 | 135 | return ( |
101 | 136 | <td {...restProps}> |
... | ... | @@ -162,6 +197,7 @@ export default function WorkItemSelector({ index, currItem, onEdit, onDelete, on |
162 | 197 | width={150} |
163 | 198 | title="数量" |
164 | 199 | dataIndex="partCnt" |
200 | + render={(cnt: number, record) => `${cnt}${record.oilUnit ?? ''}`} | |
165 | 201 | onCell={(record: Maintain.PartItem) => ({ |
166 | 202 | record, |
167 | 203 | inputType: 'number', | ... | ... |