Commit fd16749fb855af5a061f8659104c6f748a12ee46
1 parent
15244254
往来单位关系设置
Showing
13 changed files
with
859 additions
and
14 deletions
config/routers/finance.ts
... | ... | @@ -24,6 +24,10 @@ export default [ |
24 | 24 | component: "finance/CompanyRelationAuth", |
25 | 25 | }, |
26 | 26 | { |
27 | + path: "/finance2/companyRelationAuth/create", //往来单位关系设置==》新增 | |
28 | + component: "finance/CompanyRelationCreate", | |
29 | + }, | |
30 | + { | |
27 | 31 | path: "/finance2/specialAccountSetting/deductAccount", //划扣专用账户 |
28 | 32 | component: "./finance/SpecialAccount/DeductAccount", |
29 | 33 | }, | ... | ... |
src/pages/finance/CompanyRelationAuth/api.ts
... | ... | @@ -19,6 +19,10 @@ export interface CompanyRelationListVO { |
19 | 19 | compShortName?: string; //简称 |
20 | 20 | compType?: number[]; //类型 |
21 | 21 | compTypeName?: number; //类型 |
22 | + beforeReimburse?: boolean; //是否报销前提供发票 | |
23 | + billAmountRatio?: number; //发票要求金额比例(已扩大100倍,前端直接拼接百分号展示) | |
24 | + settleMethodNames?: string; // 支持结算方式 | |
25 | + accountCheckPeriod?: number; //对账周期,每月多少号 | |
22 | 26 | } |
23 | 27 | |
24 | 28 | /** | ... | ... |
src/pages/finance/CompanyRelationAuth/components/Filter.tsx
... | ... | @@ -4,6 +4,7 @@ import { useStore } from "../index"; |
4 | 4 | import { CompanyCategoryTypeEnum } from "@/pages/finance/entitys"; |
5 | 5 | import { debounce } from "lodash"; |
6 | 6 | import { deleteCompanyRelationApi } from '@/pages/finance/CompanyRelationAuth/api'; |
7 | +import { history } from 'umi'; | |
7 | 8 | |
8 | 9 | const Search = Input.Search; |
9 | 10 | const { Option } = Select; |
... | ... | @@ -50,8 +51,9 @@ export default function Filter() { |
50 | 51 | setDisabled(false); |
51 | 52 | } |
52 | 53 | |
54 | + // 新增 | |
53 | 55 | function onAdd() { |
54 | - setVisible(true); | |
56 | + history.push("/finance2/companyRelationAuth/create"); | |
55 | 57 | } |
56 | 58 | /** |
57 | 59 | * @param compId | ... | ... |
src/pages/finance/CompanyRelationAuth/components/SelectModal.tsx
src/pages/finance/CompanyRelationAuth/index.tsx
1 | 1 | import React from "react"; |
2 | -import { Card, Table } from "antd"; | |
2 | +import { Button, Card, Divider, message, Popconfirm, Table } from "antd"; | |
3 | 3 | import { PageHeaderWrapper } from "@ant-design/pro-layout"; |
4 | 4 | import { createStore } from "@/hooks/moz"; |
5 | 5 | import store from "./useStore"; |
6 | 6 | import SelectModal from "./components/SelectModal"; |
7 | 7 | import Filter from "./components/Filter"; |
8 | -import { CompanyRelationListVO } from "@/pages/finance/CompanyRelationAuth/api"; | |
8 | +import { CompanyRelationListVO, deleteCompanyRelationApi } from "@/pages/finance/CompanyRelationAuth/api"; | |
9 | 9 | |
10 | 10 | const { Column } = Table; |
11 | 11 | |
... | ... | @@ -15,8 +15,12 @@ function CompanyRelationAuth() { |
15 | 15 | const { |
16 | 16 | selected, |
17 | 17 | loading, |
18 | - | |
18 | + selectedRelation, | |
19 | 19 | setSelectedRelation, |
20 | + companyParams, | |
21 | + submitLoading, | |
22 | + setSubmitLoading, | |
23 | + setLoading, | |
20 | 24 | } = useStore(); |
21 | 25 | |
22 | 26 | const rowSelection = { |
... | ... | @@ -25,10 +29,34 @@ function CompanyRelationAuth() { |
25 | 29 | setSelectedRelation([...selectedRows]); |
26 | 30 | }, |
27 | 31 | getCheckboxProps: (record: CompanyRelationListVO) => ({ |
28 | - // disabled: record.name === "Disabled User", // Column configuration not to be checked | |
29 | 32 | name: String(record.compId), |
30 | 33 | }), |
31 | 34 | }; |
35 | + | |
36 | + /** | |
37 | + * @param compId | |
38 | + */ | |
39 | + async function onDelete() { | |
40 | + const compIdList = selectedRelation.map((item) => item.compId); | |
41 | + | |
42 | + try { | |
43 | + const pa = { ...companyParams, compIdList }; | |
44 | + console.log("删除", pa); | |
45 | + setSubmitLoading(true); | |
46 | + const { success, result } = await deleteCompanyRelationApi(pa); | |
47 | + setSubmitLoading(false); | |
48 | + | |
49 | + if (!success) { | |
50 | + return message.error(result); | |
51 | + } else { | |
52 | + message.success(result); | |
53 | + setLoading(true); | |
54 | + } | |
55 | + } catch (e) { | |
56 | + setSubmitLoading(false); | |
57 | + message.error(e.message); | |
58 | + } | |
59 | + } | |
32 | 60 | return ( |
33 | 61 | <PageHeaderWrapper title="往来单位关系设置"> |
34 | 62 | <Card> |
... | ... | @@ -46,17 +74,39 @@ function CompanyRelationAuth() { |
46 | 74 | <Column title="单位名称" dataIndex="compName" /> |
47 | 75 | <Column title="简称" dataIndex="compShortName" /> |
48 | 76 | <Column title="类型" dataIndex="compTypeName" /> |
49 | - {/* <Column | |
77 | + <Column title="发票要求" dataIndex="beforeReimburse" render={(before) => `支付${before ? "前" : "后"}`} /> | |
78 | + <Column title="发票金额要求比例" dataIndex="billAmountRatio" render={(ratio) => `${ratio}%`} /> | |
79 | + <Column title="支持结算方式" dataIndex="settleMethodNames" render={(way) => way || "--"} /> | |
80 | + <Column title="对账周期" dataIndex="accountCheckPeriod" render={(date) => (date ? `${date}日` : "--")} /> | |
81 | + <Column | |
50 | 82 | title="操作" |
51 | - dataIndex="compId" | |
52 | - render={(key) => ( | |
53 | - <Popconfirm title="是否删除" onConfirm={() => onDelete(key)} okText="确定" cancelText="取消"> | |
54 | - <Button type="link" danger loading={submitLoading}> | |
55 | - 删除 | |
56 | - </Button> | |
57 | - </Popconfirm> | |
83 | + align="center" | |
84 | + width="15%" | |
85 | + render={(row) => ( | |
86 | + <> | |
87 | + {/* <a | |
88 | + onClick={(e) => { | |
89 | + e.preventDefault(); | |
90 | + // editModal(row, true); | |
91 | + }} | |
92 | + > | |
93 | + 编辑 | |
94 | + </a> | |
95 | + <Divider type="vertical" /> */} | |
96 | + <Popconfirm | |
97 | + title="是否删除" | |
98 | + // onConfirm={() => onDelete(row.id)} | |
99 | + onConfirm={() => onDelete()} | |
100 | + okText="确定" | |
101 | + cancelText="取消" | |
102 | + > | |
103 | + <Button type="text" style={{ marginRight: 10 }} danger loading={submitLoading}> | |
104 | + 删除 | |
105 | + </Button> | |
106 | + </Popconfirm> | |
107 | + </> | |
58 | 108 | )} |
59 | - /> */} | |
109 | + /> | |
60 | 110 | </Table> |
61 | 111 | </Card> |
62 | 112 | <SelectModal /> | ... | ... |
src/pages/finance/CompanyRelationCreate/api.ts
0 → 100644
1 | +import { http } from "@/typing/http"; | |
2 | +import request from "@/utils/request"; | |
3 | +import { FINANCE2_HOST } from "@/utils/host"; | |
4 | + | |
5 | +type PrRes<T> = http.PromiseResp<T>; | |
6 | + | |
7 | +export interface CompanyRelationParams { | |
8 | + dealerId: number; | |
9 | + compCategory: number; | |
10 | + keywords?: string; | |
11 | + current?: number; | |
12 | + pageSize?: number; | |
13 | + companyType?: number; | |
14 | +} | |
15 | + | |
16 | +export interface CompanyRelationListVO { | |
17 | + compId?: number; | |
18 | + compName?: string; | |
19 | + compShortName?: string; //简称 | |
20 | + compType?: number[]; //类型 | |
21 | + compTypeName?: number; //类型 | |
22 | + beforeReimburse?: boolean; //是否报销前提供发票 | |
23 | + billAmountRatio?: number; //发票要求金额比例(已扩大100倍,前端直接拼接百分号展示) | |
24 | + settleMethodNames?: string; // 支持结算方式 | |
25 | + accountCheckPeriod?: number; //对账周期,每月多少号 | |
26 | +} | |
27 | + | |
28 | +/** | |
29 | + * 查询往来单位关系列表 | |
30 | + */ | |
31 | +export function getCompanyByDealerApi(params: CompanyRelationParams): PrRes<CompanyRelationListVO[]> { | |
32 | + return request.get(`${FINANCE2_HOST}/trade/company/relation/list`, { params }); | |
33 | +} | |
34 | + | |
35 | +interface SaveParams { | |
36 | + compIdList: number[]; //单位id集合 | |
37 | + dealerId: number; //商家id,必填 | |
38 | + compCategory: number; //单位类别,必填 | |
39 | +} | |
40 | + | |
41 | +/** | |
42 | + * 新增往来单位关系 | |
43 | + */ | |
44 | +export function saveCompanyRelationApi(params: SaveParams): PrRes<void> { | |
45 | + return request.post(`${FINANCE2_HOST}/trade/company/relation/save`, params); | |
46 | +} | |
47 | + | |
48 | +/** | |
49 | +* 删除往来单位关系 | |
50 | + /trade/company/relation/delete | |
51 | + */ | |
52 | +export function deleteCompanyRelationApi(params: SaveParams): PrRes<void> { | |
53 | + return request.post(`${FINANCE2_HOST}/trade/company/relation/delete`, params); | |
54 | +} | ... | ... |
src/pages/finance/CompanyRelationCreate/components/EditTagList.tsx
0 → 100644
1 | +import * as React from "react"; | |
2 | +import { Tag, Input, Tooltip } from "antd"; | |
3 | +import { PlusOutlined } from "@ant-design/icons"; | |
4 | +import { isArray } from "lodash"; | |
5 | +// import "./EditTagList.less"; | |
6 | + | |
7 | +interface Props { | |
8 | + value?: string[]; | |
9 | + onChange?: (value: string[]) => any; | |
10 | +} | |
11 | + | |
12 | +const colorArr = ["magenta", "geekblue", "cyan", "orange", "green", "lime", "gold", "volcano", "purple", "red"]; | |
13 | + | |
14 | +export default ({ value = [], onChange }: Props) => { | |
15 | + function handleClose(tag: string) { | |
16 | + const tags = value.filter((item) => item !== tag); | |
17 | + onChange && onChange(tags); | |
18 | + } | |
19 | + return ( | |
20 | + <> | |
21 | + <div style={{ borderStyle: "solid", borderColor: "#eee", padding: 5, borderWidth: 1 }}> | |
22 | + {isArray(value) && | |
23 | + value.map((tag, index) => { | |
24 | + const isLongTag = tag.length > 20; | |
25 | + const tagElem = ( | |
26 | + <Tag | |
27 | + className="edit-tag" | |
28 | + key={tag} | |
29 | + closable={value.length > 1} | |
30 | + color={colorArr[index % 10]} | |
31 | + onClose={() => handleClose(tag)} | |
32 | + > | |
33 | + <span>{isLongTag ? `${tag.slice(0, 20)}...` : tag}</span> | |
34 | + </Tag> | |
35 | + ); | |
36 | + return isLongTag ? ( | |
37 | + <Tooltip title={tag} key={tag}> | |
38 | + {tagElem} | |
39 | + </Tooltip> | |
40 | + ) : ( | |
41 | + tagElem | |
42 | + ); | |
43 | + })} | |
44 | + </div> | |
45 | + </> | |
46 | + ); | |
47 | +}; | ... | ... |
src/pages/finance/CompanyRelationCreate/components/Filter.tsx
0 → 100644
1 | +import React from "react"; | |
2 | +import { Button, Col, Popconfirm, Row, Select, Input, message } from "antd"; | |
3 | +import { useStore } from "../index"; | |
4 | +import { CompanyCategoryTypeEnum } from "@/pages/finance/entitys"; | |
5 | +import { debounce } from "lodash"; | |
6 | +import { deleteCompanyRelationApi } from '@/pages/finance/CompanyRelationAuth/api'; | |
7 | +import { history } from 'umi'; | |
8 | + | |
9 | +const Search = Input.Search; | |
10 | +const { Option } = Select; | |
11 | + | |
12 | +export default function Filter() { | |
13 | + const { | |
14 | + setVisible, | |
15 | + dealerList, | |
16 | + setCompanyParams, | |
17 | + dealerLoading, | |
18 | + disabled, | |
19 | + setDisabled, | |
20 | + setSelected, | |
21 | + companyList, | |
22 | + comBussinessList, | |
23 | + selectedRelation, | |
24 | + submitLoading, | |
25 | + setSubmitLoading, | |
26 | + companyParams, | |
27 | + setLoading, | |
28 | + } = useStore(); | |
29 | + const searchDealer = (dealerId: number) => { | |
30 | + setCompanyParams({ ...companyParams, dealerId }, true); | |
31 | + }; | |
32 | + | |
33 | + function searchType(compCategory: number) { | |
34 | + setCompanyParams({ ...companyParams, compCategory }, true); | |
35 | + } | |
36 | + | |
37 | + function searchCompanyType(companyType: number) { | |
38 | + setCompanyParams({ ...companyParams, companyType }, true); | |
39 | + } | |
40 | + | |
41 | + const fetchListByName = debounce((value) => { | |
42 | + setCompanyParams({ ...companyParams, keywords: value }, true); | |
43 | + }, 500); | |
44 | + | |
45 | + function onCancel() { | |
46 | + setDisabled(true); | |
47 | + setSelected([...companyList]); | |
48 | + } | |
49 | + | |
50 | + function onEdit() { | |
51 | + setDisabled(false); | |
52 | + } | |
53 | + | |
54 | + // 新增 | |
55 | + function onAdd() { | |
56 | + history.push("/finance2/companyRelationAuth/create"); | |
57 | + } | |
58 | + /** | |
59 | + * @param compId | |
60 | + */ | |
61 | + async function onDelete() { | |
62 | + const compIdList = selectedRelation.map((item) => item.compId); | |
63 | + try { | |
64 | + const pa = { ...companyParams, compIdList}; | |
65 | + setSubmitLoading(true); | |
66 | + const { success, result } = await deleteCompanyRelationApi(pa); | |
67 | + setSubmitLoading(false); | |
68 | + | |
69 | + if (!success) { | |
70 | + return message.error(result); | |
71 | + } else { | |
72 | + message.success(result); | |
73 | + setLoading(true); | |
74 | + } | |
75 | + } catch (e) { | |
76 | + setSubmitLoading(false); | |
77 | + message.error(e.message); | |
78 | + } | |
79 | + } | |
80 | + | |
81 | + return ( | |
82 | + <div | |
83 | + style={{ | |
84 | + display: "flex", | |
85 | + flexDirection: "row", | |
86 | + justifyContent: "space-between", | |
87 | + alignItems: "center", | |
88 | + marginBottom: 20, | |
89 | + }} | |
90 | + > | |
91 | + <Row style={{ display: "flex", flex: 1 }}> | |
92 | + <Col span={9}> | |
93 | + <Select | |
94 | + placeholder="请选择商家" | |
95 | + showSearch | |
96 | + loading={dealerLoading} | |
97 | + disabled={!disabled} | |
98 | + optionFilterProp="children" | |
99 | + onChange={searchDealer} | |
100 | + value={companyParams.dealerId} | |
101 | + style={{ width: "80%" }} | |
102 | + > | |
103 | + {dealerList.map((dealer) => ( | |
104 | + <Option value={dealer.id} key={dealer.id}> | |
105 | + {dealer.name} | |
106 | + </Option> | |
107 | + ))} | |
108 | + </Select> | |
109 | + </Col> | |
110 | + <Col span={5}> | |
111 | + <Search | |
112 | + allowClear | |
113 | + disabled={!disabled} | |
114 | + placeholder="搜索单位名称" | |
115 | + onChange={(e) => fetchListByName(e.target.value || undefined)} | |
116 | + style={{ width: 200 }} | |
117 | + /> | |
118 | + </Col> | |
119 | + <Col span={3}> | |
120 | + <Select | |
121 | + placeholder="搜索单位类别" | |
122 | + disabled={!disabled} | |
123 | + onChange={searchType} | |
124 | + value={companyParams.compCategory} | |
125 | + style={{ width: 100 }} | |
126 | + > | |
127 | + {[1, 2].map((i) => ( | |
128 | + <Option value={i} key={i}> | |
129 | + {CompanyCategoryTypeEnum[i]} | |
130 | + </Option> | |
131 | + ))} | |
132 | + </Select> | |
133 | + </Col> | |
134 | + <Col> | |
135 | + <Select placeholder="搜索类型" disabled={!disabled} onChange={searchCompanyType} style={{ width: 150 }}> | |
136 | + {comBussinessList.map((item) => ( | |
137 | + <Option key={item.id} value={item.id}> | |
138 | + {item.name} | |
139 | + </Option> | |
140 | + ))} | |
141 | + </Select> | |
142 | + </Col> | |
143 | + </Row> | |
144 | + <div style={{ display: "flex", flexDirection: "row-reverse" }}> | |
145 | + <Button type="primary" onClick={onAdd}> | |
146 | + 新增 | |
147 | + </Button> | |
148 | + | |
149 | + <Popconfirm title="确定删除?" onConfirm={onDelete}> | |
150 | + <Button style={{marginRight:10}} hidden={!selectedRelation.length} danger loading={submitLoading}> | |
151 | + 删除 | |
152 | + </Button> | |
153 | + </Popconfirm> | |
154 | + </div> | |
155 | + </div> | |
156 | + ); | |
157 | +} | ... | ... |
src/pages/finance/CompanyRelationCreate/components/RelationshipSettings.tsx
0 → 100644
1 | +import React, { useState, useEffect, memo } from "react"; | |
2 | +import { | |
3 | + Modal, | |
4 | + Table, | |
5 | + Select, | |
6 | + Input, | |
7 | + message, | |
8 | + Spin, | |
9 | + Form, | |
10 | + Divider, | |
11 | + Space, | |
12 | + Typography, | |
13 | + Button, | |
14 | + InputNumber, | |
15 | +} from "antd"; | |
16 | +import Column from "antd/lib/table/Column"; | |
17 | +import { RecordStateEnum } from "@/pages/finance/entitys"; | |
18 | +import usePagination from "@/hooks/usePagination"; | |
19 | +import { getCompAccountApi } from "@/pages/finance/TradeCompany/api"; | |
20 | +import { useStore } from "../index"; | |
21 | +import { saveCompanyRelationApi } from "@/pages/finance/CompanyRelationAuth/api"; | |
22 | +import { each } from "lodash"; | |
23 | +import EditTagList from "./EditTagList"; | |
24 | +import { invoiceRequirements, payWay } from "@/pages/finance/CompanyRelationCreate/entity"; | |
25 | + | |
26 | +const { Option } = Select; | |
27 | + | |
28 | +interface Props { | |
29 | + onPrevious?: () => void; | |
30 | +} | |
31 | + | |
32 | +function SelectModal({ onPrevious }: Props) { | |
33 | + const [form] = Form.useForm(); | |
34 | + const { | |
35 | + visible, | |
36 | + selected, | |
37 | + setVisible, | |
38 | + companyParams, | |
39 | + comBussinessList, | |
40 | + comBussinessLoading, | |
41 | + setDisabled, | |
42 | + setLoading, | |
43 | + selectData, | |
44 | + setSelectData, | |
45 | + } = useStore(); | |
46 | + const [submitLoading, setSubmitLoading] = useState(false); | |
47 | + | |
48 | + useEffect(() => { | |
49 | + const formDate = transFormData(selectData); | |
50 | + form.setFieldsValue({ ...formDate }); | |
51 | + }, [selectData]); | |
52 | + | |
53 | + function transFormData(originData: TradeCompany.ComList[]) { | |
54 | + let res = {}; | |
55 | + const comp = originData.map((it) => it.compName); | |
56 | + res.comp = comp; | |
57 | + return res; | |
58 | + } | |
59 | + | |
60 | + // function onSubmit(selectedData: any[]) { | |
61 | + // if (!selectedData.length) { | |
62 | + // return message.info("请先选择往来单位"); | |
63 | + // } | |
64 | + // setSubmitLoading(true); | |
65 | + // saveCompanyRelationApi({ | |
66 | + // dealerId: companyParams.dealerId, | |
67 | + // compCategory: companyParams.compCategory, | |
68 | + // compIdList: selectedData.map((item) => item.id!), | |
69 | + // }) | |
70 | + // .then((res) => { | |
71 | + // message.success("保存成功"); | |
72 | + // setLoading(true); | |
73 | + // setSubmitLoading(false); | |
74 | + // setDisabled(true); | |
75 | + // onCancel(); | |
76 | + // }) | |
77 | + // .catch((e) => { | |
78 | + // setSubmitLoading(false); | |
79 | + // message.error(e.message); | |
80 | + // }); | |
81 | + // } | |
82 | + | |
83 | + function onCancel() { | |
84 | + setVisible(false); | |
85 | + setSelectData([]); | |
86 | + } | |
87 | + | |
88 | + // 保存 | |
89 | + function _onOk(formValues:any) { | |
90 | + console.log("表单数据", formValues); | |
91 | + } | |
92 | + return ( | |
93 | + <> | |
94 | + <Form | |
95 | + form={form} | |
96 | + labelCol={{ | |
97 | + xs: { span: 24 }, | |
98 | + sm: { span: 8 }, | |
99 | + md: { span: 6 }, | |
100 | + }} | |
101 | + wrapperCol={{ | |
102 | + xs: { span: 24 }, | |
103 | + sm: { span: 10 }, | |
104 | + md: { span: 15 }, | |
105 | + }} | |
106 | + onFinish={_onOk} | |
107 | + > | |
108 | + <Form.Item label="往来单位" name="comp"> | |
109 | + <EditTagList /> | |
110 | + </Form.Item> | |
111 | + <Form.Item label="发票要求" name="beforeReimburse" rules={[{ required: true, message: "请选择发票要求" }]}> | |
112 | + <Select placeholder="请选择发票要求"> | |
113 | + {invoiceRequirements.map((item) => ( | |
114 | + <Option key={item.value} value={item.value}> | |
115 | + {item.label} | |
116 | + </Option> | |
117 | + ))} | |
118 | + </Select> | |
119 | + </Form.Item> | |
120 | + <Form.Item | |
121 | + label="发票金额要求比例" | |
122 | + name="billAmountRatio" | |
123 | + rules={[{ required: true, message: "请输入发票金额要求比例" }]} | |
124 | + > | |
125 | + <InputNumber | |
126 | + min={0} | |
127 | + max={100} | |
128 | + style={{ width: "100%" }} | |
129 | + formatter={(value) => `${value}%`} | |
130 | + parser={(value) => value!.replace("%", "")} | |
131 | + /> | |
132 | + </Form.Item> | |
133 | + <Form.Item label="支持结算方式" name="settleMethods" rules={[{ required: true, message: "请选择结算方式" }]}> | |
134 | + <Select placeholder="请选择结算方式"> | |
135 | + {payWay.map((item) => ( | |
136 | + <Option key={item.value} value={item.value}> | |
137 | + {item.label} | |
138 | + </Option> | |
139 | + ))} | |
140 | + </Select> | |
141 | + </Form.Item> | |
142 | + <Form.Item label="对账周期" name="accountCheckPeriod" rules={[{ required: true, message: "请输入对账周期" }]}> | |
143 | + <InputNumber | |
144 | + addonBefore="每月" | |
145 | + placeholder="请输入" | |
146 | + min={1} | |
147 | + precision={0} | |
148 | + max={31} | |
149 | + addonAfter="日" | |
150 | + style={{ width: "100%" }} | |
151 | + /> | |
152 | + </Form.Item> | |
153 | + </Form> | |
154 | + <div style={{ width: "100%", textAlign: "center", marginTop: 30 }}> | |
155 | + <Button type="primary" style={{ marginBottom: 10 }} onClick={() => history.back()}> | |
156 | + 返回列表 | |
157 | + </Button> | |
158 | + <Divider type="vertical" /> | |
159 | + <Button | |
160 | + type="primary" | |
161 | + style={{ marginBottom: 10 }} | |
162 | + onClick={() => { | |
163 | + const comp = form.getFieldValue("comp"); | |
164 | + const _selectData = selectData.filter((item) => comp.find((it) => it === item.compName)); | |
165 | + | |
166 | + setSelectData(_selectData); | |
167 | + onPrevious && onPrevious(); | |
168 | + }} | |
169 | + > | |
170 | + 返回上一步 | |
171 | + </Button> | |
172 | + <Divider type="vertical" /> | |
173 | + <Button type="primary" style={{ marginBottom: 10 }} onClick={() => form.submit()}> | |
174 | + 保存 | |
175 | + </Button> | |
176 | + </div> | |
177 | + </> | |
178 | + ); | |
179 | +} | |
180 | + | |
181 | +export default memo(SelectModal); | ... | ... |
src/pages/finance/CompanyRelationCreate/components/SelectCorrespondenceUnits.tsx
0 → 100644
1 | +import React, { useState, useEffect, memo } from "react"; | |
2 | +import { Modal, Table, Select, Input, message, Spin, Button, Divider } from "antd"; | |
3 | +import Column from "antd/lib/table/Column"; | |
4 | +import { RecordStateEnum } from "@/pages/finance/entitys"; | |
5 | +import usePagination from "@/hooks/usePagination"; | |
6 | +import { getCompAccountApi } from "@/pages/finance/TradeCompany/api"; | |
7 | +import { useStore } from "../index"; | |
8 | +import { debounce } from "lodash"; | |
9 | +import { saveCompanyRelationApi } from "@/pages/finance/CompanyRelationAuth/api"; | |
10 | + | |
11 | +interface Props { | |
12 | + onNext?: () => void; | |
13 | +} | |
14 | + | |
15 | +function SelectModal({ onNext }: Props) { | |
16 | + const { | |
17 | + visible, | |
18 | + selected, | |
19 | + setVisible, | |
20 | + companyParams, | |
21 | + comBussinessList, | |
22 | + comBussinessLoading, | |
23 | + setDisabled, | |
24 | + setLoading, | |
25 | + selectData, | |
26 | + setSelectData, | |
27 | + } = useStore(); | |
28 | + const [submitLoading, setSubmitLoading] = useState(false); | |
29 | + | |
30 | + const [delay, setDelay] = useState<boolean>(true); | |
31 | + // const [selectData, setSelectData] = useState<TradeCompany.ComList[]>([]); | |
32 | + | |
33 | + const { | |
34 | + list: compList, | |
35 | + loading, | |
36 | + paginationConfig, | |
37 | + setParams, | |
38 | + innerParams, | |
39 | + // } = usePagination<TradeCompany.ComList>(getCompAccountApi, { recordState: RecordStateEnum["已备案"] }, { delay }); | |
40 | + } = usePagination<TradeCompany.ComList>(getCompAccountApi, { | |
41 | + compCategory: companyParams.compCategory, | |
42 | + excludeDealerId: companyParams.dealerId, | |
43 | + }); | |
44 | + | |
45 | + const fetchListByName = debounce((value) => { | |
46 | + setParams({ ...innerParams, keywords: value }, true); | |
47 | + }, 500); | |
48 | + | |
49 | + function searchType(compTypes: number) { | |
50 | + setParams({ compTypes }, true); | |
51 | + } | |
52 | + | |
53 | + function handSave() { | |
54 | + const res = onSubmit(selectData); | |
55 | + if (res) { | |
56 | + onCancel(); | |
57 | + } | |
58 | + } | |
59 | + | |
60 | + function onSubmit(selectedData: any[]) { | |
61 | + if (!selectedData.length) { | |
62 | + return message.info("请先选择往来单位"); | |
63 | + } | |
64 | + setSubmitLoading(true); | |
65 | + saveCompanyRelationApi({ | |
66 | + dealerId: companyParams.dealerId, | |
67 | + compCategory: companyParams.compCategory, | |
68 | + compIdList: selectedData.map((item) => item.id!), | |
69 | + }) | |
70 | + .then((res) => { | |
71 | + message.success("保存成功"); | |
72 | + setLoading(true); | |
73 | + setSubmitLoading(false); | |
74 | + setDisabled(true); | |
75 | + onCancel(); | |
76 | + }) | |
77 | + .catch((e) => { | |
78 | + setSubmitLoading(false); | |
79 | + message.error(e.message); | |
80 | + }); | |
81 | + } | |
82 | + function onCancel() { | |
83 | + setVisible(false); | |
84 | + setSelectData([]); | |
85 | + } | |
86 | + | |
87 | + return ( | |
88 | + <> | |
89 | + <div style={{ display: "flex", flexDirection: "row", marginBottom: 20 }}> | |
90 | + <Input.Search | |
91 | + allowClear | |
92 | + placeholder="搜索单位名称/社会信用代码" | |
93 | + onChange={(e) => fetchListByName(e.target.value || undefined)} | |
94 | + style={{ width: 250, marginRight: 10 }} | |
95 | + /> | |
96 | + <Select | |
97 | + placeholder="搜索业务类型" | |
98 | + showSearch | |
99 | + allowClear | |
100 | + optionFilterProp="children" | |
101 | + loading={comBussinessLoading} | |
102 | + onChange={searchType} | |
103 | + style={{ width: 200 }} | |
104 | + > | |
105 | + {comBussinessList.map((item) => ( | |
106 | + <Select.Option key={item.id} value={item.id}> | |
107 | + {item.name} | |
108 | + </Select.Option> | |
109 | + ))} | |
110 | + </Select> | |
111 | + </div> | |
112 | + | |
113 | + <Table | |
114 | + loading={loading} | |
115 | + dataSource={compList} | |
116 | + pagination={{ ...paginationConfig, showSizeChanger: false }} | |
117 | + rowKey="id" | |
118 | + rowSelection={{ | |
119 | + type: "checkbox", | |
120 | + selectedRowKeys: selectData.map((row) => row.id as number), | |
121 | + onSelect: (row: any, _selected: boolean) => { | |
122 | + const index = selectData.findIndex((_row) => _row.id == row.id); | |
123 | + if (_selected) { | |
124 | + selectData.unshift(row); | |
125 | + } else if (index > -1) { | |
126 | + selectData.splice(index, 1); | |
127 | + } | |
128 | + setSelectData([...selectData]); | |
129 | + }, | |
130 | + onSelectAll: (selected, selectedRows, changeRows) => { | |
131 | + const changedKeys = changeRows.map((row) => row.id); | |
132 | + let newData = []; | |
133 | + // 全选 | |
134 | + if (selected) { | |
135 | + // 过滤掉已选的 | |
136 | + newData = selectData.concat(changeRows.filter((row) => !selectData.some((item) => item == row.id))); | |
137 | + } else { | |
138 | + // 全不选 - 去掉已选的 | |
139 | + newData = selectData.filter((row) => !changedKeys.find((y) => y === row.id)); | |
140 | + } | |
141 | + setSelectData(newData); | |
142 | + }, | |
143 | + }} | |
144 | + > | |
145 | + <Column title="账户名称" dataIndex="compName" /> | |
146 | + <Column title="业务类型" dataIndex="compTypeName" /> | |
147 | + <Column title="社会信用代码" dataIndex="creditCode" width="15%" /> | |
148 | + </Table> | |
149 | + <div style={{ width: "100%", textAlign: "center", marginTop: 30 }}> | |
150 | + <Button type="primary" style={{ marginBottom: 10 }} onClick={() => history.back()}> | |
151 | + 返回列表 | |
152 | + </Button> | |
153 | + | |
154 | + {!!selectData.length && ( | |
155 | + <> | |
156 | + <Divider type="vertical" /> | |
157 | + <Button | |
158 | + type="primary" | |
159 | + style={{ marginBottom: 10 }} | |
160 | + onClick={() => { | |
161 | + onNext && onNext(); | |
162 | + }} | |
163 | + > | |
164 | + 下一步 | |
165 | + </Button> | |
166 | + </> | |
167 | + )} | |
168 | + </div> | |
169 | + </> | |
170 | + ); | |
171 | +} | |
172 | + | |
173 | +export default memo(SelectModal); | ... | ... |
src/pages/finance/CompanyRelationCreate/entity.ts
0 → 100644
1 | +// 发票要求 1:支付前 2:支付后 | |
2 | +export const invoiceRequirements = [ | |
3 | + { | |
4 | + label: "支付前", | |
5 | + value: 1, | |
6 | + }, | |
7 | + { | |
8 | + label: "支付后", | |
9 | + value: 2, | |
10 | + }, | |
11 | +]; | |
12 | + | |
13 | +export enum RequirementsTypeEnum { | |
14 | + "支付前" = 1, | |
15 | + "支付后", | |
16 | +} | |
17 | + | |
18 | +// 往来单位支付方式 | |
19 | +export const payWay = [ | |
20 | + { label: "即时支付", value: 1 }, | |
21 | + { label: "周期支付", value: 2 }, | |
22 | + { label: "员工垫付", value: 3 }, | |
23 | +]; | |
24 | + | |
25 | + export enum PayWayEnum { | |
26 | + "即时支付" = 1, | |
27 | + "周期支付", | |
28 | + "员工垫付", | |
29 | + } | ... | ... |
src/pages/finance/CompanyRelationCreate/index.tsx
0 → 100644
1 | +import React, { useState } from "react"; | |
2 | +import { Button, Card, Divider, message, Popconfirm, Steps, Table, Tabs } from "antd"; | |
3 | +import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
4 | +import { createStore } from "@/hooks/moz"; | |
5 | +import store from "./useStore"; | |
6 | +import Filter from "./components/Filter"; | |
7 | +import SelectCorrespondenceUnits from "./components/SelectCorrespondenceUnits"; | |
8 | +import RelationshipSettings from "./components/RelationshipSettings"; | |
9 | +import { CompanyRelationListVO, deleteCompanyRelationApi } from "@/pages/finance/CompanyRelationAuth/api"; | |
10 | + | |
11 | +const { Column } = Table; | |
12 | +const { TabPane } = Tabs; | |
13 | + | |
14 | +export const { Provider, useStore } = createStore(store); | |
15 | + | |
16 | +function CompanyRelationAuth() { | |
17 | + const { Step } = Steps; | |
18 | + const [current, setCurrent] = useState<number>(0); | |
19 | + const { | |
20 | + selected, | |
21 | + loading, | |
22 | + selectedRelation, | |
23 | + setSelectedRelation, | |
24 | + companyParams, | |
25 | + submitLoading, | |
26 | + setSubmitLoading, | |
27 | + setLoading, | |
28 | + } = useStore(); | |
29 | + | |
30 | + const rowSelection = { | |
31 | + onChange: (selectedRowKeys: React.Key[], selectedRows: CompanyRelationListVO[]) => { | |
32 | + setSelectedRelation([...selectedRows]); | |
33 | + }, | |
34 | + getCheckboxProps: (record: CompanyRelationListVO) => ({ | |
35 | + name: String(record.compId), | |
36 | + }), | |
37 | + }; | |
38 | + | |
39 | + return ( | |
40 | + <PageHeaderWrapper title="往来单位关系设置"> | |
41 | + <Card> | |
42 | + <Steps type="navigation" current={current} className="site-navigation-steps"> | |
43 | + <Step title="选择往来单位" /> | |
44 | + <Step title="关系设置" /> | |
45 | + </Steps> | |
46 | + <Tabs | |
47 | + style={{ marginTop: 40 }} | |
48 | + activeKey={String(current)} | |
49 | + tabBarStyle={{ display: "hidden" }} | |
50 | + renderTabBar={() => <div />} | |
51 | + > | |
52 | + <TabPane key="0"> | |
53 | + <SelectCorrespondenceUnits onNext={() => setCurrent(current + 1)} /> | |
54 | + </TabPane> | |
55 | + <TabPane key="1"> | |
56 | + <RelationshipSettings onPrevious={() => setCurrent(0)} /> | |
57 | + </TabPane> | |
58 | + </Tabs> | |
59 | + </Card> | |
60 | + </PageHeaderWrapper> | |
61 | + ); | |
62 | +} | |
63 | + | |
64 | +export default () => ( | |
65 | + <Provider> | |
66 | + <CompanyRelationAuth /> | |
67 | + </Provider> | |
68 | +); | ... | ... |
src/pages/finance/CompanyRelationCreate/useStore.ts
0 → 100644
1 | +import { useState, useEffect } from "react"; | |
2 | +import useInitial from "@/hooks/useInitail"; | |
3 | +import { getDealerApi } from "@/common/api"; | |
4 | +import { getCompanyByDealerApi, CompanyRelationParams, CompanyRelationListVO, saveCompanyRelationApi } from "./api"; | |
5 | +import { CompanyCategoryTypeEnum } from "@/pages/finance/entitys"; | |
6 | +import { message } from "antd"; | |
7 | +import { getCompanyBusinessTypesApi } from "@/pages/finance/TradeCompany/api"; | |
8 | + | |
9 | +export default function useStore() { | |
10 | + const [delay, setDelay] = useState<boolean>(true); | |
11 | + const [disabled, setDisabled] = useState<boolean>(true); | |
12 | + const [visible, setVisible] = useState(false); | |
13 | + const [submitLoading, setSubmitLoading] = useState(false); | |
14 | + const [selectData, setSelectData] = useState<TradeCompany.ComList[]>([]); | |
15 | + // 存储已选关系,用于批量删除 | |
16 | + const [selectedRelation, setSelectedRelation] = useState<CompanyRelationListVO[]>([]); | |
17 | + | |
18 | + /** 商家下往来单位列表 */ | |
19 | + const { | |
20 | + data: companyList, | |
21 | + setParams: setCompanyParams, | |
22 | + setLoading, | |
23 | + loading, | |
24 | + params: companyParams, | |
25 | + } = useInitial<CompanyRelationListVO[], CompanyRelationParams>( | |
26 | + getCompanyByDealerApi, | |
27 | + [], | |
28 | + { compCategory: CompanyCategoryTypeEnum["供应商"], dealerId: -1 }, | |
29 | + delay | |
30 | + ); | |
31 | + // 商家的列表 | |
32 | + const { data: dealerList, loading: dealerLoading } = useInitial(getDealerApi, [], {}); | |
33 | + // 往来单位业务类型列表 | |
34 | + const { data: comBussinessList, loading: comBussinessLoading } = useInitial(getCompanyBusinessTypesApi, [], null); | |
35 | + | |
36 | + const [selected, setSelected] = useState<CompanyRelationListVO[]>([]); | |
37 | + | |
38 | + useEffect(() => { | |
39 | + if (dealerList.length) { | |
40 | + setDelay(false); | |
41 | + setCompanyParams({ ...companyParams, dealerId: dealerList[0].id }, true); //因为usePagination 未支持 delay变为false后还需手动刷新接口 | |
42 | + } else { | |
43 | + !dealerLoading && message.warning("没有授权商家,无法查看数据"); | |
44 | + } | |
45 | + }, [dealerList, dealerLoading]); | |
46 | + | |
47 | + useEffect(() => { | |
48 | + setSelected([...companyList]); | |
49 | + }, [companyList]); | |
50 | + | |
51 | + return { | |
52 | + selectData, | |
53 | + setSelectData, | |
54 | + companyList, | |
55 | + visible, | |
56 | + setVisible, | |
57 | + setCompanyParams, | |
58 | + companyParams, | |
59 | + dealerList, | |
60 | + setLoading, | |
61 | + loading, | |
62 | + dealerLoading, | |
63 | + disabled, | |
64 | + setDisabled, | |
65 | + selected, | |
66 | + setSelected, | |
67 | + submitLoading, | |
68 | + setSubmitLoading, | |
69 | + comBussinessList, | |
70 | + comBussinessLoading, | |
71 | + selectedRelation, | |
72 | + setSelectedRelation, | |
73 | + }; | |
74 | +} | ... | ... |