Commit dd3e22ff40c771075e5842c1174b8b09ad2f973c

Authored by 舒述军
1 parent 92ca4e8d

新增增购补贴

src/pages/order3/CarPurchaseSubsidy/AdditionalPurchaseSubsidy/subpages/AddConfig/index.tsx
1 1 import React, { useEffect, useState } from 'react';
2 2 import { Button, Form, Select, DatePicker, Radio, Input, message, Col, Space, Row, Card, Table, InputNumber} from 'antd';
3   -import CarSelect from '@/pages/order3/Common/CarSelect/index';
4 3 import {saveAdditionalApi, ApplyData} from '@/pages/order3/CarPurchaseSubsidy/AdditionalPurchaseSubsidy/api';
5 4 import NewDataModal from '@/pages/order3/Common/NewDataModal/index';
6 5 import moment from 'moment';
7 6 import { PageHeaderWrapper } from '@ant-design/pro-layout';
  7 +import CarTableTreeAuth from '@/components/CarTableTreeAuth';
  8 +import { PlusSquareOutlined } from '@ant-design/icons';
  9 +import { CarAuthList } from '@/components/CarTableTreeAuth/entity';
  10 +import { getShopApi, ShopVo, RequestShopParams } from '@/pages/order3/Common/api';
  11 +import { isNil } from 'lodash';
8 12  
9 13 const Requirements = [{value: true, label: '必买'}, {value: false, label: '非必买'}];
10 14  
11 15 export default function ApplyModal() {
12 16 const [form] = Form.useForm();
13 17 const [loading, setLoading] = useState<boolean>(false);
14   - const [showTree, setShowTree] = useState<any[]>([]);
15   - const [subinfo, setSubinfo] = useState<number[]>([]);
16   - const [afterCar, setAfterCar] = useState<number[]>([]);
17 18 const [hidden, setHidden] = useState<any>({data: true, price: true});
18   - const [specKey, setSpecKey] = useState<any[]>([]);
19 19 const [calc, setCalc] = useState<number>(1);
20 20 const [insure, setInsure] = useState<any>([{mustBuyTci: undefined, mustBuyVci: undefined, vciBuyAmount: undefined}]);
21 21 const [beforeData, setBeforeData] = useState<ApplyData[]>([]); // 前置资料
22 22 const [afterData, setAfterData] = useState<ApplyData[]>([]); // 后置资料
23 23 const [afterDay, setAfterDay] = useState<number>(); // 后置资料上传天数
  24 + const [shopList, setShopList] = useState<ShopVo[]>([]);
  25 + const [shopLoading, setShopLoading] = useState<boolean>(false);
  26 + const [carSelectData, setCarSelectData] = useState<CarAuthList[]>([]);
24 27  
25 28 const handleCancel = () => {
26   - setSubinfo([]);
27   - setSpecKey([]);
28   - setAfterCar([]);
29 29 setHidden({data: true, price: true});
  30 + history.back();
30 31 };
31 32  
32 33 const onCalcChange = (e:any) => {
... ... @@ -43,61 +44,49 @@ export default function ApplyModal() {
43 44 const _param: any = {
44 45 beginTime: (+moment(param.time[0], "YYYY-MM-DD HH:mm:ss").unix())*1000, // 开始时间
45 46 endTime: (+moment(param.time[1], "YYYY-MM-DD HH:mm:ss").unix())*1000, // 结束时间
46   - brandId: param.brand.value, // 品牌id
47   - brandName: param.brand.label, // 品牌名称
  47 + brandId: param.optionalAuth[0].brandId, // 品牌id
  48 + brandName: param.optionalAuth[0].brandName, // 品牌名称
48 49 applyCarType: param.applyCarType, // 适用车辆类型
49 50 subsidyMode: param.subsidyMode, // 补贴方式
50 51 subsidyValue: +param.subsidyValue, // 补贴比例/ 金额
51 52 applyShops: param.applyShops.map((item:any) => { return {shopId: item.value, shopName: item.label}; }), // 门店列表
52 53 subsidyDataUploadApply: beforeData.map((v:any) => { return {applyUpload: 1, dataType: v.dataType, dataName: v.dataName}; }), // 申请时上传资料
53 54 subsidyType: 3,
  55 + applyCarList: handleCarData(param.optionalAuth),
  56 + containOrder: param.containOrder,
  57 + insuranceRequire: param.insuranceRequire
54 58 };
55   - if (calc === 1 && !param.retailPriceType) {
56   - message.error("请选择补贴价格类型!");
57   - return;
58   - } else if ((afterDay && afterDay != 0) && afterData.length === 0) {
  59 + if ((afterDay && afterDay != 0) && afterData.length === 0) {
59 60 message.error("请勾选交车后N天内上传的资料!");
60 61 return;
61   - } else if (param.applyCarType === 2 && param.applySeriesList.length === 0) { // 部分车系
62   - message.error("请选择适用车辆!");
  62 + } else if (param.insuranceRequire && isNil(insure[0].mustBuyTci)) {
  63 + message.error("请选择是否购买交强险!");
63 64 return;
64   - } else if (param.applyCarType === 3 && showTree.length === 0) { // 部分车型
65   - message.error("请选择适用车辆!");
  65 + } else if (param.insuranceRequire && isNil(insure[0].mustBuyVci)) {
  66 + message.error("请选择商是否购买商业险购!");
  67 + return;
  68 + } else if (param.insuranceRequire && isNil(insure[0].vciBuyAmount)) {
  69 + message.error("请选择输入商业险金额!");
66 70 return;
67   - }
68   - if (calc === 1) { // 补贴价格类型
69   - _param.retailPriceType = param.retailPriceType;
70 71 }
71 72 if (afterDay && afterDay !=0) { // 交车n天后上传资料
72 73 _param.deliveryAfterDays = afterDay;
73 74 _param.subsidyDataUploadNDay = afterData.map((item: any) => { return {applyUpload: 0, dataType: item.dataType, dataName: item.dataName}; });
74   - }
  75 + }
75 76 if (param.applyCarType === 2) {
76 77 _param.applySpecList = param.applySeriesList.map((item:any) => { return {seriesId: item.value, seriesName: item.label}; });
77 78 }
78   - if (param.applyCarType === 3) {
79   - const _showTree = JSON.parse(JSON.stringify(showTree));
80   - _param.applySpecList = _showTree.map((item:any) => {
81   - const _data = item.children.map((v:any) => {
82   - return {
83   - seriesId: item.key,
84   - seriesName: item.title,
85   - specId: v.key,
86   - specName: v.title
87   - };
88   - });
89   - return [..._data];
90   - }).flat();
  79 + if (param.insuranceRequire) {
  80 + _param.mustBuyTci = insure[0].mustBuyTci;
  81 + _param.mustBuyVci = insure[0].mustBuyVci;
  82 + _param.vciBuyAmount = insure[0].vciBuyAmount;
91 83 }
92 84 setLoading(true);
93 85 saveAdditionalApi(_param)
94 86 .then(res => {
95 87 message.success(res.result);
96   - setSubinfo([]);
97   - setAfterCar([]);
98 88 setLoading(false);
99   - setSpecKey([]);
100   - setHidden({data: true, price: true});
  89 + history.back();
101 90 })
102 91 .catch(e => {
103 92 message.error(e.message);
... ... @@ -105,17 +94,121 @@ export default function ApplyModal() {
105 94 });
106 95 };
107 96  
  97 + /**
  98 + * 选择车辆范围回调
  99 + * @param value 车辆树形结构
  100 + */
  101 + function handleChange(value: CarAuthList[] = []) {
  102 + const brandIds: number[] = [];
  103 + const seriesIds: number[] = [];
  104 + const specIds: number[] = [];
  105 + value.forEach(v => {
  106 + if (v.children) {
  107 + v.children.forEach(k => {
  108 + if (k.children) {
  109 + const spec = k.children.map(q => q.specId);
  110 + specIds.push(...spec);
  111 + } else {
  112 + seriesIds.push(k.seriesId);
  113 + }
  114 + });
  115 + } else {
  116 + brandIds.push(v.brandId);
  117 + }
  118 + });
  119 + const parmas = {
  120 + brandIds,
  121 + seriesIds,
  122 + specIds
  123 + };
  124 + setCarSelectData(value || []);
  125 + getShopScope(parmas);
  126 + console.log(value);
  127 + }
  128 +
  129 + /**
  130 + * 获取所选车辆的授权门店范围
  131 + * @param params
  132 + */
  133 + function getShopScope(params: RequestShopParams) {
  134 + setShopLoading(true);
  135 + getShopApi(params)
  136 + .then(res => {
  137 + setShopLoading(false);
  138 + setShopList(res.data || []);
  139 + }).catch(e => {
  140 + setShopLoading(false);
  141 + setShopList([]);
  142 + message.error(e.message);
  143 + });
  144 + }
  145 +
  146 + function handleInsureChange(name: string, value?: number) {
  147 + setInsure([{...insure[0], [name]: value}]);
  148 + }
  149 +
  150 + function resetInsure() {
  151 + setInsure([{mustBuyTci: undefined, mustBuyVci: undefined, vciBuyAmount: undefined, id: 1}]);
  152 + }
  153 +
  154 + /**
  155 + * 将树形车辆结构转换成扁平结构
  156 + * applyCarType为最细化层级的类型
  157 + * @param value
  158 + * @returns
  159 + */
  160 + function handleCarData(value: CarAuthList[]) {
  161 + const result: any = [];
  162 + let applyCarType = 1;
  163 + value.forEach(v => {
  164 + if (v.children) {
  165 + v.children.forEach(k => {
  166 + if (k.children) {
  167 + k.children.forEach(r => {
  168 + const item = {brandId: v.brandId, brandName: v.brandName, seriesId: k.seriesId, seriesName: k.seriesName, specId: r.specId, specName: r.specName};
  169 + result.push(item);
  170 + applyCarType = Math.max(applyCarType, 3);
  171 + });
  172 + } else {
  173 + const item = {brandId: v.brandId, brandName: v.brandName, seriesId: k.seriesId, seriesName: k.seriesName};
  174 + result.push(item);
  175 + applyCarType = Math.max(applyCarType, 2);
  176 + }
  177 + });
  178 + } else {
  179 + const item = { brandId: v.brandId, brandName: v.brandName, applyCarType: v.authType};
  180 + result.push(item);
  181 + applyCarType = Math.max(applyCarType, 1);
  182 + }
  183 + });
  184 + const _result = result.map((v: any) => ({...v, applyCarType}));
  185 + return _result;
  186 + }
  187 +
108 188 return (
109   - <PageHeaderWrapper title="大客户补贴">
  189 + <PageHeaderWrapper title="增购补贴">
110 190 <Card>
111 191 <Row justify="center">
112 192 <Col span={16}>
113 193 <Form
114 194 form={form}
115   - labelCol={{ span: 8 }}
116   - wrapperCol={{ span: 16 }}
117 195 >
118   - {/* <CarSelect specKey={specKey} setSpecKey={setSpecKey} modalVis={visible} setFieldsValue={form.setFieldsValue} showTree={showTree} setShowTree={setShowTree} /> */}
  196 + <Form.Item
  197 + name="optionalAuth"
  198 + label="授权车辆范围"
  199 + rules={[{ required: true, message: "选择车辆" }]}
  200 + tooltip={<span style={{ color: '#ccc', fontSize: 12 }}>*点击图标<PlusSquareOutlined />展开授权详情</span>}
  201 + >
  202 + <CarTableTreeAuth value={carSelectData} onChange={handleChange} brandMultiple={false} />
  203 + </Form.Item>
  204 + <Form.Item
  205 + label="适用门店"
  206 + name="applyShops"
  207 + labelAlign="left"
  208 + rules={[{ required: true, message: "请选择适用门店" }]}
  209 + >
  210 + <Select mode="multiple" allowClear filterOption optionFilterProp="children" labelInValue placeholder="请选择" options={shopList.map(v => ({label: v.shopName, value: v.shopId}))} loading={shopLoading} />
  211 + </Form.Item>
119 212 <Form.Item name="time" label="有效时间" rules={[{ type: 'array' as const, required: true, message: '请选择有效时间!' }]}>
120 213 <DatePicker.RangePicker showNow showTime style={{width: "100%"}} />
121 214 </Form.Item>
... ... @@ -142,8 +235,22 @@ export default function ApplyModal() {
142 235 >
143 236 <Input placeholder="请输入" allowClear suffix={calc === 1 ? "%" : "元"} />
144 237 </Form.Item>
145   - <Form.Item hidden={hidden.price} label="补贴价格类型" name="retailPriceType">
146   - <Select>
  238 + <Form.Item
  239 + hidden={hidden.price}
  240 + label="补贴价格类型"
  241 + name="retailPriceType"
  242 + rules={[
  243 + ({ getFieldValue }) => ({
  244 + validator(_, value) {
  245 + if ((calc === 1 && isNil(value))) {
  246 + return Promise.reject(new Error('请选择补贴价格类型!'));
  247 + }
  248 + return Promise.resolve();
  249 + },
  250 + }),
  251 + ]}
  252 + >
  253 + <Select placeholder="请选择" allowClear>
147 254 <Select.Option value={1}>商家零售价</Select.Option>
148 255 <Select.Option value={2}>厂家标准零售价</Select.Option>
149 256 <Select.Option value={3}>厂家市场指导价</Select.Option>
... ... @@ -152,7 +259,7 @@ export default function ApplyModal() {
152 259 </Form.Item>
153 260  
154 261 <Form.Item labelAlign="left" label="保险要求" name="insuranceRequire" rules={[{required: true, message: "请选择保险要求!"}]}>
155   - <Radio.Group>
  262 + <Radio.Group onChange={resetInsure}>
156 263 <Radio value={false}>无要求</Radio>
157 264 <Radio value>有要求</Radio>
158 265 </Radio.Group>
... ... @@ -165,21 +272,21 @@ export default function ApplyModal() {
165 272 const bool = getFieldValue('insuranceRequire');
166 273 return bool ? (
167 274 <Card>
168   - <Table pagination={false} dataSource={insure}>
  275 + <Table pagination={false} dataSource={insure} rowKey="id">
169 276 <Table.Column
170 277 title="交强险"
171 278 dataIndex="mustBuyTci"
172   - render={(text, record) => <Select placeholder="请选择" options={Requirements} />}
  279 + render={(_text, record) => <Select value={_text} onChange={(e) => handleInsureChange("mustBuyTci", e)} placeholder="请选择" options={Requirements} />}
173 280 />
174 281 <Table.Column
175 282 title="商业险"
176   - dataIndex="mustBuyTci"
177   - render={(text, record) => <Select placeholder="请选择" options={Requirements} />}
  283 + dataIndex="mustBuyVci"
  284 + render={(_text, record) => <Select value={_text} onChange={e => handleInsureChange("mustBuyVci", e)} placeholder="请选择" options={Requirements} />}
178 285 />
179 286 <Table.Column
180 287 title="商业险金额(≥元)"
181   - dataIndex="mustBuyTci"
182   - render={(text, record) => <InputNumber controls={false} min={0} placeholder="请输入" />}
  288 + dataIndex="vciBuyAmount"
  289 + render={(_text, record) => <InputNumber value={_text} onChange={e => handleInsureChange("vciBuyAmount", e)} controls={false} min={0} precision={2} placeholder="请输入金额" />}
183 290 />
184 291 </Table>
185 292 </Card>
... ...
src/pages/order3/CarPurchaseSubsidy/KeyCustomerSubsidy/subpages/AddConfig/index.tsx
... ... @@ -53,7 +53,8 @@ export default function ApplyModal() {
53 53 subsidyDataUploadApply: beforeData.map((v:any) => { return {applyUpload: 1, dataType: v.dataType, dataName: v.dateName}; }), // 申请时上传资料
54 54 subsidyType: 1,
55 55 applyCarList: handleCarData(param.optionalAuth),
56   - containOrder: param.containOrder
  56 + containOrder: param.containOrder,
  57 + insuranceRequire: param.insuranceRequire
57 58 };
58 59 if (!isNil(afterDay) && afterData.length === 0) {
59 60 message.error("请勾选交车后N天内上传的资料!");
... ...