Commit 4af032fe01c245a3db47b96ea792eb918beaa5ac
Merge remote-tracking branch 'origin/master' into warrantyCard
Showing
20 changed files
with
900 additions
and
987 deletions
src/pages/cas/CustomerTypeWhiteList/api.ts
1 | -import { http } from '@/typing/http'; | |
2 | -import request from '@/utils/request'; | |
3 | -import { CAS_HOST, HOST } from '@/utils/host'; | |
4 | -import { PageParams } from '@/typing/common'; | |
5 | - | |
6 | -type PromisePageResp<T> = http.PromisePageResp<T>; | |
7 | - | |
8 | -interface ListParam extends PageParams { | |
9 | - current?: number, | |
10 | - pageSize?: number, | |
11 | - keywords?: string, | |
12 | - discountType?: string, //8、员工车辆 9、大客户 | |
13 | - status?: number // 1:待审批 2:生效中 3:审批拒绝 | |
14 | -} | |
15 | - | |
16 | -export interface ListVO { | |
17 | - discountType: number// 7、工作车辆 8、员工车辆 9、大客户 | |
18 | - discountTypeName?: string | |
19 | - whiteList?: List[]// 大客户vin集合 | |
20 | -} | |
21 | - | |
22 | -export interface List { | |
23 | - "vin": string, | |
24 | - "plateNo": string, | |
25 | - "ownerName": string, // 车主名称不能为空 | |
26 | - "staffId": number, // 关联员工id不能为空 | |
27 | - "staffName": string// 关联员工名称不能为空 | |
28 | -} | |
29 | - | |
30 | -export interface ListDetail extends List { | |
31 | - invalidReason: string | |
32 | - status: number | |
33 | - discountType: number | |
34 | -} | |
35 | - | |
36 | -/** 分页查询客户类型白名单列表 */ | |
37 | -export function getListApi(params: ListParam): PromisePageResp<ListDetail> { | |
38 | - return request.get(`${CAS_HOST}/erp/settle/discount/white/list`, { params }); | |
39 | -} | |
40 | - | |
41 | -/** 【白名单申请】分页查询白名单申请列表 */ | |
42 | -export function getApplyListApi(params: ListParam): PromisePageResp<ListVO> { | |
43 | - return request.get(`${CAS_HOST}/erp/settle/discount/white/list/apply/list`, { params }); | |
44 | -} | |
45 | - | |
46 | -/** 申请客户类型白名单 */ | |
47 | -export function saveApi(params?:ListVO) { | |
48 | - return request.post(`${CAS_HOST}/erp/settle/discount/white/list/apply/save`, params); | |
49 | -} | |
50 | - | |
51 | -/** 【白名单】禁用白名单车辆 */ | |
52 | -export function endApi(id?: number): http.PromiseResp<string> { | |
53 | - return request.post(`${CAS_HOST}/erp/settle/discount/white/list/delete`, { id },); | |
54 | -} | |
55 | - | |
56 | -/**【白名单申请】查询客户类型白名单申请详情 */ | |
57 | -export interface DetailParam { | |
58 | - id: number | |
59 | -} | |
60 | -export function detailApi(params: DetailParam): http.PromiseResp<ListVO> { | |
61 | - return request.get(`${CAS_HOST}/erp/settle/discount/white/list/apply/detail`, { params }); | |
62 | -} | |
1 | +import { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { CAS_HOST } from '@/utils/host'; | |
4 | +import { PageParams } from '@/typing/common'; | |
5 | + | |
6 | +type PromisePageResp<T> = http.PromisePageResp<T>; | |
7 | + | |
8 | +interface ListParam extends PageParams { | |
9 | + current?: number; | |
10 | + pageSize?: number; | |
11 | + keywords?: string; | |
12 | + discountType?: string; //8、员工车辆 9、大客户 | |
13 | + status?: number; // 1:待审批 2:生效中 3:审批拒绝 | |
14 | +} | |
15 | + | |
16 | +export interface ListVO { | |
17 | + discountType: number; // 7、工作车辆 8、员工车辆 9、大客户 | |
18 | + discountTypeName?: string; | |
19 | + whiteList?: List[]; // 大客户vin集合 | |
20 | +} | |
21 | + | |
22 | +export interface List { | |
23 | + vin: string; | |
24 | + plateNo: string; | |
25 | + ownerName: string; // 车主名称不能为空 | |
26 | + staffId: number; // 关联员工id不能为空 | |
27 | + staffName: string; // 关联员工名称不能为空 | |
28 | +} | |
29 | + | |
30 | +export interface ListDetail extends List { | |
31 | + invalidReason: string; | |
32 | + status: number; | |
33 | + discountType: number; | |
34 | +} | |
35 | + | |
36 | +/** 分页查询客户类型白名单列表 */ | |
37 | +export function getListApi(params: ListParam): PromisePageResp<ListDetail> { | |
38 | + return request.get(`${CAS_HOST}/erp/settle/discount/white/list`, { params }); | |
39 | +} | |
40 | + | |
41 | +/** 【白名单申请】分页查询白名单申请列表 */ | |
42 | +export function getApplyListApi(params: ListParam): PromisePageResp<ListVO> { | |
43 | + return request.get(`${CAS_HOST}/erp/settle/discount/white/list/apply/list`, { params }); | |
44 | +} | |
45 | + | |
46 | +/** 申请客户类型白名单 */ | |
47 | +export function saveApi(params?: ListVO) { | |
48 | + return request.post(`${CAS_HOST}/erp/settle/discount/white/list/apply/save`, params); | |
49 | +} | |
50 | + | |
51 | +/** 【白名单】禁用白名单车辆 */ | |
52 | +export function endApi(id?: number): http.PromiseResp<string> { | |
53 | + return request.post(`${CAS_HOST}/erp/settle/discount/white/list/delete`, { id }); | |
54 | +} | |
55 | + | |
56 | +/**【白名单申请】查询客户类型白名单申请详情 */ | |
57 | +export interface DetailParam { | |
58 | + id: number; | |
59 | +} | |
60 | + | |
61 | +export function detailApi(params: DetailParam): http.PromiseResp<ListVO> { | |
62 | + return request.get(`${CAS_HOST}/erp/settle/discount/white/list/apply/detail`, { params }); | |
63 | +} | ... | ... |
src/pages/cas/CustomerTypeWhiteList/components/Filter.tsx
1 | -import React, { useState, useEffect } from "react"; | |
2 | -import { Row, Select } from "antd"; | |
3 | -import { LabeledValue } from "antd/lib/select"; | |
4 | - | |
5 | -const Option = Select.Option; | |
6 | - | |
7 | -const userData = [ | |
8 | - // { value: 7, label: "工作车辆" }, | |
9 | - { value: 8, label: "员工车辆" }, | |
10 | - { value: 9, label: "大客户车辆" }, | |
11 | -]; | |
12 | - | |
13 | -const statusData = [ | |
14 | - { value: 2, label: "生效中" }, | |
15 | - { value: 99, label: "失效" }, | |
16 | -]; | |
17 | - | |
18 | -export interface FilterPara { | |
19 | - discountType?: number; | |
20 | - discountTypeName?: string; | |
21 | - [key: string]: any; | |
22 | -} | |
23 | - | |
24 | -interface Props { | |
25 | - onChange: Function; | |
26 | - filterParam: FilterPara; | |
27 | -} | |
28 | - | |
29 | -export default function Filter({ onChange, filterParam}: Props) { | |
30 | - const [type, setType] = useState<LabeledValue>(); | |
31 | - const [status, setStatus] = useState<LabeledValue>(); | |
32 | - | |
33 | - useEffect(() => { | |
34 | - if (filterParam) { | |
35 | - filterParam.discountType && filterParam.discountTypeName | |
36 | - ? setType({ | |
37 | - key: `${filterParam.discountType}`, | |
38 | - value: filterParam.discountType, | |
39 | - label: filterParam.discountTypeName, | |
40 | - }) | |
41 | - : null; | |
42 | - filterParam.discountType && filterParam.discountTypeName | |
43 | - ? setStatus({ | |
44 | - key: `${filterParam.status}`, | |
45 | - value: filterParam.status, | |
46 | - label: filterParam.statusName | |
47 | - }) | |
48 | - : null; | |
49 | - } | |
50 | - }, [filterParam]); | |
51 | - | |
52 | - function onTypeChange(value: LabeledValue) { | |
53 | - const _value = value || ({} as LabeledValue); | |
54 | - const { key, label } = _value; | |
55 | - onChange && | |
56 | - onChange( | |
57 | - { discountType: key || undefined, current: 1, discountTypeName: label }, | |
58 | - true | |
59 | - ); | |
60 | - } | |
61 | - | |
62 | - function onStatusChange(value: LabeledValue) { | |
63 | - const _value = value || ({} as LabeledValue); | |
64 | - const { key, label } = _value; | |
65 | - onChange && | |
66 | - onChange( | |
67 | - { current: 1, status: key, statusName: label }, | |
68 | - true | |
69 | - ); | |
70 | - } | |
71 | - | |
72 | - return ( | |
73 | - <Row style={{ width: "100%", alignItems: "center", marginBottom: 16 }}> | |
74 | - <span>客户类型:</span> | |
75 | - <Select | |
76 | - allowClear={false} | |
77 | - placeholder="请选择" | |
78 | - labelInValue | |
79 | - value={type} | |
80 | - onChange={onTypeChange} | |
81 | - style={{ width: 220, marginLeft: 10 }} | |
82 | - > | |
83 | - {userData.map((r) => ( | |
84 | - <Option key={r.value} value={r.value}> | |
85 | - {r.label || ""} | |
86 | - </Option> | |
87 | - ))} | |
88 | - </Select> | |
89 | - <Select | |
90 | - allowClear={false} | |
91 | - placeholder="请选择状态" | |
92 | - labelInValue | |
93 | - onChange={onStatusChange} | |
94 | - style={{ width: 220, marginLeft: 16 }} | |
95 | - value={status} | |
96 | - > | |
97 | - {statusData.map((r) => ( | |
98 | - <Option key={r.value} value={r.value}> | |
99 | - {r.label || ""} | |
100 | - </Option> | |
101 | - ))} | |
102 | - </Select> | |
103 | - </Row> | |
104 | - ); | |
105 | -} | |
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Row, Select } from 'antd'; | |
3 | +import { LabeledValue } from 'antd/lib/select'; | |
4 | + | |
5 | +const Option = Select.Option; | |
6 | + | |
7 | +const userData = [ | |
8 | + // { value: 7, label: "工作车辆" }, | |
9 | + { value: 8, label: '员工车辆' }, | |
10 | + { value: 9, label: '大客户车辆' }, | |
11 | +]; | |
12 | + | |
13 | +const statusData = [ | |
14 | + { value: 2, label: '生效中' }, | |
15 | + { value: 99, label: '失效' }, | |
16 | +]; | |
17 | + | |
18 | +export interface FilterPara { | |
19 | + discountType?: number; | |
20 | + discountTypeName?: string; | |
21 | + | |
22 | + [key: string]: any; | |
23 | +} | |
24 | + | |
25 | +interface Props { | |
26 | + onChange: Function; | |
27 | + filterParam: FilterPara; | |
28 | +} | |
29 | + | |
30 | +export default function Filter({ onChange, filterParam }: Props) { | |
31 | + const [type, setType] = useState<LabeledValue>(); | |
32 | + const [status, setStatus] = useState<LabeledValue>(); | |
33 | + | |
34 | + useEffect(() => { | |
35 | + if (filterParam) { | |
36 | + filterParam.discountType && filterParam.discountTypeName | |
37 | + ? setType({ | |
38 | + key: `${filterParam.discountType}`, | |
39 | + value: filterParam.discountType, | |
40 | + label: filterParam.discountTypeName, | |
41 | + }) | |
42 | + : null; | |
43 | + filterParam.discountType && filterParam.discountTypeName | |
44 | + ? setStatus({ | |
45 | + key: `${filterParam.status}`, | |
46 | + value: filterParam.status, | |
47 | + label: filterParam.statusName, | |
48 | + }) | |
49 | + : null; | |
50 | + } | |
51 | + }, [filterParam]); | |
52 | + | |
53 | + function onTypeChange(value: LabeledValue) { | |
54 | + const _value = value || ({} as LabeledValue); | |
55 | + const { key, label } = _value; | |
56 | + onChange && onChange({ discountType: key || undefined, current: 1, discountTypeName: label }, true); | |
57 | + } | |
58 | + | |
59 | + function onStatusChange(value: LabeledValue) { | |
60 | + const _value = value || ({} as LabeledValue); | |
61 | + const { key, label } = _value; | |
62 | + onChange && onChange({ current: 1, status: key, statusName: label }, true); | |
63 | + } | |
64 | + | |
65 | + return ( | |
66 | + <Row style={{ width: '100%', alignItems: 'center', marginBottom: 16 }}> | |
67 | + <span>客户类型:</span> | |
68 | + <Select allowClear={false} placeholder="请选择" labelInValue value={type} onChange={onTypeChange} style={{ width: 220, marginLeft: 10 }}> | |
69 | + {userData.map((r) => ( | |
70 | + <Option key={r.value} value={r.value}> | |
71 | + {r.label || ''} | |
72 | + </Option> | |
73 | + ))} | |
74 | + </Select> | |
75 | + <Select | |
76 | + allowClear={false} | |
77 | + placeholder="请选择状态" | |
78 | + labelInValue | |
79 | + onChange={onStatusChange} | |
80 | + style={{ width: 220, marginLeft: 16 }} | |
81 | + value={status} | |
82 | + > | |
83 | + {statusData.map((r) => ( | |
84 | + <Option key={r.value} value={r.value}> | |
85 | + {r.label || ''} | |
86 | + </Option> | |
87 | + ))} | |
88 | + </Select> | |
89 | + </Row> | |
90 | + ); | |
91 | +} | ... | ... |
src/pages/cas/CustomerTypeWhiteList/components/List.tsx
1 | -import { Button, Form, Table, Input } from "antd"; | |
2 | -import * as React from "react"; | |
3 | -import type { ColumnsType } from "antd/lib/table"; | |
4 | -import ListItemModal from "./ListItemModal"; | |
5 | - | |
6 | -const Search = Input.Search; | |
7 | - | |
8 | -export interface ListItem { | |
9 | - vin?: string; | |
10 | - palteNo?: string; | |
11 | - ownerName?: string; | |
12 | - staffId?: number; | |
13 | - staffName?: number | |
14 | -} | |
15 | - | |
16 | -export interface Props { | |
17 | - value?: ListItem[]; | |
18 | - onChange?: (data: ListItem[]) => void; | |
19 | - type?: number | |
20 | - item?: any | |
21 | -} | |
22 | - | |
23 | -const Index = (props: Props) => { | |
24 | - const { value = [], onChange, type, item } = props; | |
25 | - const [form] = Form.useForm(); | |
26 | - const [visible, setVisible] = React.useState(false); | |
27 | - | |
28 | - const columns: ColumnsType<ListItem> = | |
29 | - type === 8 | |
30 | - ? [ | |
31 | - { | |
32 | - title: "车架号", | |
33 | - dataIndex: "vin", | |
34 | - key: "vin", | |
35 | - align: "center", | |
36 | - }, | |
37 | - { | |
38 | - title: "车牌号", | |
39 | - dataIndex: "plateNo", | |
40 | - key: "plateNo", | |
41 | - align: "center", | |
42 | - }, | |
43 | - { | |
44 | - title: "车主名称", | |
45 | - dataIndex: "ownerName", | |
46 | - key: "ownerName", | |
47 | - align: "center", | |
48 | - }, | |
49 | - { | |
50 | - title: "关联员工", | |
51 | - dataIndex: "staffName", | |
52 | - key: "staffName", | |
53 | - align: "center", | |
54 | - }, | |
55 | - { | |
56 | - title: "操作", | |
57 | - render: (text: any, record: ListItem) => ( | |
58 | - <Button | |
59 | - danger | |
60 | - onClick={() => { | |
61 | - const _list = value; | |
62 | - const partList = _list.filter((e) => e.vin != record.vin); | |
63 | - onChange && onChange([...partList]); | |
64 | - }} | |
65 | - disabled={item.id} | |
66 | - > | |
67 | - 删除 | |
68 | - </Button> | |
69 | - ), | |
70 | - }, | |
71 | - ] | |
72 | - : [ | |
73 | - { | |
74 | - title: "车架号", | |
75 | - dataIndex: "vin", | |
76 | - key: "vin", | |
77 | - align: "center", | |
78 | - }, | |
79 | - { | |
80 | - title: "车牌号", | |
81 | - dataIndex: "plateNo", | |
82 | - key: "plateNo", | |
83 | - align: "center", | |
84 | - }, | |
85 | - { | |
86 | - title: "车主名称", | |
87 | - dataIndex: "ownerName", | |
88 | - key: "ownerName", | |
89 | - align: "center", | |
90 | - }, | |
91 | - { | |
92 | - title: "操作", | |
93 | - render: (text: any, record: ListItem) => ( | |
94 | - <Button | |
95 | - danger | |
96 | - onClick={() => { | |
97 | - const _list = value; | |
98 | - const partList = _list.filter((e) => e.vin != record.vin); | |
99 | - onChange && onChange([...partList]); | |
100 | - }} | |
101 | - disabled={item.id} | |
102 | - > | |
103 | - 删除 | |
104 | - </Button> | |
105 | - ), | |
106 | - }, | |
107 | - ]; | |
108 | - | |
109 | - const onSelect = (data: ListItem) => { | |
110 | - value.push(data); | |
111 | - onChange && onChange([...value]); | |
112 | - setVisible(false); | |
113 | - }; | |
114 | - | |
115 | - return ( | |
116 | - <div> | |
117 | - <Button | |
118 | - type="primary" | |
119 | - style={{ marginBottom: 10 }} | |
120 | - onClick={() => setVisible(true)} | |
121 | - disabled={item.id} | |
122 | - > | |
123 | - 新增 | |
124 | - </Button> | |
125 | - {/* <Search | |
126 | - enterButton | |
127 | - allowClear | |
128 | - placeholder="搜索配件编码" | |
129 | - onSearch={onSearch} | |
130 | - style={{ maxWidth: 260, marginLeft: 30 }} | |
131 | - // defaultValue={innerParams.keyword} | |
132 | - /> */} | |
133 | - <Form component={false} form={form}> | |
134 | - <Table bordered columns={columns} dataSource={[...value]} rowKey="id" /> | |
135 | - </Form> | |
136 | - <ListItemModal | |
137 | - onOk={(value) => onSelect(value)} | |
138 | - visible={visible} | |
139 | - onCancel={() => setVisible(false)} | |
140 | - type={type} | |
141 | - /> | |
142 | - </div> | |
143 | - ); | |
144 | -}; | |
145 | - | |
146 | -export default Index; | |
1 | +import { Button, Form, Input, Table } from 'antd'; | |
2 | +import * as React from 'react'; | |
3 | +import type { ColumnsType } from 'antd/lib/table'; | |
4 | +import ListItemModal from './ListItemModal'; | |
5 | + | |
6 | +const Search = Input.Search; | |
7 | + | |
8 | +export interface ListItem { | |
9 | + vin?: string; | |
10 | + palteNo?: string; | |
11 | + ownerName?: string; | |
12 | + staffId?: number; | |
13 | + staffName?: number; | |
14 | +} | |
15 | + | |
16 | +export interface Props { | |
17 | + value?: ListItem[]; | |
18 | + onChange?: (data: ListItem[]) => void; | |
19 | + type?: number; | |
20 | + item?: any; | |
21 | +} | |
22 | + | |
23 | +const Index = (props: Props) => { | |
24 | + const { value = [], onChange, type, item } = props; | |
25 | + const [form] = Form.useForm(); | |
26 | + const [visible, setVisible] = React.useState(false); | |
27 | + | |
28 | + const columns: ColumnsType<ListItem> = | |
29 | + type === 8 | |
30 | + ? [ | |
31 | + { | |
32 | + title: '车架号', | |
33 | + dataIndex: 'vin', | |
34 | + key: 'vin', | |
35 | + align: 'center', | |
36 | + }, | |
37 | + { | |
38 | + title: '车牌号', | |
39 | + dataIndex: 'plateNo', | |
40 | + key: 'plateNo', | |
41 | + align: 'center', | |
42 | + }, | |
43 | + { | |
44 | + title: '车主名称', | |
45 | + dataIndex: 'ownerName', | |
46 | + key: 'ownerName', | |
47 | + align: 'center', | |
48 | + }, | |
49 | + { | |
50 | + title: '关联员工', | |
51 | + dataIndex: 'staffName', | |
52 | + key: 'staffName', | |
53 | + align: 'center', | |
54 | + }, | |
55 | + { | |
56 | + title: '操作', | |
57 | + render: (text: any, record: ListItem) => ( | |
58 | + <Button | |
59 | + danger | |
60 | + onClick={() => { | |
61 | + const _list = value; | |
62 | + const partList = _list.filter((e) => e.vin != record.vin); | |
63 | + onChange && onChange([...partList]); | |
64 | + }} | |
65 | + disabled={item.id} | |
66 | + > | |
67 | + 删除 | |
68 | + </Button> | |
69 | + ), | |
70 | + }, | |
71 | + ] | |
72 | + : [ | |
73 | + { | |
74 | + title: '车架号', | |
75 | + dataIndex: 'vin', | |
76 | + key: 'vin', | |
77 | + align: 'center', | |
78 | + }, | |
79 | + { | |
80 | + title: '车牌号', | |
81 | + dataIndex: 'plateNo', | |
82 | + key: 'plateNo', | |
83 | + align: 'center', | |
84 | + }, | |
85 | + { | |
86 | + title: '车主名称', | |
87 | + dataIndex: 'ownerName', | |
88 | + key: 'ownerName', | |
89 | + align: 'center', | |
90 | + }, | |
91 | + { | |
92 | + title: '操作', | |
93 | + render: (text: any, record: ListItem) => ( | |
94 | + <Button | |
95 | + danger | |
96 | + onClick={() => { | |
97 | + const _list = value; | |
98 | + const partList = _list.filter((e) => e.vin != record.vin); | |
99 | + onChange && onChange([...partList]); | |
100 | + }} | |
101 | + disabled={item.id} | |
102 | + > | |
103 | + 删除 | |
104 | + </Button> | |
105 | + ), | |
106 | + }, | |
107 | + ]; | |
108 | + | |
109 | + const onSelect = (data: ListItem) => { | |
110 | + value.push(data); | |
111 | + onChange && onChange([...value]); | |
112 | + setVisible(false); | |
113 | + }; | |
114 | + | |
115 | + return ( | |
116 | + <div> | |
117 | + <Button type="primary" style={{ marginBottom: 10 }} onClick={() => setVisible(true)} disabled={item.id}> | |
118 | + 新增 | |
119 | + </Button> | |
120 | + {/* <Search | |
121 | + enterButton | |
122 | + allowClear | |
123 | + placeholder="搜索配件编码" | |
124 | + onSearch={onSearch} | |
125 | + style={{ maxWidth: 260, marginLeft: 30 }} | |
126 | + // defaultValue={innerParams.keyword} | |
127 | + /> */} | |
128 | + <Form component={false} form={form}> | |
129 | + <Table bordered columns={columns} dataSource={[...value]} rowKey="id" /> | |
130 | + </Form> | |
131 | + <ListItemModal onOk={(value) => onSelect(value)} visible={visible} onCancel={() => setVisible(false)} type={type} /> | |
132 | + </div> | |
133 | + ); | |
134 | +}; | |
135 | + | |
136 | +export default Index; | ... | ... |
src/pages/cas/CustomerTypeWhiteList/components/ListItemModal.tsx
1 | -import React, { useState, useEffect } from "react"; | |
2 | -import "@ant-design/compatible/assets/index.css"; | |
3 | -import { | |
4 | - Input, | |
5 | - Select, | |
6 | - InputNumber, | |
7 | - Modal, | |
8 | - Form, | |
9 | - Spin, | |
10 | - message, | |
11 | - Tag, | |
12 | -} from "antd"; | |
13 | -import * as API from '@/common/api'; | |
14 | -import usePagination from '@/hooks/usePagination'; | |
15 | -import _ from "lodash"; | |
16 | - | |
17 | -const FormItem = Form.Item; | |
18 | -const { Option } = Select; | |
19 | -const maxFormProps = { | |
20 | - labelCol: { span: 5 }, | |
21 | - wrapperCol: { span: 15 }, | |
22 | -}; | |
23 | - | |
24 | -interface Props { | |
25 | - visible: boolean; | |
26 | - type?: number | |
27 | - onOk: (value: any) => any; | |
28 | - onCancel: () => any | |
29 | -} | |
30 | -export default function Index(props: Props) { | |
31 | - const { onOk, visible, onCancel, type } = props; | |
32 | - const { list, setParams } = usePagination(API.getStaffApi, []); | |
33 | - const [form] = Form.useForm(); | |
34 | - | |
35 | - function save(fieldsValue: any) { | |
36 | - const _value = { | |
37 | - ...fieldsValue, | |
38 | - staffId: fieldsValue.staff ? fieldsValue.staff.value : undefined, | |
39 | - staffName: fieldsValue.staff ? fieldsValue.staff.label : undefined, | |
40 | - }; | |
41 | - onOk(_value); | |
42 | - } | |
43 | - | |
44 | - useEffect(() => { | |
45 | - if (visible) { | |
46 | - form.resetFields() | |
47 | - } | |
48 | - }, [visible]) | |
49 | - | |
50 | - const onSearch = _.debounce((val: string) => { | |
51 | - setParams({ keyWords: val, current: 1 }, true); | |
52 | - }, 500); | |
53 | - | |
54 | - return ( | |
55 | - <Modal | |
56 | - width={600} | |
57 | - visible={visible} | |
58 | - onOk={() => form.submit()} | |
59 | - onCancel={onCancel} | |
60 | - > | |
61 | - <Form | |
62 | - form={form} | |
63 | - onFinish={save} | |
64 | - //onFieldsChange={(changedFields, allFields) => onChangeFile(changedFields, allFields)} | |
65 | - > | |
66 | - <FormItem | |
67 | - label="车架号" | |
68 | - name="vin" | |
69 | - rules={[{ required: true, message: "该选项为必选项" }]} | |
70 | - {...maxFormProps} | |
71 | - > | |
72 | - <Input placeholder="请填写" maxLength={17} /> | |
73 | - </FormItem> | |
74 | - <FormItem | |
75 | - label="车牌号" | |
76 | - name="plateNo" | |
77 | - rules={[{ required: true, message: "该选项为必选项" }]} | |
78 | - {...maxFormProps} | |
79 | - > | |
80 | - <Input placeholder="请填写" maxLength={10} /> | |
81 | - </FormItem> | |
82 | - <FormItem | |
83 | - label="车主" | |
84 | - name="ownerName" | |
85 | - rules={[{ required: true, message: "该选项为必选项" }]} | |
86 | - {...maxFormProps} | |
87 | - > | |
88 | - <Input placeholder="请填写" /> | |
89 | - </FormItem> | |
90 | - {type == 8 && ( | |
91 | - <FormItem | |
92 | - label="关联员工" | |
93 | - name="staff" | |
94 | - rules={[{ required: true, message: "该选项为必选项" }]} | |
95 | - {...maxFormProps} | |
96 | - > | |
97 | - <Select | |
98 | - placeholder="请选择关联员工" | |
99 | - onSearch={onSearch} | |
100 | - labelInValue | |
101 | - showSearch | |
102 | - optionFilterProp="children" | |
103 | - > | |
104 | - {list.map((r) => ( | |
105 | - <Select.Option key={r.id} value={r.id}> | |
106 | - {r.name || ""} | |
107 | - </Select.Option> | |
108 | - ))} | |
109 | - </Select> | |
110 | - </FormItem> | |
111 | - )} | |
112 | - </Form> | |
113 | - </Modal> | |
114 | - ); | |
115 | -} | |
1 | +import React, { useEffect } from 'react'; | |
2 | +import '@ant-design/compatible/assets/index.css'; | |
3 | +import { Form, Input, Modal, Select } from 'antd'; | |
4 | +import * as API from '@/common/api'; | |
5 | +import usePagination from '@/hooks/usePagination'; | |
6 | +import _ from 'lodash'; | |
7 | + | |
8 | +const FormItem = Form.Item; | |
9 | +const { Option } = Select; | |
10 | + | |
11 | +const maxFormProps = { | |
12 | + labelCol: { span: 5 }, | |
13 | + wrapperCol: { span: 15 }, | |
14 | +}; | |
15 | + | |
16 | +interface Props { | |
17 | + visible: boolean; | |
18 | + type?: number; | |
19 | + onOk: (value: any) => any; | |
20 | + onCancel: () => any; | |
21 | +} | |
22 | + | |
23 | +export default function Index(props: Props) { | |
24 | + const { onOk, visible, onCancel, type } = props; | |
25 | + const { list, setParams } = usePagination(API.getStaffApi, []); | |
26 | + const [form] = Form.useForm(); | |
27 | + | |
28 | + function save(fieldsValue: any) { | |
29 | + const _value = { | |
30 | + ...fieldsValue, | |
31 | + staffId: fieldsValue.staff ? fieldsValue.staff.value : undefined, | |
32 | + staffName: fieldsValue.staff ? fieldsValue.staff.label : undefined, | |
33 | + }; | |
34 | + onOk(_value); | |
35 | + } | |
36 | + | |
37 | + useEffect(() => { | |
38 | + if (visible) { | |
39 | + form.resetFields(); | |
40 | + } | |
41 | + }, [visible]); | |
42 | + | |
43 | + const onSearch = _.debounce((val: string) => { | |
44 | + setParams({ keyWords: val, current: 1 }, true); | |
45 | + }, 500); | |
46 | + | |
47 | + return ( | |
48 | + <Modal title="新增员工和车辆" width={600} open={visible} onOk={() => form.submit()} onCancel={onCancel}> | |
49 | + <Form form={form} onFinish={save}> | |
50 | + <FormItem label="车架号" name="vin" rules={[{ required: true, message: '该选项为必选项' }]} {...maxFormProps}> | |
51 | + <Input placeholder="请填写" maxLength={17} /> | |
52 | + </FormItem> | |
53 | + <FormItem label="车牌号" name="plateNo" rules={[{ required: true, message: '该选项为必选项' }]} {...maxFormProps}> | |
54 | + <Input placeholder="请填写" maxLength={10} /> | |
55 | + </FormItem> | |
56 | + <FormItem label="车主" name="ownerName" rules={[{ required: true, message: '该选项为必选项' }]} {...maxFormProps}> | |
57 | + <Input placeholder="请填写" /> | |
58 | + </FormItem> | |
59 | + {type == 8 && ( | |
60 | + <FormItem label="关联员工" name="staff" rules={[{ required: true, message: '该选项为必选项' }]} {...maxFormProps}> | |
61 | + <Select placeholder="请选择关联员工" onSearch={onSearch} labelInValue showSearch optionFilterProp="children"> | |
62 | + {list.map((r) => ( | |
63 | + <Option key={r.id} value={r.id}> | |
64 | + {r.name || ''} | |
65 | + </Option> | |
66 | + ))} | |
67 | + </Select> | |
68 | + </FormItem> | |
69 | + )} | |
70 | + </Form> | |
71 | + </Modal> | |
72 | + ); | |
73 | +} | ... | ... |
src/pages/cas/CustomerTypeWhiteList/components/Modal.tsx
1 | -import React, { useState, useEffect } from "react"; | |
2 | -import "@ant-design/compatible/assets/index.css"; | |
3 | -import { | |
4 | - Input, | |
5 | - Select, | |
6 | - InputNumber, | |
7 | - Modal, | |
8 | - Form, | |
9 | - Spin, | |
10 | - message, | |
11 | - Tag, | |
12 | -} from "antd"; | |
13 | -import * as api from "../api"; | |
14 | -import List from './List'; | |
15 | - | |
16 | -const userData = [ | |
17 | - // { value: 7, label: "工作车辆" }, | |
18 | - { value: 8, label: "员工车辆" }, | |
19 | - { value: 9, label: "大客户车辆" }, | |
20 | -]; | |
21 | - | |
22 | -const maxFormProps = { | |
23 | - labelCol: { span: 5 }, | |
24 | - wrapperCol: { span: 15 }, | |
25 | -}; | |
26 | - | |
27 | -const FormItem = Form.Item; | |
28 | -const { Option } = Select; | |
29 | - | |
30 | -interface Props { | |
31 | - item: any; | |
32 | - visible: boolean; | |
33 | - onCancel: () => any; | |
34 | -} | |
35 | -export default function SaveModal(props: Props) { | |
36 | - const [form] = Form.useForm(); | |
37 | - const { item, visible, onCancel } = props; | |
38 | - const [confirmLoading, setConfirmLoading] = useState<boolean>(false); | |
39 | - const [type, setType] = useState<number>(8); | |
40 | - | |
41 | - useEffect(() => { | |
42 | - console.log('object-item', item); | |
43 | - if (item.id) { | |
44 | - api | |
45 | - .detailApi({ id: item.id }) | |
46 | - .then((res) => { | |
47 | - form.setFieldsValue({ | |
48 | - discountType: res.data && res.data.discountType, | |
49 | - whiteList: res.data && res.data.whiteList, | |
50 | - }); | |
51 | - }) | |
52 | - .catch((e) => message.error(e.message)); | |
53 | - } else { | |
54 | - form.resetFields() | |
55 | - } | |
56 | - }, [visible]) | |
57 | - | |
58 | - function save(fieldsValue: any) { | |
59 | - setConfirmLoading(true); | |
60 | - const datas = { | |
61 | - discountType: fieldsValue.discountType, | |
62 | - whiteList: fieldsValue.whiteList, | |
63 | - }; | |
64 | - api | |
65 | - .saveApi(datas) | |
66 | - .then(() => { | |
67 | - message.success("操作成功!"); | |
68 | - setConfirmLoading(false); | |
69 | - onCancel(); | |
70 | - setType(7) | |
71 | - }) | |
72 | - .catch((e) => { | |
73 | - setConfirmLoading(false); | |
74 | - message.error(e.message); | |
75 | - }); | |
76 | - } | |
77 | - | |
78 | - return ( | |
79 | - <Modal | |
80 | - title="新增" | |
81 | - width={800} | |
82 | - visible={visible} | |
83 | - confirmLoading={confirmLoading} | |
84 | - onOk={() => form.submit()} | |
85 | - onCancel={onCancel} | |
86 | - > | |
87 | - <Form | |
88 | - form={form} | |
89 | - onFinish={save} | |
90 | - //onFieldsChange={(changedFields, allFields) => onChangeFile(changedFields, allFields)} | |
91 | - > | |
92 | - <FormItem | |
93 | - label="客户类型" | |
94 | - name="discountType" | |
95 | - rules={[{ required: true, message: "该选项为必选项" }]} | |
96 | - {...maxFormProps} | |
97 | - > | |
98 | - <Select | |
99 | - placeholder="请选择客户类型" | |
100 | - onSelect={(v: any) => { | |
101 | - setType(v); | |
102 | - form.setFieldsValue({"whiteList": []}); | |
103 | - }} | |
104 | - disabled={item.id} | |
105 | - > | |
106 | - {userData.map((r) => ( | |
107 | - <Select.Option key={r.value} value={r.value}> | |
108 | - {r.label || ""} | |
109 | - </Select.Option> | |
110 | - ))} | |
111 | - </Select> | |
112 | - </FormItem> | |
113 | - <FormItem | |
114 | - label={type == 8 ? "员工车辆白名单" : "大客户车辆白名单"} | |
115 | - name="whiteList" | |
116 | - rules={[ | |
117 | - { | |
118 | - required: true, | |
119 | - min: 1, | |
120 | - message: "白名单不能为空", | |
121 | - type: "array", | |
122 | - }, | |
123 | - ]} | |
124 | - shouldUpdate | |
125 | - {...maxFormProps} | |
126 | - > | |
127 | - <List type={type} item={item} /> | |
128 | - </FormItem> | |
129 | - </Form> | |
130 | - </Modal> | |
131 | - ); | |
132 | -} | |
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import '@ant-design/compatible/assets/index.css'; | |
3 | +import { Form, message, Modal, Select } from 'antd'; | |
4 | +import * as api from '../api'; | |
5 | +import List from './List'; | |
6 | + | |
7 | +const userData = [ | |
8 | + // { value: 7, label: "工作车辆" }, | |
9 | + { value: 8, label: '员工车辆' }, | |
10 | + { value: 9, label: '大客户车辆' }, | |
11 | +]; | |
12 | + | |
13 | +const maxFormProps = { | |
14 | + labelCol: { span: 5 }, | |
15 | + wrapperCol: { span: 15 }, | |
16 | +}; | |
17 | + | |
18 | +const FormItem = Form.Item; | |
19 | +const { Option } = Select; | |
20 | + | |
21 | +interface Props { | |
22 | + item: any; | |
23 | + visible: boolean; | |
24 | + onCancel: () => any; | |
25 | +} | |
26 | + | |
27 | +export default function SaveModal(props: Props) { | |
28 | + const [form] = Form.useForm(); | |
29 | + const { item, visible, onCancel } = props; | |
30 | + const [confirmLoading, setConfirmLoading] = useState<boolean>(false); | |
31 | + const [type, setType] = useState<number>(8); | |
32 | + | |
33 | + useEffect(() => { | |
34 | + if (item.id) { | |
35 | + api | |
36 | + .detailApi({ id: item.id }) | |
37 | + .then((res) => { | |
38 | + form.setFieldsValue({ | |
39 | + discountType: res.data && res.data.discountType, | |
40 | + whiteList: res.data && res.data.whiteList, | |
41 | + }); | |
42 | + }) | |
43 | + .catch((e) => message.error(e.message)); | |
44 | + } else { | |
45 | + form.resetFields(); | |
46 | + } | |
47 | + }, [visible]); | |
48 | + | |
49 | + function save(fieldsValue: any) { | |
50 | + setConfirmLoading(true); | |
51 | + const datas = { | |
52 | + discountType: fieldsValue.discountType, | |
53 | + whiteList: fieldsValue.whiteList, | |
54 | + }; | |
55 | + api | |
56 | + .saveApi(datas) | |
57 | + .then(() => { | |
58 | + message.success('操作成功!'); | |
59 | + setConfirmLoading(false); | |
60 | + onCancel(); | |
61 | + setType(7); | |
62 | + }) | |
63 | + .catch((e) => { | |
64 | + setConfirmLoading(false); | |
65 | + message.error(e.message); | |
66 | + }); | |
67 | + } | |
68 | + | |
69 | + return ( | |
70 | + <Modal title="新增" width={800} visible={visible} confirmLoading={confirmLoading} onOk={() => form.submit()} onCancel={onCancel}> | |
71 | + <Form | |
72 | + form={form} | |
73 | + onFinish={save} | |
74 | + //onFieldsChange={(changedFields, allFields) => onChangeFile(changedFields, allFields)} | |
75 | + > | |
76 | + <FormItem label="客户类型" name="discountType" rules={[{ required: true, message: '该选项为必选项' }]} {...maxFormProps}> | |
77 | + <Select | |
78 | + placeholder="请选择客户类型" | |
79 | + onSelect={(v: any) => { | |
80 | + setType(v); | |
81 | + form.setFieldsValue({ whiteList: [] }); | |
82 | + }} | |
83 | + disabled={item.id} | |
84 | + > | |
85 | + {userData.map((r) => ( | |
86 | + <Select.Option key={r.value} value={r.value}> | |
87 | + {r.label || ''} | |
88 | + </Select.Option> | |
89 | + ))} | |
90 | + </Select> | |
91 | + </FormItem> | |
92 | + <FormItem | |
93 | + label={type == 8 ? '员工车辆白名单' : '大客户车辆白名单'} | |
94 | + name="whiteList" | |
95 | + rules={[ | |
96 | + { | |
97 | + required: true, | |
98 | + min: 1, | |
99 | + message: '白名单不能为空', | |
100 | + type: 'array', | |
101 | + }, | |
102 | + ]} | |
103 | + shouldUpdate | |
104 | + {...maxFormProps} | |
105 | + > | |
106 | + <List type={type} item={item} /> | |
107 | + </FormItem> | |
108 | + </Form> | |
109 | + </Modal> | |
110 | + ); | |
111 | +} | ... | ... |
src/pages/cas/CustomerTypeWhiteList/index.tsx
1 | -import React, { useState } from "react"; | |
2 | -import * as api from "./api"; | |
3 | -import usePagination from "@/hooks/usePagination"; | |
4 | -import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
5 | -import zhCN from "antd/lib/locale-provider/zh_CN"; | |
6 | -import { Card, ConfigProvider, Table, Button, Popconfirm, message } from "antd"; | |
7 | -import Filter from "./components/Filter"; | |
8 | -import CreateModal from "./components/Modal"; | |
9 | -import moment from 'moment'; | |
10 | -import {history} from 'umi'; | |
11 | - | |
12 | -const { Column } = Table; | |
13 | - | |
14 | -enum userData { | |
15 | - // "工作车辆" = 7, | |
16 | - "员工车辆" = 8, | |
17 | - "大客户车辆", | |
18 | -} | |
19 | - | |
20 | -export default function OrderManage() { | |
21 | - const { | |
22 | - list, | |
23 | - errMsg, | |
24 | - loading, | |
25 | - setLoading, | |
26 | - paginationConfig, | |
27 | - innerParams, | |
28 | - setParams, | |
29 | - } = usePagination(api.getListApi, { | |
30 | - discountType: 8, | |
31 | - discountTypeName: "员工车辆", | |
32 | - status: 2, | |
33 | - | |
34 | - }); | |
35 | - | |
36 | - const [visible, setVisible] = useState(false); | |
37 | - const [item, setItem] = useState<any>({}); | |
38 | - | |
39 | - const onEnd = (row: any) => { | |
40 | - row.id && | |
41 | - api | |
42 | - .endApi(row.id) | |
43 | - .then((res) => { | |
44 | - message.success("禁用成功"); | |
45 | - setLoading(true); | |
46 | - }) | |
47 | - .catch((e) => { | |
48 | - message.error(`禁用失败:${e.message}`); | |
49 | - }); | |
50 | - }; | |
51 | - | |
52 | - return ( | |
53 | - <PageHeaderWrapper title="客户类型白名单"> | |
54 | - <Card> | |
55 | - <div style={{ display: "flex", justifyContent: "space-between" }}> | |
56 | - <Filter filterParam={innerParams} onChange={setParams} /> | |
57 | - <div style={{ display: "flex" }}> | |
58 | - <Button | |
59 | - type="primary" | |
60 | - style={{ marginRight: 16 }} | |
61 | - onClick={() => history.push( | |
62 | - `/cas/CustomerType/CustomerTypeWhiteApplyList/${innerParams.discountType}` | |
63 | - )} | |
64 | - > | |
65 | - 申请列表 | |
66 | - </Button> | |
67 | - <Button type="primary" onClick={() => setVisible(true)}> | |
68 | - 发起申请 | |
69 | - </Button> | |
70 | - </div> | |
71 | - </div> | |
72 | - <ConfigProvider locale={zhCN}> | |
73 | - <Table | |
74 | - dataSource={list} | |
75 | - loading={loading} | |
76 | - pagination={paginationConfig} | |
77 | - rowKey="id" | |
78 | - key="id" | |
79 | - > | |
80 | - <Column | |
81 | - title="客户类型" | |
82 | - dataIndex="discountType" | |
83 | - align="center" | |
84 | - width={130} | |
85 | - render={(text) => <span>{userData[text] || "--"}</span>} | |
86 | - /> | |
87 | - <Column | |
88 | - title="车架号" | |
89 | - dataIndex="vin" | |
90 | - width={130} | |
91 | - align="center" | |
92 | - render={(text) => <span>{`${text}` || "--"}</span>} | |
93 | - /> | |
94 | - <Column | |
95 | - title="车牌号" | |
96 | - dataIndex="plateNo" | |
97 | - width={130} | |
98 | - align="center" | |
99 | - render={(text) => <span>{`${text}` || "--"}</span>} | |
100 | - /> | |
101 | - <Column | |
102 | - title="车主" | |
103 | - dataIndex="ownerName" | |
104 | - align="center" | |
105 | - render={(text) => <span>{`${text}` || "--"}</span>} | |
106 | - /> | |
107 | - <Column | |
108 | - title="关联员工" | |
109 | - dataIndex="staffName" | |
110 | - align="center" | |
111 | - render={(text) => <span>{text || "--"}</span>} | |
112 | - /> | |
113 | - <Column | |
114 | - title="备案时间" | |
115 | - dataIndex="recordTime" | |
116 | - align="center" | |
117 | - render={(text) => ( | |
118 | - <span>{moment(text).format("YYYY-MM-DD HH:mm:ss")}</span> | |
119 | - )} | |
120 | - /> | |
121 | - <Column title="状态" dataIndex="statusName" align="center" /> | |
122 | - <Column | |
123 | - title="操作" | |
124 | - align="center" | |
125 | - render={(t, row: any) => ( | |
126 | - <div> | |
127 | - {row.status == 2 ? ( | |
128 | - <Popconfirm title="确认禁用" onConfirm={() => onEnd(row)}> | |
129 | - <Button | |
130 | - danger | |
131 | - type="link" | |
132 | - size="small" | |
133 | - style={{ marginLeft: 10 }} | |
134 | - > | |
135 | - 禁用 | |
136 | - </Button> | |
137 | - </Popconfirm> | |
138 | - ) : ( | |
139 | - "--" | |
140 | - )} | |
141 | - </div> | |
142 | - )} | |
143 | - /> | |
144 | - </Table> | |
145 | - </ConfigProvider> | |
146 | - </Card> | |
147 | - <CreateModal | |
148 | - item={item} | |
149 | - visible={visible} | |
150 | - onCancel={() => { | |
151 | - setVisible(false); | |
152 | - setItem({}); | |
153 | - setLoading(true); | |
154 | - }} | |
155 | - /> | |
156 | - </PageHeaderWrapper> | |
157 | - ); | |
158 | -} | |
1 | +import React, { useState } from 'react'; | |
2 | +import * as api from './api'; | |
3 | +import usePagination from '@/hooks/usePagination'; | |
4 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
5 | +import zhCN from 'antd/lib/locale-provider/zh_CN'; | |
6 | +import { Button, Card, ConfigProvider, message, Popconfirm, Table } from 'antd'; | |
7 | +import Filter from './components/Filter'; | |
8 | +import CreateModal from './components/Modal'; | |
9 | +import moment from 'moment'; | |
10 | +import { history } from 'umi'; | |
11 | + | |
12 | +const { Column } = Table; | |
13 | + | |
14 | +enum userData { | |
15 | + // "工作车辆" = 7, | |
16 | + '员工车辆' = 8, | |
17 | + '大客户车辆', | |
18 | +} | |
19 | + | |
20 | +export default function OrderManage() { | |
21 | + const { list, errMsg, loading, setLoading, paginationConfig, innerParams, setParams } = usePagination(api.getListApi, { | |
22 | + discountType: 8, | |
23 | + discountTypeName: '员工车辆', | |
24 | + status: 2, | |
25 | + }); | |
26 | + | |
27 | + const [visible, setVisible] = useState(false); | |
28 | + const [item, setItem] = useState<any>({}); | |
29 | + | |
30 | + const onEnd = (row: any) => { | |
31 | + row.id && | |
32 | + api | |
33 | + .endApi(row.id) | |
34 | + .then((res) => { | |
35 | + message.success('禁用成功'); | |
36 | + setLoading(true); | |
37 | + }) | |
38 | + .catch((e) => { | |
39 | + message.error(`禁用失败:${e.message}`); | |
40 | + }); | |
41 | + }; | |
42 | + | |
43 | + return ( | |
44 | + <PageHeaderWrapper title="客户类型白名单"> | |
45 | + <Card> | |
46 | + <div style={{ display: 'flex', justifyContent: 'space-between' }}> | |
47 | + <Filter filterParam={innerParams} onChange={setParams} /> | |
48 | + <div style={{ display: 'flex' }}> | |
49 | + <Button | |
50 | + type="primary" | |
51 | + style={{ marginRight: 16 }} | |
52 | + onClick={() => history.push(`/cas/CustomerType/CustomerTypeWhiteApplyList/${innerParams.discountType}`)} | |
53 | + > | |
54 | + 申请列表 | |
55 | + </Button> | |
56 | + <Button type="primary" onClick={() => setVisible(true)}> | |
57 | + 发起申请 | |
58 | + </Button> | |
59 | + </div> | |
60 | + </div> | |
61 | + <ConfigProvider locale={zhCN}> | |
62 | + <Table dataSource={list} loading={loading} pagination={paginationConfig} rowKey="id" key="id"> | |
63 | + <Column title="客户类型" dataIndex="discountType" align="center" width={130} render={(text) => <span>{userData[text] || '--'}</span>} /> | |
64 | + <Column title="车架号" dataIndex="vin" width={130} align="center" render={(text) => <span>{`${text}` || '--'}</span>} /> | |
65 | + <Column title="车牌号" dataIndex="plateNo" width={130} align="center" render={(text) => <span>{`${text}` || '--'}</span>} /> | |
66 | + <Column title="车主" dataIndex="ownerName" align="center" render={(text) => <span>{`${text}` || '--'}</span>} /> | |
67 | + <Column title="关联员工" dataIndex="staffName" align="center" render={(text) => <span>{text || '--'}</span>} /> | |
68 | + <Column | |
69 | + title="备案时间" | |
70 | + dataIndex="recordTime" | |
71 | + align="center" | |
72 | + render={(text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>} | |
73 | + /> | |
74 | + <Column title="状态" dataIndex="statusName" align="center" /> | |
75 | + <Column | |
76 | + title="操作" | |
77 | + align="center" | |
78 | + render={(t, row: any) => ( | |
79 | + <div> | |
80 | + {row.status == 2 ? ( | |
81 | + <Popconfirm title="确认禁用" onConfirm={() => onEnd(row)}> | |
82 | + <Button danger type="link" size="small" style={{ marginLeft: 10 }}> | |
83 | + 禁用 | |
84 | + </Button> | |
85 | + </Popconfirm> | |
86 | + ) : ( | |
87 | + '--' | |
88 | + )} | |
89 | + </div> | |
90 | + )} | |
91 | + /> | |
92 | + </Table> | |
93 | + </ConfigProvider> | |
94 | + </Card> | |
95 | + <CreateModal | |
96 | + item={item} | |
97 | + visible={visible} | |
98 | + onCancel={() => { | |
99 | + setVisible(false); | |
100 | + setItem({}); | |
101 | + setLoading(true); | |
102 | + }} | |
103 | + /> | |
104 | + </PageHeaderWrapper> | |
105 | + ); | |
106 | +} | ... | ... |
src/pages/cas/CustomerTypeWhiteList/subpages/ApplyList/index.tsx
1 | -import React, { useState } from "react"; | |
2 | -import * as api from "../../api"; | |
3 | -import usePagination from "@/hooks/usePagination"; | |
4 | -import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
5 | -import zhCN from "antd/lib/locale-provider/zh_CN"; | |
6 | -import { Card, ConfigProvider, Table, Button, Popconfirm, message } from "antd"; | |
7 | -import moment from "moment"; | |
1 | +import React, { useState } from 'react'; | |
2 | +import * as api from '../../api'; | |
3 | +import usePagination from '@/hooks/usePagination'; | |
4 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
5 | +import zhCN from 'antd/lib/locale-provider/zh_CN'; | |
6 | +import { Button, Card, ConfigProvider, Table } from 'antd'; | |
8 | 7 | import { ConnectProps } from '@/typing/common'; |
9 | 8 | import { history } from 'umi'; |
10 | 9 | import ApproveModal from '@/pages/stock/AdvanceProgress/components/ApproveModal'; |
11 | -import CreateModal from "../../components/Modal"; | |
10 | +import CreateModal from '../../components/Modal'; | |
12 | 11 | |
13 | 12 | const { Column } = Table; |
14 | 13 | |
15 | 14 | enum userData { |
16 | 15 | // "工作车辆" = 7, |
17 | - "员工车辆" = 8, | |
18 | - "大客户车辆", | |
16 | + '员工车辆' = 8, | |
17 | + '大客户车辆', | |
19 | 18 | } |
20 | 19 | |
21 | 20 | interface Props extends ConnectProps {} |
22 | 21 | |
23 | 22 | export default function Index({ match }: Props) { |
24 | 23 | const type = Number(match.params.type); |
25 | - const { | |
26 | - list, | |
27 | - loading, | |
28 | - paginationConfig, | |
29 | - } = usePagination(api.getApplyListApi, { | |
24 | + const { list, loading, paginationConfig } = usePagination(api.getApplyListApi, { | |
30 | 25 | discountType: type, |
31 | 26 | }); |
32 | 27 | |
33 | - const [approve, setApprove] = useState({ visible: false, orderNo: "" }); | |
28 | + const [approve, setApprove] = useState({ visible: false, orderNo: '' }); | |
34 | 29 | |
35 | 30 | const [visible, setVisible] = useState(false); |
36 | 31 | const [item, setItem] = useState<any>({}); |
37 | 32 | |
38 | 33 | return ( |
39 | - <PageHeaderWrapper | |
40 | - title={`${type == 8 ? "员工车辆" : "大客户"}白名单申请列表`} | |
41 | - > | |
34 | + <PageHeaderWrapper title={`${type == 8 ? '员工车辆' : '大客户'}白名单申请列表`}> | |
42 | 35 | <Card> |
43 | - <div style={{ marginBottom: "20px" }}> | |
36 | + <div style={{ marginBottom: '20px' }}> | |
44 | 37 | <Button type="primary" onClick={() => history.goBack()}> |
45 | 38 | 返回 |
46 | 39 | </Button> |
47 | 40 | </div> |
48 | 41 | <ConfigProvider locale={zhCN}> |
49 | - <Table | |
50 | - dataSource={list} | |
51 | - loading={loading} | |
52 | - pagination={paginationConfig} | |
53 | - rowKey="id" | |
54 | - > | |
55 | - <Column | |
56 | - title="客户类型" | |
57 | - dataIndex="discountType" | |
58 | - align="center" | |
59 | - render={(text) => <span>{userData[text] || "--"}</span>} | |
60 | - /> | |
42 | + <Table dataSource={list} loading={loading} pagination={paginationConfig} rowKey="id"> | |
43 | + <Column title="客户类型" dataIndex="discountType" align="center" render={(text) => <span>{userData[text] || '--'}</span>} /> | |
61 | 44 | <Column title="状态" dataIndex="statusName" /> |
62 | 45 | <Column |
63 | 46 | title="审批进度" |
64 | 47 | dataIndex="approvalOrderNo" |
65 | 48 | render={(text) => ( |
66 | - <Button | |
67 | - type="link" | |
68 | - onClick={() => (text | |
69 | - ? setApprove({ visible: true, orderNo: text }) | |
70 | - : undefined)} | |
71 | - > | |
72 | - {" "} | |
73 | - {text ? "查看" : "--"} | |
49 | + <Button type="link" onClick={() => (text ? setApprove({ visible: true, orderNo: text }) : undefined)}> | |
50 | + {' '} | |
51 | + {text ? '查看' : '--'} | |
74 | 52 | </Button> |
75 | 53 | )} |
76 | 54 | /> |
... | ... | @@ -83,9 +61,9 @@ export default function Index({ match }: Props) { |
83 | 61 | type="primary" |
84 | 62 | style={{ marginLeft: 10 }} |
85 | 63 | onClick={() => { |
86 | - setVisible(true); | |
87 | - setItem(record); | |
88 | - }} | |
64 | + setVisible(true); | |
65 | + setItem(record); | |
66 | + }} | |
89 | 67 | > |
90 | 68 | 查看详情 |
91 | 69 | </Button> |
... | ... | @@ -102,11 +80,7 @@ export default function Index({ match }: Props) { |
102 | 80 | setItem({}); |
103 | 81 | }} |
104 | 82 | /> |
105 | - <ApproveModal | |
106 | - visible={approve.visible} | |
107 | - orderNo={approve.orderNo} | |
108 | - onCancel={() => setApprove({ visible: false, orderNo: "" })} | |
109 | - /> | |
83 | + <ApproveModal visible={approve.visible} orderNo={approve.orderNo} onCancel={() => setApprove({ visible: false, orderNo: '' })} /> | |
110 | 84 | </Card> |
111 | 85 | </PageHeaderWrapper> |
112 | 86 | ); | ... | ... |
src/pages/cas/afterSaleConfiguration/jobManagement/api.ts
1 | -import { http } from '@/typing/http'; | |
1 | +import {http} from '@/typing/http'; | |
2 | 2 | import request from '@/utils/request'; |
3 | -import { CAS_HOST, OOP_HOST, PMS_HOST } from '@/utils/host'; | |
3 | +import {CAS_HOST, OOP_HOST, PMS_HOST} from '@/utils/host'; | |
4 | 4 | |
5 | 5 | /** 作业项管理分页数据*/ |
6 | 6 | export function getWorkControl(params: WorkProject.queryList): http.PromisePageResp<WorkProject.showUpdatedetails> { |
... | ... | @@ -11,6 +11,7 @@ export function getWorkControl(params: WorkProject.queryList): http.PromisePageR |
11 | 11 | export function fetchItemListApi(params: Maintain.ItemListParams): http.PromisePageResp<WorkProject.showUpdatedetails> { |
12 | 12 | return request.get(`/cas/erp/common/work/item/page`, { params }); |
13 | 13 | } |
14 | + | |
14 | 15 | /** 保存作业项*/ |
15 | 16 | export function saveWorkProject(params: WorkProject.saveWorkPj): http.PromiseResp<any[]> { |
16 | 17 | return request.post(`${CAS_HOST}/erp/work/item/save`, params); |
... | ... | @@ -64,29 +65,31 @@ export function getBrandApi(params?: PmsPartOilSpace.QueryParams): http.PromiseR |
64 | 65 | } |
65 | 66 | |
66 | 67 | /** |
67 | - * | |
68 | + * | |
68 | 69 | * @param params 根据整车型号,查询车型信息 |
69 | - * @returns | |
70 | + * @returns | |
70 | 71 | */ |
71 | 72 | |
72 | 73 | export interface ListParams { |
73 | - brandId?: number | |
74 | - exhaust?: number | |
75 | - seriesId?: number | |
76 | - inhaleType?: number | |
74 | + brandId?: number; | |
75 | + exhaust?: number; | |
76 | + seriesId?: number; | |
77 | + inhaleType?: number; | |
77 | 78 | } |
78 | -export interface SpecList{ | |
79 | - "id": number | |
80 | - "brandId": number | |
81 | - "seriesId": number | |
82 | - "specCode":string | |
83 | - "specCodeName": string | |
84 | - "exhaust": number | |
85 | - "motorOil": number | |
86 | - "brandName": string | |
87 | - "seriesName": string | |
88 | - "inhaleType": number | |
79 | + | |
80 | +export interface SpecList { | |
81 | + id: number; | |
82 | + brandId: number; | |
83 | + seriesId: number; | |
84 | + specCode: string; | |
85 | + specCodeName: string; | |
86 | + exhaust: number; | |
87 | + motorOil: number; | |
88 | + brandName: string; | |
89 | + seriesName: string; | |
90 | + inhaleType: number; | |
89 | 91 | } |
92 | + | |
90 | 93 | export function getSpecListApi(params: ListParams): http.PromiseResp<SpecList[]> { |
91 | 94 | return request.get(`${OOP_HOST}/select/get/code/list`, { params }); |
92 | -} | |
93 | 95 | \ No newline at end of file |
96 | +} | ... | ... |
src/pages/cas/afterSaleConfiguration/jobManagement/components/CreateModal.tsx
1 | -import React, { useState, useEffect } from 'react'; | |
1 | +import React, { useEffect, useState } from 'react'; | |
2 | 2 | import '@ant-design/compatible/assets/index.css'; |
3 | -import { Input, Select, InputNumber, message, Modal, Form, Spin, Radio } from 'antd'; | |
3 | +import { Form, Input, InputNumber, message, Modal, Radio, Select, Spin } from 'antd'; | |
4 | 4 | import * as api from '../api'; |
5 | 5 | import List from './List'; |
6 | 6 | import { getGroupCasBrandApi, getSeriesApi } from '@/common/api'; |
... | ... | @@ -15,20 +15,18 @@ const maxFormProps = { |
15 | 15 | wrapperCol: { span: 15 }, |
16 | 16 | }; |
17 | 17 | |
18 | -interface Scope { | |
19 | - hidden: boolean; | |
20 | - data: any; | |
21 | -} | |
22 | 18 | interface Props { |
19 | + /** 是否复制 */ | |
20 | + isCopy?: boolean; | |
23 | 21 | item: WorkProject.showUpdatedetails; |
24 | 22 | fetchList: () => any; |
25 | 23 | onCancel: () => any; |
26 | 24 | brandId: any; |
27 | 25 | brandName?: string; |
28 | 26 | } |
29 | -export default function SaveModal(props: Props) { | |
27 | + | |
28 | +export default function SaveModal({ isCopy, onCancel, item, fetchList, brandName }: Props) { | |
30 | 29 | const [form] = Form.useForm(); |
31 | - const { onCancel, item, fetchList, brandName } = props; | |
32 | 30 | const [delay, setDelay] = useState(true); |
33 | 31 | const [brandId, setBrandId] = useState<any>(); |
34 | 32 | |
... | ... | @@ -47,7 +45,7 @@ export default function SaveModal(props: Props) { |
47 | 45 | // hidden: false, |
48 | 46 | // data: {}, |
49 | 47 | // }); |
50 | - const [visible, setVisible] = useState(false); | |
48 | + // const [visible, setVisible] = useState(false); | |
51 | 49 | |
52 | 50 | useEffect(() => { |
53 | 51 | item.id && _fetchDetail(); |
... | ... | @@ -78,23 +76,33 @@ export default function SaveModal(props: Props) { |
78 | 76 | .then((res) => { |
79 | 77 | const { data = {} } = res; |
80 | 78 | // data && onSelectCode(data.specGroupCode); |
81 | - form.setFieldsValue({ | |
82 | - ...data, | |
83 | - series: data && data.seriesId ? '2' : '1', | |
84 | - vehicleCode: data && data.specCodes ? '2' : '1', | |
85 | - }); | |
86 | - const _list = (data && data.specCodes) || []; | |
87 | - setList([..._list]); | |
88 | - setWorkType(data?.workType); | |
89 | - setBrandId(data?.brandId); | |
90 | - setObjVisible({ | |
91 | - seriesVisible: !(data && data.seriesId), | |
92 | - carVisible: !(data && data.specCodes), | |
93 | - }); | |
79 | + if (isCopy) { | |
80 | + form.setFieldsValue({ | |
81 | + ...data, | |
82 | + brandId: '', | |
83 | + brandName: undefined, | |
84 | + series: '1', | |
85 | + vehicleCode: '1', | |
86 | + }); | |
87 | + } else { | |
88 | + form.setFieldsValue({ | |
89 | + ...data, | |
90 | + series: data && data.seriesId ? '2' : '1', | |
91 | + vehicleCode: data && data.specCodes ? '2' : '1', | |
92 | + }); | |
93 | + const _list = (data && data.specCodes) || []; | |
94 | + setList([..._list]); | |
95 | + setWorkType(data?.workType); | |
96 | + setBrandId(data?.brandId); | |
97 | + setObjVisible({ | |
98 | + seriesVisible: !(data && data.seriesId), | |
99 | + carVisible: !(data && data.specCodes), | |
100 | + }); | |
94 | 101 | |
95 | - // get series data | |
96 | - setDelay(false); | |
97 | - setParams(data.brandId!, true); | |
102 | + // get series data | |
103 | + setDelay(false); | |
104 | + setParams(data.brandId!, true); | |
105 | + } | |
98 | 106 | }) |
99 | 107 | .catch((e) => { |
100 | 108 | message.error(e.message); |
... | ... | @@ -108,7 +116,7 @@ export default function SaveModal(props: Props) { |
108 | 116 | setConfirmLoading(true); |
109 | 117 | const datas = { |
110 | 118 | ...fieldsValue, |
111 | - id: item.id || undefined, | |
119 | + id: isCopy ? undefined : item.id || undefined, | |
112 | 120 | brandId, |
113 | 121 | stdType: 2, |
114 | 122 | seriesId: fieldsValue.series === '2' ? fieldsValue.seriesId : undefined, |
... | ... | @@ -135,8 +143,8 @@ export default function SaveModal(props: Props) { |
135 | 143 | return ( |
136 | 144 | <Modal |
137 | 145 | title={!item.id ? '新增' : '编辑'} |
138 | - width={600} | |
139 | - visible | |
146 | + width={820} | |
147 | + open | |
140 | 148 | confirmLoading={confirmLoading} |
141 | 149 | onOk={() => form.submit()} |
142 | 150 | onCancel={() => { |
... | ... | @@ -203,13 +211,14 @@ export default function SaveModal(props: Props) { |
203 | 211 | <Input |
204 | 212 | placeholder="请输入作业代码" |
205 | 213 | allowClear |
206 | - disabled={!(workType == workTypeEnum['机修'] || workType == workTypeEnum['电器'] || workType == workTypeEnum['厂家喷漆'])} | |
214 | + disabled={ | |
215 | + isCopy ? false : !(workType == workTypeEnum['机修'] || workType == workTypeEnum['电器'] || workType == workTypeEnum['厂家喷漆']) | |
216 | + } | |
207 | 217 | /> |
208 | 218 | </FormItem> |
209 | 219 | ) : null} |
210 | - <FormItem label="品牌" name="brandName"> | |
211 | - {/* <Input style={{ width: "60%" }} disabled /> */} | |
212 | - <Select placeholder="请选择" disabled={!!item.id} onChange={selectSpec} allowClear> | |
220 | + <FormItem label="品牌" name="brandName" rules={[{ required: true, message: '该选择品牌' }]}> | |
221 | + <Select placeholder="请选择" disabled={isCopy ? false : !!item.id} onChange={selectSpec} allowClear> | |
213 | 222 | {brand.map((e) => ( |
214 | 223 | <Option value={e.id} key={e.id}> |
215 | 224 | {e.name} |
... | ... | @@ -217,15 +226,16 @@ export default function SaveModal(props: Props) { |
217 | 226 | ))} |
218 | 227 | </Select> |
219 | 228 | </FormItem> |
220 | - <FormItem label="车系" name="series"> | |
229 | + <FormItem label="车系" name="series" hidden={!brandId}> | |
221 | 230 | <Radio.Group |
222 | 231 | onChange={(e) => { |
232 | + setList([]); // 车系改变后,清空车型数据 | |
223 | 233 | if (e.target.value === '2') { |
224 | - setList([]); | |
225 | 234 | setObjVisible({ ...objVisible, seriesVisible: false }); |
226 | 235 | } else { |
227 | 236 | form.setFieldsValue({ |
228 | 237 | seriesId: undefined, |
238 | + vehicleCode: '1', // 选择全部车系,默认为全部车型 | |
229 | 239 | }); |
230 | 240 | setObjVisible({ ...objVisible, seriesVisible: true }); |
231 | 241 | } |
... | ... | @@ -235,18 +245,18 @@ export default function SaveModal(props: Props) { |
235 | 245 | <Radio value="2">单一车系</Radio> |
236 | 246 | </Radio.Group> |
237 | 247 | </FormItem> |
238 | - <FormItem | |
239 | - name="seriesId" | |
240 | - // rules={[{ required: true }]} | |
241 | - hidden={objVisible.seriesVisible} | |
242 | - style={{ marginLeft: 120 }} | |
243 | - > | |
248 | + <FormItem name="seriesId" hidden={objVisible.seriesVisible} wrapperCol={{ offset: 5, span: 15 }}> | |
244 | 249 | <Select |
245 | 250 | placeholder="请选择车系" |
246 | 251 | style={{ width: '60%' }} |
247 | 252 | showSearch |
248 | 253 | filterOption={filterDealer} |
249 | - // onSelect={(e: any) => onSelectCode(e)} | |
254 | + onSelect={() => { | |
255 | + // 车系改变后,清空车型数据 | |
256 | + setList([]); | |
257 | + form.setFieldsValue({ vehicleCode: '1' }); | |
258 | + setObjVisible({ ...objVisible, carVisible: true }); | |
259 | + }} | |
250 | 260 | > |
251 | 261 | {specs.map((item: any, index: number) => ( |
252 | 262 | <Option value={item.id} key={item.id}> |
... | ... | @@ -255,7 +265,7 @@ export default function SaveModal(props: Props) { |
255 | 265 | ))} |
256 | 266 | </Select> |
257 | 267 | </FormItem> |
258 | - <FormItem label="整车型号" name="vehicleCode"> | |
268 | + <FormItem label="整车型号" name="vehicleCode" hidden={!brandId}> | |
259 | 269 | <Radio.Group |
260 | 270 | onChange={(e) => { |
261 | 271 | if (e.target.value === '2') { |
... | ... | @@ -269,8 +279,9 @@ export default function SaveModal(props: Props) { |
269 | 279 | <Radio value="2"> 部分整车型号</Radio> |
270 | 280 | </Radio.Group> |
271 | 281 | </FormItem> |
272 | - <FormItem name="specCodes" hidden={objVisible.carVisible} style={{ marginLeft: 120 }}> | |
282 | + <FormItem name="specCodes" hidden={objVisible.carVisible} wrapperCol={{ offset: 5, span: 15 }}> | |
273 | 283 | <List |
284 | + key={form.getFieldValue('seriesId')} | |
274 | 285 | list={list} |
275 | 286 | setList={setList} |
276 | 287 | current={current} |
... | ... | @@ -352,10 +363,10 @@ export default function SaveModal(props: Props) { |
352 | 363 | <FormItem |
353 | 364 | label="作业描述" |
354 | 365 | name="itemDesc" |
355 | - extra="请填写用于推荐项展示,更吸引客户,并让客户了解做什么" | |
366 | + extra="用于推荐项展示,更吸引客户,并让客户了解做什么" | |
356 | 367 | rules={[{ required: false, max: 50, message: '输入内容不超过50个字' }]} |
357 | 368 | > |
358 | - <TextArea rows={3} placeholder="请输入" /> | |
369 | + <TextArea rows={3} placeholder="请输入作业描述" /> | |
359 | 370 | </FormItem> |
360 | 371 | </Form> |
361 | 372 | </Spin> | ... | ... |
src/pages/cas/afterSaleConfiguration/jobManagement/components/List.tsx
1 | -import React, { useEffect, useState } from 'react'; | |
2 | -import { Button, Table, Tabs } from 'antd'; | |
3 | -import Modal from './Modal'; | |
1 | +import React, { useState } from 'react'; | |
2 | +import { Button, Table } from 'antd'; | |
3 | + | |
4 | +import SpecSelector from '@/pages/cas/common/SpecSelector'; | |
4 | 5 | |
5 | 6 | const { Column } = Table; |
6 | -const { TabPane } = Tabs; | |
7 | 7 | |
8 | 8 | export interface Props { |
9 | 9 | setList?: (data: any) => any; |
... | ... | @@ -16,43 +16,50 @@ function List(props: Props) { |
16 | 16 | const { list = [], setList, current, onClick } = props; |
17 | 17 | const [visible, setVisible] = useState<boolean>(false); |
18 | 18 | |
19 | - function onDelete(record: any) { | |
20 | - console.log(record); | |
21 | - const _data = list.filter((e) => e.carId !== record.carId); | |
22 | - setList && setList([..._data]); | |
19 | + function handleDelete(index: number) { | |
20 | + list.splice(index, 1); | |
21 | + setList && setList([...list]); | |
23 | 22 | } |
24 | 23 | |
25 | - const _onOk = (data: any) => { | |
26 | - list.push(data); | |
27 | - setList && setList([...list]); | |
24 | + const handleConfirm = (data: any[]) => { | |
25 | + setList && setList([...data]); | |
28 | 26 | setVisible(false); |
29 | 27 | }; |
30 | 28 | |
31 | 29 | return ( |
32 | - <div style={{ width: 345 }}> | |
33 | - <Button | |
34 | - type="primary" | |
35 | - onClick={() => { | |
36 | - setVisible(true); | |
37 | - onClick && onClick(); | |
38 | - }} | |
39 | - > | |
40 | - 新增 | |
41 | - </Button> | |
42 | - <Table dataSource={[...list]} bordered pagination={false} rowKey={(row, index) => `index_${index}`}> | |
30 | + <div style={{ marginTop: -24 }}> | |
31 | + <div style={{ display: 'flex', justifyContent: 'flex-end' }}> | |
32 | + <Button | |
33 | + type="primary" | |
34 | + onClick={() => { | |
35 | + setVisible(true); | |
36 | + onClick && onClick(); | |
37 | + }} | |
38 | + > | |
39 | + 新增 | |
40 | + </Button> | |
41 | + </div> | |
42 | + <Table style={{ marginTop: 10 }} dataSource={[...list]} bordered pagination={false} rowKey="specCode" scroll={{ y: 400 }}> | |
43 | 43 | <Column title="整车型号名称" dataIndex="specCodeName" /> |
44 | - <Column title="整车型号" dataIndex="specCode" /> | |
44 | + <Column title="整车型号" dataIndex="specCode" width="35%" /> | |
45 | 45 | <Column |
46 | 46 | title="操作" |
47 | - width="10%" | |
48 | - render={(text, record: Maintain.OilGroup) => ( | |
49 | - <Button onClick={() => onDelete(record)} type="link" danger size="small"> | |
47 | + width="80px" | |
48 | + align="center" | |
49 | + render={(text, record: Maintain.OilGroup, index: number) => ( | |
50 | + <Button type="link" danger size="small" onClick={() => handleDelete(index)}> | |
50 | 51 | 删除 |
51 | 52 | </Button> |
52 | 53 | )} |
53 | 54 | /> |
54 | 55 | </Table> |
55 | - <Modal visible={visible} onCancel={() => setVisible(false)} onOk={_onOk} current={current} /> | |
56 | + <SpecSelector | |
57 | + visible={visible} | |
58 | + seriesId={current?.seriesId} | |
59 | + selectedItems={list} | |
60 | + onCancel={() => setVisible(false)} | |
61 | + onConfirm={handleConfirm} | |
62 | + /> | |
56 | 63 | </div> |
57 | 64 | ); |
58 | 65 | } | ... | ... |
src/pages/cas/afterSaleConfiguration/jobManagement/components/Modal.tsx deleted
1 | -import React, { useEffect, useState } from "react"; | |
2 | -import { Modal, Form, Select} from "antd"; | |
3 | -import _ from "lodash"; | |
4 | -import useInitail from "@/hooks/useInitail"; | |
5 | -import * as API from '../api'; | |
6 | - | |
7 | -interface Props { | |
8 | - visible: boolean; | |
9 | - onCancel: () => void; | |
10 | - onOk?: (data: any) => any; | |
11 | - current?: any | |
12 | -} | |
13 | - | |
14 | -function Index(props: Props) { | |
15 | - const { visible, onCancel, onOk, current} = props; | |
16 | - const [form] = Form.useForm(); | |
17 | - const [delay, setDelay] = useState(true); | |
18 | - const { data, setParams } = useInitail(API.getSpecListApi, [], {}, delay); | |
19 | - | |
20 | - useEffect(() => { | |
21 | - if (visible) { | |
22 | - setDelay(false); | |
23 | - setParams({ ...current, seriesId: current.seriesId }, true); | |
24 | - } | |
25 | - }, [visible]); | |
26 | - | |
27 | - function _onOk(value: any) { | |
28 | - const data = { | |
29 | - specCode: value.car.value, | |
30 | - specCodeName: value.car.label, | |
31 | - }; | |
32 | - onOk && onOk(data); | |
33 | - } | |
34 | - | |
35 | - return ( | |
36 | - <Modal | |
37 | - width={650} | |
38 | - forceRender | |
39 | - title="新增整车型号" | |
40 | - visible={visible} | |
41 | - onOk={form.submit} | |
42 | - onCancel={onCancel} | |
43 | - > | |
44 | - <Form form={form} onFinish={_onOk} component={false}> | |
45 | - <Form.Item label="整车型号" name="car" rules={[{ required: true }]}> | |
46 | - <Select labelInValue placeholder="请选择整车型号"> | |
47 | - {data.map((i) => ( | |
48 | - <Select.Option value={i.specCode || 0} key={i.specCode || 0}> | |
49 | - {i.specCode} {i.specCodeName || "--"} | |
50 | - </Select.Option> | |
51 | - ))} | |
52 | - </Select> | |
53 | - </Form.Item> | |
54 | - </Form> | |
55 | - </Modal> | |
56 | - ); | |
57 | -} | |
58 | - | |
59 | -export default Index; |
src/pages/cas/afterSaleConfiguration/jobManagement/components/SpecModal.tsx
1 | -import React, { useEffect, useState } from "react"; | |
2 | -import { Modal, Table } from "antd"; | |
1 | +import React from 'react'; | |
2 | +import { Button, Modal, Table } from 'antd'; | |
3 | 3 | |
4 | 4 | const Column = Table.Column; |
5 | + | |
5 | 6 | interface Props { |
6 | 7 | list: any[]; |
7 | 8 | visible: boolean; |
... | ... | @@ -11,20 +12,20 @@ interface Props { |
11 | 12 | export default function SpecModal({ list, visible, setVisible }: Props) { |
12 | 13 | return ( |
13 | 14 | <Modal |
14 | - title="整车型号代码" | |
15 | - visible={visible} | |
16 | - onCancel={() => setVisible(false)} | |
17 | - onOk={() => setVisible(false)} | |
18 | - width="50%" | |
15 | + title="查看整车型号" | |
16 | + open={visible} | |
17 | + width={600} | |
19 | 18 | maskClosable={false} |
19 | + onCancel={() => setVisible(false)} | |
20 | + footer={ | |
21 | + <Button type="primary" onClick={() => setVisible(false)}> | |
22 | + 关闭 | |
23 | + </Button> | |
24 | + } | |
20 | 25 | > |
21 | - <Table | |
22 | - dataSource={list} | |
23 | - rowKey="id" | |
24 | - pagination={false} | |
25 | - scroll={{ y: 500 }} | |
26 | - > | |
27 | - <Column title="整车型号代码" dataIndex="specCode" align="center" /> | |
26 | + <Table style={{ marginTop: 0 }} dataSource={list} rowKey="specCode" pagination={false} scroll={{ y: 500 }}> | |
27 | + <Column title="整车型号名称" dataIndex="specCodeName" /> | |
28 | + <Column title="整车型号" dataIndex="specCode" /> | |
28 | 29 | </Table> |
29 | 30 | </Modal> |
30 | 31 | ); | ... | ... |
src/pages/cas/afterSaleConfiguration/jobManagement/index.less deleted
1 | -@import '~antd/lib/style/themes/default.less'; | |
2 | - | |
3 | -.page { | |
4 | - position: relative; | |
5 | - .header { | |
6 | - margin-bottom: 10px; | |
7 | - display: flex; | |
8 | - justify-content: space-between; | |
9 | - .add { | |
10 | - position: absolute; | |
11 | - right: 28px; | |
12 | - // top: 24px; | |
13 | - // z-index: 10; | |
14 | - } | |
15 | - | |
16 | - } | |
17 | -} | |
18 | - | |
19 | - | |
20 | -.ant-table-wrapper { | |
21 | - margin-top: 32px; | |
22 | -} | |
23 | -.titlecontant{ | |
24 | - margin-top: 30px; | |
25 | - margin-bottom: 40px; | |
26 | -} |
src/pages/cas/afterSaleConfiguration/jobManagement/index.tsx
... | ... | @@ -11,8 +11,6 @@ import SpecModal from './components/SpecModal'; |
11 | 11 | import UploadModal from './components/UploadModal'; |
12 | 12 | |
13 | 13 | const { Column } = Table; |
14 | -const { Option } = Select; | |
15 | -const indexS = require('@/pages/cas/afterSaleConfiguration/jobManagement/index.less'); | |
16 | 14 | |
17 | 15 | interface DataType { |
18 | 16 | key: React.Key; |
... | ... | @@ -28,6 +26,7 @@ const sortTypes = { |
28 | 26 | |
29 | 27 | export default function FactoryList() { |
30 | 28 | const [visibleEdit, setVisibleEdit] = useState<boolean>(false); |
29 | + const [isCopy, setIsCopy] = useState(false); | |
31 | 30 | const [visibleUpload, setVisibleUpload] = useState<boolean>(false); |
32 | 31 | const [item, setItem] = useState<WorkProject.showUpdatedetails>({}); |
33 | 32 | const [brand, setBrand] = useState<CommonApi.OptionVO[]>([]); |
... | ... | @@ -96,8 +95,8 @@ export default function FactoryList() { |
96 | 95 | |
97 | 96 | return ( |
98 | 97 | <PageHeaderWrapper title="作业项标准管理"> |
99 | - <Card className={indexS.page}> | |
100 | - <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 20 }}> | |
98 | + <Card> | |
99 | + <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}> | |
101 | 100 | <Filter onFilter={(value) => setParams({ ...value, current: 1 }, true)} brandList={brand} /> |
102 | 101 | <Button type="primary" onClick={handleMenuClick}> |
103 | 102 | 新增 |
... | ... | @@ -108,8 +107,7 @@ export default function FactoryList() { |
108 | 107 | pagination={paginationConfig} |
109 | 108 | dataSource={list} |
110 | 109 | loading={loading} |
111 | - rowKey={(record) => String(record.id)} | |
112 | - style={{ marginTop: 20 }} | |
110 | + rowKey="id" | |
113 | 111 | onChange={handleTableChange} |
114 | 112 | > |
115 | 113 | <Column title="作业项代码" dataIndex="itemCode" align="center" /> |
... | ... | @@ -119,21 +117,18 @@ export default function FactoryList() { |
119 | 117 | <Column title="车系" dataIndex="seriesName" align="center" render={(text) => <span>{text || '全部车系'}</span>} /> |
120 | 118 | <Column |
121 | 119 | title="整车型号" |
122 | - dataIndex="specCodes" | |
120 | + dataIndex="specCodeNames" | |
123 | 121 | align="center" |
124 | - render={(text, record: any) => ( | |
122 | + render={(items) => ( | |
125 | 123 | <Button |
126 | 124 | type="link" |
127 | 125 | onClick={() => { |
128 | 126 | setSpecVisible(true); |
129 | - const _list = (record.specCodes || []).map((e: any) => ({ | |
130 | - specCode: e, | |
131 | - })); | |
132 | - setSpecList([..._list]); | |
127 | + setSpecList([...items]); | |
133 | 128 | }} |
134 | - disabled={!(text && text.length > 0)} | |
129 | + disabled={!(items && items.length > 0)} | |
135 | 130 | > |
136 | - {!(text && text.length > 0) ? '全部整车代码' : '查看'} | |
131 | + {!(items && items.length > 0) ? '全部整车代码' : '查看'} | |
137 | 132 | </Button> |
138 | 133 | )} |
139 | 134 | /> |
... | ... | @@ -162,26 +157,42 @@ export default function FactoryList() { |
162 | 157 | {' '} |
163 | 158 | 编辑 |
164 | 159 | </a> |
165 | - <span> | |
166 | - <Divider type="vertical" /> | |
167 | - <Popconfirm title={`是否删除【${record.itemName}】?`} onConfirm={() => handleDelete(record.id)} okText="确定" cancelText="取消"> | |
168 | - <a onClick={(e) => e.preventDefault()} style={{ color: 'red' }}> | |
169 | - 删除 | |
170 | - </a> | |
171 | - </Popconfirm> | |
172 | - </span> | |
160 | + <Divider type="vertical" /> | |
161 | + | |
162 | + <Button | |
163 | + type="link" | |
164 | + style={{ color: '#4189FD' }} | |
165 | + onClick={() => { | |
166 | + setItem(record); | |
167 | + setVisibleEdit(true); | |
168 | + setIsCopy(true); | |
169 | + setBrandItem(record.brandId); | |
170 | + }} | |
171 | + > | |
172 | + 复制 | |
173 | + </Button> | |
174 | + | |
175 | + <Divider type="vertical" /> | |
176 | + | |
177 | + <Popconfirm title={`是否删除【${record.itemName}】?`} onConfirm={() => handleDelete(record.id)} okText="确定" cancelText="取消"> | |
178 | + <a onClick={(e) => e.preventDefault()} style={{ color: 'red' }}> | |
179 | + 删除 | |
180 | + </a> | |
181 | + </Popconfirm> | |
173 | 182 | </div> |
174 | 183 | )} |
175 | 184 | /> |
176 | 185 | </Table> |
186 | + | |
177 | 187 | {visibleUpload && <UploadModal brandList={brand} onCancel={() => setVisibleUpload(false)} />} |
178 | 188 | {visibleEdit && ( |
179 | 189 | <CreateModal |
190 | + isCopy={isCopy} | |
191 | + brandId={brandItem} | |
192 | + brandName={brandName} | |
180 | 193 | item={item} |
181 | 194 | fetchList={() => setLoading(true)} |
182 | 195 | onCancel={() => setVisibleEdit(false)} |
183 | - brandId={brandItem} | |
184 | - brandName={brandName} | |
185 | 196 | /> |
186 | 197 | )} |
187 | 198 | <SpecModal list={specList} visible={specVisible} setVisible={setSpecVisible} /> | ... | ... |
src/pages/cas/afterSaleConfiguration/jobManagement/interface.d.ts
... | ... | @@ -51,12 +51,13 @@ declare namespace WorkProject { |
51 | 51 | stdManHours?: number; // 标准工时 |
52 | 52 | cusFeeManHours?: number; // 标准工时 |
53 | 53 | applyType?: number; // 适用范围类型 |
54 | - id?: number; //作业项id | |
54 | + id: number; //作业项id | |
55 | 55 | brandId?: number; // 品牌id |
56 | 56 | seriesId?: number; // 车系id |
57 | 57 | specId?: number; |
58 | 58 | vehicleCodes?: any[]; |
59 | 59 | specCodes?: Spec[]; |
60 | + specCodeNames?: Spec[]; | |
60 | 61 | } |
61 | 62 | |
62 | 63 | export interface Spec { | ... | ... |
src/pages/cas/afterSaleConfiguration/manHoursDiscountConfig/index.tsx
... | ... | @@ -38,7 +38,7 @@ export default function ManHoursDiscountConfig() { |
38 | 38 | return ( |
39 | 39 | <PageHeaderWrapper title="工时减免配置"> |
40 | 40 | <Card> |
41 | - <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}> | |
41 | + <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}> | |
42 | 42 | <Filter params={innerParams} onFilter={setParams} brandList={brands} /> |
43 | 43 | <Dropdown |
44 | 44 | overlay={ | ... | ... |
src/pages/cas/common/SpecSelector/index.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Modal, Spin, Table } from 'antd'; | |
3 | +import { ColumnProps } from 'antd/lib/table'; | |
4 | + | |
5 | +import useInitail from '@/hooks/useInitail'; | |
6 | +import { getSpecListApi, type SpecItem } from '@/pages/cas/common/api'; | |
7 | + | |
8 | +import st from './style.less'; | |
9 | + | |
10 | +interface Props { | |
11 | + visible: boolean; | |
12 | + seriesId: number; | |
13 | + selectedItems?: SpecItem[]; | |
14 | + mode?: 'radio' | 'checkbox'; | |
15 | + onCancel: () => void; | |
16 | + onConfirm: (selectItems: SpecItem[]) => void; | |
17 | +} | |
18 | + | |
19 | +/** | |
20 | + * 车型代码选择器 | |
21 | + * @onConfirm specCodes:选中的车型代码数组 | |
22 | + */ | |
23 | +export default function SpecSelector({ visible, seriesId, mode = 'checkbox', selectedItems, onCancel, onConfirm }: Props) { | |
24 | + const [delay, setDelay] = useState(true); | |
25 | + const { data, loading, setParams } = useInitail(getSpecListApi, [], {}, delay); | |
26 | + | |
27 | + const [selectItems, setSelectItems] = useState<SpecItem[]>([]); | |
28 | + | |
29 | + useEffect(() => { | |
30 | + if (visible && !!seriesId) { | |
31 | + setDelay(false); | |
32 | + setParams({ seriesId }, true); | |
33 | + } | |
34 | + }, [visible, seriesId]); | |
35 | + | |
36 | + useEffect(() => { | |
37 | + if (visible && selectedItems && selectedItems.length > 0) { | |
38 | + setSelectItems(selectedItems); | |
39 | + } | |
40 | + }, [visible, selectedItems]); | |
41 | + | |
42 | + const columns: ColumnProps<SpecItem>[] = [ | |
43 | + { | |
44 | + title: '整车型号名称', | |
45 | + dataIndex: 'specCodeName', | |
46 | + key: 'specCodeName', | |
47 | + }, | |
48 | + { | |
49 | + title: '整车型号', | |
50 | + dataIndex: 'specCode', | |
51 | + key: 'specCode', | |
52 | + }, | |
53 | + ]; | |
54 | + | |
55 | + return ( | |
56 | + <Modal | |
57 | + title="选择整车型号" | |
58 | + width={700} | |
59 | + open={visible} | |
60 | + destroyOnClose | |
61 | + okButtonProps={{ disabled: selectItems.length === 0 }} | |
62 | + onCancel={onCancel} | |
63 | + onOk={() => onConfirm(selectItems)} | |
64 | + > | |
65 | + <Spin spinning={loading}> | |
66 | + <Table | |
67 | + style={{ marginTop: 0 }} | |
68 | + scroll={{ y: 400 }} | |
69 | + columns={columns} | |
70 | + dataSource={data} | |
71 | + pagination={false} | |
72 | + rowClassName={st.clickableRow} | |
73 | + rowKey="specCode" | |
74 | + rowSelection={{ | |
75 | + type: mode, | |
76 | + selectedRowKeys: selectItems.map((si) => si.specCode) || [], | |
77 | + onChange: (selectedRowKeys, selectedRows: SpecItem[]) => { | |
78 | + setSelectItems(selectedRows); | |
79 | + }, | |
80 | + }} | |
81 | + onRow={(record) => ({ | |
82 | + onClick: () => { | |
83 | + if (selectItems.some((si) => si.specCode === record.specCode)) { | |
84 | + setSelectItems([...selectItems.filter((si) => si.specCode !== record.specCode)]); | |
85 | + } else { | |
86 | + setSelectItems([...selectItems, record]); | |
87 | + } | |
88 | + }, | |
89 | + })} | |
90 | + /> | |
91 | + </Spin> | |
92 | + </Modal> | |
93 | + ); | |
94 | +} | ... | ... |
src/pages/cas/common/SpecSelector/style.less
0 → 100644
src/pages/cas/common/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { OOP_HOST } from '@/utils/host'; | |
4 | + | |
5 | +/** | |
6 | + * 车型代码列表 | |
7 | + * @desc 包含品牌车系等详情信息 | |
8 | + */ | |
9 | +export interface ListParams { | |
10 | + brandId?: number; | |
11 | + exhaust?: number; | |
12 | + seriesId?: number; | |
13 | + inhaleType?: number; | |
14 | +} | |
15 | + | |
16 | +export interface SpecItem { | |
17 | + id: number; | |
18 | + brandId: number; | |
19 | + seriesId: number; | |
20 | + specCode: string; | |
21 | + specCodeName: string; | |
22 | + exhaust: number; | |
23 | + motorOil: number; | |
24 | + brandName: string; | |
25 | + seriesName: string; | |
26 | + inhaleType: number; | |
27 | +} | |
28 | + | |
29 | +export function getSpecListApi(params: ListParams): http.PromiseResp<SpecItem[]> { | |
30 | + return request.get(`${OOP_HOST}/select/get/code/list`, { params }); | |
31 | +} | ... | ... |
src/pages/performance/KpiGroupSetting/EditComfirm/index.tsx
... | ... | @@ -19,7 +19,6 @@ import _ from 'lodash'; |
19 | 19 | import useInitial from '@/hooks/useInitail'; |
20 | 20 | import { fetchRealtimeStaffs } from '../api'; |
21 | 21 | |
22 | - | |
23 | 22 | const Option = Select.Option; |
24 | 23 | |
25 | 24 | // 星级数据: |
... | ... | @@ -125,7 +124,7 @@ function Index(props: Props) { |
125 | 124 | }, [id]); |
126 | 125 | // 控制回显 |
127 | 126 | useEffect(() => { |
128 | - if (configId && data && type ) { | |
127 | + if (configId && data && type) { | |
129 | 128 | const arr = JSON.parse(JSON.stringify(data)); |
130 | 129 | // if (arr.kpiGroups && arr.kpiGroups.length > 0) { |
131 | 130 | // arr.kpiGroups.forEach((i1: any) => { |
... | ... | @@ -370,7 +369,7 @@ function Index(props: Props) { |
370 | 369 | return null; |
371 | 370 | }} |
372 | 371 | </Form.Item> |
373 | - <div style={{ marginBottom: 15 }}> | |
372 | + <div style={{ marginBottom: 5 }}> | |
374 | 373 | 绩效得分率相同情况,按以下指标当前达成值确定排名(非必选,最多选3个,从左至右依次为优先级1、优先级2、优先级3) |
375 | 374 | </div> |
376 | 375 | <Form.Item |
... | ... | @@ -382,6 +381,7 @@ function Index(props: Props) { |
382 | 381 | value && value.length > 0 && value.length > 3 ? Promise.reject(new Error('最多只能选择3个指标')) : Promise.resolve(), |
383 | 382 | }, |
384 | 383 | ]} |
384 | + style={{ marginBottom: 40 }} | |
385 | 385 | > |
386 | 386 | <Select placeholder="选择指标" showSearch allowClear optionFilterProp="children" mode="multiple" disabled={readOnly}> |
387 | 387 | {intersectionList.map((item) => ( |
... | ... | @@ -399,7 +399,7 @@ function Index(props: Props) { |
399 | 399 | }} |
400 | 400 | </Form.Item> |
401 | 401 | {/* // 默认工作项数量和一级浏览量 */} |
402 | - <div style={{ marginBottom: 15 }}>在上述自定义优先级指标不能区分排名时, 将默认采用以下指标进行排名</div> | |
402 | + <div style={{ marginBottom: 5 }}>在上述自定义优先级指标不能区分排名时, 将默认采用以下指标进行排名</div> | |
403 | 403 | <Form.Item label="默认排名指标" name="defaultRankMethodRule" initialValue={['4aef43E5723b4526', '231d5B904F684b24']}> |
404 | 404 | <Select placeholder="选择指标" showSearch allowClear optionFilterProp="children" mode="multiple" disabled={true}> |
405 | 405 | {[ | ... | ... |