Commit c1417ae61b1dded3c177f570c020a34493ab9b2b
Merge remote-tracking branch 'origin/master' into kpiFirstInd
Showing
34 changed files
with
1885 additions
and
171 deletions
config/config.ts
... | ... | @@ -38,6 +38,16 @@ export default defineConfig({ |
38 | 38 | manifest: { |
39 | 39 | basePath: '/', |
40 | 40 | }, |
41 | + headScripts: | |
42 | + (REACT_APP_ENV || 'dev') === 'prod' && process.env.NODE_ENV == 'production' | |
43 | + ? [ | |
44 | + `(function(c,l,a,r,i,t,y){ | |
45 | + c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)}; | |
46 | + t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i; | |
47 | + y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y); | |
48 | + })(window, document, "clarity", "script", "lc90bxidj2");`, | |
49 | + ] | |
50 | + : [], | |
41 | 51 | base: '/', |
42 | 52 | hash: process.env.NODE_ENV != 'development', |
43 | 53 | history: { | ... | ... |
config/routers/finance.ts
... | ... | @@ -23,6 +23,20 @@ export default [ |
23 | 23 | path: '/finance2/companyRelationAuth', //往来单位关系设置 |
24 | 24 | component: 'finance/CompanyRelationAuth', |
25 | 25 | }, |
26 | + /** | |
27 | + * 往来单位设置,往来单位关系设置增加只读菜单 | |
28 | + */ | |
29 | + { | |
30 | + path: '/finance2/ViewTradeCompany', // 查询往来单位设置 | |
31 | + component: 'finance/ViewTradeCompany', | |
32 | + }, | |
33 | + { | |
34 | + path: '/finance2/ViewCompanyRelationAuth', //查询往来单位关系设置 | |
35 | + component: 'finance/ViewCompanyRelationAuth', | |
36 | + }, | |
37 | + | |
38 | + | |
39 | + | |
26 | 40 | { |
27 | 41 | path: '/finance2/companyRelationAuth/create', //往来单位关系设置==》新增 |
28 | 42 | component: 'finance/CompanyRelationCreate', | ... | ... |
src/pages/approval/ApprovalSetting/api.ts
1 | 1 | import request from '@/utils/request'; |
2 | 2 | import type { http } from '@/typing/http'; |
3 | 3 | import { Approval_HOST, OA_HOST, OFFICE } from '@/utils/host'; |
4 | +import type { Pagination } from '@/typing/common'; | |
4 | 5 | |
5 | 6 | /** |
6 | 7 | * 审批配置分页列表 |
... | ... | @@ -69,6 +70,6 @@ export function getOfficeWordTypes(): http.PromiseResp<CommonApi.ShopRpTypeVO[]> |
69 | 70 | /** |
70 | 71 | * 查询所有合同类型列表 |
71 | 72 | */ |
72 | -export function getContractTypes(): http.PromisePageResp<CommonApi.ShopRpTypeVO> { | |
73 | - return request.get(`${OA_HOST}/contract/erp/contract/type/page`); | |
73 | +export function getContractTypes(params: Pagination): http.PromisePageResp<CommonApi.ShopRpTypeVO> { | |
74 | + return request.get(`${OA_HOST}/contract/erp/contract/type/page`, { params }); | |
74 | 75 | } | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/ContractTypeSelector.tsx
... | ... | @@ -22,7 +22,7 @@ export const ContractTypeSelector = ({ visible, index, item, readOnly, onChange |
22 | 22 | useEffect(() => { |
23 | 23 | if (visible) { |
24 | 24 | setDelay(false); |
25 | - setParams({ pageSize: 1000, canEditName: true }, true); | |
25 | + setParams({ pageSize: 1000 }, true); | |
26 | 26 | } |
27 | 27 | }, [visible]); |
28 | 28 | ... | ... |
src/pages/attendance/Attend/subpages/SpecialFestivals/components/SaveModal.tsx
1 | 1 | import React, { useState, useEffect, useRef } from 'react'; |
2 | 2 | import { Button, message, Modal, Select, Form, Input, DatePicker, Radio } from 'antd'; |
3 | +import type { RadioChangeEvent } from 'antd'; | |
3 | 4 | import { saveApi, getNationality, fetchPostList } from '../api'; |
4 | 5 | import useInitail from '@/hooks/useInitail'; |
5 | 6 | import { TimeTypeData, StaffRangeData, SexRangeData, TimeTypeEnum } from '@/pages/attendance/entity'; |
... | ... | @@ -44,6 +45,7 @@ export default function SaveModal(props: Props) { |
44 | 45 | if (visible) { |
45 | 46 | form.setFieldsValue({ |
46 | 47 | ...item, |
48 | + type: 1, | |
47 | 49 | }); |
48 | 50 | } else { |
49 | 51 | form.resetFields(); |
... | ... | @@ -84,7 +86,6 @@ export default function SaveModal(props: Props) { |
84 | 86 | setParams({ pageSize: page.current }, true); |
85 | 87 | } |
86 | 88 | }; |
87 | - | |
88 | 89 | return ( |
89 | 90 | <Modal |
90 | 91 | title={`${item.id ? '编辑' : '新增'}特殊节日`} |
... | ... | @@ -111,53 +112,78 @@ export default function SaveModal(props: Props) { |
111 | 112 | <Item name="type" label="特殊日类型" rules={[{ required: true, message: '请选择特殊日类型' }]}> |
112 | 113 | <Radio.Group> |
113 | 114 | {/* <Radio value={20}>上班日</Radio> */} |
114 | - <Radio value={60}>休息日</Radio> | |
115 | + <Radio value={1} key={1}>休息日</Radio> | |
116 | + <Radio value={2} key={2}>固定日任选半天</Radio> | |
117 | + <Radio value={3} key={3}>月中任选半天</Radio> | |
115 | 118 | </Radio.Group> |
116 | 119 | </Item> |
117 | - <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'flex-end', paddingRight: 92 }}> | |
118 | - <Item label="开始时间" name="startTime" required rules={[{ required: true, message: '请选择' }]}> | |
119 | - <DatePicker | |
120 | - format={format} | |
121 | - style={{ width: 197 }} | |
122 | - placeholder="请选择" | |
123 | - onChange={(value) => setStartTime((value && moment(moment(value).format(format))) || null)} | |
124 | - disabledDate={(current) => !!current && current < moment().add(1, 'day').startOf('day')} | |
125 | - /> | |
126 | - </Item> | |
127 | - <Item name="startTimeType" required rules={[{ required: true, message: '请选择' }]}> | |
128 | - <Select placeholder="请选择" style={{ width: 145, marginLeft: 5 }} onChange={(value: number) => setStartTimeType(value)}> | |
129 | - {TimeTypeData.map((i) => ( | |
130 | - <Option value={i.value || 0} key={i.value || 0}> | |
131 | - {i.label || '--'} | |
132 | - </Option> | |
133 | - ))} | |
134 | - </Select> | |
135 | - </Item> | |
136 | - </div> | |
137 | - <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'flex-end', paddingRight: 92 }}> | |
138 | - <Item label="结束时间" name="endTime" required rules={[{ required: true, message: '请选择' }]}> | |
139 | - <DatePicker | |
140 | - format={format} | |
141 | - style={{ width: 197 }} | |
142 | - onChange={(value) => setEndTime((value && moment(moment(value).format(format))) || null)} | |
143 | - disabledDate={(current) => !!current && current < (startTime || moment().add(1, 'day').startOf('day'))} | |
144 | - placeholder="请选择" | |
145 | - /> | |
146 | - </Item> | |
147 | - <Item name="endTimeType" required rules={[{ required: true, message: '请选择' }]}> | |
148 | - <Select placeholder="请选择" style={{ width: 145, marginLeft: 5 }}> | |
149 | - {TimeTypeData.filter((i) => | |
150 | - startTime && endTime && startTime.valueOf() == endTime.valueOf() && startTimeType == TimeTypeEnum.AFTERNOON | |
151 | - ? i.value != TimeTypeEnum.MORNING | |
152 | - : true, | |
153 | - ).map((i) => ( | |
154 | - <Option value={i.value || 0} key={i.value || 0}> | |
155 | - {i.label || '--'} | |
156 | - </Option> | |
157 | - ))} | |
158 | - </Select> | |
159 | - </Item> | |
160 | - </div> | |
120 | + <Item | |
121 | + noStyle | |
122 | + shouldUpdate={(prew, cur) => prew.type !== cur.type}> | |
123 | + {({ getFieldValue }) => { | |
124 | + const type = getFieldValue('type'); | |
125 | + return ( | |
126 | + <> | |
127 | + <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', paddingRight: 92 }}> | |
128 | + <Item label={[1].includes(type) ? "开始时间" : "时间"} name="startTime" required rules={[{ required: true, message: '请选择' }]}> | |
129 | + <DatePicker | |
130 | + picker={[1, 2].includes(type) ? "date" : "month"} | |
131 | + format={[1, 2].includes(type) ? format : "YYYY-MM"} | |
132 | + style={{ width: 197 }} | |
133 | + placeholder="请选择" | |
134 | + onChange={(value) => setStartTime((value && moment(moment(value).format(format))) || null)} | |
135 | + disabledDate={(current) => !!current && current < moment().add(1, 'day').startOf('day')} | |
136 | + /> | |
137 | + </Item> | |
138 | + { | |
139 | + [1].includes(type) && | |
140 | + <Item name="startTimeType" required rules={[{ required: true, message: '请选择' }]}> | |
141 | + <Select placeholder="请选择" style={{ width: 145, marginLeft: 5 }} onChange={(value: number) => setStartTimeType(value)}> | |
142 | + {TimeTypeData.map((i) => ( | |
143 | + <Option value={i.value || 0} key={i.value || 0}> | |
144 | + {i.label || '--'} | |
145 | + </Option> | |
146 | + ))} | |
147 | + </Select> | |
148 | + </Item> | |
149 | + } | |
150 | + </div> | |
151 | + { | |
152 | + [1].includes(type) && | |
153 | + <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', paddingRight: 92 }}> | |
154 | + <Item label="结束时间" name="endTime" required rules={[{ required: true, message: '请选择' }]}> | |
155 | + <DatePicker | |
156 | + format={format} | |
157 | + style={{ width: 197 }} | |
158 | + onChange={(value) => setEndTime((value && moment(moment(value).format(format))) || null)} | |
159 | + disabledDate={(current) => !!current && current < (startTime || moment().add(1, 'day').startOf('day'))} | |
160 | + placeholder="请选择" | |
161 | + /> | |
162 | + </Item> | |
163 | + <Item name="endTimeType" required rules={[{ required: true, message: '请选择' }]}> | |
164 | + <Select placeholder="请选择" style={{ width: 145, marginLeft: 5 }}> | |
165 | + {TimeTypeData.filter((i) => | |
166 | + startTime && endTime && startTime.valueOf() == endTime.valueOf() && startTimeType == TimeTypeEnum.AFTERNOON | |
167 | + ? i.value != TimeTypeEnum.MORNING | |
168 | + : true, | |
169 | + ).map((i) => ( | |
170 | + <Option value={i.value || 0} key={i.value || 0}> | |
171 | + {i.label || '--'} | |
172 | + </Option> | |
173 | + ))} | |
174 | + </Select> | |
175 | + </Item> | |
176 | + </div> | |
177 | + } | |
178 | + </> | |
179 | + | |
180 | + | |
181 | + ); | |
182 | + }} | |
183 | + </Item> | |
184 | + | |
185 | + | |
186 | + | |
161 | 187 | <Item {...formItemLayout} label="员工范围" name="staffRange" required rules={[{ required: true, message: '请选择' }]}> |
162 | 188 | <Select |
163 | 189 | placeholder="请选择" | ... | ... |
src/pages/capital/Maintenance/StockQuery/components/Inventory.tsx
... | ... | @@ -26,6 +26,7 @@ export default function SpecConfig({ standardId }: Props) { |
26 | 26 | <Column title="资产归属门店" dataIndex="assetShopName" /> |
27 | 27 | <Column title="使用门店" dataIndex="useShopName" /> |
28 | 28 | <Column title="是否代管" dataIndex="agent" render={(t) => (t ? '是' : '否')} /> |
29 | + <Column title="单价(元)" dataIndex="unitPrice" /> | |
29 | 30 | <Column title="库存数量" dataIndex="storageNum" render={(t, record: api.ListItems) => `${t || 0}${record.unit}`} /> |
30 | 31 | <Column title="管理员工" dataIndex="staffName" /> |
31 | 32 | <Column title="入库时间" dataIndex="storageTime" render={(t) => (t && moment(t).format('YYYY-MM-DD HH:mm')) || '--'} /> | ... | ... |
src/pages/capital/Maintenance/StockQuery/index.tsx
... | ... | @@ -38,6 +38,7 @@ export default function SpecConfig() { |
38 | 38 | render={(text, record) => <RenderGoodsSpec specList={text && JSON.parse(text)} />} |
39 | 39 | /> |
40 | 40 | <Column title="物品类型" dataIndex="type" render={(value) => <span>{AssetTypeEnum[value]}</span>} /> |
41 | + <Column title="单价(元)" dataIndex="unitPrice" /> | |
41 | 42 | <Column title="库存数量" dataIndex="num" render={(t, record: api.ListItems) => `${t || 0}${record.unit}`} /> |
42 | 43 | <Column |
43 | 44 | title="详情" | ... | ... |
src/pages/capital/ReceiveRules/subPages/GoodsDimension/components/PageAuthEdit/index.tsx
... | ... | @@ -187,6 +187,7 @@ export default function SpecConfig(props: Props) { |
187 | 187 | <Column title="门店" dataIndex="shopName" /> |
188 | 188 | <Column title="岗位" dataIndex="postName" /> |
189 | 189 | <Column title="型号规格" dataIndex="specList" render={(text, record) => <RenderGoodsSpec specList={text} />} /> |
190 | + <Column title="单价(元)" dataIndex="unitPrice" /> | |
190 | 191 | <Column |
191 | 192 | title="最大免费领用数量" |
192 | 193 | dataIndex="maxNum" | ... | ... |
src/pages/contract/BearCostSetting/components/SaveModal/index.tsx
... | ... | @@ -56,7 +56,7 @@ const SaveModal = ({ item, visible, onCancel, onRefresh }: Props) => { |
56 | 56 | shareRateItemList, |
57 | 57 | ...rest |
58 | 58 | } = item; |
59 | - const newShares = shareRateItemList?.map((item) => ({ ...item, shareRate: item.shareRate * 100 })); | |
59 | + const newShares = shareRateItemList?.map((item) => ({ ...item, key: item.id, shareRate: Number((item.shareRate * 100).toFixed(2)) })); | |
60 | 60 | const initialData = { |
61 | 61 | ...rest, |
62 | 62 | id, | ... | ... |
src/pages/contract/BearCostSetting/components/ShareRateItemlist/index.tsx
... | ... | @@ -19,7 +19,7 @@ const ShareRateItemlist = ({ onChange, value = [] }: Props) => { |
19 | 19 | ]; |
20 | 20 | const [form] = Form.useForm(); |
21 | 21 | const [data, setData] = useState<BearCostSetting.Data>({}); |
22 | - const [item, setItem] = useState<BearCostSetting.Item>({}); | |
22 | + const [title, setTitle] = useState(''); | |
23 | 23 | const [compsList, setCompsList] = useState<BearCostSetting.Comp[]>([] as BearCostSetting.Comp[]); |
24 | 24 | const [shoplist, setShoplist] = useState<BearCostSetting.Shop[]>([]); |
25 | 25 | const [visible, setVisible] = useState(false); |
... | ... | @@ -112,6 +112,7 @@ const ShareRateItemlist = ({ onChange, value = [] }: Props) => { |
112 | 112 | type="primary" |
113 | 113 | icon={<PlusOutlined />} |
114 | 114 | onClick={() => { |
115 | + setTitle('新增分摊比例'); | |
115 | 116 | setVisible(true); |
116 | 117 | }} |
117 | 118 | > |
... | ... | @@ -129,7 +130,7 @@ const ShareRateItemlist = ({ onChange, value = [] }: Props) => { |
129 | 130 | <span> |
130 | 131 | <a |
131 | 132 | onClick={() => { |
132 | - console.log('index', index); | |
133 | + setTitle('编辑分摊比例'); | |
133 | 134 | edit(row); |
134 | 135 | setVisible(true); |
135 | 136 | }} |
... | ... | @@ -152,7 +153,7 @@ const ShareRateItemlist = ({ onChange, value = [] }: Props) => { |
152 | 153 | /> |
153 | 154 | </Table> |
154 | 155 | |
155 | - <Modal title="新增分摊比例" visible={visible} onCancel={closeModal} onOk={form.submit}> | |
156 | + <Modal title={title} open={visible} onCancel={closeModal} onOk={form.submit}> | |
156 | 157 | <Form form={form} labelCol={{ span: '4' }} onFinish={handleItemSave}> |
157 | 158 | <Form.Item label="对象类型:" name="type" rules={[{ required: true, message: '请选择缴费方式' }]}> |
158 | 159 | <Select | ... | ... |
src/pages/finance/ViewCompanyRelationAuth/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 | +} | |
55 | + | |
56 | +interface UpdataParams{ | |
57 | +id?: number; | |
58 | +compId?: number;//往来单位id | |
59 | +dealerId?: number;//商家id | |
60 | +compCategory?: number;//单位类别(See: 往来单位类别) | |
61 | +beforeReimburse?: boolean;//是否报销前提供发票 | |
62 | +billAmountRatio?: number;//发票要求金额比例 | |
63 | +settleMethods?: string;//支持结算方式,多个英文逗号分隔 | |
64 | +accountCheckPeriod?: number;//对账周期,每月多少号 | |
65 | +} | |
66 | +/** | |
67 | + * 修改往来单位关系 | |
68 | + * /trade/company/relation/update | |
69 | + */ | |
70 | +export function updateCompanyRelationApi(params: UpdataParams): PrRes<void> { | |
71 | + return request.post(`${FINANCE2_HOST}/trade/company/relation/update`, params); | |
72 | +} | ... | ... |
src/pages/finance/ViewCompanyRelationAuth/components/Filter.tsx
0 → 100644
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2024-02-19 15:52:37 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2024-02-29 15:34:38 | |
6 | + * @FilePath: \fw-cms\src\pages\finance\CompanyRelationAuth\components\Filter.tsx | |
7 | + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | |
8 | + */ | |
9 | +import React from 'react'; | |
10 | +import { Button, Col, Popconfirm, Row, Select, Input, message } from 'antd'; | |
11 | +import { useStore } from '../index'; | |
12 | +import { CompanyCategoryTypeEnum } from '@/pages/finance/entitys'; | |
13 | +import { debounce } from 'lodash'; | |
14 | +import { deleteCompanyRelationApi } from '@/pages/finance/CompanyRelationAuth/api'; | |
15 | +import { history } from 'umi'; | |
16 | + | |
17 | +const Search = Input.Search; | |
18 | +const { Option } = Select; | |
19 | + | |
20 | +export default function Filter() { | |
21 | + const { | |
22 | + setVisible, | |
23 | + dealerList, | |
24 | + setCompanyParams, | |
25 | + dealerLoading, | |
26 | + // disabled, | |
27 | + // setDisabled, | |
28 | + setSelected, | |
29 | + companyList, | |
30 | + comBussinessList, | |
31 | + selectedRelation, | |
32 | + submitLoading, | |
33 | + setSubmitLoading, | |
34 | + companyParams, | |
35 | + setLoading, | |
36 | + } = useStore(); | |
37 | + const searchDealer = (dealerId: number) => { | |
38 | + setCompanyParams({ ...companyParams, dealerId }, true); | |
39 | + }; | |
40 | + | |
41 | + function searchType(compCategory: number) { | |
42 | + setCompanyParams({ ...companyParams, compCategory }, true); | |
43 | + } | |
44 | + | |
45 | + function searchCompanyType(companyType: number) { | |
46 | + setCompanyParams({ ...companyParams, companyType }, true); | |
47 | + } | |
48 | + | |
49 | + const fetchListByName = debounce((value) => { | |
50 | + setCompanyParams({ ...companyParams, keywords: value }, true); | |
51 | + }, 500); | |
52 | + | |
53 | + // function onCancel() { | |
54 | + // setDisabled(true); | |
55 | + // setSelected([...companyList]); | |
56 | + // } | |
57 | + | |
58 | + // function onEdit() { | |
59 | + // setDisabled(false); | |
60 | + // } | |
61 | + | |
62 | + // 新增 | |
63 | + function onAdd() { | |
64 | + history.push({ pathname: '/finance2/companyRelationAuth/create', state: companyParams }); | |
65 | + } | |
66 | + /** | |
67 | + * @param compId | |
68 | + */ | |
69 | + async function onDelete() { | |
70 | + const compIdList = selectedRelation.map((item) => item.compId); | |
71 | + try { | |
72 | + const pa = { ...companyParams, compIdList }; | |
73 | + setSubmitLoading(true); | |
74 | + const { success, result } = await deleteCompanyRelationApi(pa); | |
75 | + setSubmitLoading(false); | |
76 | + | |
77 | + if (!success) { | |
78 | + return message.error(result); | |
79 | + } else { | |
80 | + message.success(result); | |
81 | + setLoading(true); | |
82 | + } | |
83 | + } catch (e: any) { | |
84 | + setSubmitLoading(false); | |
85 | + message.error(e.message); | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + return ( | |
90 | + <div | |
91 | + style={{ | |
92 | + display: 'flex', | |
93 | + flexDirection: 'row', | |
94 | + justifyContent: 'space-between', | |
95 | + alignItems: 'center', | |
96 | + marginBottom: 20, | |
97 | + }} | |
98 | + > | |
99 | + <Row style={{ display: 'flex', flex: 1 }}> | |
100 | + {/* <Col span={4}> */} | |
101 | + <Select | |
102 | + placeholder="请选择商家" | |
103 | + showSearch | |
104 | + loading={dealerLoading} | |
105 | + // disabled={!disabled} | |
106 | + optionFilterProp="children" | |
107 | + onChange={searchDealer} | |
108 | + value={companyParams.dealerId} | |
109 | + style={{ width: 250 }} | |
110 | + > | |
111 | + {dealerList.map((dealer) => ( | |
112 | + <Option value={dealer.id} key={dealer.id}> | |
113 | + {dealer.name} | |
114 | + </Option> | |
115 | + ))} | |
116 | + </Select> | |
117 | + {/* </Col> */} | |
118 | + {/* <Col span={4}> */} | |
119 | + <Search | |
120 | + allowClear | |
121 | + // disabled={!disabled} | |
122 | + placeholder="搜索单位名称" | |
123 | + onChange={(e) => fetchListByName(e.target.value || undefined)} | |
124 | + style={{ width: 200,marginLeft: 10 }} | |
125 | + /> | |
126 | + <Select | |
127 | + placeholder="选择单位类别" | |
128 | + // disabled={!disabled} | |
129 | + optionFilterProp="children" | |
130 | + showSearch | |
131 | + onChange={searchType} | |
132 | + value={companyParams.compCategory} | |
133 | + style={{ width: 160, marginLeft: 10 }} | |
134 | + > | |
135 | + {[1, 2, 3].map((i) => ( | |
136 | + <Option value={i} key={i}> | |
137 | + {CompanyCategoryTypeEnum[i]} | |
138 | + </Option> | |
139 | + ))} | |
140 | + </Select> | |
141 | + <Select | |
142 | + placeholder="选择往来单位业务类型" | |
143 | + showSearch | |
144 | + optionFilterProp="children" | |
145 | + // disabled={!disabled} | |
146 | + allowClear | |
147 | + onChange={searchCompanyType} | |
148 | + style={{ width: 190,marginLeft: 10}} | |
149 | + > | |
150 | + {comBussinessList.map((item) => ( | |
151 | + <Option key={item.id} value={item.id}> | |
152 | + {item.name} | |
153 | + </Option> | |
154 | + ))} | |
155 | + </Select> | |
156 | + {/* </Col> */} | |
157 | + </Row> | |
158 | + {/* <div style={{ display: 'flex', flexDirection: 'row-reverse' }}> | |
159 | + <Button type="primary" onClick={onAdd}> | |
160 | + 新增 | |
161 | + </Button> | |
162 | + | |
163 | + <Popconfirm title="确定删除?" onConfirm={onDelete}> | |
164 | + <Button style={{ marginRight: 10 }} hidden={!selectedRelation.length} danger loading={submitLoading}> | |
165 | + 删除 | |
166 | + </Button> | |
167 | + </Popconfirm> | |
168 | + </div> */} | |
169 | + </div> | |
170 | + ); | |
171 | +} | ... | ... |
src/pages/finance/ViewCompanyRelationAuth/index.tsx
0 → 100644
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2023-05-26 00:02:50 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2024-03-06 15:06:04 | |
6 | + * @FilePath: \fw-cms\src\pages\finance\CompanyRelationAuth\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 { Button, Card, Table } from "antd"; | |
11 | +import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
12 | +import { createStore } from "@/hooks/moz"; | |
13 | +import store from "./useStore"; | |
14 | +import Filter from "./components/Filter"; | |
15 | +import { CompanyRelationListVO } from "@/pages/finance/CompanyRelationAuth/api"; | |
16 | +import { history } from "umi"; | |
17 | + | |
18 | +const { Column } = Table; | |
19 | + | |
20 | +export const { Provider, useStore } = createStore(store); | |
21 | + | |
22 | +function CompanyRelationAuth() { | |
23 | + const { selected, loading, setSelectedRelation, companyParams } = useStore(); | |
24 | + const rowSelection = { | |
25 | + onChange: (selectedRowKeys: React.Key[], selectedRows: CompanyRelationListVO[]) => { | |
26 | + console.log(`selectedRowKeys: ${selectedRowKeys}`, "selectedRows: ", selectedRows); | |
27 | + setSelectedRelation([...selectedRows]); | |
28 | + }, | |
29 | + getCheckboxProps: (record: CompanyRelationListVO) => ({ | |
30 | + name: String(record.compId), | |
31 | + }), | |
32 | + }; | |
33 | + | |
34 | + // 编辑 | |
35 | + | |
36 | + // function onEdit(record: CompanyRelationListVO) { | |
37 | + // history.push({ pathname: "/finance2/companyRelationAuth/edit", state: { ...companyParams, current: record } }); | |
38 | + // } | |
39 | + return ( | |
40 | + <PageHeaderWrapper title="查询往来单位关系设置"> | |
41 | + <Card> | |
42 | + <Filter /> | |
43 | + <Table | |
44 | + rowKey="compId" | |
45 | + dataSource={selected} | |
46 | + pagination={{ pageSize: 10, total: selected.length }} | |
47 | + loading={loading} | |
48 | + // rowSelection={{ | |
49 | + // type: "checkbox", | |
50 | + // ...rowSelection, | |
51 | + // }} | |
52 | + > | |
53 | + <Column title="单位名称" dataIndex="compName" /> | |
54 | + <Column title="简称" dataIndex="compShortName" /> | |
55 | + <Column title="往来单位业务类型" dataIndex="compTypeName" /> | |
56 | + <Column title="发票要求" dataIndex="beforeReimburse" render={(before) => `支付${before ? "前" : "后"}`} /> | |
57 | + <Column title="发票金额要求比例" dataIndex="billAmountRatio" render={(ratio) => `${ratio}%`} /> | |
58 | + <Column title="支持结算方式" dataIndex="settleMethodNames" render={(way) => way || "--"} /> | |
59 | + <Column title="对账周期" dataIndex="accountCheckPeriod" render={(date) => (date ? `${date}日` : "--")} /> | |
60 | + {/* <Column | |
61 | + title="操作" | |
62 | + align="center" | |
63 | + render={(text, record: TradeCompany.ComList) => ( | |
64 | + <> | |
65 | + <Button type="link" onClick={() => onEdit(record)}> | |
66 | + 编辑 | |
67 | + </Button> | |
68 | + </> | |
69 | + )} | |
70 | + /> */} | |
71 | + </Table> | |
72 | + </Card> | |
73 | + </PageHeaderWrapper> | |
74 | + ); | |
75 | +} | |
76 | + | |
77 | +export default () => ( | |
78 | + <Provider> | |
79 | + <CompanyRelationAuth /> | |
80 | + </Provider> | |
81 | +); | ... | ... |
src/pages/finance/ViewCompanyRelationAuth/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 | + // 存储已选关系,用于批量删除 | |
15 | + const [selectedRelation, setSelectedRelation] = useState<CompanyRelationListVO[]>([]); | |
16 | + | |
17 | + /** 商家下往来单位列表 */ | |
18 | + const { | |
19 | + data: companyList, | |
20 | + setParams: setCompanyParams, | |
21 | + setLoading, | |
22 | + loading, | |
23 | + params: companyParams, | |
24 | + } = useInitial<CompanyRelationListVO[], CompanyRelationParams>( | |
25 | + getCompanyByDealerApi, | |
26 | + [], | |
27 | + {dealerId: -1 },// 取消默认查询往来单位关系设置列表,需要有单位类别 | |
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 | + companyList, | |
53 | + visible, | |
54 | + setVisible, | |
55 | + setCompanyParams, | |
56 | + companyParams, | |
57 | + dealerList, | |
58 | + setLoading, | |
59 | + loading, | |
60 | + dealerLoading, | |
61 | + // disabled, | |
62 | + // setDisabled, | |
63 | + selected, | |
64 | + setSelected, | |
65 | + submitLoading, | |
66 | + setSubmitLoading, | |
67 | + comBussinessList, | |
68 | + comBussinessLoading, | |
69 | + selectedRelation, | |
70 | + setSelectedRelation, | |
71 | + }; | |
72 | +} | ... | ... |
src/pages/finance/ViewTradeCompany/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 | +type PrPageRes<T> = http.PromisePageResp<T>; | |
7 | + | |
8 | +/** | |
9 | + * 获取往来单位列表 | |
10 | + */ | |
11 | +export function getCompAccountApi(params: TradeCompany.CompListParams): PrPageRes<TradeCompany.ComList> { | |
12 | + return request.get(`${FINANCE2_HOST}/trade/company/list`, { params }); | |
13 | +} | |
14 | + | |
15 | +/** | |
16 | + * 查询往来单位详情 | |
17 | + */ | |
18 | +export function getDetailComAccountApi(id: number): PrRes<TradeCompany.CompDetailVO> { | |
19 | + return request.get(`${FINANCE2_HOST}/trade/company/detail`, { params: { id } }); | |
20 | +} | |
21 | + | |
22 | +/** | |
23 | + * 新增往来单位 | |
24 | + */ | |
25 | +export function createCompanyApi(params: TradeCompany.CompDetailVO): PrRes<void> { | |
26 | + return request.post(`${FINANCE2_HOST}/trade/company/add`, params); | |
27 | +} | |
28 | + | |
29 | +/** | |
30 | + * 编辑往来单位 | |
31 | + */ | |
32 | +export function updateCompanyApi(params: TradeCompany.CompDetailVO): PrRes<void> { | |
33 | + return request.post(`${FINANCE2_HOST}/trade/company/update`, params); | |
34 | +} | |
35 | + | |
36 | +interface paramsId { | |
37 | + id: number | |
38 | + remark?: string | |
39 | +} | |
40 | + | |
41 | +/** | |
42 | + * 注销往来单位 | |
43 | + */ | |
44 | +export function CancelApitalAccountApi(params: paramsId): PrRes<void> { | |
45 | + return request.post(`${FINANCE2_HOST}/trade/company/cancel`, params); | |
46 | +} | |
47 | + | |
48 | +/*银行选择器*/ | |
49 | +export function SelectBank(keywords?: string): any { | |
50 | + return request.get(`${FINANCE2_HOST}/selector/banks?kewords=${keywords}`); | |
51 | +} | |
52 | + | |
53 | +/*类型选择器*/ | |
54 | +export function getCompanyBusinessTypesApi(): PrRes<TradeCompany.CompanyBusinessVO[]> { | |
55 | + return request.get(`${FINANCE2_HOST}/selector/company/type`); | |
56 | +} | |
0 | 57 | \ No newline at end of file | ... | ... |
src/pages/finance/ViewTradeCompany/components/AccountsInput/CreateModal.tsx
0 → 100644
1 | +import useInitial from '@/hooks/useInitail'; | |
2 | +import { FinanceBankAccountTypeEnum } from '@/pages/finance/entitys'; | |
3 | +import { Form, Input, Modal, Select } from 'antd'; | |
4 | +import React, { memo, useEffect, useRef } from 'react'; | |
5 | +import { SelectBank } from '../../api'; | |
6 | + | |
7 | +const FormItem = Form.Item; | |
8 | +const { Option } = Select; | |
9 | + | |
10 | +interface Bank { | |
11 | + code: string; | |
12 | + name: string; | |
13 | +} | |
14 | + | |
15 | +interface Props { | |
16 | + visible: boolean; | |
17 | + onCancel: () => any; | |
18 | + onOk: (data: TradeCompany.Accounts) => any; | |
19 | + row: TradeCompany.Accounts; | |
20 | + value: TradeCompany.Accounts[]; | |
21 | +} | |
22 | + | |
23 | +function SelectModal({ onCancel, onOk, row = {}, visible, value = [] }: Props) { | |
24 | + const { data } = useInitial<Bank[], any>(SelectBank, [], '0'); | |
25 | + const [form] = Form.useForm(); | |
26 | + /** 用于判断账户重复添加 */ | |
27 | + const listRef = useRef<any[]>([]); | |
28 | + | |
29 | + useEffect(() => { | |
30 | + if (visible) { | |
31 | + form.setFieldsValue({ | |
32 | + bankInfo: row.bank ? { value: row.bank, label: row.bankName } : undefined, | |
33 | + accountName: row.accountName, | |
34 | + accountType: row.accountType, | |
35 | + accountNo: row.accountNo, | |
36 | + depositBank: row.depositBank, | |
37 | + }); | |
38 | + listRef.current = value.map((val) => val.accountNo); | |
39 | + } | |
40 | + }, [visible]); | |
41 | + | |
42 | + function handSave(feilds: any) { | |
43 | + const newRow = { | |
44 | + key: row.key || value.length + 1, | |
45 | + bankName: feilds.bankInfo.label, | |
46 | + bank: feilds.bankInfo.value, | |
47 | + accountName: feilds.accountName, | |
48 | + accountNo: feilds.accountNo.trim(), | |
49 | + depositBank: feilds.depositBank, | |
50 | + accountType: feilds.accountType, | |
51 | + }; | |
52 | + onOk && onOk(newRow); | |
53 | + onCancel && onCancel(); | |
54 | + } | |
55 | + | |
56 | + /** 校验账号 */ | |
57 | + function validatorNo(rules: any, _val: string) { | |
58 | + const _pattern = /^[0-9]\d*$/; | |
59 | + if (!_val) { | |
60 | + return Promise.reject(new Error('请输入账号')); | |
61 | + } | |
62 | + if (_val != row.accountNo && listRef.current.includes(_val)) { | |
63 | + return Promise.reject(new Error('该账号已添加,请勿重复添加')); | |
64 | + } | |
65 | + if (_val && (!_pattern.test(_val))) { | |
66 | + return Promise.reject(new Error('请输入正确的数字卡号')); | |
67 | + } | |
68 | + return Promise.resolve(); | |
69 | + } | |
70 | + | |
71 | + return ( | |
72 | + <Modal width={700} open={visible} title="账户信息" onCancel={onCancel} onOk={form.submit}> | |
73 | + <Form form={form} onFinish={handSave} wrapperCol={{ span: 15 }} labelCol={{ span: 6 }}> | |
74 | + <FormItem name="bankInfo" label="开户银行" rules={[{ required: true, message: '请填写开户银行' }]}> | |
75 | + <Select placeholder="请选择" labelInValue showSearch optionFilterProp="children"> | |
76 | + {data.map((item) => ( | |
77 | + <Option key={item.code} value={item.code}> | |
78 | + {item.name} | |
79 | + </Option> | |
80 | + ))} | |
81 | + </Select> | |
82 | + </FormItem> | |
83 | + <FormItem name="depositBank" label="开户行名称" rules={[{ required: true, message: '请填写开户银行支行' }]}> | |
84 | + <Input width="100%" placeholder="请填入开户银行支行" /> | |
85 | + </FormItem> | |
86 | + <FormItem label="账户类型" name="accountType" rules={[{ required: true, message: '请选择账户类型' }]}> | |
87 | + <Select placeholder="请选择账户类型"> | |
88 | + {[10, 20, 50].map((item) => ( | |
89 | + <Option value={item} key={item}> | |
90 | + {FinanceBankAccountTypeEnum[item]} | |
91 | + </Option> | |
92 | + ))} | |
93 | + </Select> | |
94 | + </FormItem> | |
95 | + <FormItem label="户名" rules={[{ required: true, message: '请填写户名' }]} name="accountName"> | |
96 | + <Input maxLength={64} style={{ width: '100%' }} placeholder="请输入户名" /> | |
97 | + </FormItem> | |
98 | + <FormItem label="账号" name="accountNo" required rules={[{ validator: validatorNo }]}> | |
99 | + <Input maxLength={32} style={{ width: '100%' }} placeholder="请输入账号" /> | |
100 | + </FormItem> | |
101 | + </Form> | |
102 | + </Modal> | |
103 | + ); | |
104 | +} | |
105 | + | |
106 | +export default memo(SelectModal); | ... | ... |
src/pages/finance/ViewTradeCompany/components/AccountsInput/index.tsx
0 → 100644
1 | +import React, { useCallback, useState, memo, Ref, forwardRef } from 'react'; | |
2 | +import { Card, Button, Table, Divider, Popconfirm, Tooltip } from 'antd'; | |
3 | +import { PlusOutlined } from '@ant-design/icons'; | |
4 | +import CreateModal from './CreateModal'; | |
5 | +import { FinanceBankAccountTypeEnum } from '@/pages/finance/entitys'; | |
6 | + | |
7 | +const { Column } = Table; | |
8 | + | |
9 | +interface Props { | |
10 | + value?: TradeCompany.Accounts[], | |
11 | + onChange?: (newValue: TradeCompany.Accounts[]) => any, | |
12 | + disabled?: boolean | |
13 | +} | |
14 | + | |
15 | +function AccountsInput({ value = [], onChange, disabled }: Props, ref: Ref<any>) { | |
16 | + const [visiData, setVisiData] = useState<{ visible: boolean, row: TradeCompany.Accounts }>({ visible: false, row: {} }); | |
17 | + | |
18 | + function onDelete(key: number) { | |
19 | + const newValue = value.filter(val => val.key != key); | |
20 | + onChange && onChange(newValue); | |
21 | + } | |
22 | + | |
23 | + const onOk = useCallback((newRow: TradeCompany.Accounts) => { | |
24 | + const newValue = [...value]; | |
25 | + const index = newValue.findIndex(val => val.key == newRow.key); | |
26 | + if (index > -1) { | |
27 | + newValue.splice(index, 1, newRow); | |
28 | + } else { | |
29 | + newValue.push(newRow); | |
30 | + } | |
31 | + onChange && onChange(newValue); | |
32 | + }, [value]); | |
33 | + | |
34 | + /** 切换弹窗显示 */ | |
35 | + const triggerModal = useCallback((row: TradeCompany.Accounts = {}, visible: boolean = false) => { | |
36 | + setVisiData({ visible, row }); | |
37 | + }, []); | |
38 | + | |
39 | + return ( | |
40 | + <Card | |
41 | + extra={ | |
42 | + !disabled && ( | |
43 | + <div | |
44 | + style={{ | |
45 | + flex: 1, | |
46 | + display: "flex", | |
47 | + justifyContent: "space-between", | |
48 | + flexDirection: "row", | |
49 | + }} | |
50 | + > | |
51 | + <Button | |
52 | + type="primary" | |
53 | + icon={<PlusOutlined />} | |
54 | + onClick={() => triggerModal({}, true)} | |
55 | + > | |
56 | + 新增 | |
57 | + </Button> | |
58 | + </div> | |
59 | + ) | |
60 | + } | |
61 | + > | |
62 | + <Table | |
63 | + rowKey="accountNo" | |
64 | + dataSource={value} | |
65 | + pagination={false} | |
66 | + bordered | |
67 | + size="small" | |
68 | + > | |
69 | + <Column | |
70 | + title="开户银行" | |
71 | + dataIndex="bankName" | |
72 | + width="20%" | |
73 | + ellipsis | |
74 | + render={(text: any, record: any) => (record.bankName ? ( | |
75 | + <Tooltip title={record.bankName}> | |
76 | + <span>{record.bankName}</span> | |
77 | + </Tooltip> | |
78 | + ) : ( | |
79 | + <Tooltip title={record.bank.label}> | |
80 | + <span>{record.bank.label}</span> | |
81 | + </Tooltip> | |
82 | + ))} | |
83 | + /> | |
84 | + <Column | |
85 | + title="开户行名称" | |
86 | + dataIndex="depositBank" | |
87 | + width="20%" | |
88 | + ellipsis | |
89 | + render={(accountNo: string) => ( | |
90 | + <Tooltip title={accountNo}> | |
91 | + <span>{accountNo}</span> | |
92 | + </Tooltip> | |
93 | + )} | |
94 | + /> | |
95 | + <Column | |
96 | + title="户名" | |
97 | + dataIndex="accountName" | |
98 | + ellipsis | |
99 | + render={(accountNo: string) => ( | |
100 | + <Tooltip title={accountNo}> | |
101 | + <span>{accountNo}</span> | |
102 | + </Tooltip> | |
103 | + )} | |
104 | + /> | |
105 | + <Column | |
106 | + title="账户类型" | |
107 | + dataIndex="accountType" | |
108 | + width="20%" | |
109 | + render={(type) => FinanceBankAccountTypeEnum[type]} | |
110 | + /> | |
111 | + <Column | |
112 | + title="账号" | |
113 | + dataIndex="accountNo" | |
114 | + ellipsis | |
115 | + render={(accountNo: string) => ( | |
116 | + <Tooltip title={accountNo}> | |
117 | + <span>{accountNo}</span> | |
118 | + </Tooltip> | |
119 | + )} | |
120 | + /> | |
121 | + {!disabled && ( | |
122 | + <Column | |
123 | + title="操作" | |
124 | + align="center" | |
125 | + width="20%" | |
126 | + dataIndex="accountNo" | |
127 | + render={(no, row: TradeCompany.Accounts, i) => ( | |
128 | + <> | |
129 | + <a | |
130 | + onClick={(e) => { | |
131 | + e.preventDefault(); | |
132 | + triggerModal(row, true); | |
133 | + }} | |
134 | + > | |
135 | + 编辑 | |
136 | + </a> | |
137 | + <Divider type="vertical" /> | |
138 | + <Popconfirm | |
139 | + title={`是否删除${row.bankName}?`} | |
140 | + onConfirm={() => onDelete(i+1)} | |
141 | + okText="确定" | |
142 | + cancelText="取消" | |
143 | + > | |
144 | + <a onClick={(e) => e.preventDefault()}>删除</a> | |
145 | + </Popconfirm> | |
146 | + </> | |
147 | + )} | |
148 | + /> | |
149 | + )} | |
150 | + </Table> | |
151 | + <CreateModal | |
152 | + row={visiData.row} | |
153 | + visible={visiData.visible} | |
154 | + onCancel={triggerModal} | |
155 | + onOk={onOk} | |
156 | + value={value} | |
157 | + /> | |
158 | + </Card> | |
159 | + ); | |
160 | +} | |
161 | + | |
162 | +export default memo(forwardRef(AccountsInput)); | ... | ... |
src/pages/finance/ViewTradeCompany/components/AdressSelect.tsx
0 → 100644
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2023-12-01 17:17:04 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2023-12-01 17:24:30 | |
6 | + * @FilePath: \fw-cms\src\pages\finance\TradeCompany\components\AdressSelect.tsx | |
7 | + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | |
8 | + */ | |
9 | +import React, { useEffect, useState } from "react"; | |
10 | +import { Modal, Form, Select, Input, Radio } from "antd"; | |
11 | +import PositionSelector from "@/components/PositionSelector"; | |
12 | +import ShopSelect from "@/components/ShopSelect"; | |
13 | +import * as API from "@/common/api"; | |
14 | +import useInitial from "@/hooks/useInitail"; | |
15 | +import { FormInstance } from "antd/es/form/Form"; | |
16 | + | |
17 | +const FormItem = Form.Item; | |
18 | + | |
19 | +interface Props { | |
20 | + form: FormInstance; | |
21 | + required?: boolean; | |
22 | +} | |
23 | + | |
24 | +function AdressSelect(props: Props) { | |
25 | + const { form ,required} = props; | |
26 | + const [hiddern, setHidden] = useState(true); //控制地图选择 | |
27 | + const [own, setOwn] = useState(1); //配置控制 | |
28 | + | |
29 | + const _onChange = (e: any) => { | |
30 | + form.setFieldsValue({ | |
31 | + addrslng: undefined, | |
32 | + addrslat: undefined, | |
33 | + }); | |
34 | + if (e.target.value === 1) { | |
35 | + setHidden(true); | |
36 | + setOwn(e.target.value); | |
37 | + } else { | |
38 | + setHidden(false); | |
39 | + setOwn(e.target.value); | |
40 | + } | |
41 | + }; | |
42 | + | |
43 | + const onAd = (e: any) => { | |
44 | + form.setFieldsValue({ | |
45 | + addrslng: e.point.lng, | |
46 | + addrslat: e.point.lat, | |
47 | + }); | |
48 | + }; | |
49 | + | |
50 | + return ( | |
51 | + <> | |
52 | + <FormItem label="地理位置" > | |
53 | + {/* <FormItem label="地理位置" rules={[{ required: true, message: "请配置地址" }]}> */} | |
54 | + <Radio.Group onChange={(e: any) => _onChange(e)} value={own}> | |
55 | + <Radio value={1}>地图配置</Radio> | |
56 | + <Radio value={2}>自定义配置</Radio> | |
57 | + </Radio.Group> | |
58 | + </FormItem> | |
59 | + {hiddern && ( | |
60 | + // <FormItem name="location" label="地址" rules={[{ required: true, message: "必填" }]}> | |
61 | + <FormItem name="location" label="地址" > | |
62 | + <PositionSelector style={{ width: "100%" }} onChange={(e: any) => onAd(e)} /> | |
63 | + </FormItem> | |
64 | + )} | |
65 | + <div | |
66 | + style={{ | |
67 | + display: "flex", | |
68 | + justifyContent: "space-between", | |
69 | + width: "80%", | |
70 | + marginLeft: "15%", | |
71 | + }} | |
72 | + > | |
73 | + {/* <FormItem name="addrslng" label="经度" style={{ width: "45%" }} rules={[{ required: true, message: "必填" }]}> */} | |
74 | + <FormItem name="addrslng" label="经度" style={{ width: "45%" }}> | |
75 | + <Input style={{ width: "100%" }} disabled={own === 1} /> | |
76 | + </FormItem> | |
77 | + {/* <FormItem name="addrslat" label="纬度" style={{ width: "45%" }} rules={[{ required: true, message: "必填" }]}> */} | |
78 | + <FormItem name="addrslat" label="纬度" style={{ width: "45%" }}> | |
79 | + <Input style={{ width: "100%" }} disabled={own === 1} /> | |
80 | + </FormItem> | |
81 | + </div> | |
82 | + </> | |
83 | + ); | |
84 | +} | |
85 | + | |
86 | +export default AdressSelect; | ... | ... |
src/pages/finance/ViewTradeCompany/components/CancelModal.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { Modal, Input, message } from 'antd'; | |
3 | +import { useStore } from '../index'; | |
4 | +import { CancelApitalAccountApi } from '../api'; | |
5 | + | |
6 | +const TextArea = Input.TextArea; | |
7 | + | |
8 | +export default function CreateModal() { | |
9 | + const { setCancelVisible, cancelVisible, current, setLoading } = useStore(); | |
10 | + const [remark, setRemark] = useState<string>(''); | |
11 | + const [saveLoading, setSaveLoading] = useState(false); | |
12 | + | |
13 | + function changeRemark(e: any) { | |
14 | + const value = e.target.value; | |
15 | + setRemark(value); | |
16 | + } | |
17 | + | |
18 | + function handleSave() { | |
19 | + if (!remark || !current.id) return; | |
20 | + const param = { | |
21 | + id: current.id, | |
22 | + remark, | |
23 | + }; | |
24 | + setSaveLoading(true); | |
25 | + CancelApitalAccountApi(param) | |
26 | + .then((res) => { | |
27 | + message.success('注销成功'); | |
28 | + setSaveLoading(false); | |
29 | + setLoading(true); | |
30 | + setCancelVisible(false); | |
31 | + setRemark(''); | |
32 | + }) | |
33 | + .catch((err) => { | |
34 | + message.error(err.message); | |
35 | + setSaveLoading(false); | |
36 | + }); | |
37 | + } | |
38 | + | |
39 | + return ( | |
40 | + <Modal | |
41 | + open={cancelVisible} | |
42 | + title="填写注销的原因" | |
43 | + onCancel={() => setCancelVisible(false)} | |
44 | + maskClosable={false} | |
45 | + onOk={handleSave} | |
46 | + confirmLoading={saveLoading} | |
47 | + > | |
48 | + <TextArea placeholder="请输入注销的原因" value={remark} onChange={changeRemark} rows={6} /> | |
49 | + </Modal> | |
50 | + ); | |
51 | +} | ... | ... |
src/pages/finance/ViewTradeCompany/components/ContactsInput/CreateModal.tsx
0 → 100644
1 | +import React, { useEffect, memo, useRef } from 'react'; | |
2 | +import { Modal, Input, Form } from 'antd'; | |
3 | +import { isIdCardNo } from '@/utils/validate'; | |
4 | + | |
5 | +const FormItem = Form.Item; | |
6 | + | |
7 | +interface Props { | |
8 | + visible: boolean, | |
9 | + onCancel: () => any, | |
10 | + onOk: (data: TradeCompany.Contacts) => any, | |
11 | + row: TradeCompany.Contacts, | |
12 | + value: TradeCompany.Contacts[] | |
13 | +} | |
14 | + | |
15 | +function SelectModal({ onCancel, onOk, row = {}, visible, value = [] }: Props) { | |
16 | + const [form] = Form.useForm(); | |
17 | + /** 用于判断身份证重复添加 */ | |
18 | + const listRef = useRef<any[]>([]); | |
19 | + | |
20 | + useEffect(() => { | |
21 | + if (visible) { | |
22 | + form.setFieldsValue({ | |
23 | + contactName: row.contactName, | |
24 | + contactMobile: row.contactMobile, | |
25 | + idCard: row.idCard | |
26 | + }); | |
27 | + listRef.current = value.map(val => val.contactMobile); | |
28 | + } | |
29 | + }, [visible]); | |
30 | + | |
31 | + function handSave(feilds: TradeCompany.Contacts) { | |
32 | + console.log('row', row); | |
33 | + const newRow = { | |
34 | + ...feilds, | |
35 | + // key: row.key || value.length + 1, | |
36 | + }; | |
37 | + onOk && onOk(newRow); | |
38 | + onCancel && onCancel(); | |
39 | + } | |
40 | + | |
41 | + /** 校验身份证号 */ | |
42 | + const validatorIdCardNo = (rules: any, value: string) => { | |
43 | + if (!value) { | |
44 | + return Promise.resolve(); | |
45 | + } | |
46 | + if (value && listRef.current.includes(value)) { | |
47 | + return Promise.reject("该身份证已添加,请勿重复添加"); | |
48 | + } | |
49 | + const result = isIdCardNo(value); | |
50 | + if (result.success) return Promise.resolve(); | |
51 | + else return Promise.reject(result.msg); | |
52 | + }; | |
53 | + | |
54 | + /** 校验电话号码 */ | |
55 | + function validatorMobile(rules: any, value: string) { | |
56 | + if (!value) { | |
57 | + return Promise.reject("请输入联系方式"); | |
58 | + } | |
59 | + if (value != row.contactMobile && listRef.current.includes(value)) { | |
60 | + return Promise.reject("该联系方式已添加,请勿重复添加"); | |
61 | + } | |
62 | + return Promise.resolve(); | |
63 | + } | |
64 | + | |
65 | + return ( | |
66 | + <Modal | |
67 | + width={700} | |
68 | + visible={visible} | |
69 | + title="联系人信息" | |
70 | + onCancel={onCancel} | |
71 | + onOk={form.submit} | |
72 | + > | |
73 | + <Form form={form} onFinish={handSave} wrapperCol={{ span: 15 }} labelCol={{ span: 6 }}> | |
74 | + <FormItem label="联系人姓名" name="contactName" rules={[{ required: true, message: '请输入姓名' }]}> | |
75 | + <Input placeholder="请输入姓名" style={{ width: "100%" }} maxLength={30} /> | |
76 | + </FormItem> | |
77 | + <FormItem label="联系方式" required rules={[{ validator: validatorMobile }]} name="contactMobile"> | |
78 | + <Input maxLength={24} style={{ width: "100%" }} placeholder="请输入联系方式" /> | |
79 | + </FormItem> | |
80 | + <FormItem label="身份证号码" name="idCard" rules={[{ validator: validatorIdCardNo }]}> | |
81 | + <Input maxLength={20} style={{ width: "100%" }} placeholder="请输入身份证" /> | |
82 | + </FormItem> | |
83 | + </Form> | |
84 | + </Modal> | |
85 | + ); | |
86 | +} | |
87 | + | |
88 | +export default memo(SelectModal); | ... | ... |
src/pages/finance/ViewTradeCompany/components/ContactsInput/index.tsx
0 → 100644
1 | +import React, { useCallback, useState, memo, Ref, forwardRef } from 'react'; | |
2 | +import { Card, Button, Table, Divider, Popconfirm, Tooltip } from 'antd'; | |
3 | +import { PlusOutlined } from '@ant-design/icons'; | |
4 | +import CreateModal from './CreateModal'; | |
5 | + | |
6 | +const { Column } = Table; | |
7 | + | |
8 | +interface Props { | |
9 | + value?: TradeCompany.Contacts[], | |
10 | + onChange?: (newValue: TradeCompany.Contacts[]) => any, | |
11 | + disabled?: boolean | |
12 | +} | |
13 | + | |
14 | +function ContactsInput({ value = [], onChange, disabled }: Props, ref: Ref<any>) { | |
15 | + const [visiData, setVisiData] = useState<{ visible: boolean, row: TradeCompany.Contacts }>({ visible: false, row: {} }); | |
16 | + | |
17 | + function onDelete(key: number) { | |
18 | + const newValue = value.filter(val => val.key != key); | |
19 | + onChange && onChange(newValue); | |
20 | + } | |
21 | + | |
22 | + const onOk = useCallback((newRow: TradeCompany.Contacts) => { | |
23 | + const newValue = [...value]; | |
24 | + const index = newValue.findIndex(val => val.key == newRow.key); | |
25 | + if (index> -1) { | |
26 | + newValue.splice(index, 1, newRow); | |
27 | + } else { | |
28 | + newValue.push(newRow); | |
29 | + } | |
30 | + onChange && onChange(newValue); | |
31 | + }, [value]); | |
32 | + | |
33 | + /** 切换弹窗显示 */ | |
34 | + const triggerModal = useCallback((row: TradeCompany.Contacts = {}, visible: boolean = false) => { | |
35 | + console.log('row--->', row); | |
36 | + setVisiData({ visible, row }); | |
37 | + }, []); | |
38 | + | |
39 | + return ( | |
40 | + <Card | |
41 | + extra={!disabled && ( | |
42 | + <div style={{ flex: 1, display: 'flex', justifyContent: "space-between", flexDirection: 'row' }}> | |
43 | + <Button type="primary" icon={<PlusOutlined />} onClick={() => triggerModal({}, true)}>新增</Button> | |
44 | + </div> | |
45 | + )} | |
46 | + > | |
47 | + <Table | |
48 | + rowKey="contactMobile" | |
49 | + dataSource={value} | |
50 | + pagination={false} | |
51 | + bordered | |
52 | + size="small" | |
53 | + > | |
54 | + <Column title="姓名" dataIndex="contactName" width="20%" /> | |
55 | + <Column title="联系方式" dataIndex="contactMobile" width="35%" render={no => no || "-"} /> | |
56 | + <Column | |
57 | + title="身份证号码" | |
58 | + dataIndex="idCard" | |
59 | + ellipsis | |
60 | + render={(idCard: string) => ( | |
61 | + <Tooltip title={idCard}> | |
62 | + <span>{idCard}</span> | |
63 | + </Tooltip> | |
64 | + )} | |
65 | + /> | |
66 | + {!disabled && ( | |
67 | + <Column | |
68 | + title="操作" | |
69 | + dataIndex="contactMobile" | |
70 | + align="center" | |
71 | + width="20%" | |
72 | + render={(moblie, row: TradeCompany.Contacts, i) => ( | |
73 | + <> | |
74 | + <a onClick={(e) => { e.preventDefault(); triggerModal(row, true); }}>编辑</a> | |
75 | + <Divider type="vertical" /> | |
76 | + <Popconfirm | |
77 | + title={`是否删除${row.contactName}?`} | |
78 | + onConfirm={() => onDelete(i+1)} | |
79 | + okText="确定" | |
80 | + cancelText="取消" | |
81 | + > | |
82 | + <a onClick={(e) => e.preventDefault()}>删除</a> | |
83 | + </Popconfirm> | |
84 | + </> | |
85 | + )} | |
86 | + /> | |
87 | + )} | |
88 | + </Table> | |
89 | + <CreateModal | |
90 | + row={visiData.row} | |
91 | + visible={visiData.visible} | |
92 | + onCancel={triggerModal} | |
93 | + onOk={onOk} | |
94 | + value={value} | |
95 | + /> | |
96 | + </Card> | |
97 | + ); | |
98 | +} | |
99 | + | |
100 | +export default memo(forwardRef(ContactsInput)); | ... | ... |
src/pages/finance/ViewTradeCompany/components/CreateModal.tsx
0 → 100644
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2023-09-16 15:14:15 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2024-01-02 15:53:12 | |
6 | + * @FilePath: \fw-cms\src\pages\finance\TradeCompany\components\CreateModal.tsx | |
7 | + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | |
8 | + */ | |
9 | +import React, { useState, useEffect } from 'react'; | |
10 | +import { Modal, Form, Input, Select, message, Radio, Spin } from 'antd'; | |
11 | +import { useStore } from '../index'; | |
12 | +import { CompanyBusinessTypeEnum, CompanyCategoryTypeEnum, SubjectTypeEnum } from '@/pages/finance/entitys'; | |
13 | +import Contact from './ContactsInput'; | |
14 | +import Account from './AccountsInput'; | |
15 | +import { createCompanyApi, updateCompanyApi, getDetailComAccountApi } from '../api'; | |
16 | +import AdressSelect from '@/pages/finance/TradeCompany/components/AdressSelect'; | |
17 | +import { LabeledValue } from 'antd/lib/select'; | |
18 | + | |
19 | +const FormItem = Form.Item; | |
20 | +const { Option } = Select; | |
21 | + | |
22 | +export default function CreateModal() { | |
23 | + const { visible, setVisible, current, setCurrent, setLoading, comBussinessList, comBussinessLoading, brandList } = useStore(); | |
24 | + const [form] = Form.useForm(); | |
25 | + const [savelLoading, setSavelLoading] = useState(false); | |
26 | + const [detailLoading, setDetailLoading] = useState(false); | |
27 | + const [creditCodeDesc, setCreditCodeDesc] = useState<string>('社会信用代码'); | |
28 | + const [required, setRequired] = useState(true); | |
29 | + /** | |
30 | + * 账户信息是否必填,默认都是必填 | |
31 | + * 新增、编辑单位类别为”服务商“时账户信息非必填 | |
32 | + * */ | |
33 | + const [accountInfoRequired, setaccountInfoRequired] = useState(true); | |
34 | + | |
35 | + useEffect(() => { | |
36 | + if (visible && current.id) { | |
37 | + initData(current.id); | |
38 | + } | |
39 | + }, [visible, current.id]); | |
40 | + | |
41 | + async function initData(rowId?: number) { | |
42 | + try { | |
43 | + let item: TradeCompany.CompDetailVO = {}; | |
44 | + if (rowId) { | |
45 | + setDetailLoading(true); | |
46 | + const { data = {} } = await getDetailComAccountApi(rowId); | |
47 | + item = data; | |
48 | + setDetailLoading(false); | |
49 | + } | |
50 | + form.setFieldsValue({ | |
51 | + ...item, | |
52 | + compName: item.compName, | |
53 | + compShortName: item.compShortName, | |
54 | + subjectType: item.subjectType, | |
55 | + compType: item.compType || [], | |
56 | + compCategory: item.compCategory || CompanyCategoryTypeEnum['供应商'], | |
57 | + compAddress: item.compAddress, | |
58 | + creditCode: item.creditCode, | |
59 | + brands: (item.brands || []).map((it) => ({ label: it.brandName, value: it.brandId })), | |
60 | + location: item.compAddress | |
61 | + ? { | |
62 | + // address: "", | |
63 | + //@ts-ignored; | |
64 | + address: item.lonLatAddress || '', | |
65 | + point: { | |
66 | + lng: item.longitude, | |
67 | + lat: item.latitude, | |
68 | + }, | |
69 | + } | |
70 | + : undefined, | |
71 | + addrslng: Number(item.longitude), | |
72 | + addrslat: Number(item.latitude), | |
73 | + contacts: (item.contacts || []).map((it, i) => ({ ...it, key: i + 1 })), | |
74 | + accounts: (item.accounts || []).map((it, i) => ({ ...it, key: i + 1 })), | |
75 | + }); | |
76 | + if (item.subjectType == 1) { | |
77 | + setRequired(false); | |
78 | + } else { | |
79 | + setRequired(true); | |
80 | + } | |
81 | + if (item.compCategory == 2) {//单位类别为服务商,账户信息非必填 | |
82 | + setaccountInfoRequired(false); | |
83 | + } else { | |
84 | + setaccountInfoRequired(true); | |
85 | + } | |
86 | + } catch (e: any) { | |
87 | + message.error(e.message); | |
88 | + setVisible(false); | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + function submit(item: any) { | |
93 | + const param = { | |
94 | + id: current.id, | |
95 | + ...item, | |
96 | + brands: (item.brands || []).map((item: LabeledValue) => ({ brandId: item.value, brandName: item.label })), | |
97 | + longitude: Number(item.addrslng), | |
98 | + latitude: Number(item.addrslat), | |
99 | + lonLatAddress: item.location ? item.location.address : '', | |
100 | + }; | |
101 | + setSavelLoading(true); | |
102 | + const saveApi = current.id ? updateCompanyApi : createCompanyApi; | |
103 | + saveApi(param) | |
104 | + .then((res) => { | |
105 | + message.success('保存成功'); | |
106 | + setLoading(true); | |
107 | + setVisible(false); | |
108 | + setSavelLoading(false); | |
109 | + }) | |
110 | + .catch((err) => { | |
111 | + message.error(err.message); | |
112 | + setSavelLoading(false); | |
113 | + }); | |
114 | + } | |
115 | + | |
116 | + function onCancel() { | |
117 | + setVisible(false); | |
118 | + } | |
119 | + | |
120 | + function changeSubjectType(value: number) { | |
121 | + if (value === 1) { | |
122 | + setCreditCodeDesc('身份证号码'); | |
123 | + setRequired(false); | |
124 | + } else { | |
125 | + setCreditCodeDesc('社会信用代码'); | |
126 | + setRequired(true); | |
127 | + } | |
128 | + } | |
129 | + | |
130 | + return ( | |
131 | + <Modal | |
132 | + title={`${current.id ? '编辑' : '新增'}往来单位`} | |
133 | + open={visible} | |
134 | + onOk={form.submit} | |
135 | + onCancel={onCancel} | |
136 | + maskClosable={false} | |
137 | + confirmLoading={savelLoading || detailLoading} | |
138 | + afterClose={() => { | |
139 | + setCurrent({}); | |
140 | + form.resetFields(); | |
141 | + }} | |
142 | + width="60%" | |
143 | + > | |
144 | + <Spin spinning={detailLoading}> | |
145 | + <Form form={form} onFinish={submit} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }}> | |
146 | + <FormItem name="compName" label="往来单位名称" rules={[{ required: true, message: '请填入往来单位名称' }]}> | |
147 | + <Input placeholder="请填入往来单位名称" maxLength={64} /> | |
148 | + </FormItem> | |
149 | + <FormItem name="compShortName" label="往来单位简称" rules={[{ required: true, message: '请填入往来单位简称' }]}> | |
150 | + <Input placeholder="请填入往来单位简称" maxLength={64} /> | |
151 | + </FormItem> | |
152 | + <FormItem name="subjectType" label="单位主体类型" rules={[{ required: true, message: '请选择主体类型' }]}> | |
153 | + <Select placeholder="请选择主体类型" showSearch onChange={changeSubjectType}> | |
154 | + {[SubjectTypeEnum['个人'], SubjectTypeEnum['公司'], SubjectTypeEnum['个体工商户'], SubjectTypeEnum['公共组织']].map((i) => ( | |
155 | + <Option key={i} value={i}> | |
156 | + {SubjectTypeEnum[i]} | |
157 | + </Option> | |
158 | + ))} | |
159 | + </Select> | |
160 | + </FormItem> | |
161 | + <FormItem name="compCategory" label="单位类别" rules={[{ required: true, message: '请选择类别' }]} | |
162 | + > | |
163 | + <Radio.Group onChange={(e) => { | |
164 | + const _value = e.target.value; | |
165 | + if (_value === 2) { | |
166 | + setaccountInfoRequired(false); | |
167 | + } else { | |
168 | + setaccountInfoRequired(true); | |
169 | + } | |
170 | + }}> | |
171 | + <Radio value={CompanyCategoryTypeEnum['供应商']}>供应商</Radio> | |
172 | + <Radio value={CompanyCategoryTypeEnum['服务商']}>服务商</Radio> | |
173 | + <Radio value={CompanyCategoryTypeEnum['供应商与服务商']}>供应商与服务商</Radio> | |
174 | + </Radio.Group> | |
175 | + </FormItem> | |
176 | + <FormItem name="compType" label="往来单位业务类型" rules={[{ required: true, message: '请选项往来单位业务类型' }]}> | |
177 | + <Select placeholder="请选项往来单位业务类型" mode="multiple" showSearch optionFilterProp="children" loading={comBussinessLoading}> | |
178 | + {comBussinessList.map((item) => ( | |
179 | + <Option key={item.id} value={item.id}> | |
180 | + {item.name} | |
181 | + </Option> | |
182 | + ))} | |
183 | + </Select> | |
184 | + </FormItem> | |
185 | + <FormItem noStyle shouldUpdate={(prevValues, currentValues) => prevValues.compType != currentValues.compType}> | |
186 | + {({ getFieldValue }): any => { | |
187 | + const _compType = getFieldValue('compType'); | |
188 | + return _compType?.includes(CompanyBusinessTypeEnum['新车采购(主机厂)']) || | |
189 | + _compType?.includes(CompanyBusinessTypeEnum['配件采购']) ? ( | |
190 | + <FormItem name="brands" label="品牌" rules={[{ required: true, message: '请选择品牌' }]}> | |
191 | + <Select placeholder="请选择品牌" labelInValue showSearch optionFilterProp="children" mode="multiple"> | |
192 | + {brandList?.map((item) => ( | |
193 | + <Option key={item.id} value={item.id}> | |
194 | + {item.name} | |
195 | + </Option> | |
196 | + ))} | |
197 | + </Select> | |
198 | + </FormItem> | |
199 | + ) : null; | |
200 | + }} | |
201 | + </FormItem> | |
202 | + {/* <FormItem name="creditCode" label={creditCodeDesc} rules={[{ required: true, message: '请输入' + creditCodeDesc }]}> */} | |
203 | + <FormItem name="creditCode" label={creditCodeDesc} rules={[{ required: required, message: '请输入' + creditCodeDesc }]}> | |
204 | + <Input placeholder={`请输入${creditCodeDesc}`} maxLength={30} /> | |
205 | + </FormItem> | |
206 | + {/* <FormItem name="compAddress" label="通信地址" rules={[{ required: true, message: '请输入地址' }]}> */} | |
207 | + <FormItem name="compAddress" label="通信地址" rules={[{ required: required, message: '请输入地址' }]}> | |
208 | + <Input placeholder="请输入通信地址" /> | |
209 | + </FormItem> | |
210 | + <AdressSelect form={form} required={required} /> | |
211 | + <FormItem name="contacts" label="联系方式" rules={[{ required: true }]}> | |
212 | + <Contact /> | |
213 | + </FormItem> | |
214 | + <FormItem name="accounts" label="账户信息" rules={[{ required: accountInfoRequired }]}> | |
215 | + <Account /> | |
216 | + </FormItem> | |
217 | + </Form> | |
218 | + </Spin> | |
219 | + </Modal> | |
220 | + ); | |
221 | +} | ... | ... |
src/pages/finance/ViewTradeCompany/components/Filter.tsx
0 → 100644
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2023-12-13 09:15:08 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2023-12-20 17:50:50 | |
6 | + * @FilePath: \fw-cms\src\pages\finance\TradeCompany\components\Filter.tsx | |
7 | + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | |
8 | + */ | |
9 | +import React from 'react'; | |
10 | +import { Button, Row, Select, Col, Input } from 'antd'; | |
11 | +import { useStore } from '../index'; | |
12 | +import { debounce } from 'lodash'; | |
13 | +import { SubjectTypeEnum } from '@/pages/finance/entitys'; | |
14 | + | |
15 | +const { Option } = Select; | |
16 | +const Search = Input.Search; | |
17 | + | |
18 | +export default function AccountList() { | |
19 | + const { setVisible, setParams, innerParams, comBussinessList, comBussinessLoading } = useStore(); | |
20 | + | |
21 | + function searchTypes(compTypes: number) { | |
22 | + setParams({ compTypes }, true); | |
23 | + } | |
24 | + | |
25 | + const fetchListByName = debounce(value => { | |
26 | + setParams({ ...innerParams, keywords: value }, true); | |
27 | + }, 500); | |
28 | + | |
29 | + /** 查找单位主体类型 未返回subjectType */ | |
30 | + function searchSubjectType(subjectType: number) { | |
31 | + setParams({ subjectType }, true); | |
32 | + } | |
33 | + | |
34 | + return ( | |
35 | + <div | |
36 | + style={{ | |
37 | + display: "flex", | |
38 | + flexDirection: "row", | |
39 | + justifyContent: "space-between", | |
40 | + alignItems: "center", | |
41 | + marginBottom: 20, | |
42 | + }} | |
43 | + > | |
44 | + <Row style={{ display: "flex", flex: 1 }}> | |
45 | + <Col span={6}> | |
46 | + <Select | |
47 | + placeholder="搜索往来单位业务类型" | |
48 | + showSearch | |
49 | + allowClear | |
50 | + optionFilterProp="children" | |
51 | + value={innerParams.compTypes} | |
52 | + loading={comBussinessLoading} | |
53 | + style={{ width: 200 }} | |
54 | + onChange={searchTypes} | |
55 | + > | |
56 | + {comBussinessList.map((item) => ( | |
57 | + <Option key={item.id} value={item.id}> | |
58 | + {item.name} | |
59 | + </Option> | |
60 | + ))} | |
61 | + </Select> | |
62 | + </Col> | |
63 | + <Col span={7}> | |
64 | + <Search | |
65 | + allowClear | |
66 | + placeholder="搜索单位名称/社会信用代码" | |
67 | + onChange={(e) => fetchListByName(e.target.value || undefined)} | |
68 | + style={{ width: 250, marginLeft: 10 }} | |
69 | + /> | |
70 | + </Col> | |
71 | + <Col span={5}> | |
72 | + <Select | |
73 | + placeholder="搜索单位主体类型" | |
74 | + showSearch | |
75 | + allowClear | |
76 | + optionFilterProp="children" | |
77 | + value={innerParams.subjectType} | |
78 | + loading={comBussinessLoading} | |
79 | + style={{ width: 200 }} | |
80 | + onChange={searchSubjectType} | |
81 | + > | |
82 | + {[ | |
83 | + SubjectTypeEnum["个人"], | |
84 | + SubjectTypeEnum["公司"], | |
85 | + SubjectTypeEnum["个体工商户"], | |
86 | + SubjectTypeEnum["公共组织"], | |
87 | + ].map((i) => ( | |
88 | + <Option key={i} value={i}> | |
89 | + {SubjectTypeEnum[i]} | |
90 | + </Option> | |
91 | + ))} | |
92 | + </Select> | |
93 | + </Col> | |
94 | + </Row> | |
95 | + {/* <Button type="primary" onClick={() => setVisible(true)}> | |
96 | + 新增 | |
97 | + </Button> */} | |
98 | + </div> | |
99 | + ); | |
100 | +} | ... | ... |
src/pages/finance/ViewTradeCompany/components/List.tsx
0 → 100644
1 | +import React, { useRef } from 'react'; | |
2 | +import { Table, Modal, Button, message } from 'antd'; | |
3 | +import { useStore } from '../index'; | |
4 | +import { CompanyCategoryTypeEnum, RecordAuditTypeEnum, RecordStateEnum } from '../../entitys'; | |
5 | +import { getDetailComAccountApi } from '../api'; | |
6 | +import Contacts from './ContactsInput'; | |
7 | +import Accounts from './AccountsInput'; | |
8 | +import ApprovalProgressModal, { ApprovalProgressModalRef } from '@/components/ApprovalProgressModal'; | |
9 | + | |
10 | +const { Column } = Table; | |
11 | + | |
12 | +export default function AccountList() { | |
13 | + const approvalProgressRef = useRef<ApprovalProgressModalRef | null>(null); | |
14 | + const { setCurrent, setVisible, comAccountList, loading, paginationConfig, setCancelVisible, innerParams } = useStore(); | |
15 | + | |
16 | + function getApprovalProgress(item: TradeCompany.CompDetailVO) { | |
17 | + approvalProgressRef.current?.setApprovalProgressModalInfo({ | |
18 | + visible: true, | |
19 | + orderNo: item.approvalNo, | |
20 | + }); | |
21 | + } | |
22 | + | |
23 | + function viewDetail(row: TradeCompany.ComList) { | |
24 | + message.loading('查询中...'); | |
25 | + row.id && | |
26 | + getDetailComAccountApi(row.id) | |
27 | + .then((res) => { | |
28 | + const data = res.data || {}; | |
29 | + message.destroy(); | |
30 | + Modal.info({ | |
31 | + title: data.compName, | |
32 | + width: 800, | |
33 | + content: ( | |
34 | + <div> | |
35 | + <p style={{ marginTop: 10 }}>{`单位简称:${data.compShortName || '-'}`}</p> | |
36 | + <p style={{ marginTop: 10 }}>{`${data.subjectTypeName === '个人' ? '身份证号码' : '社会信用代码'}:${data.creditCode || '-'}`}</p> | |
37 | + <p style={{ marginTop: 10 }}>{`单位主体类型:${data.subjectTypeName || '-'}`}</p> | |
38 | + <p style={{ marginTop: 10 }}>{`单位类别:${CompanyCategoryTypeEnum[data.compCategory!]}`}</p> | |
39 | + <p style={{ marginTop: 10 }}>{`往来单位业务类型:${data.compTypeName}`}</p> | |
40 | + {/* {data.brandName ? <p style={{ marginTop: 10 }}>{`品牌:${data.brandName}`}</p> : null} */} | |
41 | + {data.brands?.length ? <p style={{ marginTop: 10 }}>{`品牌:${data.brands.map((it) => it.brandName).join(',')}`}</p> : null} | |
42 | + <p style={{ marginTop: 10 }}>{`公司地址:${data.compAddress || '-'}`}</p> | |
43 | + <p style={{ marginTop: 10 }}>联系人信息:</p> | |
44 | + <Contacts value={data.contacts} disabled /> | |
45 | + <p style={{ marginTop: 10 }}>账户信息:</p> | |
46 | + <Accounts value={data.accounts} disabled /> | |
47 | + <p style={{ marginTop: 10 }}>{`审核类型:${RecordAuditTypeEnum[data.recordAuditType!] || ''}`}</p> | |
48 | + {data.recordAuditType == RecordAuditTypeEnum['注销'] ? ( | |
49 | + <p style={{ marginTop: 10 }}>{`申请原因:${data.cancelReason || '-'}`}</p> | |
50 | + ) : null} | |
51 | + <p | |
52 | + style={{ | |
53 | + color: data.recordState == RecordStateEnum['已驳回'] ? '#FF0000' : '#4189FD', | |
54 | + marginTop: 10, | |
55 | + cursor: 'pointer', | |
56 | + }} | |
57 | + onClick={() => getApprovalProgress(data)} | |
58 | + > | |
59 | + {`审核状态:${RecordStateEnum[data.recordState || 0]}`} | |
60 | + </p> | |
61 | + {data.recordState == RecordStateEnum['已驳回'] ? <p style={{ marginTop: 10 }}>{`驳回原因:${data.rejectReason || '-'}`}</p> : null} | |
62 | + </div> | |
63 | + ), | |
64 | + }); | |
65 | + }) | |
66 | + .catch((e) => { | |
67 | + message.destroy(); | |
68 | + message.error(e.message); | |
69 | + }); | |
70 | + } | |
71 | + | |
72 | + return ( | |
73 | + <> | |
74 | + <Table dataSource={comAccountList} pagination={paginationConfig} rowKey="id" loading={loading}> | |
75 | + <Column title="名称" dataIndex="compName" width="15%" /> | |
76 | + {/* <Column title="单位主体类型" dataIndex="subjectType" width="15%" /> */} | |
77 | + <Column title="简称" dataIndex="compShortName" width="15%" /> | |
78 | + <Column title="社会信用代码" dataIndex="creditCode" width="15%" /> | |
79 | + <Column title="往来单位业务类型" dataIndex="compTypeName" /> | |
80 | + <Column | |
81 | + title="审核状态" | |
82 | + dataIndex="recordState" | |
83 | + render={(type, row: TradeCompany.ComList) => | |
84 | + <p> | |
85 | + <span> | |
86 | + { `${RecordStateEnum[type]}${row.recordAuditType ? `(${RecordAuditTypeEnum[row.recordAuditType!] || '-'})` : ''}`} | |
87 | + </span> | |
88 | + {row.approvalNo ? | |
89 | + <span style={{ color: "#4189FD", marginLeft: 5, cursor: 'pointer', }} onClick={() => getApprovalProgress(row)}> | |
90 | + {`审批进度>`} | |
91 | + </span> : | |
92 | + null} | |
93 | + </p> | |
94 | + } | |
95 | + /> | |
96 | + {/* TODO | |
97 | + 查看详情 -> 待审核,已驳回 | |
98 | + 编辑 -> 已驳回,已备案 | |
99 | + 注销 -> 已备案,注销并且被驳回,修改并且被驳回 | |
100 | + */} | |
101 | + <Column | |
102 | + title="操作" | |
103 | + align="center" | |
104 | + render={(text, record: TradeCompany.ComList) => ( | |
105 | + <> | |
106 | + {[RecordStateEnum['待审核'], RecordStateEnum['已驳回']].includes(Number(record.recordState)) && ( | |
107 | + <Button type="link" onClick={() => viewDetail(record)}> | |
108 | + 详情 | |
109 | + </Button> | |
110 | + )} | |
111 | + {/* {[RecordStateEnum['已驳回'], RecordStateEnum['已备案']].includes(Number(record.recordState)) && ( | |
112 | + <Button | |
113 | + type="link" | |
114 | + onClick={() => { | |
115 | + setCurrent(record); | |
116 | + setVisible(true); | |
117 | + }} | |
118 | + > | |
119 | + 编辑 | |
120 | + </Button> | |
121 | + )} */} | |
122 | + {/* {(record.recordState == RecordStateEnum['已备案'] || | |
123 | + (record.recordState == RecordStateEnum['已驳回'] && | |
124 | + [RecordAuditTypeEnum['注销'], RecordAuditTypeEnum['修改']].includes(record.recordAuditType || 0))) && ( | |
125 | + <Button | |
126 | + type="link" | |
127 | + onClick={() => { | |
128 | + setCurrent(record); | |
129 | + setCancelVisible(true); | |
130 | + }} | |
131 | + > | |
132 | + 注销 | |
133 | + </Button> | |
134 | + )} */} | |
135 | + </> | |
136 | + )} | |
137 | + /> | |
138 | + </Table> | |
139 | + <ApprovalProgressModal ref={approvalProgressRef} /> | |
140 | + </> | |
141 | + ); | |
142 | +} | ... | ... |
src/pages/finance/ViewTradeCompany/index.tsx
0 → 100644
1 | +/* | |
2 | + * @Author: zhaofeng 1272190090@qq.com | |
3 | + * @Date: 2024-03-06 14:30:32 | |
4 | + * @LastEditors: zhaofeng 1272190090@qq.com | |
5 | + * @LastEditTime: 2024-03-06 14:47:02 | |
6 | + * @FilePath: \fw-cms\src\pages\finance\ViewTradeCompany\index.tsx | |
7 | + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE | |
8 | + */ | |
9 | +import React from "react"; | |
10 | +import { Card } from "antd"; | |
11 | +import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
12 | +import { createStore } from "@/hooks/moz"; | |
13 | +import store from "./useStore"; | |
14 | +import ListAccount from "./components/List"; | |
15 | +import Filter from "./components/Filter"; | |
16 | +import CreateModal from "./components/CreateModal"; | |
17 | +import CancelModal from "./components/CancelModal"; | |
18 | + | |
19 | +export const { Provider, useStore } = createStore(store); | |
20 | + | |
21 | +function ViewTradeCompany() { | |
22 | + return ( | |
23 | + <PageHeaderWrapper title="查询往来单位设置"> | |
24 | + <Card> | |
25 | + <Filter /> | |
26 | + <ListAccount /> | |
27 | + </Card> | |
28 | + <CancelModal /> | |
29 | + <CreateModal /> | |
30 | + </PageHeaderWrapper> | |
31 | + ); | |
32 | +} | |
33 | + | |
34 | +export default () => ( | |
35 | + <Provider> | |
36 | + <ViewTradeCompany /> | |
37 | + </Provider> | |
38 | +); | ... | ... |
src/pages/finance/ViewTradeCompany/interface.d.ts
0 → 100644
1 | +declare namespace TradeCompany { | |
2 | + interface CompListParams { | |
3 | + /** 单位名称 */ | |
4 | + keywords?: string; | |
5 | + /** 单位类型集合 */ | |
6 | + compTypes?: string; | |
7 | + /** 备案状态 */ | |
8 | + recordState?: string; | |
9 | + /** 单位类别 */ | |
10 | + compCategory?: number; | |
11 | + current?: number; | |
12 | + pageSize?: number; | |
13 | + } | |
14 | + interface ComList { | |
15 | + /** 单位id */ | |
16 | + id?: number; | |
17 | + // 往来单位名称 | |
18 | + compName?: string; | |
19 | + /** 单位编码 */ | |
20 | + compNo?: string; | |
21 | + /** 社会信用编码 */ | |
22 | + creditCode?: string; | |
23 | + /* 单位主体类型 */ | |
24 | + subjectType?: number; | |
25 | + subjectTypeName?: string; | |
26 | + // 业务类型 | |
27 | + compType?: number[]; // 变成多选 | |
28 | + compTypeName?: string; | |
29 | + brandId?: number; | |
30 | + brands?: Brands[]; //品牌列表 | |
31 | + brandName?: string; | |
32 | + /** 状态 */ | |
33 | + recordState?: number; | |
34 | + /** 备案审核状态 */ | |
35 | + recordAuditType?: number; | |
36 | + /** 图片 */ | |
37 | + compImage?: string; | |
38 | + // 通信地址 | |
39 | + compAddress?: string; | |
40 | + // 单位类别 | |
41 | + compCategory?: number; | |
42 | + // 往来单位简称 | |
43 | + compShortName?: string; | |
44 | + // 审批单号 | |
45 | + approvalNo?: string; | |
46 | + } | |
47 | + interface Brands { | |
48 | + brandId?: number; | |
49 | + brandName?: string; | |
50 | + } | |
51 | + | |
52 | + interface CompDetailVO extends ComList { | |
53 | + // 联系人 | |
54 | + contacts?: Contacts[]; | |
55 | + // 账户列表 | |
56 | + accounts?: Accounts[]; | |
57 | + /** 经度 */ | |
58 | + longitude?: number; | |
59 | + /** 纬度 */ | |
60 | + latitude?: number; | |
61 | + /** 备案状态 */ | |
62 | + recordState?: number; | |
63 | + /** 备案审核状态 */ | |
64 | + recordAuditType?: number; | |
65 | + /** 注销原因 */ | |
66 | + cancelReason?: string; | |
67 | + /** 驳回原因 */ | |
68 | + rejectReason?: string; | |
69 | + approvalNo?: string; | |
70 | + } | |
71 | + | |
72 | + interface Contacts { | |
73 | + /** 判断唯一性 */ | |
74 | + key?: number; | |
75 | + // 联系人 | |
76 | + contactName?: string; | |
77 | + // 联系手机 | |
78 | + contactMobile?: string; | |
79 | + // 身份账号 | |
80 | + idCard?: string; | |
81 | + } | |
82 | + | |
83 | + interface Accounts { | |
84 | + /** 判断唯一性 */ | |
85 | + key?: number; | |
86 | + //银行code | |
87 | + bank?: string; | |
88 | + // 银行名称 | |
89 | + bankName?: string; | |
90 | + //账户类型 | |
91 | + accountType?: number; | |
92 | + // 户名 | |
93 | + accountName?: string; | |
94 | + // 账号 | |
95 | + accountNo?: string; | |
96 | + //银行支行 | |
97 | + depositBank?: string; | |
98 | + } | |
99 | + | |
100 | + interface CompanyBusinessVO { | |
101 | + id: number; | |
102 | + name: string; | |
103 | + } | |
104 | +} | ... | ... |
src/pages/finance/ViewTradeCompany/useStore.ts
0 → 100644
1 | +import { useState } from 'react'; | |
2 | +import { getCompAccountApi, getCompanyBusinessTypesApi } from './api'; | |
3 | +import usePagination from '@/hooks/usePagination'; | |
4 | +import useInitial from '@/hooks/useInitail'; | |
5 | +import { getBrandFilterApi, getDealerApi } from '@/common/api'; | |
6 | + | |
7 | +export default function useStore() { | |
8 | + const [visible, setVisible] = useState(false); | |
9 | + // 商家的列表 | |
10 | + const { data: dealerList, loading: dealerLoading } = useInitial(getDealerApi, [], {}); | |
11 | + // 往来单位业务类型列表 | |
12 | + const { data: comBussinessList, loading: comBussinessLoading } = useInitial(getCompanyBusinessTypesApi, [], null); | |
13 | + // 获取单位列表 | |
14 | + const { list: comAccountList, loading, setLoading, paginationConfig, setParams, innerParams } = usePagination<TradeCompany.ComList>(getCompAccountApi, {}); | |
15 | + // 获取品牌 | |
16 | + const { data: brandList } = useInitial<CommonApi.OptionVO[], {}>(getBrandFilterApi, [], {}); | |
17 | + | |
18 | + const [current, setCurrent] = useState<TradeCompany.ComList>({}); | |
19 | + const [addFlag, setAddFlag] = useState<boolean>(true); | |
20 | + const [addFlagAccount, setAddFlagAccount] = useState<boolean>(true); | |
21 | + const [cancelVisible, setCancelVisible] = useState(false); | |
22 | + | |
23 | + return { | |
24 | + visible, | |
25 | + setVisible, | |
26 | + current, | |
27 | + setCurrent, | |
28 | + comAccountList, | |
29 | + loading, | |
30 | + setLoading, | |
31 | + addFlag, | |
32 | + setAddFlag, | |
33 | + addFlagAccount, | |
34 | + setAddFlagAccount, | |
35 | + paginationConfig, | |
36 | + cancelVisible, | |
37 | + setCancelVisible, | |
38 | + setParams, | |
39 | + innerParams, | |
40 | + dealerLoading, | |
41 | + dealerList, | |
42 | + comBussinessList, | |
43 | + comBussinessLoading, | |
44 | + brandList, | |
45 | + }; | |
46 | +} | ... | ... |
src/pages/oop/Dealer/Shop/Comps/Modal.tsx
... | ... | @@ -55,26 +55,26 @@ export default function ShopModal({ visible, onCancel, onSave, record, dealerLis |
55 | 55 | const address = |
56 | 56 | record.addr && record.lng && record.lat |
57 | 57 | ? { |
58 | - address: record.addr, | |
59 | - point: { | |
60 | - lat: record.lat, | |
61 | - lng: record.lng, | |
62 | - }, | |
63 | - } | |
58 | + address: record.addr, | |
59 | + point: { | |
60 | + lat: record.lat, | |
61 | + lng: record.lng, | |
62 | + }, | |
63 | + } | |
64 | 64 | : {}; |
65 | 65 | |
66 | 66 | const { data: brands } = useInitial(API.queryAllCarBrands, [], { groupId, dealerId }); |
67 | 67 | |
68 | 68 | const list = record.shopLogo |
69 | 69 | ? [ |
70 | - { | |
71 | - uid: '-1', | |
72 | - name: 'dealerLogo.png', | |
73 | - status: 'done', | |
74 | - url: record.shopLogo, | |
75 | - thumbUrl: record.shopLogo, | |
76 | - }, | |
77 | - ] | |
70 | + { | |
71 | + uid: '-1', | |
72 | + name: 'dealerLogo.png', | |
73 | + status: 'done', | |
74 | + url: record.shopLogo, | |
75 | + thumbUrl: record.shopLogo, | |
76 | + }, | |
77 | + ] | |
78 | 78 | : []; |
79 | 79 | |
80 | 80 | useEffect(() => { |
... | ... | @@ -90,9 +90,9 @@ export default function ShopModal({ visible, onCancel, onSave, record, dealerLis |
90 | 90 | brand: { value: record.brandId, label: record.brandName }, |
91 | 91 | shopMappingList: record.shopMappingList |
92 | 92 | ? record.shopMappingList.map((i) => ({ |
93 | - value: i.shopId, | |
94 | - label: i.shopName, | |
95 | - })) | |
93 | + value: i.shopId, | |
94 | + label: i.shopName, | |
95 | + })) | |
96 | 96 | : undefined, |
97 | 97 | }); |
98 | 98 | fetchShopList(); |
... | ... | @@ -392,7 +392,7 @@ export default function ShopModal({ visible, onCancel, onSave, record, dealerLis |
392 | 392 | <Form.Item |
393 | 393 | label="对应线下实体门店" |
394 | 394 | name="shopMappingList" |
395 | - // rules={[{ required: true, message: "请选择实体门店" }]} | |
395 | + // rules={[{ required: true, message: "请选择实体门店" }]} | |
396 | 396 | > |
397 | 397 | <Select mode="multiple" labelInValue optionFilterProp="children"> |
398 | 398 | {data.map((item: any) => { |
... | ... | @@ -456,7 +456,7 @@ export default function ShopModal({ visible, onCancel, onSave, record, dealerLis |
456 | 456 | </FormItem> |
457 | 457 | )} |
458 | 458 | <Form.Item label="映射的门店" name="shopMappingList"> |
459 | - <Select optionFilterProp="children" showSearch mode="multiple" labelInValue placeholder="选择对应的销售门店(可多选)"> | |
459 | + <Select optionFilterProp="children" showSearch mode="multiple" labelInValue placeholder="选择映射门店(可多选)"> | |
460 | 460 | {saleShops.map((item: any) => { |
461 | 461 | return ( |
462 | 462 | <Option key={item.id} value={item.id}> | ... | ... |
src/pages/stock/ProductSetting/ChangePrice/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 { FVM_HOST, OOP_HOST } from '@/utils/host'; |
4 | 4 | |
5 | 5 | /** |
6 | - * 门店授权门店授权车辆基础信息列表 | |
7 | - */ | |
8 | -export function getPageListApi(params?: Product.QuerryList): http.PromisePageResp<Product.List> { | |
9 | - return request.get(`${OOP_HOST}/select/shop/car/base/page`, { params }); | |
10 | -} | |
11 | - | |
12 | -/** | |
13 | 6 | * 调价申请 |
14 | 7 | */ |
15 | 8 | export function saveApi(params?: Product.ChangeParams): http.PromiseResp<void> { |
16 | - return request.post(`${FVM_HOST}/erp/vehicle/info/save/adjust`, params, {contentType: 'json'}); | |
9 | + return request.post(`${FVM_HOST}/erp/vehicle/info/save/adjust`, params, { contentType: 'json' }); | |
17 | 10 | } |
18 | 11 | \ No newline at end of file | ... | ... |
src/pages/stock/ProductSetting/VehicleDimension/ChangePrice/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 { FVM_HOST, OOP_HOST } from '@/utils/host'; |
4 | 4 | |
... | ... | @@ -15,13 +15,6 @@ interface DtoList { |
15 | 15 | } |
16 | 16 | |
17 | 17 | /** |
18 | - * 门店授权门店授权车辆基础信息列表 | |
19 | - */ | |
20 | -export function getPageListApi(params?: Product.QuerryList): http.PromisePageResp<Product.List> { | |
21 | - return request.get(`${OOP_HOST}/select/shop/car/base/page`, { params }); | |
22 | -} | |
23 | - | |
24 | -/** | |
25 | 18 | * 批量调价申请 |
26 | 19 | */ |
27 | 20 | export function saveApi(params?: ApplyChangeParams): http.PromiseResp<void> { | ... | ... |
src/pages/stock/ProductSetting/VehicleDimension/PutonShelf/index.tsx
src/pages/stock/ShopAuth/api.ts
1 | 1 | import { MCAR_HOST, OOP_HOST } from '@/utils/host'; |
2 | -import { http } from '@/typing/http'; | |
2 | +import type { http } from '@/typing/http'; | |
3 | 3 | import request from '@/utils/request'; |
4 | -import { CarShop } from './interface.d'; | |
4 | +import type { CarShop } from './interface.d'; | |
5 | 5 | |
6 | 6 | type PrRes<T> = http.PromiseResp<T>; |
7 | 7 | type PrResArr<T> = http.PromiseResp<T[]>; |
... | ... | @@ -48,14 +48,10 @@ export function getAuthListApi(params: CarShop.QueryCarListParams): PrResArr<Car |
48 | 48 | export function getSeriesreeApi(groupId?: number): PrResArr<CarShop.CarSeries> { |
49 | 49 | return request.get(getUrl('/select/brand/series', OOP_HOST), { params: { groupId } }); |
50 | 50 | } |
51 | -/** 保存门店授权车系信息 */ | |
51 | +/** 保存门店授权车系信息 (已弃用) */ | |
52 | 52 | export function authCarApi(params: CarShop.authCar): PrRes<void> { |
53 | 53 | return request.post(getUrl('/erp/shop/auth/series'), { ...params }); |
54 | 54 | } |
55 | -/** 取消门店车辆授权 */ | |
56 | -export function cancelAuthApi(id: number): PrRes<void> { | |
57 | - return request.get(getUrl('/erp/shop/sale/cancel'), { params: { id } }); | |
58 | -} | |
59 | 55 | |
60 | 56 | /** 根据当前登录人信息获取品牌列表 */ |
61 | 57 | export function getBrandApi(): PrResArr<CarShop.optionItem> { | ... | ... |
src/pages/stock/ShopAuth/components/Filter.tsx
1 | 1 | import React, { useState, useEffect } from 'react'; |
2 | -import { Cascader, message, Row, Col } from 'antd'; | |
3 | -import { CascaderOptionType } from 'antd/lib/cascader'; | |
2 | +import { Cascader, message, Row, Col, Select } from 'antd'; | |
3 | +import type { CascaderOptionType } from 'antd/lib/cascader'; | |
4 | 4 | import { getBrandApi, getSeriesApi } from '../api'; |
5 | +import useInitail from '@/hooks/useInitail'; | |
6 | +import { getShopApi } from '@/common/api'; | |
5 | 7 | |
6 | 8 | interface FilterProps { |
7 | - shopValue: any[], | |
8 | - shopOption: any[], | |
9 | - onChangeShop: any, | |
10 | 9 | onFilter: any |
11 | - } | |
10 | +} | |
12 | 11 | |
13 | 12 | export default function Filter(props: FilterProps) { |
14 | - const { shopOption, shopValue, onChangeShop, onFilter } = props; | |
13 | + const { onFilter } = props; | |
14 | + const { data: shops } = useInitail<CommonApi.OptionVO[], CommonApi.ShopParam>(getShopApi, [], { bizType: 1 }); | |
15 | 15 | const [specOptions, setSpecOptions] = useState<any[]>([]); |
16 | - | |
16 | + | |
17 | 17 | useEffect(() => { |
18 | 18 | getBrandApi().then(res => { |
19 | - const { data=[] } = res; | |
19 | + const { data = [] } = res; | |
20 | 20 | const brandList = data.map(brand => ({ ...brand, isLeaf: false })); |
21 | 21 | setSpecOptions(brandList); |
22 | 22 | }).catch(e => { |
... | ... | @@ -30,7 +30,7 @@ export default function Filter(props: FilterProps) { |
30 | 30 | targetOption.loading = true; |
31 | 31 | if (length === 1) { |
32 | 32 | getSeriesApi(targetOption.id).then(res => { |
33 | - const { data=[] } = res; | |
33 | + const { data = [] } = res; | |
34 | 34 | targetOption.loading = false; |
35 | 35 | targetOption.children = []; |
36 | 36 | data.forEach((list, index) => { |
... | ... | @@ -65,26 +65,24 @@ export default function Filter(props: FilterProps) { |
65 | 65 | |
66 | 66 | function filterByCar(value) { |
67 | 67 | const carFilter = { |
68 | - brandId: value[0], | |
69 | - seriesId: value[1], | |
70 | - // specId: value[2], | |
68 | + brandId: value ? value[0] : undefined, | |
69 | + seriesId: value ? value[1] : undefined, | |
71 | 70 | }; |
72 | 71 | onFilter(carFilter); |
73 | 72 | } |
74 | 73 | |
75 | - function filterByShop(value) { | |
74 | + function filterByShop(value: number) { | |
76 | 75 | const carFilter = { |
77 | - shopId: value[1] | |
76 | + shopId: value | |
78 | 77 | }; |
79 | - onChangeShop(value); | |
80 | 78 | onFilter(carFilter); |
81 | 79 | } |
82 | 80 | |
83 | 81 | return ( |
84 | 82 | <div> |
85 | - <Row style={{ marginBottom: 10 }}> | |
86 | - <span style={{ color: "red", margin: 5 }}>*</span>商家/门店: | |
87 | - <Cascader | |
83 | + <Row style={{ marginBottom: 10, alignItems: 'center' }}> | |
84 | + <span style={{ color: "red" }}>*</span>门店: | |
85 | + {/* <Cascader | |
88 | 86 | allowClear={false} |
89 | 87 | value={shopValue} |
90 | 88 | expandTrigger="hover" |
... | ... | @@ -93,21 +91,35 @@ export default function Filter(props: FilterProps) { |
93 | 91 | onChange={filterByShop} |
94 | 92 | notFoundContent="暂无数据" |
95 | 93 | style={{ width: 415 }} |
96 | - /> | |
97 | - </Row> | |
98 | - <Row> | |
99 | - 品牌/车系: | |
100 | - <Cascader | |
94 | + /> */} | |
95 | + <Select | |
96 | + style={{ width: 200, marginRight: 20 }} | |
101 | 97 | allowClear |
102 | - changeOnSelect | |
103 | - options={specOptions} | |
104 | - placeholder="请选择品牌/车系" | |
105 | - loadData={(selectedOptions) => loadData(selectedOptions)} | |
106 | - onChange={filterByCar} | |
107 | - fieldNames={{ value: 'id', label: 'name', }} | |
108 | - notFoundContent="暂无数据" | |
109 | - style={{ width: 400, marginRight: 10 }} | |
110 | - /> | |
98 | + placeholder="搜索门店" | |
99 | + showSearch | |
100 | + filterOption | |
101 | + optionFilterProp="children" | |
102 | + onChange={filterByShop} | |
103 | + > | |
104 | + {shops.map((item, i) => ( | |
105 | + <Select.Option key={item.id} value={item.id}> | |
106 | + {item.name} | |
107 | + </Select.Option> | |
108 | + ))} | |
109 | + </Select> | |
110 | + <div> | |
111 | + 品牌/车系: | |
112 | + <Cascader | |
113 | + allowClear | |
114 | + changeOnSelect | |
115 | + options={specOptions} | |
116 | + placeholder="请选择品牌/车系" | |
117 | + loadData={(selectedOptions) => loadData(selectedOptions)} | |
118 | + onChange={filterByCar} | |
119 | + fieldNames={{ value: 'id', label: 'name', }} | |
120 | + notFoundContent="暂无数据" | |
121 | + /> | |
122 | + </div> | |
111 | 123 | </Row> |
112 | 124 | </div> |
113 | 125 | ); | ... | ... |
src/pages/stock/ShopAuth/index.tsx
... | ... | @@ -4,8 +4,8 @@ import { PlusOutlined } from '@ant-design/icons'; |
4 | 4 | import { Button, Card, ConfigProvider, message, Popconfirm, Table } from 'antd'; |
5 | 5 | import zhCN from 'antd/lib/locale-provider/zh_CN'; |
6 | 6 | import moment from 'moment'; |
7 | -import { getListApi, cancelAuthApi, _carList, getDealerTreeApi } from './api'; | |
8 | -import { CarShop } from './interface.d'; | |
7 | +import { getListApi, _carList, getDealerTreeApi } from './api'; | |
8 | +import type { CarShop } from './interface.d'; | |
9 | 9 | import Filter from './components/Filter'; |
10 | 10 | import AuthModal from './components/AuthModal'; |
11 | 11 | import usePagination from '@/hooks/usePagination'; |
... | ... | @@ -16,13 +16,12 @@ const indexS = require('./index.less'); |
16 | 16 | |
17 | 17 | export default function CarShopList() { |
18 | 18 | const [shopOptions, setShopOptions] = useState<any[]>([]); |
19 | - const [shopValue, setShopValue] = useState<number[]>([]); | |
20 | 19 | const [visible, setVisible] = useState<boolean>(false); |
21 | 20 | const { list, loading, setLoading, setParams, paginationConfig, } = usePagination(getListApi, {}); |
22 | 21 | |
23 | - useEffect(() => { | |
24 | - fetchshopFlite(); | |
25 | - }, []); | |
22 | + // useEffect(() => { | |
23 | + // fetchshopFlite(); | |
24 | + // }, []); | |
26 | 25 | |
27 | 26 | async function fetchshopFlite() { |
28 | 27 | setLoading(true); |
... | ... | @@ -36,15 +35,6 @@ export default function CarShopList() { |
36 | 35 | } |
37 | 36 | } |
38 | 37 | |
39 | - function cancelAuth(id: number) { | |
40 | - cancelAuthApi(id).then(res => { | |
41 | - message.success("取消成功"); | |
42 | - setLoading(true); | |
43 | - }).catch(e => { | |
44 | - message.error(e.message); | |
45 | - }); | |
46 | - } | |
47 | - | |
48 | 38 | async function handleChangePage(_filterValue = {}) { |
49 | 39 | setParams({ ..._filterValue, current: 1 }, true) |
50 | 40 | } |
... | ... | @@ -53,26 +43,21 @@ export default function CarShopList() { |
53 | 43 | <PageHeaderWrapper title="门店授权"> |
54 | 44 | <Card className={indexS.page}> |
55 | 45 | <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}> |
56 | - <Filter | |
57 | - shopOption={shopOptions} | |
58 | - shopValue={shopValue} | |
59 | - onChangeShop={(value: number[]) => setShopValue(value)} | |
60 | - onFilter={(value: CarShop.QueryCarListParams) => handleChangePage(value)} | |
61 | - /> | |
62 | - <Button icon={<PlusOutlined />} type="primary" onClick={() => setVisible(true)}> | |
46 | + <Filter onFilter={(value: CarShop.QueryCarListParams) => handleChangePage(value)} /> | |
47 | + {/* <Button icon={<PlusOutlined />} type="primary" onClick={() => setVisible(true)}> | |
63 | 48 | 门店授权 |
64 | - </Button> | |
49 | + </Button> */} | |
65 | 50 | </div> |
66 | 51 | <ConfigProvider locale={zhCN}> |
67 | 52 | <Table |
68 | 53 | dataSource={list} |
69 | 54 | pagination={paginationConfig} |
70 | - rowKey={(record) => `${record.carId}`} | |
55 | + rowKey={(record) => `${record.id}`} | |
71 | 56 | loading={loading} |
72 | 57 | className={indexS.table} |
73 | 58 | > |
74 | - <Column title="门店ID" dataIndex="shopId" /> | |
75 | 59 | <Column title="门店名称" dataIndex="shopName" /> |
60 | + <Column title="门店ID" dataIndex="shopId" /> | |
76 | 61 | <Column |
77 | 62 | title="车辆图片" |
78 | 63 | dataIndex="carImg" |
... | ... | @@ -89,21 +74,6 @@ export default function CarShopList() { |
89 | 74 | dataIndex="createTime" |
90 | 75 | render={text => `${text ? moment(text).format("YYYY-MM-DD") : "-"}`} |
91 | 76 | /> |
92 | - <Column | |
93 | - title="操作" | |
94 | - render={(text, record: CarShop.carData) => ( | |
95 | - <React.Fragment> | |
96 | - <Popconfirm | |
97 | - title="确定取消授权?" | |
98 | - onConfirm={() => cancelAuth(record.id)} | |
99 | - okText="确定" | |
100 | - cancelText="取消" | |
101 | - > | |
102 | - <Button size="small">取消授权</Button> | |
103 | - </Popconfirm> | |
104 | - </React.Fragment> | |
105 | - )} | |
106 | - /> | |
107 | 77 | </Table> |
108 | 78 | </ConfigProvider> |
109 | 79 | <AuthModal | ... | ... |