Commit ea25ffa7e7c00ec965545803815f6d94025b3f8c
Merge remote-tracking branch 'origin/master' into office
Showing
44 changed files
with
1273 additions
and
1364 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/contract/BearCostSetting/interface.d.ts
... | ... | @@ -31,9 +31,9 @@ declare namespace BearCostSetting { |
31 | 31 | shareRate?: number;//分摊比率 |
32 | 32 | paymentMode?: number;//缴费方式,1充值、2账单 |
33 | 33 | unit?: string;//计量单位 |
34 | - placeType: number; | |
35 | - placeName: string; | |
36 | - placeId: number; | |
34 | + placeType?: number; | |
35 | + placeName?: string; | |
36 | + placeId?: number; | |
37 | 37 | } |
38 | 38 | interface FeeTypeList{ |
39 | 39 | typeName?: string;//费用类型名称 | ... | ... |
src/pages/contract/ItemAmountSetting/components/AddModel/index.tsx
1 | -import React, { useCallback, useEffect, useState } from "react"; | |
2 | -import { Modal, Skeleton, Select, Form, Radio, message } from "antd"; | |
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Modal, Skeleton, Select, Form, Radio, message } from 'antd'; | |
3 | 3 | import * as API from '../../api'; |
4 | -import useInitial from "@/hooks/useInitail"; | |
5 | -import { fromPairs } from "lodash"; | |
6 | 4 | |
7 | -interface Props{ | |
8 | - visible:boolean; | |
9 | - row?:API.Item; | |
10 | - feeTypeList:any[], | |
11 | - roleList:any[], | |
12 | - onRefresh: () => void; | |
13 | - onCancel?: () => void; | |
5 | +interface Props { | |
6 | + visible: boolean; | |
7 | + row?: API.Item; | |
8 | + feeTypeList: any[]; | |
9 | + roleList: any[]; | |
10 | + onRefresh: () => void; | |
11 | + onCancel?: () => void; | |
14 | 12 | } |
15 | 13 | |
16 | -function AddModel({visible, row, feeTypeList, roleList, onCancel, onRefresh}:Props) { | |
17 | - const [form] = Form.useForm(); | |
18 | - const [loading, setLoading] = useState<boolean>(false); | |
19 | - const {id, execRoleName, feeTypeName, stagelyExec} = row || {}; | |
20 | - useEffect(() => { | |
21 | - if (id) { | |
22 | - form.setFieldsValue({ | |
23 | - feeTypeValue: feeTypeList.filter((item:any) => item.typeName === feeTypeName).map((i:any) => ({label: i.typeName, value: i.typeValue}))[0], | |
24 | - execRoleCode: execRoleName && roleList.filter((item:any) => item.roleName === execRoleName).map((i:any) => ({label: i.roleName, value: i.roleCode}))[0], | |
25 | - stagelyExec: stagelyExec ? 1 : 0 | |
26 | - }); | |
27 | - } | |
28 | - }, [row]); | |
29 | - | |
30 | - /** | |
31 | - * @description: 表单提交 | |
32 | - * @param {any} feildValue | |
33 | - * @return {*} | |
34 | - */ | |
35 | - const handleSave = (feildValue: any) => { | |
36 | - setLoading(true); | |
37 | - const {feeTypeValue, execRoleCode, stagelyExec} = feildValue || {}; | |
38 | - const params = { | |
39 | - feeTypeValue: feeTypeValue.value, | |
40 | - execRoleCode: execRoleCode && execRoleCode.value, | |
41 | - stagelyExec: stagelyExec === 1, | |
42 | - id | |
43 | - }; | |
44 | - API.addItemAmount({...params}) | |
45 | - .then(res => { | |
46 | - message.success("操作成功"); | |
47 | - _onCancel(); | |
48 | - setLoading(false); | |
49 | - onRefresh(); | |
50 | - }) | |
51 | - .catch(err => { | |
52 | - message.error(err?.message); | |
53 | - setLoading(false); | |
54 | - }); | |
55 | - }; | |
56 | - /** | |
57 | - * @description: 关闭弹框 | |
58 | - * @param {*} | |
59 | - * @return {*} | |
60 | - */ | |
61 | - const _onCancel = () => { | |
62 | - onCancel && onCancel(); | |
63 | - form.resetFields(); | |
14 | +function AddModel({ visible, row, feeTypeList, roleList, onCancel, onRefresh }: Props) { | |
15 | + const [form] = Form.useForm(); | |
16 | + const [loading, setLoading] = useState<boolean>(false); | |
17 | + const { id, execRoleName, feeTypeName, stagelyExec } = row || {}; | |
18 | + useEffect(() => { | |
19 | + if (id) { | |
20 | + form.setFieldsValue({ | |
21 | + feeTypeValue: feeTypeList | |
22 | + .filter((item: any) => item.typeName === feeTypeName) | |
23 | + .map((i: any) => ({ label: i.typeName, value: i.typeValue }))[0], | |
24 | + execRoleCode: | |
25 | + execRoleName && | |
26 | + roleList.filter((item: any) => item.roleName === execRoleName).map((i: any) => ({ label: i.roleName, value: i.roleCode }))[0], | |
27 | + stagelyExec: stagelyExec ? 1 : 0, | |
28 | + }); | |
29 | + } | |
30 | + }, [row]); | |
31 | + | |
32 | + /** | |
33 | + * @description: 表单提交 | |
34 | + * @param {any} feildValue | |
35 | + * @return {*} | |
36 | + */ | |
37 | + const handleSave = (feildValue: any) => { | |
38 | + setLoading(true); | |
39 | + const { feeTypeValue, execRoleCode, stagelyExec } = feildValue || {}; | |
40 | + const params = { | |
41 | + feeTypeValue: feeTypeValue.value, | |
42 | + execRoleCode: execRoleCode && execRoleCode.value, | |
43 | + stagelyExec: stagelyExec === 1, | |
44 | + id, | |
64 | 45 | }; |
65 | - | |
66 | - return ( | |
67 | - <Modal | |
68 | - title={`${id ? '编辑':'新增'}事项款配置`} | |
69 | - visible={visible} | |
70 | - confirmLoading={loading} | |
71 | - onCancel={_onCancel} | |
72 | - onOk={form.submit} | |
73 | - cancelButtonProps={{ hidden: true }} | |
74 | - width="50%" | |
75 | - > | |
76 | - <Skeleton | |
77 | - loading={false} | |
78 | - > | |
79 | - <Form form={form} onFinish={handleSave} wrapperCol={{ span: 18 }} labelCol={{ span: 4 }}> | |
80 | - <Form.Item | |
81 | - label="费用类型" | |
82 | - name="feeTypeValue" | |
83 | - rules={[{ required: true, message: '请选择费用类型' }]} | |
84 | - > | |
85 | - <Select | |
86 | - placeholder="请选择" | |
87 | - showSearch | |
88 | - optionFilterProp="children" | |
89 | - labelInValue | |
90 | - onSelect={(it:any) => { | |
91 | - const item = feeTypeList.filter((i:any) => it.value === i.typeValue); | |
92 | - }} | |
93 | - filterOption={(input, option: any) => option?.children.indexOf(input) >= 0} | |
94 | - > | |
95 | - { | |
96 | - feeTypeList && feeTypeList.map((item:any) => ( | |
97 | - <Select.Option value={item.typeValue} key={item.typeValue}> | |
98 | - {item.typeName} | |
99 | - </Select.Option> | |
100 | - )) | |
101 | - } | |
102 | - </Select> | |
103 | - </Form.Item> | |
104 | - <Form.Item | |
105 | - label="执行角色" | |
106 | - name="execRoleCode" | |
107 | - rules={[{ required: false, message: '请选择角色编码' }]} | |
46 | + API.addItemAmount({ ...params }) | |
47 | + .then(() => { | |
48 | + message.success('操作成功'); | |
49 | + // eslint-disable-next-line @typescript-eslint/no-use-before-define | |
50 | + _onCancel(); | |
51 | + setLoading(false); | |
52 | + onRefresh(); | |
53 | + }) | |
54 | + .catch((err) => { | |
55 | + message.error(err?.message); | |
56 | + setLoading(false); | |
57 | + }); | |
58 | + }; | |
59 | + /** | |
60 | + * @description: 关闭弹框 | |
61 | + * @param {*} | |
62 | + * @return {*} | |
63 | + */ | |
64 | + const _onCancel = () => { | |
65 | + onCancel && onCancel(); | |
66 | + form.resetFields(); | |
67 | + }; | |
68 | + | |
69 | + return ( | |
70 | + <Modal | |
71 | + title={`${id ? '编辑' : '新增'}付款申请阶段付款配置`} | |
72 | + open={visible} | |
73 | + confirmLoading={loading} | |
74 | + onCancel={_onCancel} | |
75 | + onOk={form.submit} | |
76 | + cancelButtonProps={{ hidden: true }} | |
77 | + width="50%" | |
78 | + > | |
79 | + <Skeleton loading={false}> | |
80 | + <Form form={form} onFinish={handleSave} wrapperCol={{ span: 18 }} labelCol={{ span: 4 }}> | |
81 | + <Form.Item label="付款申请款项类型" name="feeTypeValue" rules={[{ required: true, message: '请选择付款申请款项类型' }]}> | |
82 | + <Select | |
83 | + placeholder="请选择" | |
84 | + showSearch | |
85 | + optionFilterProp="children" | |
86 | + labelInValue | |
87 | + filterOption={(input, option: any) => option?.children.indexOf(input) >= 0} | |
108 | 88 | > |
109 | - <Select | |
110 | - placeholder="默认执行角色为申请人自身" | |
111 | - showSearch | |
112 | - allowClear | |
113 | - optionFilterProp="children" | |
114 | - labelInValue | |
115 | - onSelect={(it:any) => { | |
116 | - const item = roleList.filter((i:any) => it.value === i.roleCode); | |
117 | - }} | |
118 | - filterOption={(input, option: any) => option?.children.indexOf(input) >= 0} | |
119 | - > | |
120 | - { | |
121 | - roleList && roleList.map((item:any) => ( | |
122 | - <Select.Option value={item.roleCode} key={item.id}> | |
123 | - {item.roleName} | |
124 | - </Select.Option> | |
125 | - )) | |
126 | - } | |
127 | - </Select> | |
128 | - </Form.Item> | |
129 | - <Form.Item | |
130 | - label="阶段执行" | |
131 | - name="stagelyExec" | |
132 | - rules={[{ required: true, message: '是否阶段执行' }]} | |
89 | + {feeTypeList && | |
90 | + feeTypeList.map((item: any) => ( | |
91 | + <Select.Option value={item.typeValue} key={item.typeValue}> | |
92 | + {item.typeName} | |
93 | + </Select.Option> | |
94 | + ))} | |
95 | + </Select> | |
96 | + </Form.Item> | |
97 | + <Form.Item label="执行角色" name="execRoleCode" rules={[{ required: false, message: '请选择角色编码' }]}> | |
98 | + <Select | |
99 | + placeholder="默认执行角色为申请人自身" | |
100 | + showSearch | |
101 | + allowClear | |
102 | + optionFilterProp="children" | |
103 | + labelInValue | |
104 | + filterOption={(input, option: any) => option?.children.indexOf(input) >= 0} | |
133 | 105 | > |
134 | - <Radio.Group> | |
135 | - <Radio value={1}> 是 </Radio> | |
136 | - <Radio value={0}> 否 </Radio> | |
137 | - </Radio.Group> | |
138 | - </Form.Item> | |
139 | - </Form> | |
140 | - </Skeleton> | |
141 | - </Modal> | |
142 | - ); | |
106 | + {roleList && | |
107 | + roleList.map((item: any) => ( | |
108 | + <Select.Option value={item.roleCode} key={item.id}> | |
109 | + {item.roleName} | |
110 | + </Select.Option> | |
111 | + ))} | |
112 | + </Select> | |
113 | + </Form.Item> | |
114 | + {/* <Form.Item label="阶段付款" name="stagelyExec" rules={[{ required: true, message: '是否阶段付款' }]}> | |
115 | + <Radio.Group> | |
116 | + <Radio value={1}> 是 </Radio> | |
117 | + <Radio value={0}> 否 </Radio> | |
118 | + </Radio.Group> | |
119 | + </Form.Item> */} | |
120 | + </Form> | |
121 | + </Skeleton> | |
122 | + </Modal> | |
123 | + ); | |
143 | 124 | } |
144 | 125 | |
145 | -export default AddModel; | |
146 | 126 | \ No newline at end of file |
127 | +export default AddModel; | ... | ... |
src/pages/contract/ItemAmountSetting/components/Filter/index.tsx
1 | -import React, { useCallback, useState } from "react"; | |
2 | -import { Row, Col, Select } from "antd"; | |
3 | -import * as common from "@/typing/common"; | |
4 | -import * as API from '../../api'; | |
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2024-02-18 11:54:02 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2024-02-18 14:12:29 | |
6 | + * @FilePath: \fw-cms\src\pages\contract\ItemAmountSetting\components\Filter\index.tsx | |
7 | + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | |
8 | + */ | |
9 | +import React, { useState } from 'react'; | |
10 | +import { Row, Col, Select } from 'antd'; | |
11 | +import type * as API from '../../api'; | |
5 | 12 | |
6 | -interface Params extends common.PaginationParam { | |
7 | - [key: string]: any; | |
8 | - } | |
9 | -interface Props{ | |
10 | - feeTypeList?:any[], | |
11 | - roleList?:any[], | |
12 | - setParams:any, | |
13 | - innerParams?:any, | |
13 | +interface Props { | |
14 | + feeTypeList?: any[]; | |
15 | + roleList?: any[]; | |
16 | + setParams: any; | |
17 | + innerParams?: any; | |
14 | 18 | } |
15 | 19 | |
16 | -function Filter({feeTypeList, roleList, setParams, innerParams}:Props) { | |
17 | - const stagelyExecList = [{label: '是', value: 1}, {label: '否', value: 0}]; | |
20 | +function Filter({ feeTypeList, roleList, setParams, innerParams }: Props) { | |
21 | + const stagelyExecList = [ | |
22 | + { label: '是', value: 1 }, | |
23 | + { label: '否', value: 0 }, | |
24 | + ]; | |
18 | 25 | const [searchValue, setSearchValue] = useState<API.PageParams>({}); |
19 | 26 | |
20 | - return ( | |
21 | - <Row | |
22 | - style={{ display: 'flex', flex: 1 }} | |
23 | - > | |
24 | - <Col span={6}> | |
25 | - <Select | |
26 | - placeholder="请选择费用类型" | |
27 | - showSearch | |
28 | - optionFilterProp="children" | |
29 | - allowClear | |
30 | - style={{ width: 200 }} | |
31 | - onChange={(feeTypeValue) => { | |
32 | - setSearchValue({...searchValue, feeTypeValue}); | |
33 | - setParams({...innerParams, ...searchValue, feeTypeValue}, true); | |
34 | - }} | |
35 | - > | |
36 | - { | |
37 | - feeTypeList && feeTypeList.map((item:any) => ( | |
38 | - <Select.Option value={item.typeValue} key={item.typeValue}> | |
39 | - {item.typeName} | |
40 | - </Select.Option> | |
41 | - )) | |
27 | + return ( | |
28 | + <Row style={{ display: 'flex', flex: 1 }}> | |
29 | + <Col span={6}> | |
30 | + <Select | |
31 | + placeholder="请选择付款申请款项类型" | |
32 | + showSearch | |
33 | + optionFilterProp="children" | |
34 | + allowClear | |
35 | + style={{ width: 200 }} | |
36 | + onChange={(feeTypeValue) => { | |
37 | + setSearchValue({ ...searchValue, feeTypeValue }); | |
38 | + setParams({ ...innerParams, ...searchValue, feeTypeValue }, true); | |
39 | + }} | |
40 | + > | |
41 | + {feeTypeList && | |
42 | + feeTypeList.map((item: any) => ( | |
43 | + <Select.Option value={item.typeValue} key={item.typeValue}> | |
44 | + {item.typeName} | |
45 | + </Select.Option> | |
46 | + ))} | |
47 | + </Select> | |
48 | + </Col> | |
49 | + <Col span={6}> | |
50 | + <Select | |
51 | + placeholder="请选择执行角色" | |
52 | + showSearch | |
53 | + optionFilterProp="children" | |
54 | + allowClear | |
55 | + style={{ width: 200 }} | |
56 | + onChange={(execRoleCode) => { | |
57 | + setSearchValue({ ...searchValue, execRoleCode }); | |
58 | + setParams({ ...innerParams, ...searchValue, execRoleCode }, true); | |
59 | + }} | |
60 | + > | |
61 | + {roleList && | |
62 | + roleList.map((item: any) => ( | |
63 | + <Select.Option value={item.roleCode} key={item.id}> | |
64 | + {item.roleName} | |
65 | + </Select.Option> | |
66 | + ))} | |
67 | + </Select> | |
68 | + </Col> | |
69 | + {/* <Col span={6}> | |
70 | + <Select | |
71 | + placeholder="阶段付款" | |
72 | + showSearch | |
73 | + optionFilterProp="children" | |
74 | + allowClear | |
75 | + style={{ width: 200 }} | |
76 | + onChange={(stagelyExec) => { | |
77 | + setSearchValue({ ...searchValue, stagelyExec }); | |
78 | + let _stagelyExec; | |
79 | + if (stagelyExec) { | |
80 | + _stagelyExec = true; | |
81 | + } else if (stagelyExec === 0) { | |
82 | + _stagelyExec = false; | |
83 | + } else { | |
84 | + _stagelyExec = undefined; | |
42 | 85 | } |
43 | - </Select> | |
44 | - </Col> | |
45 | - <Col span={6}> | |
46 | - <Select | |
47 | - placeholder="请选择执行角色" | |
48 | - showSearch | |
49 | - optionFilterProp="children" | |
50 | - allowClear | |
51 | - style={{ width: 200 }} | |
52 | - onChange={(execRoleCode) => { | |
53 | - setSearchValue({...searchValue, execRoleCode}); | |
54 | - setParams({...innerParams, ...searchValue, execRoleCode}, true); | |
55 | - }} | |
56 | - > | |
57 | - { | |
58 | - roleList && roleList.map((item:any) => ( | |
59 | - <Select.Option value={item.roleCode} key={item.id}> | |
60 | - {item.roleName} | |
61 | - </Select.Option> | |
62 | - )) | |
63 | - } | |
64 | - </Select> | |
65 | - </Col> | |
66 | - <Col span={6}> | |
67 | - <Select | |
68 | - placeholder="阶段执行" | |
69 | - showSearch | |
70 | - optionFilterProp="children" | |
71 | - allowClear | |
72 | - style={{ width: 200 }} | |
73 | - onChange={(stagelyExec) => { | |
74 | - setSearchValue({...searchValue, stagelyExec}); | |
75 | - let _stagelyExec; | |
76 | - if (stagelyExec) { | |
77 | - _stagelyExec = true; | |
78 | - } else if (stagelyExec === 0) { | |
79 | - _stagelyExec = false; | |
80 | - } else { | |
81 | - _stagelyExec = undefined; | |
82 | - } | |
83 | - setParams({...innerParams, ...searchValue, stagelyExec: _stagelyExec}, true); | |
84 | - }} | |
85 | - > | |
86 | - { | |
87 | - stagelyExecList && stagelyExecList.map((item:any) => ( | |
88 | - <Select.Option value={item.value} key={item.label}> | |
89 | - {item.label} | |
90 | - </Select.Option> | |
91 | - )) | |
92 | - } | |
93 | - </Select> | |
94 | - </Col> | |
95 | - </Row> | |
96 | - ); | |
86 | + setParams({ ...innerParams, ...searchValue, stagelyExec: _stagelyExec }, true); | |
87 | + }} | |
88 | + > | |
89 | + {stagelyExecList && | |
90 | + stagelyExecList.map((item: any) => ( | |
91 | + <Select.Option value={item.value} key={item.label}> | |
92 | + {item.label} | |
93 | + </Select.Option> | |
94 | + ))} | |
95 | + </Select> | |
96 | + </Col> */} | |
97 | + </Row> | |
98 | + ); | |
97 | 99 | } |
98 | 100 | |
99 | -export default Filter; | |
100 | 101 | \ No newline at end of file |
102 | +export default Filter; | ... | ... |
src/pages/contract/ItemAmountSetting/index.tsx
... | ... | @@ -31,7 +31,7 @@ function ItemAmountSetting() { |
31 | 31 | * @param {*} |
32 | 32 | * @return {*} |
33 | 33 | */ |
34 | - const _delete = (row:API.Item) => { | |
34 | + const _delete = (row: API.Item) => { | |
35 | 35 | const {id} =row; |
36 | 36 | API.delItemAmount({id}) |
37 | 37 | .then(() => { |
... | ... | @@ -48,7 +48,7 @@ function ItemAmountSetting() { |
48 | 48 | * @param {API} row |
49 | 49 | * @return {*} |
50 | 50 | */ |
51 | - const edit = async (row:API.Item) => { | |
51 | + const edit = async (row: API.Item) => { | |
52 | 52 | await setRow(row); |
53 | 53 | setVisible(true); |
54 | 54 | }; |
... | ... | @@ -62,7 +62,7 @@ function ItemAmountSetting() { |
62 | 62 | setParams({ ...innerParams, }, true); |
63 | 63 | }, 350); |
64 | 64 | return ( |
65 | - <PageHeaderWrapper title="事项款配置"> | |
65 | + <PageHeaderWrapper title="付款申请阶段付款配置"> | |
66 | 66 | <ConfigProvider locale={zhCN}> |
67 | 67 | <Card className={st.page}> |
68 | 68 | <div className={st.header}> |
... | ... | @@ -91,14 +91,14 @@ function ItemAmountSetting() { |
91 | 91 | rowKey={(item: API.Item) => `${item.id}`} |
92 | 92 | onChange={(_pagination) => setParams({ ..._pagination }, true)} |
93 | 93 | > |
94 | - <Column title="费用类型" width={200} dataIndex="feeTypeName" render={(t) => t || "-"} /> | |
95 | - <Column title="阶段执行" width={200} dataIndex="stagelyExec" render={(t) => (t?'是':'否')} /> | |
94 | + <Column title="付款申请款项类型" width={200} dataIndex="feeTypeName" render={(t) => t || "-"} /> | |
95 | + {/* <Column title="阶段付款" width={200} dataIndex="stagelyExec" render={(t) => (t?'是':'否')} /> */} | |
96 | 96 | <Column title="执行角色" width={200} dataIndex="execRoleName" render={(t) => t || "-"} /> |
97 | 97 | <Column |
98 | 98 | title="操作" |
99 | 99 | width={100} |
100 | 100 | dataIndex="unit" |
101 | - render={(text, row:API.Item) => ( | |
101 | + render={(text, row: API.Item) => ( | |
102 | 102 | <span> |
103 | 103 | <Popconfirm title="是否编辑?" onConfirm={() => edit(row)} okText="确定" cancelText="取消"> |
104 | 104 | <a | ... | ... |
src/pages/finance/MatterApplicationConfig/components/ApitalModal.tsx
1 | 1 | import React, { useState, useEffect } from "react"; |
2 | -import { Modal, Form, Select, message } from "antd"; | |
2 | +import { Modal, Form, Select, message, Radio } from "antd"; | |
3 | 3 | import { useStore } from "../index"; |
4 | 4 | import { getRpTypeConfigSaveApi, commonRpTypesApi, RpTypesItem } from "@/pages/finance/PaymentAllocation/api"; |
5 | 5 | import useInitial from "@/hooks/useInitail"; |
6 | -import { ProcessMode } from "@/pages/finance/entitys"; | |
6 | +import { ProcessMode, ProcessModeEnum } from '@/pages/finance/entitys'; | |
7 | 7 | import { getCompanyBusinessTypesApi } from "@/pages/finance/TradeCompany/api"; |
8 | 8 | import { getAllRoleCodeApi } from "@/common/api"; |
9 | 9 | |
... | ... | @@ -86,8 +86,8 @@ export default function CreateModal() { |
86 | 86 | |
87 | 87 | return ( |
88 | 88 | <Modal |
89 | - title={`${current.id ? "编辑" : "新增"}事项申请款项配置`} | |
90 | - open={visible} | |
89 | + title={`${current.id ? '编辑' : '新增'}付款申请款项配置`} | |
90 | + open={visible} | |
91 | 91 | onOk={() => form.submit()} |
92 | 92 | onCancel={onCancel} |
93 | 93 | maskClosable={false} |
... | ... | @@ -98,8 +98,8 @@ export default function CreateModal() { |
98 | 98 | }} |
99 | 99 | > |
100 | 100 | <Form form={form} onFinish={submit} labelCol={{ span: 7 }} wrapperCol={{ span: 16 }}> |
101 | - <FormItem name="typeValue" label="事项申请款项" rules={[{ required: true, message: "请选择款项" }]}> | |
102 | - <Select placeholder="请选择事项申请款项" labelInValue showSearch optionFilterProp="children" disabled={!!current.id}> | |
101 | + <FormItem name="typeValue" label="付款申请款项" rules={[{ required: true, message: '请选择款项' }]}> | |
102 | + <Select placeholder="请选择付款申请款项" labelInValue showSearch optionFilterProp="children" disabled={!!current.id}> | |
103 | 103 | {data.map((item) => ( |
104 | 104 | <Option key={item.value} value={item.value}> |
105 | 105 | {item.name} |
... | ... | @@ -107,8 +107,8 @@ export default function CreateModal() { |
107 | 107 | ))} |
108 | 108 | </Select> |
109 | 109 | </FormItem> |
110 | - | |
111 | - <FormItem name="processMode" label="款项处理" rules={[{ required: true, message: "请选择款项处理方式" }]}> | |
110 | + | |
111 | + <FormItem name="processMode" label="款项处理" rules={[{ required: true, message: '请选择款项处理方式' }]}> | |
112 | 112 | <Select placeholder="请选择款项处理方式" showSearch optionFilterProp="children"> |
113 | 113 | {ProcessMode.map((item) => ( |
114 | 114 | <Option key={item.value} value={item.value}> |
... | ... | @@ -117,6 +117,20 @@ export default function CreateModal() { |
117 | 117 | ))} |
118 | 118 | </Select> |
119 | 119 | </FormItem> |
120 | + <FormItem noStyle shouldUpdate={(prevValues, curValues) => prevValues.processMode !== curValues.processMode}> | |
121 | + {({ getFieldValue }) => { | |
122 | + const _processMode = getFieldValue('processMode') || {}; | |
123 | + console.log('_processMode999:', _processMode); | |
124 | + return _processMode === ProcessModeEnum['冲应付款'] ? ( | |
125 | + <FormItem label="是否提前导入应付款" initialValue={false} name="mustImport" rules={[{ required: true, message: '请选择' }]}> | |
126 | + <Radio.Group> | |
127 | + <Radio value>是</Radio> | |
128 | + <Radio value={false}>否</Radio> | |
129 | + </Radio.Group> | |
130 | + </FormItem> | |
131 | + ) : null; | |
132 | + }} | |
133 | + </FormItem> | |
120 | 134 | <FormItem name="companyTypes" label="往来单位业务类型"> |
121 | 135 | <Select |
122 | 136 | placeholder="请选择往来单位业务类型" |
... | ... | @@ -142,7 +156,7 @@ export default function CreateModal() { |
142 | 156 | optionFilterProp="children" |
143 | 157 | loading={loading} |
144 | 158 | autoClearSearchValue={false} |
145 | - > | |
159 | + > | |
146 | 160 | {roleList.map((item) => ( |
147 | 161 | <Option key={item.roleCode} value={item.roleCode}> |
148 | 162 | {item.roleName} | ... | ... |
src/pages/finance/MatterApplicationConfig/components/Filter.tsx
... | ... | @@ -33,7 +33,7 @@ export default function AccountList() { |
33 | 33 | <Col span={6}> |
34 | 34 | <Search |
35 | 35 | allowClear |
36 | - placeholder="搜索事项申请款项" | |
36 | + placeholder="搜索付款申请款项" | |
37 | 37 | onChange={(e) => fetchListByName(e.target.value || undefined)} |
38 | 38 | style={{ width: 200, marginLeft: 10 }} |
39 | 39 | /> | ... | ... |
src/pages/finance/MatterApplicationConfig/components/ListAccounts.tsx
... | ... | @@ -36,8 +36,9 @@ export default function AccountList() { |
36 | 36 | return ( |
37 | 37 | <> |
38 | 38 | <Table dataSource={typeConifgList} rowKey="id" loading={loading} pagination={paginationConfig}> |
39 | - <Column title="事项申请款项" dataIndex="typeName" /> | |
39 | + <Column title="付款申请款项" dataIndex="typeName" /> | |
40 | 40 | <Column title="款项处理" dataIndex="processMode" render={(mode) => ProcessModeEnum[mode]} /> |
41 | + <Column title="是否提前导入应付款" dataIndex="mustImport" render={(value: string) => (value ? '是' : '否')} /> | |
41 | 42 | <Column |
42 | 43 | title="往来单位业务类型" |
43 | 44 | dataIndex="compTypeList" |
... | ... | @@ -52,7 +53,7 @@ export default function AccountList() { |
52 | 53 | 查看 |
53 | 54 | </Button> |
54 | 55 | ) : ( |
55 | - "--" | |
56 | + '--' | |
56 | 57 | ) |
57 | 58 | } |
58 | 59 | /> |
... | ... | @@ -70,7 +71,7 @@ export default function AccountList() { |
70 | 71 | 查看 |
71 | 72 | </Button> |
72 | 73 | ) : ( |
73 | - "--" | |
74 | + '--' | |
74 | 75 | ) |
75 | 76 | } |
76 | 77 | /> |
... | ... | @@ -89,12 +90,7 @@ export default function AccountList() { |
89 | 90 | 编辑 |
90 | 91 | </Button> |
91 | 92 | <Divider type="vertical" /> |
92 | - <Popconfirm | |
93 | - title={`是否删除【${record.typeName}】?`} | |
94 | - onConfirm={() => handleDelete(+record.id!)} | |
95 | - okText="确定" | |
96 | - cancelText="取消" | |
97 | - > | |
93 | + <Popconfirm title={`是否删除【${record.typeName}】?`} onConfirm={() => handleDelete(+record.id!)} okText="确定" cancelText="取消"> | |
98 | 94 | <a href="">删除</a> |
99 | 95 | </Popconfirm> |
100 | 96 | </> | ... | ... |
src/pages/finance/MatterApplicationConfig/index.tsx
src/pages/finance/PaymentAllocation/index.tsx
src/pages/finance/PoundageConfig/PoundageMerchant/index.tsx
... | ... | @@ -41,7 +41,7 @@ export default function PoundageMerchant() { |
41 | 41 | <p style={{ marginTop: 10 }}>配置:</p> |
42 | 42 | <p style={{ marginLeft: 20 }}> |
43 | 43 | {data.configList?.map((item) => ( |
44 | - <div style={{marginTop: 5}}> | |
44 | + <div style={{ marginTop: 5 }}> | |
45 | 45 | <span style={{ display: 'inline-block', minWidth: 250 }}>{`交易方式:${FinanceTradeMethodEnum[item.type]}`}</span> |
46 | 46 | <span style={{ display: 'inline-block', minWidth: 180 }}>{`手续费费率:${item.poundage}%`}</span> |
47 | 47 | <span style={{ display: 'inline-block', minWidth: 200 }}>{`封顶金额:${rmb.p(item.max)}元`}</span> |
... | ... | @@ -68,11 +68,15 @@ export default function PoundageMerchant() { |
68 | 68 | <Button |
69 | 69 | type="primary" |
70 | 70 | onClick={() => { |
71 | - const s = data?.map((t) => t.dealers?.map((d) => d.id)); | |
71 | + const _data = data || []; | |
72 | + const s = _data?.map((t) => { | |
73 | + const dealers = t.dealers || []; | |
74 | + return dealers.map((d) => d.id) | |
75 | + }); | |
72 | 76 | setVisiData({ |
73 | 77 | visible: true, |
74 | 78 | row: {}, |
75 | - dealers: s.reduce((a, b) => a?.concat(b || 0)), | |
79 | + dealers: s.reduce((a, b) => a?.concat(b || 0),[]), | |
76 | 80 | }); |
77 | 81 | }} |
78 | 82 | > | ... | ... |
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 | {[ | ... | ... |
src/pages/pms/part/Repertory/api.ts
1 | -import { http } from '@/typing/http'; | |
1 | +import type { http } from '@/typing/http'; | |
2 | 2 | import request from '@/utils/request'; |
3 | 3 | import { PMS_HOST, HOST, OOP_HOST } from "@/utils/host"; |
4 | 4 | |
... | ... | @@ -65,16 +65,16 @@ export const getAllBrandApi = (params: any) => { |
65 | 65 | return request.get<PartRepertorySpace.BrandItem[]>(`/oop/select/brand/all`, params); |
66 | 66 | }; |
67 | 67 | interface PartType{ |
68 | - value?:number | |
69 | - label?:string | |
68 | + value?: number | |
69 | + label?: string | |
70 | 70 | } |
71 | 71 | // 配件类型获取 |
72 | -export function getPartTypeApi():http.PromiseResp<PartType[]> { | |
72 | +export function getPartTypeApi(): http.PromiseResp<PartType[]> { | |
73 | 73 | return request.get(`${PMS_HOST}/app/common/get/part/types`); |
74 | 74 | } |
75 | 75 | interface UploadParams { |
76 | 76 | type?: number |
77 | - brandIds?:string | |
77 | + brandIds?: string | |
78 | 78 | file?: any |
79 | 79 | } |
80 | 80 | export function uploadApi(params: UploadParams) { |
... | ... | @@ -84,7 +84,7 @@ export interface ListV0{ |
84 | 84 | /** |
85 | 85 | * 品牌id |
86 | 86 | */ |
87 | - brandId?:number; | |
87 | + brandId?: number; | |
88 | 88 | /** |
89 | 89 | * 品牌名称 |
90 | 90 | */ |
... | ... | @@ -92,30 +92,39 @@ export interface ListV0{ |
92 | 92 | /** |
93 | 93 | * 车系id |
94 | 94 | */ |
95 | - seriesId?:number; | |
95 | + seriesId?: number; | |
96 | 96 | /** |
97 | 97 | * 车系名称 |
98 | 98 | */ |
99 | - seriesName?:string; | |
99 | + seriesName?: string; | |
100 | 100 | /** |
101 | 101 | * 车型id |
102 | 102 | */ |
103 | - modelId?:number; | |
103 | + modelId?: number; | |
104 | 104 | /** |
105 | 105 | * 车型名称 |
106 | 106 | */ |
107 | - modelName?:string; | |
107 | + modelName?: string; | |
108 | 108 | /** |
109 | 109 | * 整车型号/配置代码 |
110 | 110 | */ |
111 | - specCode?:string; | |
111 | + specCode?: string; | |
112 | 112 | } |
113 | 113 | export interface Params { |
114 | - current?:number | |
115 | - pageSize?:number | |
116 | - keywords?:string | |
117 | - brandId?:number | |
114 | + current?: number | |
115 | + pageSize?: number | |
116 | + keywords?: string | |
117 | + brandId?: number | |
118 | 118 | } |
119 | -export function getSpecList(params: Params):http.PromisePageResp<ListV0> { | |
119 | +export function getSpecList(params: Params): http.PromisePageResp<ListV0> { | |
120 | 120 | return request.get(`${PMS_HOST}/erp/spec/get/page`, { params }); |
121 | -} | |
122 | 121 | \ No newline at end of file |
122 | +} | |
123 | + | |
124 | +export interface Parttype { | |
125 | + value?: number; | |
126 | + label?: string; | |
127 | + children?: Parttype[] | |
128 | +} | |
129 | +export function getPartType(): http.PromiseResp<Parttype[]> { | |
130 | + return request.get(`${PMS_HOST}/app/common/get/part/category`, {}); | |
131 | +} | ... | ... |
src/pages/pms/part/Repertory/components/Filter.tsx
... | ... | @@ -6,14 +6,14 @@ const { Search } = Input; |
6 | 6 | const { Option } = Select; |
7 | 7 | |
8 | 8 | export default function Filter() { |
9 | - const { setParams, series, getSeries, brands, tabType, specPagination, partTypeData } = useStore(); | |
9 | + const { setParams, series, getSeries, brands, tabType, specPagination, partTypes, innerParams } = useStore(); | |
10 | 10 | const { setParams: setSpecParams } = specPagination; |
11 | 11 | |
12 | 12 | const [brandId, setBrandId] = useState<number>(); |
13 | 13 | const [factoryId, setFactoryId] = useState<number>(); |
14 | 14 | const [seriesId, setSeriesId] = useState<number>(); |
15 | 15 | |
16 | - const handleChangeBrand = (value: { keywords?: string; type?: any; brandId?: any }) => { | |
16 | + const handleChangeBrand = (value: { keywords?: string; type?: number; brandId?: number, category?: number }) => { | |
17 | 17 | const queryParams = { current: 1, ...value }; |
18 | 18 | setParams(queryParams, true); |
19 | 19 | }; |
... | ... | @@ -82,19 +82,32 @@ export default function Filter() { |
82 | 82 | <Search |
83 | 83 | allowClear |
84 | 84 | enterButton |
85 | - placeholder="请输入配件名称/编码/件号" | |
85 | + placeholder="输入配件名称/编码/件号" | |
86 | 86 | onSearch={e => handleChangeBrand({ keywords: e })} |
87 | 87 | style={{ maxWidth: 260 }} |
88 | 88 | /> |
89 | 89 | <Select |
90 | 90 | allowClear |
91 | 91 | style={{ width: 200, marginLeft: 20 }} |
92 | + onChange={(category) => handleChangeBrand({ category, type: undefined })} | |
93 | + placeholder="选择配件一级类型" | |
94 | + showSearch | |
95 | + filterOption={(input: any, option: any) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} | |
96 | + > | |
97 | + {partTypes.map(item => ( | |
98 | + <Option value={item.value} key={item.value}>{item.label}</Option> | |
99 | + ))} | |
100 | + </Select> | |
101 | + <Select | |
102 | + allowClear | |
103 | + value={innerParams.type} | |
104 | + style={{ width: 200, marginLeft: 20 }} | |
92 | 105 | onChange={(type) => handleChangeBrand({ type })} |
93 | - placeholder="请选择配件类型" | |
106 | + placeholder="选择配件类型" | |
94 | 107 | showSearch |
95 | 108 | filterOption={(input: any, option: any) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
96 | 109 | > |
97 | - {partTypeData.map((item: any) => ( | |
110 | + {(partTypes.find(i => i.value == innerParams.category)?.children || []).map((item: any) => ( | |
98 | 111 | <Option value={item.value} key={item.value}>{item.label}</Option> |
99 | 112 | ))} |
100 | 113 | </Select> | ... | ... |
src/pages/pms/part/Repertory/components/List.tsx
... | ... | @@ -25,6 +25,7 @@ export default function Filter() { |
25 | 25 | <Column title="配件名称" dataIndex="partName" /> |
26 | 26 | <Column title="规格" dataIndex="specification" /> |
27 | 27 | <Column title="单位" dataIndex="unit" /> |
28 | + <Column title="一级类型" dataIndex="categoryName" /> | |
28 | 29 | <Column title="类型" dataIndex="typeName" /> |
29 | 30 | <Column title="备件计划归属品牌" dataIndex="brandNames" /> |
30 | 31 | <Column | ... | ... |
src/pages/pms/part/Repertory/components/SavePartModal.tsx
... | ... | @@ -23,18 +23,21 @@ const formItemLayout = { |
23 | 23 | const { Option } = Select; |
24 | 24 | const { Item } = Form; |
25 | 25 | export default function SaveModal(props: Props) { |
26 | - const { brands, partTypeData } = useStore(); | |
26 | + const { brands, partTypes, partTypeData } = useStore(); | |
27 | 27 | const { visible, onCancel, fetchList, item } = props; |
28 | 28 | const [loading, setLoading] = useState(false); |
29 | 29 | const [form] = Form.useForm(); |
30 | + const [category, setCategory] = useState<any>([]); | |
30 | 31 | |
31 | 32 | useEffect(() => { |
32 | 33 | if (visible) { |
33 | 34 | form.setFieldsValue({ |
34 | 35 | ...item, |
35 | 36 | }); |
37 | + setCategory(item.category); | |
36 | 38 | } else { |
37 | 39 | form.resetFields(); |
40 | + setCategory([]); | |
38 | 41 | } |
39 | 42 | }, [visible]); |
40 | 43 | |
... | ... | @@ -63,7 +66,7 @@ export default function SaveModal(props: Props) { |
63 | 66 | <Modal |
64 | 67 | title={`${item.id ? '编辑' : '新增'}配件`} |
65 | 68 | width={600} |
66 | - visible={visible} | |
69 | + open={visible} | |
67 | 70 | maskClosable={false} |
68 | 71 | onCancel={() => onCancel()} |
69 | 72 | footer={[ |
... | ... | @@ -105,20 +108,36 @@ export default function SaveModal(props: Props) { |
105 | 108 | ))} |
106 | 109 | </Select> |
107 | 110 | </Item> |
108 | - <Item label="配件类型" name="type" required rules={[{ required: true, message: '请选择配件类型' }]}> | |
111 | + <Item label="配件一级类型" name="category" required rules={[{ required: true, message: '请选择配件一级类型' }]}> | |
109 | 112 | <Select |
110 | - placeholder="请选择配件类型" | |
113 | + placeholder="请选择配件一级类型" | |
111 | 114 | showSearch |
112 | 115 | mode="multiple" |
116 | + value={category} | |
117 | + onChange={v => setCategory(v)} | |
113 | 118 | filterOption={(input: any, option: any) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
114 | 119 | > |
115 | - {partTypeData.map((item: any) => ( | |
120 | + {partTypes.map(item => ( | |
116 | 121 | <Option value={item.value} key={item.value}> |
117 | 122 | {item.label} |
118 | 123 | </Option> |
119 | 124 | ))} |
120 | 125 | </Select> |
121 | 126 | </Item> |
127 | + <Item label="配件类型" name="type" required rules={[{ required: true, message: '请选择配件类型' }]}> | |
128 | + <Select | |
129 | + placeholder="请选择配件类型" | |
130 | + showSearch | |
131 | + mode="multiple" | |
132 | + filterOption={(input: any, option: any) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} | |
133 | + > | |
134 | + {(category.length ? (partTypes.filter(i => category.includes(i.value))?.map(it => it.children)).flat() : partTypeData).map(item => ( | |
135 | + <Option value={item?.value} key={item?.value}> | |
136 | + {item?.label} | |
137 | + </Option> | |
138 | + ))} | |
139 | + </Select> | |
140 | + </Item> | |
122 | 141 | </Form> |
123 | 142 | </Modal> |
124 | 143 | ); | ... | ... |
src/pages/pms/part/Repertory/components/UploadExcel.tsx
1 | 1 | import React, { useState } from 'react'; |
2 | 2 | import { InboxOutlined } from '@ant-design/icons'; |
3 | -import { Button, Modal, Upload, message, Select, Popconfirm } from 'antd'; | |
3 | +import { Button, Modal, Upload, message, Popconfirm } from 'antd'; | |
4 | 4 | import { useStore } from '@/pages/pms/part/Repertory'; |
5 | 5 | import _ from 'lodash'; |
6 | 6 | import { uploadApi } from '../api'; |
7 | 7 | import type { UploadFile, UploadProps } from 'antd/es/upload/interface'; |
8 | 8 | |
9 | 9 | const Dragger = Upload.Dragger; |
10 | -const { Option } = Select; | |
11 | 10 | |
12 | 11 | export default function UploadExcel() { |
13 | - const { importVisible, setImportVisible, partTypeData, brands } = useStore(); | |
12 | + const { importVisible, setImportVisible } = useStore(); | |
14 | 13 | const [fileList, setFileList] = useState<UploadFile[]>([]); |
15 | 14 | const [uploadResult, setUploadResult] = useState<any>(); |
16 | - const [type, setType] = useState(); | |
17 | - const [brandIds, setBrandIds] = useState([]); | |
18 | 15 | const [confirmLoading, setConfirmLoading] = useState(false); |
19 | 16 | |
20 | 17 | function beforeUpload(file: any) { |
21 | - if (!type) { | |
22 | - message.error('请选择配件类型'); | |
23 | - return false; | |
24 | - } | |
25 | 18 | const isLt2M = file.size / 1024 / 1024 < 20; |
26 | 19 | if (!isLt2M) { |
27 | 20 | message.error('文件不能超过20MB!'); |
... | ... | @@ -41,10 +34,9 @@ export default function UploadExcel() { |
41 | 34 | fileList, |
42 | 35 | }; |
43 | 36 | |
44 | - function handleChange(info: any) { | |
37 | + function handleChange() { | |
45 | 38 | setConfirmLoading(true); |
46 | - console.log('11', {type, brandIds: brandIds.join(','), file: fileList[0]}); | |
47 | - uploadApi({ type, brandIds: brandIds.join(','), file: fileList[0] }) | |
39 | + uploadApi({ file: fileList[0] }) | |
48 | 40 | .then((res) => { |
49 | 41 | setConfirmLoading(false); |
50 | 42 | setUploadResult(res.data); |
... | ... | @@ -62,7 +54,7 @@ export default function UploadExcel() { |
62 | 54 | |
63 | 55 | return ( |
64 | 56 | <Modal |
65 | - visible={importVisible} | |
57 | + open={importVisible} | |
66 | 58 | maskClosable={false} |
67 | 59 | title={uploadResult ? '导入结果' : '文件导入'} |
68 | 60 | onCancel={cancel} |
... | ... | @@ -87,47 +79,13 @@ export default function UploadExcel() { |
87 | 79 | > |
88 | 80 | {!uploadResult ? ( |
89 | 81 | <div style={{ display: 'flex', flexDirection: 'column' }}> |
90 | - <Select | |
91 | - style={{ width: 200, marginBottom: 20 }} | |
92 | - onChange={(value) => { | |
93 | - setType(value); | |
94 | - }} | |
95 | - placeholder="请选择配件类型" | |
96 | - showSearch | |
97 | - filterOption={(input: any, option: any) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} | |
98 | - > | |
99 | - {partTypeData.map((item: any) => ( | |
100 | - <Option value={item.value} key={item.value}> | |
101 | - {item.label} | |
102 | - </Option> | |
103 | - ))} | |
104 | - </Select> | |
105 | - <Select | |
106 | - style={{ width: 200, marginBottom: 20 }} | |
107 | - mode="multiple" | |
108 | - onChange={(value) => { | |
109 | - setBrandIds(value); | |
110 | - }} | |
111 | - placeholder="备件计划归属品牌" | |
112 | - showSearch | |
113 | - filterOption={(input: any, option: any) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} | |
114 | - > | |
115 | - {brands.map((item) => ( | |
116 | - <Option value={item.id} key={item.id}> | |
117 | - {item.name} | |
118 | - </Option> | |
119 | - ))} | |
120 | - </Select> | |
121 | - <Dragger | |
122 | - {...uploadProps} | |
123 | - // showUploadList={false} | |
124 | - // multiple | |
125 | - > | |
82 | + <Dragger {...uploadProps} style={{marginBottom: 20}}> | |
126 | 83 | <p className="ant-upload-drag-icon"> |
127 | - <InboxOutlined /> | |
84 | + <InboxOutlined rev={undefined} /> | |
128 | 85 | </p> |
129 | 86 | <p className="ant-upload-text">将文件拖到此处上传</p> |
130 | 87 | </Dragger> |
88 | + {!fileList.length && <a href="/api/pms/erp/part/template/part/import">下载配件标准导入模版</a>} | |
131 | 89 | </div> |
132 | 90 | ) : ( |
133 | 91 | <div> | ... | ... |
src/pages/pms/part/Repertory/index.tsx
1 | 1 | import React from 'react'; |
2 | 2 | import { Card, ConfigProvider, Button, Tabs } from "antd"; |
3 | -import { PlusOutlined } from '@ant-design/icons'; | |
3 | +import { UploadOutlined } from '@ant-design/icons'; | |
4 | 4 | import zhCN from "antd/lib/locale-provider/zh_CN"; |
5 | 5 | import st from "./style.less"; |
6 | 6 | import { PageHeaderWrapper } from "@ant-design/pro-layout"; |
... | ... | @@ -34,17 +34,12 @@ function RepertoryIndex() { |
34 | 34 | </div> |
35 | 35 | <div> |
36 | 36 | <Button |
37 | - icon={(<PlusOutlined />)} | |
37 | + icon={(<UploadOutlined rev={undefined} />)} | |
38 | 38 | type="primary" |
39 | 39 | onClick={() => setImportVisible(true)} |
40 | 40 | > |
41 | 41 | 导入 |
42 | 42 | </Button> |
43 | - <Button type="default" style={{ marginLeft: 10 }}> | |
44 | - <a href="/api/pms/erp/part/template/part/import"> | |
45 | - 下载模板 | |
46 | - </a> | |
47 | - </Button> | |
48 | 43 | </div> |
49 | 44 | </div> |
50 | 45 | <ImportModal /> | ... | ... |
src/pages/pms/part/Repertory/interface.d.ts
src/pages/pms/part/Repertory/store.ts
1 | 1 | import usePagination from "@/hooks/usePagination"; |
2 | 2 | import useInitail from "@/hooks/useInitail"; |
3 | -import { getPageListApi, getSpecList, getAllBrandApi, getPartTypeApi, ListV0 } from './api'; | |
3 | +import type { ListV0} from './api'; | |
4 | +import { getPageListApi, getSpecList, getAllBrandApi, getPartTypeApi, getPartType } from './api'; | |
4 | 5 | import { useState, useEffect } from 'react'; |
5 | 6 | import { getSeriesApi } from '@/common/api'; |
6 | 7 | |
7 | -let bodyEl = document.body; | |
8 | +const bodyEl = document.body; | |
8 | 9 | let top = 0; |
9 | 10 | // 当蒙层出现,固定body,不让其跟着蒙层滚动,蒙层消失,恢复其原来的位置 |
10 | 11 | function stopBodyScroll(isFixed: boolean) { |
... | ... | @@ -31,6 +32,7 @@ export default function useStore() { |
31 | 32 | const [currentInfo, setCurrentInfo] = useState<PartRepertorySpace.PartEpc>({}); |
32 | 33 | const [series, setSeries] = useState<PartRepertorySpace.SeriesItem[]>([]); |
33 | 34 | const { data: partTypeData } = useInitail(getPartTypeApi, [], {}); |
35 | + const { data: partTypes } = useInitail(getPartType, [], {}) | |
34 | 36 | |
35 | 37 | useEffect(() => { |
36 | 38 | if (epcVisible || importVisible) { |
... | ... | @@ -66,6 +68,7 @@ export default function useStore() { |
66 | 68 | setCurrentInfo, |
67 | 69 | specVisible, |
68 | 70 | setSpecVisible, |
69 | - partTypeData | |
71 | + partTypeData, | |
72 | + partTypes | |
70 | 73 | }; |
71 | 74 | } | ... | ... |
src/pages/pms/partPlan/AppointPart/comonents/PartModal.tsx
1 | 1 | import styles from '@/components/PositionSelector/index.less'; |
2 | 2 | import usePagination from '@/hooks/usePagination'; |
3 | 3 | import PmsSelect from '@/pages/pms/comonents/PmsSelect'; |
4 | -import { getPurchasePart, partItem } from '@/pages/pms/purchase/PurchaseRecord/api'; | |
4 | +import type { partItem } from '@/pages/pms/purchase/PurchaseRecord/api'; | |
5 | +import { getPurchasePart } from '@/pages/pms/purchase/PurchaseRecord/api'; | |
5 | 6 | import { PlusOutlined } from '@ant-design/icons'; |
6 | 7 | import { Input, Modal, Table } from 'antd'; |
7 | 8 | import Column from 'antd/lib/table/Column'; |
8 | 9 | import { debounce } from 'lodash'; |
9 | 10 | import React, { useEffect, useState } from 'react'; |
11 | +import { getPartTypeApi } from '@/pages/pms/part/Repertory/api'; | |
12 | +import useInitial from '@/hooks/useInitail'; | |
10 | 13 | |
11 | 14 | const Search = Input.Search; |
12 | 15 | interface Props { |
... | ... | @@ -21,22 +24,13 @@ interface Props { |
21 | 24 | onChange?: Function; |
22 | 25 | partParams?: { stId?: number; spId?: number }; |
23 | 26 | } |
24 | -const partType = [ | |
25 | - { value: 1, label: '配件' }, | |
26 | - { value: 2, label: '装潢' }, | |
27 | - { value: 4, label: '养护' }, | |
28 | - { value: 5, label: '机修辅料' }, | |
29 | - { value: 6, label: '钣金辅料' }, | |
30 | - { value: 7, label: '喷漆辅料' }, | |
31 | - { value: 8, label: '装潢辅料' }, | |
32 | - { value: 9, label: '打磨辅料' }, | |
33 | -]; | |
34 | 27 | |
35 | 28 | export default function Index({ value = { partCode: '', partName: '', price: undefined }, onChange, isclear, setIsclear, partParams }: Props) { |
36 | 29 | const [visible, setVisible] = useState<boolean>(false); |
37 | 30 | const [selectedParts, setSelectedParts] = useState(value); |
38 | 31 | const [delay, setDelay] = useState(true); |
39 | 32 | const { list, setParams, loading, paginationConfig } = usePagination<partItem>(getPurchasePart, {}, { delay }); |
33 | + const { data: partTypeData } = useInitial(getPartTypeApi, [], {}); | |
40 | 34 | |
41 | 35 | useEffect(() => { |
42 | 36 | if (visible && partParams?.spId) { |
... | ... | @@ -92,7 +86,7 @@ export default function Index({ value = { partCode: '', partName: '', price: und |
92 | 86 | setParams({ type: v }, true); |
93 | 87 | }} |
94 | 88 | style={{ width: 200 }} |
95 | - options={partType} | |
89 | + options={partTypeData} | |
96 | 90 | /> |
97 | 91 | </div> |
98 | 92 | <Table | ... | ... |
src/pages/pms/purchase/PurchaseRecord/comonents/PartModal.tsx
... | ... | @@ -7,6 +7,8 @@ import styles from '@/components/PositionSelector/index.less'; |
7 | 7 | import usePagination from '@/hooks/usePagination'; |
8 | 8 | import type { partItem } from '../api'; |
9 | 9 | import { getPurchasePart } from '../api'; |
10 | +import useInitial from '@/hooks/useInitail'; | |
11 | +import { getPartTypeApi } from '@/pages/pms/part/Repertory/api'; | |
10 | 12 | |
11 | 13 | const Search = Input.Search; |
12 | 14 | interface Props { |
... | ... | @@ -24,20 +26,11 @@ interface Props { |
24 | 26 | partParams?: { stId?: number; spId?: number }; |
25 | 27 | } |
26 | 28 | |
27 | -const partType = [ | |
28 | - { value: 1, label: '配件' }, | |
29 | - { value: 2, label: '装潢' }, | |
30 | - { value: 4, label: '养护' }, | |
31 | - { value: 5, label: '机修辅料' }, | |
32 | - { value: 6, label: '钣金辅料' }, | |
33 | - { value: 7, label: '喷漆辅料' }, | |
34 | - { value: 8, label: '装潢辅料' }, | |
35 | - { value: 9, label: '打磨辅料' }, | |
36 | -]; | |
37 | 29 | |
38 | 30 | export default function Index({ value = { partCode: '', partName: '', price: undefined }, onChange, isclear, setIsclear, partParams }: Props) { |
39 | 31 | const [visible, setVisible] = useState<boolean>(false); |
40 | 32 | const [selectedParts, setSelectedParts] = useState(value); |
33 | + const { data: partTypeData } = useInitial(getPartTypeApi, [], {}); | |
41 | 34 | const [delay, setDelay] = useState(true); |
42 | 35 | const { list, setParams, loading, paginationConfig } = usePagination<partItem>(getPurchasePart, {}, { delay }); |
43 | 36 | |
... | ... | @@ -102,7 +95,7 @@ export default function Index({ value = { partCode: '', partName: '', price: und |
102 | 95 | setParams({ type: v }, true); |
103 | 96 | }} |
104 | 97 | style={{ width: 200 }} |
105 | - options={partType} | |
98 | + options={partTypeData} | |
106 | 99 | /> |
107 | 100 | </div> |
108 | 101 | <Table | ... | ... |
src/pages/pms/storage/partShop/components/Filter.tsx
... | ... | @@ -2,7 +2,7 @@ import React from 'react'; |
2 | 2 | import { Input } from 'antd'; |
3 | 3 | import { useStore } from '../index'; |
4 | 4 | import debounce from 'lodash/debounce'; |
5 | -import { getPartTypeApi } from '@/pages/pms/part/Repertory/api'; | |
5 | +import { getPartTypeApi, getPartType } from '@/pages/pms/part/Repertory/api'; | |
6 | 6 | import useInitail from '@/hooks/useInitail'; |
7 | 7 | import PmsSelect from '@/pages/pms/comonents/PmsSelect'; |
8 | 8 | |
... | ... | @@ -10,7 +10,7 @@ const { Search } = Input; |
10 | 10 | |
11 | 11 | export default function Filter() { |
12 | 12 | const { setParams, storages, innerParams } = useStore(); |
13 | - const { data: partTypeData } = useInitail(getPartTypeApi, [], {}); | |
13 | + const { data: partTypeData } = useInitail(getPartType, [], {}); | |
14 | 14 | |
15 | 15 | const handleChangeKeywords = debounce((value: string) => { |
16 | 16 | setParams({ current: 1, keyword: value }, true); |
... | ... | @@ -44,18 +44,28 @@ export default function Filter() { |
44 | 44 | onChange={(value) => { |
45 | 45 | setParams({ current: 1, storageId: value }, true); |
46 | 46 | }} |
47 | - placeholder="请选择库房" | |
47 | + placeholder="选择库房" | |
48 | 48 | options={storages |
49 | 49 | .map(item => ({ value: item.shopId, label: item.shopShortName }))} |
50 | 50 | /> |
51 | 51 | <PmsSelect |
52 | 52 | allowClear |
53 | 53 | style={{ width: 220, marginRight: 10, marginBottom: 10 }} |
54 | + onChange={(category) => { | |
55 | + setParams({ ...innerParams, current: 1, category, type: undefined }, true); | |
56 | + }} | |
57 | + placeholder="选择配件一级类型" | |
58 | + options={partTypeData.map((item: any) => ({ value: item.value, label: item.label }))} | |
59 | + /> | |
60 | + <PmsSelect | |
61 | + allowClear | |
62 | + value={innerParams.type} | |
63 | + style={{ width: 220, marginRight: 10, marginBottom: 10 }} | |
54 | 64 | onChange={(type) => { |
55 | 65 | setParams({ ...innerParams, current: 1, type }, true); |
56 | 66 | }} |
57 | - placeholder="请选择配件类型" | |
58 | - options={partTypeData.map((item: any) => ({ value: item.value, label: item.label }))} | |
67 | + placeholder="选择配件类型" | |
68 | + options={partTypeData.find(i => i.value == innerParams.category)?.children?.map((item: any) => ({ value: item.value, label: item.label }))} | |
59 | 69 | /> |
60 | 70 | <PmsSelect |
61 | 71 | allowClear | ... | ... |
src/pages/pms/storage/partShop/components/List.tsx
... | ... | @@ -45,6 +45,7 @@ export default function Filter() { |
45 | 45 | <Column title="配件编码" dataIndex="partCode" /> |
46 | 46 | <Column title="配件名称" dataIndex="partName" /> |
47 | 47 | <Column title="规格" dataIndex="specification" /> |
48 | + <Column title="一级类型" dataIndex="categoryName" /> | |
48 | 49 | <Column title="配件类型" dataIndex="partType" /> |
49 | 50 | <Column title="加权成本价(含税)" render={(r) => (r.costPrice ? `${r.costPrice}${r.capacity ? '元/桶' : '元'}` : 0)} /> |
50 | 51 | {/* <Column title="总库存数量" dataIndex="stock" /> */} | ... | ... |
src/pages/pms/storage/partShop/components/LockDetailModal.tsx
... | ... | @@ -20,7 +20,7 @@ export default function Index({ item = {}, visible, onCancel }: Props) { |
20 | 20 | const { data, loading, setParams } = useInitail<PmsStoragePartShop.LockDetailVO[], PmsStoragePartShop.LockParams>(getLockDetail, [], {}, delay); |
21 | 21 | const [visableLoackStockModal, setVisableLoackStockModal] = useState(false); |
22 | 22 | const [row, setRow] = useState<PmsStoragePartShop.unLock>({}); |
23 | - const { fw } = useStore(); | |
23 | + const { fw, fwS } = useStore(); | |
24 | 24 | |
25 | 25 | useEffect(() => { |
26 | 26 | if (item.storageId && item.partId && visible) { |
... | ... | @@ -111,7 +111,7 @@ export default function Index({ item = {}, visible, onCancel }: Props) { |
111 | 111 | }} |
112 | 112 | /> |
113 | 113 | <Column title="锁库天数" dataIndex="days" render={(t: number) => (t || 0).toFixed(0)} /> |
114 | - {fw && <Column title="操作" render={(record) => <a onClick={() => unLock(record)}>释放库存</a>} />} | |
114 | + {fw && !fwS && <Column title="操作" render={(record) => <a onClick={() => unLock(record)}>释放库存</a>} />} | |
115 | 115 | </Table> |
116 | 116 | <LoackStockModal |
117 | 117 | row={row} | ... | ... |
src/pages/pms/storage/partShop/index.tsx
... | ... | @@ -69,9 +69,11 @@ function PartShop() { |
69 | 69 | > |
70 | 70 | 锁件批量导出 |
71 | 71 | </Button> |
72 | + {!fwS && | |
72 | 73 | <Button type="primary" onClick={() => setMore(true)} className="button"> |
73 | 74 | 库存批量导出 |
74 | 75 | </Button> |
76 | + } | |
75 | 77 | <Button type="primary" onClick={() => setStorageFlowVisible(true)} className="button"> |
76 | 78 | 库房流水导出 |
77 | 79 | </Button> | ... | ... |