index.tsx
14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
import React, { useEffect, useState } from 'react';
import { Table, Button, Form, Space, DatePicker, Tree, Input, message, Card, Row, Col, Radio, Select, InputNumber} from 'antd';
import {saveReplacementApi, ApplyData} from '@/pages/order3/CarPurchaseSubsidy/ReplacementSubsidy/api';
import { getAllBrandApi, getSeriesApi } from "@/common/api";
import useInitial from '@/hooks/useInitail';
import NewDataModal from '@/pages/order3/Common/NewDataModal/index';
import moment from 'moment';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import CarTableTreeAuth from '@/components/CarTableTreeAuth';
import { PlusSquareOutlined } from '@ant-design/icons';
import { CarAuthList } from '@/components/CarTableTreeAuth/entity';
import { getShopApi, ShopVo, RequestShopParams } from '@/pages/order3/Common/api';
import { isNil } from 'lodash';
interface DataNode {
title: string;
key: string;
isLeaf?: boolean;
children?: DataNode[];
}
const Requirements = [{value: true, label: '必买'}, {value: false, label: '非必买'}];
export default function ApplyModal() {
const [form] = Form.useForm();
const [loading, setLoading] = useState<boolean>(false);
const {data} = useInitial(getAllBrandApi, [], {});
const [treeData, setTreeData] = useState<any>([]);
const [checked, setChecked] = useState<any[]>([]);
const [beforeData, setBeforeData] = useState<ApplyData[]>([]); // 前置资料
const [afterData, setAfterData] = useState<ApplyData[]>([]); // 后置资料
const [afterDay, setAfterDay] = useState<number>(); // 后置资料上传天数
const [shopList, setShopList] = useState<ShopVo[]>([]);
const [shopLoading, setShopLoading] = useState<boolean>(false);
const [carSelectData, setCarSelectData] = useState<CarAuthList[]>([]);
const [insure, setInsure] = useState<any>([{mustBuyTci: undefined, mustBuyVci: undefined, vciBuyAmount: undefined, id: 1}]);
useEffect(() => {
if (data.length) {
const _data = data.map((v:any) => {
return { title: v.name, key: `${v.id}${v.initial}` };
});
setTreeData(_data);
}
}, [data.length]);
useEffect(() => {
if (checked.length) {
form.setFieldsValue({sameBrandRange: checked});
} else {
form.setFieldsValue({sameBrandRange: undefined});
}
}, [checked.length]);
const onCheck = (value:any) => {
setChecked(value);
};
const brandList = (value:any[]) => {
const _data: any[] = JSON.parse(JSON.stringify(treeData));
const parent = _data.filter(v => value.includes(v.key));
const children = _data.filter(v => !value.includes(v.key));
let childrenNode: any[] = [];
children.map(k => {
if (k.children && k.children.length>0) {
k.children.map((v:any) => {
if (value.includes(v.key)) {
const node = {brandId: parseInt(k.key, 10), brandName: k.title, seriesId: v.key, seriesName: v.title};
childrenNode.push(node);
}
return v;
});
}
return k;
});
parent.map(k => {
if (value.includes(k.key)) {
childrenNode.push({brandId: parseInt(k.key, 10), brandName: k.title});
}
return k;
});
return childrenNode;
};
function updateTreeData(list: DataNode[], key: React.Key, children: DataNode[]): DataNode[] {
return list.map(node => {
if (node.key === key) {
return {
...node,
children,
};
}
// if (node.children) {
// return {
// ...node,
// children: updateTreeData(node.children, key, children),
// };
// }
return node;
});
}
const onLoadData = async ({key, children} : any) => {
if (children) {
return;
}
const {data: childrenNode} = await getSeriesApi(parseInt(key, 10));
const _childrenNode = (childrenNode || []).map((v:any) => { return {key: v.id, title: v.name, isLeaf: true}; });
setTreeData((origin:any) => updateTreeData(origin, key, _childrenNode));
};
const handleCancel = () => {
setChecked([]);
setChecked([]);
};
const onFinsh = async () => {
const param = await form.validateFields();
const _param: any = {
beginTime: (+moment(param.time[0], "YYYY-MM-DD HH:mm:ss").unix())*1000, // 开始时间
endTime: (+moment(param.time[1], "YYYY-MM-DD HH:mm:ss").unix())*1000, // 结束时间
brandId: param.brand.value, // 品牌id
brandName: param.brand.label, // 品牌名称
applyCarType: param.applyCarType, // 适用车辆范围
sameBrandAmount: +param.sameBrandAmount, // 本品牌补贴金额
diffBrandAmount: +param.diffBrandAmount, // 非本品牌补贴金额
extraAmount: +param.extraAmount, // 4S店老客户升级置换额外享受补贴
applyShops: param.applyShops.map((item:any) => { return {shopId: item.value, shopName: item.label}; }), // 门店列表
subsidyDataUploadApply: beforeData.map((v:any) => { return {applyUpload: 1, dataType: v.dataType, dataName: v.dataName}; }), // 申请时上传资料
subsidyType: 2,
applyCarList: handleCarData(param.optionalAuth),
containOrder: param.containOrder,
insuranceRequire: param.insuranceRequire
};
if (checked.length === 0) {
message.error("请选择本品牌范围!");
return;
} else if (!isNil(afterDay) && afterData.length === 0) {
message.error("请勾选交车后N天内上传的资料!");
return;
} else if (param.insuranceRequire && isNil(insure[0].mustBuyTci)) {
message.error("请选择是否购买交强险!");
return;
} else if (param.insuranceRequire && isNil(insure[0].mustBuyVci)) {
message.error("请选择商是否购买商业险购!");
return;
} else if (param.insuranceRequire && isNil(insure[0].vciBuyAmount)) {
message.error("请选择输入商业险金额!");
return;
}
if (!isNil(afterDay)) {
_param.deliveryAfterDays = afterDay;
_param.subsidyDataUploadNDay = afterData.map((item: any) => { return {applyUpload: 0, dataType: item.dataType, dataName: item.dateName}; });
}
if (param.insuranceRequire) {
_param.mustBuyTci = insure[0].mustBuyTci;
_param.mustBuyVci = insure[0].mustBuyVci;
_param.vciBuyAmount = insure[0].vciBuyAmount;
}
if (param.applyCarType === 2) {
_param.applySpecList = param.applySeriesList.map((item:any) => { return {seriesId: item.value, seriesName: item.label}; });
}
const sameBrandRange = brandList(checked);
_param.sameBrandRange = sameBrandRange;
setLoading(true);
saveReplacementApi(_param)
.then(res => {
message.success(res.result);
setLoading(false);
})
.catch(e => {
message.error(e.message);
setLoading(false);
});
};
/**
* 选择车辆范围回调
* @param value 车辆树形结构
*/
function handleChange(value: CarAuthList[] = []) {
const brandIds: number[] = [];
const seriesIds: number[] = [];
const specIds: number[] = [];
value.forEach(v => {
if (v.children) {
v.children.forEach(k => {
if (k.children) {
const spec = k.children.map(q => q.specId);
specIds.push(...spec);
} else {
seriesIds.push(k.seriesId);
}
});
} else {
brandIds.push(v.brandId);
}
});
const parmas = {
brandIds,
seriesIds,
specIds
};
setCarSelectData(value || []);
getShopScope(parmas);
console.log(value);
}
/**
* 获取所选车辆的授权门店范围
* @param params
*/
function getShopScope(params: RequestShopParams) {
setShopLoading(true);
getShopApi(params)
.then(res => {
setShopLoading(false);
setShopList(res.data || []);
}).catch(e => {
setShopLoading(false);
setShopList([]);
message.error(e.message);
});
}
function handleInsureChange(name: string, value?: number) {
setInsure([{...insure[0], [name]: value}]);
}
function resetInsure() {
setInsure([{mustBuyTci: undefined, mustBuyVci: undefined, vciBuyAmount: undefined, id: 1}]);
}
/**
* 将树形车辆结构转换成扁平结构
* applyCarType为最细化层级的类型
* @param value
* @returns
*/
function handleCarData(value: CarAuthList[]) {
const result: any = [];
let applyCarType = 1;
value.forEach(v => {
if (v.children) {
v.children.forEach(k => {
if (k.children) {
k.children.forEach(r => {
const item = {brandId: v.brandId, brandName: v.brandName, seriesId: k.seriesId, seriesName: k.seriesName, specId: r.specId, specName: r.specName};
result.push(item);
applyCarType = Math.max(applyCarType, 3);
});
} else {
const item = {brandId: v.brandId, brandName: v.brandName, seriesId: k.seriesId, seriesName: k.seriesName};
result.push(item);
applyCarType = Math.max(applyCarType, 2);
}
});
} else {
const item = { brandId: v.brandId, brandName: v.brandName, applyCarType: v.authType};
result.push(item);
applyCarType = Math.max(applyCarType, 1);
}
});
const _result = result.map((v: any) => ({...v, applyCarType}));
return _result;
}
return (
<PageHeaderWrapper title="置换补贴">
<Card>
<Row justify="center">
<Col span={16}>
<Form
form={form}
>
<Form.Item
name="optionalAuth"
label="授权车辆范围"
rules={[{ required: true, message: "选择车辆" }]}
tooltip={<span style={{ color: '#ccc', fontSize: 12 }}>*点击图标<PlusSquareOutlined />展开授权详情</span>}
>
<CarTableTreeAuth value={carSelectData} onChange={handleChange} brandMultiple={false} />
</Form.Item>
<Form.Item
label="适用门店"
name="applyShops"
labelAlign="left"
rules={[{ required: true, message: "请选择适用门店" }]}
>
<Select mode="multiple" allowClear filterOption optionFilterProp="children" labelInValue placeholder="请选择" options={shopList.map(v => ({label: v.shopName, value: v.shopId}))} loading={shopLoading} />
</Form.Item>
<Form.Item name="time" label="有效时间" rules={[{ type: 'array' as const, required: true, message: '请选择有效时间!' }]}>
<DatePicker.RangePicker showTime style={{width: "100%"}} />
</Form.Item>
<Form.Item name="sameBrandAmount" label="补贴金额(本品牌)" rules={[{required: true, pattern: /^(\d+|\d+\.\d{1,2})$/, message: "请输入正确的本品牌补贴金额!"}]}>
<Input placeholder="请输入本品牌补贴金额" suffix="元" />
</Form.Item>
<Form.Item name="diffBrandAmount" label="补贴金额(非本品牌)" rules={[{required: true, pattern: /^(\d+|\d+\.\d{1,2})$/, message: "请输入正确的非本品牌补贴金额!"}]}>
<Input placeholder="请输入非本品牌补贴金额" suffix="元" />
</Form.Item>
<Form.Item name="sameBrandRange" label="本品牌范围" rules={[{required: true, message: "请选择本品牌范围!"}]}>
<Tree
height={330}
checkable
onCheck={(value) => onCheck(value)}
checkedKeys={checked || []}
loadData={onLoadData}
treeData={treeData}
/>
</Form.Item>
<Form.Item name="extraAmount" label="4S店老客户升级置换额外享受补贴" rules={[{required: true, pattern: /^(\d+|\d+\.\d{1,2})$/, message: "请输入正确的补贴值!"}]}>
<Input />
</Form.Item>
<Form.Item labelAlign="left" label="保险要求" name="insuranceRequire" rules={[{required: true, message: "请选择保险要求!"}]}>
<Radio.Group onChange={resetInsure}>
<Radio value={false}>无要求</Radio>
<Radio value>有要求</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) => prevValues.insuranceRequire !== curValues.insuranceRequire}
>
{({ getFieldValue }) => {
const bool = getFieldValue('insuranceRequire');
return bool ? (
<Card>
<Table pagination={false} dataSource={insure} rowKey="id">
<Table.Column
title="交强险"
dataIndex="mustBuyTci"
render={(_text, record) => <Select value={_text} onChange={(e) => handleInsureChange("mustBuyTci", e)} placeholder="请选择" options={Requirements} />}
/>
<Table.Column
title="商业险"
dataIndex="mustBuyVci"
render={(_text, record) => <Select value={_text} onChange={e => handleInsureChange("mustBuyVci", e)} placeholder="请选择" options={Requirements} />}
/>
<Table.Column
title="商业险金额(≥元)"
dataIndex="vciBuyAmount"
render={(_text, record) => <InputNumber value={_text} onChange={e => handleInsureChange("vciBuyAmount", e)} controls={false} min={0} precision={2} placeholder="请输入金额" />}
/>
</Table>
</Card>
) : null;
}}
</Form.Item>
<Form.Item labelAlign="left" label="政策适用范围" name="containOrder" rules={[{required: true, message: "请选择政策适用范围!"}]}>
<Radio.Group>
<Radio value>是</Radio>
<Radio value={false}>否</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
labelAlign="left"
label="置换补贴资料"
required
/>
<NewDataModal checked={afterData} selectData={beforeData} setSelectData={setBeforeData} />
<NewDataModal postData checked={beforeData} selectData={afterData} setSelectData={setAfterData} afterDay={afterDay} setAfterDay={setAfterDay} />
</Form>
<Row justify="center">
<Space>
<Button key="cancel" onClick={handleCancel} style={{marginLeft: 10}}>取消</Button>
<Button key="submit" onClick={onFinsh} type="primary" htmlType="submit" loading={loading}>确认</Button>
</Space>
</Row>
</Col>
</Row>
</Card>
</PageHeaderWrapper>
);
}