Commit 39bd8a072a89135a881d9e72d6f03d8f53f118d1

Authored by Kurisu
2 parents 4939d11d b8badb2a

Merge remote-tracking branch 'origin/master' into bug_fix

build.txt
1   -https://gate.feewee.cn/file/show?fid=539953927090245
2 1 \ No newline at end of file
  2 +https://gate.feewee.cn/file/show?fid=539994370875461
3 3 \ No newline at end of file
... ...
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',
... ...