Commit ea25ffa7e7c00ec965545803815f6d94025b3f8c

Authored by 王强
2 parents 6b41ff10 ad36aacd

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 &#39;./components/SpecModal&#39;;
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
  1 +.clickableRow {
  2 + cursor: pointer;
  3 +}
0 4 \ No newline at end of file
... ...
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
... ... @@ -19,7 +19,7 @@ export const { Provider, useStore } = createStore(store);
19 19  
20 20 function PaymentApplicationPaymentConfig() {
21 21 return (
22   - <PageHeaderWrapper title="事项申请款项配置">
  22 + <PageHeaderWrapper title="付款申请款项配置">
23 23 <Card>
24 24 <Filter />
25 25 <ListAccount />
... ...
src/pages/finance/PaymentAllocation/index.tsx
1 1 /*
2 2 * @Author: zhaofeng 1272190090@qq.com
3   - * @Date: 2023-08-04 09:51:24
  3 + * @Date: 2023-08-04 09:51:24
4 4 * @LastEditors: zhaofeng 1272190090@qq.com
5 5 * @LastEditTime: 2023-11-08 15:27:09
6 6 * @FilePath: \fw-cms\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 &#39;lodash&#39;;
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) =&gt; {
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
... ... @@ -37,6 +37,7 @@ declare namespace PartRepertorySpace {
37 37 capacity?: number; //容量(单位L/桶)
38 38 residueCnt?: number; //按照容量出库后单桶剩余容量,排除stock外的数量
39 39 lockResidueCnt?: number;
  40 + category?: number[];
40 41 }
41 42  
42 43 /** 车型列表 */
... ...
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: &#39;&#39;, partName: &#39;&#39;, 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 &#39;@/components/PositionSelector/index.less&#39;;
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: &#39;&#39;, partName: &#39;&#39;, 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 &#39;react&#39;;
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>
... ...