Commit deb451b3f2cd641b421bf54a03732f0753376a74

Authored by 王强
2 parents bf620067 6f86f8a0

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

config/routers/contract.ts
... ... @@ -99,4 +99,8 @@ export default [
99 99 path: '/contract/kt/stampmatter', //盖章事项
100 100 component: './contract/StampMatter',
101 101 },
  102 + {
  103 + path: '/contract/foodWhiteList', // 就餐白名单
  104 + component: './contract/FoodWhiteList',
  105 + },
102 106 ];
... ...
src/components/Condition/BrandToSeries/index.tsx
... ... @@ -5,47 +5,50 @@ import * as API from './api';
5 5  
6 6 interface BrandToSeriesProps extends CascaderProps {
7 7 /** 第一层 品牌列表 */
8   - brandList?: API.Brand[] | API.optionItem[],
9   - labelInValue?: boolean,
10   - value?: any[],
11   - onChange?: (value: any, ...other: any) => any,
  8 + brandList?: API.Brand[] | API.optionItem[];
  9 + labelInValue?: boolean;
  10 + value?: any[];
  11 + onChange?: (value: any, ...other: any) => any;
12 12 /** 是否授权品牌(授权品牌接口是admin,非授权品牌接口是oop) */
13   - authBrand?: boolean
  13 + authBrand?: boolean;
  14 + placeholder?: string;
14 15 }
15 16  
16 17 /**
17 18 * 基于Cascader封装的品牌车系级联选择框
18 19 */
19 20 export default function BrandToSeries(props: BrandToSeriesProps) {
20   - const { value = [], onChange, labelInValue, brandList, placeholder = "请选择品牌/车系", authBrand, ...other } = props;
  21 + const { value = [], onChange, labelInValue, brandList, placeholder = '请选择品牌/车系', authBrand, ...other } = props;
21 22 const [options, setOptions] = useState<any[]>([]);
22 23 const [selected, setSelected] = useState<any[]>([]);
23 24  
24 25 useEffect(() => {
25 26 if (!brandList) {
26 27 const brandApi: any = authBrand ? API.authBrandsApi : API.brandByOopApi;
27   - brandApi().then(res => {
28   - const { data = [] } = res;
29   - const _data = data.map(brand => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false }));
30   - setOptions([..._data]);
31   - }).catch(e => {
32   - message.error(e.message);
33   - });
  28 + brandApi()
  29 + .then((res) => {
  30 + const { data = [] } = res;
  31 + const _data = data.map((brand) => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false }));
  32 + setOptions([..._data]);
  33 + })
  34 + .catch((e) => {
  35 + message.error(e.message);
  36 + });
34 37 } else {
35   - setOptions(brandList.map(brand => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false })))
  38 + setOptions(brandList.map((brand) => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false })));
36 39 }
37   - }, [])
  40 + }, []);
38 41  
39 42 useEffect(() => {
40 43 if (selected.length === 0 && value.length > 0) {
41 44 const valueBrandId = labelInValue ? value[0].id : value[0];
42   - loadData(options.filter(item => item.id === valueBrandId));
  45 + loadData(options.filter((item) => item.id === valueBrandId));
43 46 }
44 47 if (value[1] !== selected[1]) {
45   - const _value = labelInValue ? value.map(item => item.id) : value;
  48 + const _value = labelInValue ? value.map((item) => item.id) : value;
46 49 setSelected(_value);
47 50 }
48   - }, [value[1]])
  51 + }, [value[1]]);
49 52  
50 53 function loadData(selectedOptions?: CascaderOptionType[]) {
51 54 if (selectedOptions && selectedOptions.length > 0) {
... ... @@ -53,23 +56,25 @@ export default function BrandToSeries(props: BrandToSeriesProps) {
53 56 const targetOption = selectedOptions[length - 1];
54 57 targetOption.loading = true;
55 58 if (length === 1) {
56   - API.getSeriesApi(targetOption.id).then(res => {
57   - const { data = [] } = res;
58   - targetOption.loading = false;
59   - targetOption.children = data.map((list, index) => ({
60   - id: list.id,
61   - name: list.name,
62   - }));
63   - setOptions([...options])
64   - }).catch(e => {
65   - message.error(e.message);
66   - });
  59 + API.getSeriesApi(targetOption.id)
  60 + .then((res) => {
  61 + const { data = [] } = res;
  62 + targetOption.loading = false;
  63 + targetOption.children = data.map((list, index) => ({
  64 + id: list.id,
  65 + name: list.name,
  66 + }));
  67 + setOptions([...options]);
  68 + })
  69 + .catch((e) => {
  70 + message.error(e.message);
  71 + });
67 72 }
68 73 }
69 74 }
70 75  
71 76 function _onChange(value: string[], selectedOptions: any[] = []) {
72   - const _value = labelInValue ? selectedOptions.map(item => ({ id: item.id, name: item.name })) : value;
  77 + const _value = labelInValue ? selectedOptions.map((item) => ({ id: item.id, name: item.name })) : value;
73 78 setSelected(value || []);
74 79 onChange && onChange(_value || [], selectedOptions);
75 80 }
... ... @@ -82,9 +87,8 @@ export default function BrandToSeries(props: BrandToSeriesProps) {
82 87 loadData={loadData}
83 88 value={selected.length <= 0 ? undefined : selected}
84 89 onChange={_onChange}
85   - fieldNames={{ value: 'id', label: 'name', }}
  90 + fieldNames={{ value: 'id', label: 'name' }}
86 91 notFoundContent="暂无数据"
87 92 />
88   -
89 93 );
90 94 }
... ...
src/pages/approval/components/ShopSelectByBizType/index.tsx
... ... @@ -107,8 +107,8 @@ function ShopSelectByBizType(
107 107 (children || [])
108 108 .filter((child) => !child.disabled)
109 109 .map((shop) => ({
110   - label: `${shop.shopName}`,
111   - value: shop.shopId,
  110 + label: shop.title,
  111 + value: shop.value,
112 112 })),
113 113 );
114 114 if (index === byBizTypeList.length - 1) {
... ... @@ -135,8 +135,8 @@ function ShopSelectByBizType(
135 135 // 将商家下的门店赋值给allValues
136 136 allValues.current = allValues.current.concat(
137 137 (children || []).map((shop) => ({
138   - label: shop.shopName,
139   - value: shop.shopId,
  138 + label: shop.title,
  139 + value: shop.value,
140 140 })),
141 141 );
142 142 if (index === byDealerList.length - 1) {
... ... @@ -220,6 +220,7 @@ function ShopSelectByBizType(
220 220 }
221 221  
222 222 function processingChildrenData(data: ShopItem, showIds?: number[], hiddenIds?: number[], disabledIds?: number[]): DataItem[] | undefined {
  223 + // todo hiddenIds 需要拼接 bizType 处理
223 224 let _data: ShopItem[] | undefined, _children: DataItem[] | undefined;
224 225  
225 226 if (showIds?.length) {
... ...
src/pages/carinsur/LoanClientConfig/api.ts deleted
1   -import { http } from '@/typing/http';
2   -import request from '@/utils/request';
3   -import { ANGEL_Host, FVM_HOST } from "@/utils/host";
4   -import * as IF from './interface';
5   -
6   -/**
7   - * 查询列表
8   - */
9   -export function getPageListApi(brandId?: IF.QueryParams): http.PromisePageResp<IF.Item> {
10   - return request.get(`${ANGEL_Host}/loancusinsureqconfig/page`, { params: brandId });
11   -}
12   -/**查询配置授权车型 */
13   -export function getSpecListApi(additionalId?: number): http.PromiseResp<IF.Option[]> {
14   - return request.get(`${FVM_HOST}/erp/subsidy/additional/auth/spec/list`, { params: { additionalId } });
15   -}
16   -
17   -/**
18   - * 保存
19   - */
20   -export function saveApi(params: IF.SaveParams): http.PromiseResp<void> {
21   - return request.post(`${ANGEL_Host}/loancusinsureqconfig/save`, params);
22   -}
23   -
24   -// 配置删除
25   -export function deleteApi(id: number): http.PromiseResp<null> {
26   - return request.post(`${ANGEL_Host}/loancusinsureqconfig/delete`, {id});
27   -}
src/pages/carinsur/LoanClientConfig/components/EditModal.tsx deleted
1   -import React, { useState, useEffect } from "react";
2   -import { message, Modal, Select, Form, DatePicker, InputNumber, Spin, Space, Radio } from "antd";
3   -import { saveApi } from "../api";
4   -import moment from "moment";
5   -import { getSeriesApi } from "@/common/api";
6   -import * as IF from "../interface";
7   -
8   -const RangePicker = DatePicker.RangePicker;
9   -interface Props {
10   - visible: boolean;
11   - onCancel: Function;
12   - item: IF.Item;
13   - fetchList: () => any;
14   - brandList: CommonApi.OptionVO[];
15   -}
16   -
17   -const formItemLayout = {
18   - labelCol: {
19   - xs: { span: 24 },
20   - sm: { span: 6 },
21   - md: { span: 6 },
22   - },
23   - wrapperCol: {
24   - xs: { span: 24 },
25   - sm: { span: 15 },
26   - md: { span: 15 },
27   - },
28   -};
29   -
30   -const Item = Form.Item;
31   -
32   -function SaveModal(props: Props) {
33   - const { item, onCancel, fetchList, visible, brandList } = props;
34   - const [loading, setLoading] = useState(false);
35   - const [initLoading, setInitLoading] = useState(false);
36   - const [form] = Form.useForm();
37   - const [seriesList, setSeriesList] = useState<CommonApi.OptionVO[]>([]);
38   - // const [seriesId, setSeriesId] = useState<number>();
39   - // const [specData, setSpecData] = useState<IF.Option[]>([]);
40   -
41   - useEffect(() => {
42   - if (visible && item.id) {
43   - form.setFieldsValue({
44   - startDate: [item.startDate && moment(item.startDate), item.endDate && moment(item.endDate)],
45   - brandId: { value: item.brandId, label: item.brandName, key: item.brandId },
46   - seriesId: item.series?.map((item) => ({ value: item.seriesId, label: item.seriesName, key: item.seriesId })),
47   - subsidyType: item.subsidyType,
48   - needBuyTci: item.needBuyTci,
49   - needBuyVci: item.needBuyVci,
50   - vciReqAmount: item.vciReqAmount && item.vciReqAmount,
51   - });
52   -
53   - item.brandId && getSeries(item.brandId);
54   - // setInitLoading(true);
55   - } else {
56   - // setSpecData([]);
57   - // setSeriesId(undefined);
58   - setSeriesList([]);
59   - }
60   - }, [visible]);
61   -
62   - function getSeries(brandId: number) {
63   - getSeriesApi(brandId)
64   - .then((res) => {
65   - setSeriesList(res.data || []);
66   - })
67   - .catch((err) => {
68   - message.error(err.message);
69   - });
70   - }
71   -
72   - function submit() {
73   - form.validateFields().then((fields) => {
74   - // 车系
75   - const series = fields.seriesId.map((item:any) => ({ seriesId: item.key, seriesName: item.label }));
76   - const params: IF.SaveParams = {
77   - id: item && item.id,
78   - ...fields,
79   - brandId: fields.brandId.value,
80   - brandName: fields.brandId.label,
81   - series,
82   - startDate: fields.startDate[0].valueOf(),
83   - endDate: fields.startDate[1].valueOf(),
84   - };
85   - setLoading(true);
86   - saveApi(params)
87   - .then(() => {
88   - message.success("保存成功");
89   - fetchList();
90   - onCancel();
91   - setLoading(false);
92   - })
93   - .catch((e) => {
94   - setLoading(false);
95   - message.error(e.message);
96   - });
97   - });
98   - }
99   -
100   - return (
101   - <Modal title={item.id ? "编辑" : "新增"} width={700} visible={visible} maskClosable={false} afterClose={() => form.resetFields()} onCancel={() => onCancel()} onOk={() => form.submit()} confirmLoading={loading}>
102   - <Spin spinning={initLoading}>
103   - <Form form={form} {...formItemLayout} onFinish={submit}>
104   - <Item label="有效期" name="startDate" rules={[{ required: true, message: "请选择生效时间" }]}>
105   - <RangePicker disabledDate={(current) => !!current && current < moment().startOf("day")} style={{ width: "100%" }} format="YYYY-MM-DD" />
106   - </Item>
107   - <Item label="适用品牌" name="brandId" rules={[{ required: true, message: "请选择品牌" }]}>
108   - <Select
109   - optionFilterProp="children"
110   - placeholder="请选择品牌"
111   - labelInValue
112   - showSearch
113   - onChange={(v: any) => {
114   - getSeries(v.value);
115   - form.setFieldsValue({ seriesId: undefined, specList: undefined });
116   - }}
117   - >
118   - {brandList.map((i) => (
119   - <Select.Option value={i.id} key={i.id}>
120   - {i.name}
121   - </Select.Option>
122   - ))}
123   - </Select>
124   - </Item>
125   -
126   - <Item label="适用车系" name="seriesId" rules={[{ required: true, message: "请选择车系" }]}>
127   - <Select
128   - mode="multiple"
129   - optionFilterProp="children"
130   - placeholder="请选择车系"
131   - notFoundContent="暂无数据"
132   - labelInValue
133   - showSearch
134   - onChange={(v: any) => {
135   - // setSeriesId(v.value);
136   - // form.setFieldsValue({ specList: undefined });
137   - }}
138   - >
139   - {seriesList.map((i) => (
140   - <Select.Option value={i.id} key={i.id}>
141   - {i.name}
142   - </Select.Option>
143   - ))}
144   - </Select>
145   - </Item>
146   - {/* 交强险 */}
147   - <Item name="needBuyTci" label="要求购买交强险" rules={[{ required: true, message: "请选择是否要求购买交强险" }]}>
148   - <Radio.Group
149   - options={[
150   - { label: "是", value: true },
151   - { label: "否", value: false },
152   - ]}
153   - />
154   - </Item>
155   - {/* 商业险 */}
156   - <Item name="needBuyVci" label="要求购买商业险" rules={[{ required: true, message: "请选择是否要求购买交强险" }]}>
157   - <Radio.Group
158   - options={[
159   - { label: "是", value: true },
160   - { label: "否", value: false },
161   - ]}
162   - />
163   - </Item>
164   -
165   - <Item noStyle shouldUpdate={(prevValues, curValues) => prevValues.needBuyVci !== curValues.needBuyVci}>
166   - {({ getFieldValue }) => {
167   - const type = getFieldValue("needBuyVci");
168   - return type ? (
169   - <Form.Item label="商业险要求金额(>=)">
170   - <Space>
171   - <Item
172   - name="vciReqAmount"
173   - noStyle
174   - rules={[
175   - { required: true, message: "请输入" },
176   - { pattern: /^(?!(0[0-9]{0,}$))[0-9]{1,}[.]{0,}[0-9]{0,}$/, message: "请输入正数" },
177   - ]}
178   - >
179   - <InputNumber style={{ width: "100%" }} placeholder="请输入" precision={2} />
180   - </Item>
181   - <span>元</span>
182   - </Space>
183   - </Form.Item>
184   - ) : null;
185   - }}
186   - </Item>
187   - </Form>
188   - </Spin>
189   - </Modal>
190   - );
191   -}
192   -
193   -export default SaveModal;
src/pages/carinsur/LoanClientConfig/components/SpecModal.tsx deleted
1   -import React, { useState, useEffect } from "react";
2   -import "@ant-design/compatible/assets/index.css";
3   -import { Modal, Button, Table } from "antd";
4   -
5   -import * as IF from "../interface";
6   -
7   -interface Props {
8   - visible: boolean;
9   - onCancel: () => any;
10   - item: IF.Item;
11   -}
12   -
13   -function SpecModal(props: Props) {
14   - const { visible, onCancel, item } = props;
15   - const [tableList, setTableList] = useState<IF.SeriesItem[]>([]);
16   - useEffect(() => {
17   - let list = [];
18   - if (item.series) {
19   - for (let i = 0; i < item.series.length; i++) {
20   - let obj = { ...item.series[i] };
21   - obj.brandName = item.brandName;
22   - list.push(obj);
23   - }
24   - setTableList([...tableList, ...list]);
25   - } else {
26   - setTableList([]);
27   - }
28   - }, [item.id]);
29   - const columns = [
30   - {
31   - title: "品牌",
32   - dataIndex: "brandName",
33   - },
34   - {
35   - title: "适用车系",
36   - dataIndex: "seriesName",
37   - },
38   - ];
39   -
40   - return (
41   - <Modal
42   - title="车辆信息"
43   - style={{ width: 400 }}
44   - maskClosable={false}
45   - visible={visible}
46   - onCancel={() => onCancel()}
47   - footer={
48   - <Button type="default" onClick={() => onCancel()}>
49   - 取消
50   - </Button>
51   - }
52   - >
53   - <Table columns={columns} dataSource={tableList} rowKey={record => record.seriesId} />
54   - </Modal>
55   - );
56   -}
57   -
58   -export default React.memo(SpecModal);
src/pages/carinsur/LoanClientConfig/index.tsx deleted
1   -import React, { useState } from "react";
2   -import { PlusOutlined } from "@ant-design/icons";
3   -import { Button, Card, Divider, message, Popconfirm, Table, Select } from "antd";
4   -import { PageHeaderWrapper } from "@ant-design/pro-layout";
5   -import usePagination from "@/hooks/usePagination";
6   -import SaveModal from "./components/EditModal";
7   -import SpecModal from "./components/SpecModal";
8   -import { deleteApi, getPageListApi } from "./api";
9   -import * as IF from "./interface";
10   -import useInitial from "@/hooks/useInitail";
11   -import { getBrandFilterApi } from "@/common/api";
12   -import moment from "moment";
13   -
14   -const Column = Table.Column;
15   -
16   -export default function StorageList() {
17   - const { list, paginationConfig, loading, setLoading, setParams, innerParams } = usePagination<StorageMaintain.Item>(getPageListApi, {});
18   - const [specVisible, setSpecVisible] = useState(false);
19   - const { data: brandList } = useInitial<CommonApi.OptionVO[], {}>(getBrandFilterApi, [], {});
20   - const [visible, setVisible] = useState(false);
21   - const [item, setItem] = useState<IF.Item>({});
22   -
23   - /**删除 */
24   - function handleDelete(item: IF.Item) {
25   - item.id &&
26   - deleteApi(item.id)
27   - .then((res) => {
28   - setLoading(true);
29   - message.success("操作成功");
30   - })
31   - .catch((e) => {
32   - message.error(e.message);
33   - });
34   - }
35   -
36   - return (
37   - <PageHeaderWrapper title="贷款客户保险要求配置">
38   - <Card>
39   - <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", marginBottom: 20 }}>
40   - <div style={{ display: "flex", flexDirection: "row" }}>
41   - <Select style={{ width: 250 }} placeholder="请选择品牌" value={innerParams.brandId} onChange={(v) => setParams({ ...innerParams, brandId: v }, true)} allowClear>
42   - {brandList.map((item) => (
43   - <Select.Option value={item.id} key={item.id}>
44   - {item.name}
45   - </Select.Option>
46   - ))}
47   - </Select>
48   - </div>
49   - <Button
50   - type="primary"
51   - icon={<PlusOutlined />}
52   - onClick={() => {
53   - setVisible(true);
54   - setItem({});
55   - }}
56   - >
57   - 新增
58   - </Button>
59   - </div>
60   - <Table size="small" loading={loading} pagination={paginationConfig} rowKey={(item) => String(item.id)} dataSource={list} onChange={(_pagination) => setParams({ ..._pagination }, true)}>
61   - <Column title="品牌" width="10%" align="center" dataIndex="brandName" />
62   - <Column
63   - title="适用车系"
64   - width="10%"
65   - align="center"
66   - render={(text, record: IF.Item) => (
67   - <Button
68   - type="link"
69   - onClick={() => {
70   - setSpecVisible(true);
71   - setItem(record);
72   - }}
73   - >
74   - 查看
75   - </Button>
76   - )}
77   - />
78   - <Column
79   - title="有效期"
80   - width="16%"
81   - align="center"
82   - render={(text, record: IF.Item) => <span>{`${(record.startDate && moment(record.startDate).format("YYYY-MM-DD")) || "——"}~${(record.endDate && moment(record.endDate).format("YYYY-MM-DD")) || "——"}`}</span>}
83   - />
84   - <Column title="要求购买交强险" dataIndex="needBuyTci" width="10%" align="center" render={(text) => (text ? <span>是</span> : <span>否</span>)} />
85   - <Column title="要求购买商业险" dataIndex="needBuyVci" width="10%" align="center" render={(text) => (text ? <span>是</span> : <span>否</span>)} />
86   - <Column
87   - title="商业险要求金额(>=)"
88   - dataIndex="vciReqAmount"
89   - width="10%"
90   - align="center"
91   - render={(text: number) => {
92   - return text > 0? <span>{`${text || 0}元`}</span> :"--";
93   - }}
94   - />
95   -
96   - <Column
97   - title="操作"
98   - align="center"
99   - width="15%"
100   - render={(text, record: IF.Item) => (
101   - <>
102   - <Button
103   - type="link"
104   - style={{ padding: 0 }}
105   - onClick={() => {
106   - setVisible(true);
107   - setItem(record);
108   - }}
109   - >
110   - 编辑
111   - </Button>
112   - <Divider type="vertical" />
113   - <Popconfirm placement="top" title="确认删除?" onConfirm={() => handleDelete(record)}>
114   - <Button type="link" style={{ padding: 0 }}>
115   - 删除
116   - </Button>
117   - </Popconfirm>
118   - </>
119   - )}
120   - />
121   - </Table>
122   - </Card>
123   - <SaveModal
124   - visible={visible}
125   - brandList={brandList}
126   - item={item}
127   - fetchList={() => setLoading(true)}
128   - onCancel={() => {
129   - setVisible(false);
130   - setItem({});
131   - }}
132   - />
133   - {/* {specModal} */}
134   -
135   - <SpecModal
136   - visible={specVisible}
137   - item={item}
138   - onCancel={() => {
139   - setSpecVisible(false);
140   - setItem({});
141   - }}
142   - />
143   - </PageHeaderWrapper>
144   - );
145   -}
src/pages/carinsur/LoanClientConfig/interface.d.ts deleted
1   -/**
2   - * 查询参数
3   - */
4   -export interface QueryParams {
5   - brandId?: number,
6   - current?: number,
7   - pageSize?: number,
8   -}
9   -
10   -// export interface QueryParams {
11   -// brandId?: number;
12   -// }
13   -/**
14   - * 列表项
15   - */
16   -export interface Item {
17   - id?: number;
18   - brandId?: number;
19   - brandName?: string;
20   - seriesName?: string;
21   - startDate?: number;
22   - endDate?: number;
23   - subsidyAmount?: number;
24   - subsidyType?: number;
25   - needBuyTci?: boolean; //是否要求买交强险
26   - needBuyVci?: boolean; // 是否要求买商业险
27   - series?: { seriesId: number; seriesName: string; brandName?: string }[];
28   - vciReqAmount?: number;
29   - name?:string;
30   -}
31   -
32   -export interface SaveParams {
33   - id?: number;
34   - brandId?: number;
35   - brandName?: string;
36   - series?: { seriesId: number; seriesName: string }[];
37   - startDate?: number;
38   - endDate?: number;
39   - needBuyTci?: boolean;
40   - needBuyVci?: boolean;
41   - vciReqAmount?: number; //商业险补贴金额
42   - subsidyType?: number; //补贴类型 1增购补贴、2大客户购车补贴、3置换补贴、4最美职业补贴
43   - subsidyAmount?: number; //补贴金额
44   -}
45   -
46   -interface SeriesItem {
47   - seriesId: number;
48   - seriesName: string;
49   - brandName?: string;
50   -}
51   -
52   -interface SimilarItem {
53   - brandId: number,
54   - brandName: string,
55   -}
56   -/**
57   - * 授权参数
58   - */
59   -export interface ShopItem {
60   - shopId?: number, // 所属门店
61   - shopName?: string
62   -}
63   -
64   -export interface SelecSpecParams {
65   - seriesId: number, //车系id
66   - startTime: number, // 开始时间
67   - endTime: number, //结束时间
68   - additionalId?: number, //配置id(编辑使用)
69   -}
70   -/**
71   - * 选项
72   - */
73   -export interface CustomerOption {
74   - customerType: number,
75   - typeName?: string
76   -}
77   -
78   -export interface Option {
79   - specId?: number,
80   - specName?: string
81   -}
82 0 \ No newline at end of file
src/pages/carinsur/LoanClientRequires/components/AddModal/index.tsx
... ... @@ -6,6 +6,7 @@ import BrandSeriesFormItem from &#39;../BrandSeriesFormItem&#39;;
6 6 import ShopSelectorByAll from '../ShopSelectorByAll';
7 7 import LoanTypeFormItem from '../LoanTypeFormItem';
8 8 import type { LabeledValue } from 'antd/lib/select';
  9 +import st from './style.less';
9 10  
10 11 interface Props {
11 12 visible: boolean;
... ... @@ -64,7 +65,7 @@ function AddModal({ visible, row, onCancel, onRefresh }: Props) {
64 65 <Form.Item label="适用品牌车系" name="allBrandSeries" rules={[{ required: true, message: '请选择' }]}>
65 66 <Radio.Group>
66 67 <Radio value={true}>全部品牌全部车系</Radio>
67   - <Radio value={false}>部分品牌部分车系</Radio>
  68 + <Radio value={false}>指定</Radio>
68 69 </Radio.Group>
69 70 </Form.Item>
70 71 <Form.Item
... ... @@ -80,7 +81,7 @@ function AddModal({ visible, row, onCancel, onRefresh }: Props) {
80 81 return null;
81 82 }
82 83 return (
83   - <Form.Item label="部分品牌部分车系" name="brandSeries" rules={[{ required: true, message: '请选择' }]}>
  84 + <Form.Item className={st.hidden} label={<></>} name="brandSeries" rules={[{ required: true, message: '请至少添加一种适应品牌车系' }]}>
84 85 <BrandSeriesFormItem />
85 86 </Form.Item>
86 87 );
... ...
src/pages/carinsur/LoanClientRequires/components/AddModal/style.less 0 → 100644
  1 +.hidden {
  2 + :global {
  3 + .ant-form-item-required {
  4 + visibility: hidden;
  5 + }
  6 + }
  7 +}
0 8 \ No newline at end of file
... ...
src/pages/carinsur/LoanClientRequires/components/BrandSeriesAddModal.tsx
... ... @@ -46,7 +46,7 @@ export default function Index({ brands, visible, value, onCancel, onChange }: Pr
46 46 }
47 47  
48 48 return (
49   - <Modal title={`${value ? '编辑' : '新增'}品牌车系`} style={{ width: 600 }} open={visible} onCancel={closeModal} onOk={form.submit}>
  49 + <Modal title={`${value ? '编辑' : '添加'}适用品牌车系`} style={{ width: 600 }} open={visible} onCancel={closeModal} onOk={form.submit}>
50 50 <Form form={form} labelCol={{ span: '6' }} onFinish={handleSave}>
51 51 <FormItem label="品牌" name="brand" rules={[{ required: true, message: '请选择品牌' }]}>
52 52 <Select
... ...
src/pages/carinsur/LoanClientRequires/components/BrandSeriesFormItem.tsx
... ... @@ -77,7 +77,7 @@ export default function Index({ readOnly = false, value = [], onChange }: Props)
77 77 });
78 78 }}
79 79 >
80   - 新增
  80 + 添加
81 81 </Button>
82 82 </Row>
83 83 )}
... ...
src/pages/carinsur/LoanClientRequires/components/BrandSeriesModal.tsx
... ... @@ -11,7 +11,7 @@ interface Props {
11 11 export default function Index({ brandSeriesModal, onCancel }: Props) {
12 12 const { visible, brandSeries = [] } = brandSeriesModal;
13 13 return (
14   - <Modal title="部分品牌部分车系" open={visible} onCancel={() => onCancel()} footer={null} width={600}>
  14 + <Modal title="适用品牌车系" open={visible} onCancel={() => onCancel()} footer={null} width={600}>
15 15 <BrandSeriesFormItem value={brandSeries} readOnly />
16 16 </Modal>
17 17 );
... ...
src/pages/carinsur/LoanClientRequires/components/Filter/index.tsx
1   -import React from 'react';
  1 +import React, { memo } from 'react';
2 2 import { Row, Select } from 'antd';
3 3 import _ from 'lodash';
4 4 import type { PageParams } from '../../api';
5   -import { getBrandFilterApi, getSaleSeries, getShopApi } from '@/common/api';
  5 +import { getShopApi } from '@/common/api';
6 6 import useInitial from '@/hooks/useInitail';
  7 +import BrandToSeries from '@/components/Condition/BrandToSeries';
7 8  
8 9 interface Props {
9 10 innerParams?: any;
... ... @@ -11,8 +12,6 @@ interface Props {
11 12 }
12 13  
13 14 function Filter({ innerParams, setParams }: Props) {
14   - const { data: brands } = useInitial(getBrandFilterApi, [], {});
15   - const { data: series } = useInitial(getSaleSeries, [], {});
16 15 const { data: shops } = useInitial<CommonApi.OptionVO[], undefined>(getShopApi, [], undefined);
17 16  
18 17 const onChange = _.debounce((newParams) => {
... ... @@ -21,35 +20,16 @@ function Filter({ innerParams, setParams }: Props) {
21 20  
22 21 return (
23 22 <Row style={{ display: 'flex', flex: 1 }}>
24   - <Select
25   - style={{ width: 200 }}
26   - showSearch
27   - allowClear
28   - // optionFilterProp="children"
29   - placeholder="筛选品牌"
30   - options={brands}
31   - fieldNames={{ label: 'name', value: 'id' }}
32   - onChange={(value) => {
33   - onChange({ brandId: value });
34   - }}
35   - />
36   - <Select
37   - style={{ width: 200, marginLeft: 20 }}
38   - showSearch
39   - allowClear
40   - // optionFilterProp="children"
41   - placeholder="筛选车系"
42   - options={series}
43   - fieldNames={{ label: 'name', value: 'id' }}
44   - onChange={(value) => {
45   - onChange({ seriesId: value });
46   - }}
  23 + <BrandToSeries
  24 + //@ts-ignore
  25 + style={{ width: 260 }}
  26 + placeholder="筛选品牌车系"
  27 + onChange={(v) => onChange({ brandId: v[0], seriesId: v && v.length === 2 ? v[1] : undefined })}
47 28 />
48 29 <Select
49   - style={{ width: 200, marginLeft: 20 }}
  30 + style={{ width: 260, marginLeft: 20 }}
50 31 showSearch
51 32 allowClear
52   - // optionFilterProp="children"
53 33 placeholder="筛选门店"
54 34 options={shops}
55 35 fieldNames={{ label: 'name', value: 'id' }}
... ...
src/pages/carinsur/LoanClientRequires/components/LoanTypeFormItem.tsx
... ... @@ -12,14 +12,15 @@ export default function Index({ form, name, label }: Props) {
12 12 return (
13 13 <Form.Item label={label} name={[name, 'type']} rules={[{ required: true, message: '请选择' }]}>
14 14 <Radio.Group>
  15 + <Radio value={LoanTypeEnum.无要求}>无要求</Radio>
15 16 <Radio value={LoanTypeEnum.购买即可}>购买即可</Radio>
16   - <Radio value={LoanTypeEnum.购保要求金额}>
  17 + <Radio value={LoanTypeEnum.保费有要求}>
17 18 <div style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
18   - <span>购保要求金额</span>
  19 + <span>保费有要求</span>
19 20 <Form.Item
20 21 noStyle
21 22 shouldUpdate={(prev, curr) => {
22   - if (prev[name] && curr[name] && prev[name].type !== curr[name].type && curr[name].type !== LoanTypeEnum.购保要求金额) {
  23 + if (prev[name] && curr[name] && prev[name].type !== curr[name].type && curr[name].type !== LoanTypeEnum.保费有要求) {
23 24 form.setFieldValue([name, 'amount'], undefined);
24 25 }
25 26 return prev[name] !== curr[name];
... ... @@ -27,7 +28,7 @@ export default function Index({ form, name, label }: Props) {
27 28 >
28 29 {({ getFieldValue }) => {
29 30 const type = (getFieldValue(name) ?? {}).type;
30   - if (type !== LoanTypeEnum.购保要求金额) return null;
  31 + if (type !== LoanTypeEnum.保费有要求) return null;
31 32 return (
32 33 <Form.Item
33 34 style={{ marginBottom: 0, marginLeft: 10 }}
... ... @@ -35,14 +36,13 @@ export default function Index({ form, name, label }: Props) {
35 36 required
36 37 rules={[{ required: true, message: '请填写金额' }]}
37 38 >
38   - <InputNumber addonBefore="≥" addonAfter="元" style={{ minWidth: 120 }} min={0.01} precision={2} placeholder="请填写金额" />
  39 + <InputNumber addonBefore="≥" addonAfter="元" style={{ width: 200 }} min={0.01} precision={2} placeholder="请填写金额" />
39 40 </Form.Item>
40 41 );
41 42 }}
42 43 </Form.Item>
43 44 </div>
44 45 </Radio>
45   - <Radio value={LoanTypeEnum.无要求}>无要求</Radio>
46 46 </Radio.Group>
47 47 </Form.Item>
48 48 );
... ...
src/pages/carinsur/LoanClientRequires/index.tsx
... ... @@ -53,7 +53,7 @@ export default function Index() {
53 53 };
54 54  
55 55 const renderLoanTypeEle = (value: API.LoanType) => {
56   - return value ? (value.type !== LoanTypeEnum.购保要求金额 ? LoanTypeEnum[value.type] : `保费 ≥ ${value.amount}元`) : '--';
  56 + return value ? (value.type !== LoanTypeEnum.保费有要求 ? LoanTypeEnum[value.type] : `保费 ≥ ${value.amount}元`) : '--';
57 57 };
58 58  
59 59 return (
... ... @@ -100,7 +100,11 @@ export default function Index() {
100 100 )
101 101 }
102 102 />
103   - <Column title="适用门店" dataIndex="useShopIds" render={(value) => <TextWithMore title="适用门店" dataIndex="shopName" list={value} />} />
  103 + <Column
  104 + title="适用门店"
  105 + dataIndex="useShopIds"
  106 + render={(value) => <TextWithMore title="适用门店" dataIndex="shopName" list={value} unit="个门店" />}
  107 + />
104 108 <Column title="新保交强险" dataIndex="newTci" render={renderLoanTypeEle} />
105 109 <Column title="新保商业险" dataIndex="newVci" render={renderLoanTypeEle} />
106 110 <Column title="新保驾意险" dataIndex="newTai" render={renderLoanTypeEle} />
... ...
src/pages/carinsur/entity.ts
... ... @@ -8,6 +8,6 @@ export interface IdNameOption {
8 8 }
9 9 export enum LoanTypeEnum {
10 10 '购买即可' = 1,
11   - '购保要求金额',
  11 + '保费有要求',
12 12 '无要求',
13 13 }
14 14 \ No newline at end of file
... ...
src/pages/contract/ExpressLogisticsArticleSetting/components/UserAddModal.tsx
... ... @@ -40,7 +40,7 @@ export default function UserAddModal({ visible, value, onCancel, onChange }: Pro
40 40 name="userName"
41 41 rules={[
42 42 { required: true, message: '请填写姓名' },
43   - { max: 20, message: '输入长度应该小于20' },
  43 + { max: 32, message: '输入长度应该小于32' },
44 44 { whitespace: true, message: '不能输入空白字符' },
45 45 ]}
46 46 >
... ... @@ -55,7 +55,7 @@ export default function UserAddModal({ visible, value, onCancel, onChange }: Pro
55 55 pattern: /^((\+86)|(86))?(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
56 56 message: '请输入有效的电话号码',
57 57 },
58   - { max: 20, message: '输入长度应该小于20' },
  58 + { max: 16, message: '输入长度应该小于16' },
59 59 { whitespace: true, message: '不能输入空白字符' },
60 60 ]}
61 61 >
... ...
src/pages/contract/FoodWhiteList/api.ts 0 → 100644
  1 +import type { http } from '@/typing/http';
  2 +import request from '@/utils/request';
  3 +import { OA_HOST } from '@/utils/host';
  4 +import type { Pagination } from '@/typing/common';
  5 +
  6 +export interface Item {
  7 + id?: number;
  8 + name: string;
  9 + mobile: string;
  10 + remark: string;
  11 +}
  12 +
  13 +export interface PageParams extends Pagination {
  14 + name?: string;
  15 + mobile?: string;
  16 + remark?: string;
  17 +}
  18 +
  19 +/**
  20 + * 分页查询
  21 + */
  22 +export function getFoodWhitePage(params?: PageParams): http.PromisePageResp<Item> {
  23 + return request.get(`${OA_HOST}/contract/erp/repast/white/page`, { params });
  24 +}
  25 +
  26 +/**
  27 + * 新增/编辑
  28 + */
  29 +export function addFoodWhite(data?: Item): http.PromiseResp<void> {
  30 + return request.post(`${OA_HOST}/contract/erp/repast/white/save`, data);
  31 +}
  32 +
  33 +/**
  34 + * 删除
  35 + */
  36 +export function delFoodWhite(id: number): http.PromisePageResp<void> {
  37 + return request.post(`${OA_HOST}/contract/erp/repast/white/delete`, { id });
  38 +}
... ...
src/pages/contract/FoodWhiteList/components/AddModal/index.tsx 0 → 100644
  1 +import React, { useEffect, memo } from 'react';
  2 +import { Modal, Form, message, Input } from 'antd';
  3 +import * as API from '../../api';
  4 +import { useRequest } from 'umi';
  5 +
  6 +interface Props {
  7 + visible: boolean;
  8 + row?: API.Item;
  9 + onCancel: () => void;
  10 + onRefresh: () => void;
  11 +}
  12 +
  13 +function AddModal({ visible, row, onCancel, onRefresh }: Props) {
  14 + const { id } = row ?? {};
  15 + const [form] = Form.useForm();
  16 +
  17 + const saveHook = useRequest(API.addFoodWhite, {
  18 + manual: true,
  19 + throwOnError: true,
  20 + });
  21 +
  22 + useEffect(() => {
  23 + if (visible) {
  24 + if (row) {
  25 + form.setFieldsValue(row);
  26 + }
  27 + } else {
  28 + form.resetFields();
  29 + }
  30 + }, [visible, row]);
  31 +
  32 + const handleSave = (feildValue: any) => {
  33 + saveHook
  34 + .run(feildValue)
  35 + .then(() => {
  36 + message.success('操作成功');
  37 + onCancel();
  38 + onRefresh();
  39 + })
  40 + .catch((e) => {
  41 + message.error(e.message);
  42 + });
  43 + };
  44 +
  45 + return (
  46 + <Modal title={`${id ? '编辑' : '新增'}`} open={visible} confirmLoading={saveHook.loading} onCancel={onCancel} onOk={form.submit} width={600}>
  47 + <Form form={form} onFinish={handleSave} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }}>
  48 + <Form.Item name="id" hidden />
  49 + <Form.Item
  50 + label="姓名"
  51 + name="name"
  52 + rules={[
  53 + { required: true, message: '请填写姓名' },
  54 + { max: 32, message: '输入长度应该小于32' },
  55 + { whitespace: true, message: '不能输入空白字符' },
  56 + ]}
  57 + >
  58 + <Input placeholder="请填写" />
  59 + </Form.Item>
  60 + <Form.Item
  61 + label="手机号"
  62 + name="mobile"
  63 + rules={[
  64 + { required: true, message: '请填写联系电话' },
  65 + {
  66 + pattern: /^((\+86)|(86))?(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
  67 + message: '请输入有效的电话号码',
  68 + },
  69 + { max: 16, message: '输入长度应该小于16' },
  70 + { whitespace: true, message: '不能输入空白字符' },
  71 + ]}
  72 + >
  73 + <Input placeholder="请填写" />
  74 + </Form.Item>
  75 + <Form.Item label="备注" name="remark" rules={[{ required: true, message: '请填写' }]}>
  76 + <Input.TextArea placeholder="请填写" maxLength={64} />
  77 + </Form.Item>
  78 + </Form>
  79 + </Modal>
  80 + );
  81 +}
  82 +
  83 +export default memo(AddModal);
... ...
src/pages/contract/FoodWhiteList/components/Filter/index.tsx 0 → 100644
  1 +import React from 'react';
  2 +import { Input, Row } from 'antd';
  3 +import _ from 'lodash';
  4 +import type { PageParams } from '../../api';
  5 +
  6 +interface Props {
  7 + innerParams?: any;
  8 + setParams: (params: PageParams, refreshing: boolean) => void;
  9 +}
  10 +
  11 +function Filter({ innerParams, setParams }: Props) {
  12 + const onChange = _.debounce((newParams) => {
  13 + setParams({ ...innerParams, ...newParams }, true);
  14 + }, 600);
  15 +
  16 + return (
  17 + <Row style={{ display: 'flex', flex: 1 }}>
  18 + <Input
  19 + style={{ width: 200 }}
  20 + allowClear
  21 + placeholder="搜索姓名"
  22 + onChange={(e) => {
  23 + onChange({ name: e.target.value });
  24 + }}
  25 + />
  26 + <Input
  27 + style={{ width: 200, marginLeft: 20 }}
  28 + allowClear
  29 + placeholder="搜索手机号"
  30 + onChange={(e) => {
  31 + onChange({ mobile: e.target.value });
  32 + }}
  33 + />
  34 + </Row>
  35 + );
  36 +}
  37 +
  38 +export default Filter;
... ...
src/pages/contract/FoodWhiteList/index.tsx 0 → 100644
  1 +import React, { useState } from 'react';
  2 +import { Button, Card, ConfigProvider, Divider, message, Popconfirm, Row, Table } from 'antd';
  3 +import { PageHeaderWrapper } from '@ant-design/pro-layout';
  4 +import zhCN from 'antd/lib/locale-provider/zh_CN';
  5 +import usePagination from '@/hooks/usePagination';
  6 +import { PlusOutlined } from '@ant-design/icons';
  7 +import AddModal from './components/AddModal';
  8 +import Filter from './components/Filter';
  9 +import * as API from './api';
  10 +import _ from 'lodash';
  11 +
  12 +const { Column } = Table;
  13 +
  14 +export default function Index() {
  15 + // 新增 | 编辑
  16 + const [addModal, setAddModal] = useState<{
  17 + visible: boolean;
  18 + row?: API.Item;
  19 + }>({
  20 + visible: false,
  21 + });
  22 +
  23 + const { list, paginationConfig, loading, innerParams, setParams } = usePagination<API.Item>(API.getFoodWhitePage);
  24 +
  25 + const handleDelete = (row: API.Item) => {
  26 + const { id } = row;
  27 + API.delFoodWhite(id!)
  28 + .then((res) => {
  29 + message.success(res.result);
  30 + setParams({ ...innerParams }, true);
  31 + })
  32 + .catch((e) => {
  33 + message.error(e.message);
  34 + });
  35 + };
  36 +
  37 + const handleEdit = (row: API.Item) => {
  38 + setAddModal({
  39 + visible: true,
  40 + row,
  41 + });
  42 + };
  43 +
  44 + return (
  45 + <PageHeaderWrapper title="就餐白名单">
  46 + <ConfigProvider locale={zhCN}>
  47 + <Card>
  48 + <Row align="middle" justify="space-between" style={{ marginBottom: 20 }}>
  49 + <Filter innerParams={innerParams} setParams={setParams} />
  50 + <Button
  51 + type="primary"
  52 + icon={<PlusOutlined />}
  53 + onClick={() => {
  54 + setAddModal({
  55 + visible: true,
  56 + });
  57 + }}
  58 + >
  59 + 新增
  60 + </Button>
  61 + </Row>
  62 + <Table
  63 + loading={loading}
  64 + dataSource={list}
  65 + pagination={paginationConfig}
  66 + rowKey="id"
  67 + onChange={(_pagination) => setParams({ ..._pagination }, true)}
  68 + >
  69 + <Column title="姓名" dataIndex="name" />
  70 + <Column title="手机号" dataIndex="mobile" />
  71 + <Column title="备注" dataIndex="remark" />
  72 + <Column
  73 + title="操作"
  74 + dataIndex="btns"
  75 + render={(text, row: API.Item) => (
  76 + <span>
  77 + <a
  78 + onClick={(e) => {
  79 + e.preventDefault();
  80 + handleEdit(row);
  81 + }}
  82 + >
  83 + 编辑
  84 + </a>
  85 + <Divider type="vertical" />
  86 + <Popconfirm title="是否删除?" onConfirm={() => handleDelete(row)}>
  87 + <a
  88 + onClick={(e) => {
  89 + e.preventDefault();
  90 + }}
  91 + style={{ color: 'red' }}
  92 + >
  93 + 删除
  94 + </a>
  95 + </Popconfirm>
  96 + </span>
  97 + )}
  98 + />
  99 + </Table>
  100 + </Card>
  101 + <AddModal
  102 + visible={addModal.visible}
  103 + row={addModal.row}
  104 + onCancel={() => {
  105 + setAddModal({ visible: false });
  106 + }}
  107 + onRefresh={() => setParams({ ...innerParams }, true)}
  108 + />
  109 + </ConfigProvider>
  110 + </PageHeaderWrapper>
  111 + );
  112 +}
... ...