Commit c1417ae61b1dded3c177f570c020a34493ab9b2b

Authored by 曾柯
2 parents 18220776 49e9d82b

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) =&gt; {
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) =&gt; {
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) =&gt; {
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) =&gt; {
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) =&gt; {
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
... ... @@ -169,8 +169,7 @@ function ProductSetting() {
169 169 setRecord(record);
170 170 }}
171 171 >
172   - {' '}
173   - 设置上架门店{' '}
  172 + 设置上架门店
174 173 </Button>
175 174 </div>
176 175 <div>
... ...
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&lt;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 &#39;@ant-design/icons&#39;;
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(&#39;./index.less&#39;);
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
... ...