Commit bc9db829e40de19f6ee76d2e9590ab4039648bc2

Authored by 舒述军
1 parent dd3e22ff

新增置换补贴

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