Commit 2a14661064c5dc14290fa1846708c33a1a1e2b52
Merge branch 'master' into d-cas
Showing
77 changed files
with
3011 additions
and
486 deletions
config/routers/order3.ts
... | ... | @@ -316,6 +316,21 @@ export default [ |
316 | 316 | component: './order3/BuyCarLoanCost/subpages/AddConfig', |
317 | 317 | }, |
318 | 318 | { |
319 | + // 车贷银行返利和提成配置 | |
320 | + path: '/order3/rebateCommission', | |
321 | + component: './order3/RebateCommission', | |
322 | + }, | |
323 | + { | |
324 | + // 车贷银行返利和提成分期条件列表 | |
325 | + path: '/order3/rebateCommission/loanCondition', | |
326 | + component: './order3/RebateCommission/subpages/LoanCondition', | |
327 | + }, | |
328 | + { | |
329 | + // 车贷银行返利和提成分期条件新增 | |
330 | + path: '/order3/rebateCommission/loanCondition/edit', | |
331 | + component: './order3/RebateCommission/subpages/LoanCondition/subpages/LoanConditionEdit', | |
332 | + }, | |
333 | + { | |
319 | 334 | // 直营策车厂家促销设置 |
320 | 335 | path: '/order3/promotionSettings/directCarPromotion', |
321 | 336 | component: './order3/DirectCarPromotion', | ... | ... |
config/routers/performance.ts
... | ... | @@ -99,6 +99,11 @@ export default [ |
99 | 99 | path: '/morax/evaDataImport', |
100 | 100 | component: './performance/EvaDataImport', |
101 | 101 | }, |
102 | + /** 数据导入 */ | |
103 | + { | |
104 | + path: '/morax/DataImport', | |
105 | + component: './performance/DataImport', | |
106 | + }, | |
102 | 107 | /** 考评数据导入==> 查看数据清单 */ |
103 | 108 | { |
104 | 109 | path: '/morax/evaDataImport/edit/:id?/:dimensionType?', | ... | ... |
src/components/ApprovalProgress/index.tsx
... | ... | @@ -43,41 +43,6 @@ export default function ApprovalProgress({ orderNo }: Props) { |
43 | 43 | setProgress({ |
44 | 44 | loading: false, |
45 | 45 | data: res.data || [], |
46 | - // data: [ | |
47 | - // { | |
48 | - // // 审批中倒计时 | |
49 | - // approveTime: 1709741004000, | |
50 | - // approverName: 'Shinner', | |
51 | - // approverId: 2144, | |
52 | - // status: 1, | |
53 | - // opinion: '测试理由', | |
54 | - // efficientTime: 1709781004000, | |
55 | - // createTime: 1709721004000, | |
56 | - // roleNames: ['销售一级管理', '销售二级管理', '销售三级管理'], | |
57 | - // }, | |
58 | - // { | |
59 | - // // 审批中超时 | |
60 | - // approveTime: 1799722004000, | |
61 | - // approverName: 'Shinner', | |
62 | - // approverId: 2145, | |
63 | - // status: 1, | |
64 | - // opinion: '测试理由', | |
65 | - // efficientTime: 1709721004000, | |
66 | - // createTime: 1709721004000, | |
67 | - // roleNames: ['销售一级管理', '销售二级管理', '销售三级管理'], | |
68 | - // }, | |
69 | - // { | |
70 | - // // 审批结束超时 | |
71 | - // approveTime: 1799722004000, | |
72 | - // approverName: 'Shinner', | |
73 | - // approverId: 2146, | |
74 | - // status: 2, | |
75 | - // opinion: '测试理由', | |
76 | - // efficientTime: 1709781004000, | |
77 | - // createTime: 1709721004000, | |
78 | - // roleNames: ['销售一级管理', '销售二级管理', '销售三级管理'], | |
79 | - // }, | |
80 | - // ], | |
81 | 46 | }); |
82 | 47 | }) |
83 | 48 | .catch((error) => { | ... | ... |
src/components/ShopSelectNew/components/ShopModal.tsx
... | ... | @@ -38,6 +38,7 @@ interface Props { |
38 | 38 | showBrand?: boolean; //表格中是否展示授权品牌,默认展示 |
39 | 39 | showAfshop?: boolean; //表格中是否展示对应售后门店,默认展示 |
40 | 40 | destroyOnClose?: boolean; |
41 | + diyOptions?: Option; | |
41 | 42 | } |
42 | 43 | |
43 | 44 | export default function ShopModal({ |
... | ... | @@ -59,6 +60,7 @@ export default function ShopModal({ |
59 | 60 | showBrand = true, |
60 | 61 | showAfshop = true, |
61 | 62 | destroyOnClose = false, |
63 | + diyOptions, | |
62 | 64 | }: Props) { |
63 | 65 | const optionsStatus = useMemo(() => { |
64 | 66 | return { |
... | ... | @@ -191,12 +193,12 @@ export default function ShopModal({ |
191 | 193 | setSelected( |
192 | 194 | checked |
193 | 195 | ? listInitial.data |
194 | - .map((item) => ({ | |
195 | - ...item, | |
196 | - value: item.shopId ?? -1, | |
197 | - label: item.shopShortName, | |
198 | - })) | |
199 | - .filter((item) => (disabledShopIds.includes(item.shopId!) ? selected.find((s) => s.shopId === item.shopId) : true)) | |
196 | + .map((item) => ({ | |
197 | + ...item, | |
198 | + value: item.shopId ?? -1, | |
199 | + label: item.shopShortName, | |
200 | + })) | |
201 | + .filter((item) => (disabledShopIds.includes(item.shopId!) ? selected.find((s) => s.shopId === item.shopId) : true)) | |
200 | 202 | : selected.filter((s) => disabledShopIds.includes(s.shopId!)), |
201 | 203 | ); |
202 | 204 | }; |
... | ... | @@ -260,7 +262,7 @@ export default function ShopModal({ |
260 | 262 | <div style={{ width: 10 }} /> |
261 | 263 | <FeeweeFilterOption title="业态"> |
262 | 264 | <Select |
263 | - allowClear | |
265 | + allowClear={!diyOptions?.bizList?.length} | |
264 | 266 | placeholder="请选择业态" |
265 | 267 | mode="multiple" |
266 | 268 | disabled={disabledOptions?.includes('bizTypes')} |
... | ... | @@ -310,8 +312,8 @@ export default function ShopModal({ |
310 | 312 | </> |
311 | 313 | )} |
312 | 314 | > |
313 | - {optionInitial.data.bizList?.map((biz) => ( | |
314 | - <Select.Option key={biz.type} value={'' + biz.type!} disabled={defaultOptions.bizTypes?.includes('' + biz.type)}> | |
315 | + {(diyOptions?.bizList ?? optionInitial.data.bizList)?.map((biz) => ( | |
316 | + <Select.Option key={biz.type} value={'' + biz.type!} disabled={!diyOptions?.bizList?.length && defaultOptions.bizTypes?.includes('' + biz.type)}> | |
315 | 317 | {biz.name} |
316 | 318 | </Select.Option> |
317 | 319 | ))} |
... | ... | @@ -319,7 +321,7 @@ export default function ShopModal({ |
319 | 321 | </FeeweeFilterOption> |
320 | 322 | <FeeweeFilterOption title="区域"> |
321 | 323 | <Select |
322 | - allowClear | |
324 | + allowClear={!diyOptions?.regionList?.length} | |
323 | 325 | placeholder="请选择区域" |
324 | 326 | mode="multiple" |
325 | 327 | disabled={disabledOptions?.includes('regions')} |
... | ... | @@ -369,8 +371,8 @@ export default function ShopModal({ |
369 | 371 | </> |
370 | 372 | )} |
371 | 373 | > |
372 | - {optionInitial.data.regionList?.map((region) => ( | |
373 | - <Select.Option key={region.bh} value={region.bh!} disabled={defaultOptions.regions?.includes('' + region.bh)}> | |
374 | + {(diyOptions?.regionList ?? optionInitial.data.regionList)?.map((region) => ( | |
375 | + <Select.Option key={region.bh} value={region.bh!} disabled={!diyOptions?.regionList?.length && defaultOptions.regions?.includes('' + region.bh)}> | |
374 | 376 | {region.fullName} |
375 | 377 | </Select.Option> |
376 | 378 | ))} |
... | ... | @@ -378,7 +380,7 @@ export default function ShopModal({ |
378 | 380 | </FeeweeFilterOption> |
379 | 381 | <FeeweeFilterOption title="品牌"> |
380 | 382 | <Select |
381 | - allowClear | |
383 | + allowClear={!diyOptions?.brandList?.length} | |
382 | 384 | placeholder="请选择品牌" |
383 | 385 | mode="multiple" |
384 | 386 | disabled={disabledOptions?.includes('brands')} |
... | ... | @@ -428,8 +430,8 @@ export default function ShopModal({ |
428 | 430 | </> |
429 | 431 | )} |
430 | 432 | > |
431 | - {optionInitial.data.brandList?.map((brand) => ( | |
432 | - <Select.Option key={brand.id} value={'' + brand.id!} disabled={defaultOptions.brands?.includes('' + brand.id)}> | |
433 | + {(diyOptions?.brandList ?? optionInitial.data.brandList)?.map((brand) => ( | |
434 | + <Select.Option key={brand.id} value={'' + brand.id!} disabled={!diyOptions?.brandList?.length && defaultOptions.brands?.includes('' + brand.id)}> | |
433 | 435 | {brand.name} |
434 | 436 | </Select.Option> |
435 | 437 | ))} |
... | ... | @@ -437,7 +439,7 @@ export default function ShopModal({ |
437 | 439 | </FeeweeFilterOption> |
438 | 440 | <FeeweeFilterOption title="商家"> |
439 | 441 | <Select |
440 | - allowClear | |
442 | + allowClear={!diyOptions?.dealerList?.length} | |
441 | 443 | placeholder="请选择商家" |
442 | 444 | mode="multiple" |
443 | 445 | disabled={disabledOptions?.includes('dealers')} |
... | ... | @@ -487,8 +489,8 @@ export default function ShopModal({ |
487 | 489 | </> |
488 | 490 | )} |
489 | 491 | > |
490 | - {optionInitial.data.dealerList?.map((dealer) => ( | |
491 | - <Select.Option key={dealer.id} value={'' + dealer.id!} disabled={defaultOptions.dealers?.includes('' + dealer.id)}> | |
492 | + {(diyOptions?.dealerList ?? optionInitial.data.dealerList)?.map((dealer) => ( | |
493 | + <Select.Option key={dealer.id} value={'' + dealer.id!} disabled={!diyOptions?.dealerList?.length && defaultOptions.dealers?.includes('' + dealer.id)}> | |
492 | 494 | {dealer.name} |
493 | 495 | </Select.Option> |
494 | 496 | ))} | ... | ... |
src/components/ShopSelectNew/index.tsx
... | ... | @@ -9,7 +9,7 @@ import { isObjectChanged } from '@/utils/validate'; |
9 | 9 | import { Tag } from 'antd'; |
10 | 10 | import type { Ref } from 'react'; |
11 | 11 | import React, { forwardRef, memo, useEffect, useImperativeHandle, useState } from 'react'; |
12 | -import type { QueryParams, ShopSelectNewOptions, Value } from './api'; | |
12 | +import type { QueryParams, ShopSelectNewOptions, Value, Option } from './api'; | |
13 | 13 | import { getShopListApi, getShopListChooseOptionsApi } from './api'; |
14 | 14 | import Close from './components/Close'; |
15 | 15 | import ShopModal from './components/ShopModal'; |
... | ... | @@ -41,6 +41,7 @@ interface Props { |
41 | 41 | showBrand?: boolean; |
42 | 42 | showAfshop?: boolean; |
43 | 43 | destroyOnClose?: boolean; |
44 | + diyOptions?: Option; //自定义筛选项 | |
44 | 45 | } |
45 | 46 | |
46 | 47 | export interface ShopSelectNewRef { |
... | ... | @@ -66,6 +67,7 @@ function ShopSelectNew( |
66 | 67 | showBrand, |
67 | 68 | showAfshop, |
68 | 69 | destroyOnClose, |
70 | + diyOptions, | |
69 | 71 | }: Props, |
70 | 72 | ref: Ref<ShopSelectNewRef>, |
71 | 73 | ) { |
... | ... | @@ -223,6 +225,7 @@ function ShopSelectNew( |
223 | 225 | showBrand={showBrand} |
224 | 226 | showAfshop={showAfshop} |
225 | 227 | destroyOnClose={destroyOnClose} |
228 | + diyOptions={diyOptions} | |
226 | 229 | /> |
227 | 230 | )} |
228 | 231 | </div> | ... | ... |
src/pages/Login/index.tsx
... | ... | @@ -29,7 +29,7 @@ let tiktakTimer: any = null; |
29 | 29 | // 轮询开始时间 |
30 | 30 | let loopstartTime: any = null; |
31 | 31 | // 二维码超时时间 |
32 | -const overDueTimeLimit: number = 1000 * 10; | |
32 | +const overDueTimeLimit: number = 1000 * 20; | |
33 | 33 | |
34 | 34 | const LoginPage = () => { |
35 | 35 | const [qrStatusCode, setQrStatusCode] = useState<number>(-1); | ... | ... |
src/pages/Pay/wxPayConfig/components/EditModal.tsx
... | ... | @@ -25,13 +25,13 @@ function EditModal({ visible, onCancel, handleOk, itemData, onRefresh, configLis |
25 | 25 | |
26 | 26 | useEffect(() => { |
27 | 27 | queryShop({ dealerId: itemData.dealerId }); |
28 | - if (form) { | |
28 | + if (form && visible) { | |
29 | 29 | const defaultList = itemData.shopInfos || []; |
30 | 30 | form.setFieldsValue({ |
31 | 31 | shops: defaultList |
32 | 32 | }); |
33 | 33 | } |
34 | - }, [itemData]); | |
34 | + }, [itemData, visible]); | |
35 | 35 | |
36 | 36 | // 筛选出已经有关联的门店 |
37 | 37 | const shopList = useMemo(() => { | ... | ... |
src/pages/attendance/FieldService/subpages/WorkAddress/api.tsx
1 | -import { http } from "@/typing/http"; | |
2 | -import request from "@/utils/request"; | |
3 | -import { ATTENDANCE_HOST,FVM_HOST } from "@/utils/host"; | |
1 | +import type { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { ATTENDANCE_HOST, FVM_HOST } from '@/utils/host'; | |
4 | 4 | |
5 | 5 | type PromiseResp<T> = http.PromiseResp<T>; |
6 | 6 | type PromisePageResp<T> = http.PromisePageResp<T>; |
... | ... | @@ -74,7 +74,7 @@ export interface AddParams { |
74 | 74 | addressType?: number; //地址类型 |
75 | 75 | } |
76 | 76 | |
77 | -export interface Reason { | |
77 | +export interface Reason extends AddParams { | |
78 | 78 | id?: number; |
79 | 79 | reason?: string; //理由 |
80 | 80 | addressType?: number; |
... | ... | @@ -103,7 +103,7 @@ export function reasonSaveOrUpdateApi(params: AddParams) { |
103 | 103 | * 删除理由 |
104 | 104 | * /reason/setting/del |
105 | 105 | */ |
106 | -export function reasonDeleteApi(params: { reasonId?: number,[key:string]:any }) { | |
106 | +export function reasonDeleteApi(params: { reasonId?: number; [key: string]: any }) { | |
107 | 107 | return request.del(`${ATTENDANCE_HOST}/reason/setting/del`, { params }); |
108 | 108 | } |
109 | 109 | |
... | ... | @@ -132,7 +132,7 @@ export function GetAddressApi(params: AddressParams): PromisePageResp<AddressIte |
132 | 132 | |
133 | 133 | export interface StorageParams { |
134 | 134 | brandId?: number; |
135 | - type?:number; | |
135 | + type?: number; | |
136 | 136 | } |
137 | 137 | export interface StorageItems { |
138 | 138 | id?: number; //库房id |
... | ... | @@ -165,10 +165,10 @@ export function reasonAddressDeleteApi(params: { addressId?: number; [key: strin |
165 | 165 | return request.del(`${ATTENDANCE_HOST}/reason/address/del`, { params }); |
166 | 166 | } |
167 | 167 | |
168 | -interface OutsideTypeItem{ | |
169 | - outsideType?:number;//外勤类型值 | |
170 | - outsideTypeName?:string;//外勤类型名称 | |
171 | - tags?:string; | |
168 | +interface OutsideTypeItem { | |
169 | + outsideType?: number; //外勤类型值 | |
170 | + outsideTypeName?: string; //外勤类型名称 | |
171 | + tags?: string; | |
172 | 172 | } |
173 | 173 | /** |
174 | 174 | * 获取系统配置的外勤类型列表 |
... | ... | @@ -177,4 +177,4 @@ interface OutsideTypeItem{ |
177 | 177 | |
178 | 178 | export function getOutsideTypeListApi(): PromiseResp<OutsideTypeItem[]> { |
179 | 179 | return request.get(`${ATTENDANCE_HOST}/reason/setting/getOutsideTypeList`); |
180 | -} | |
181 | 180 | \ No newline at end of file |
181 | +} | ... | ... |
src/pages/attendance/FieldService/subpages/WorkAddress/components/TripReasonModal.tsx
1 | -import React, { useEffect, useState } from "react"; | |
2 | -import { Modal, Form, message, Select, Input } from "antd"; | |
3 | -import * as API from "../api"; | |
4 | -import { addrData } from "@/pages/attendance/TravelSetting/TravelAddress/entity"; | |
5 | -import { Reason, getOutsideTypeListApi } from "../api"; | |
6 | -import useInitial from "@/hooks/useInitail"; | |
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Modal, Form, message, Select, Input } from 'antd'; | |
3 | +import * as API from '../api'; | |
4 | +import { addrData } from '@/pages/attendance/TravelSetting/TravelAddress/entity'; | |
5 | +import type { Reason} from '../api'; | |
6 | +import { getOutsideTypeListApi } from '../api'; | |
7 | +import useInitial from '@/hooks/useInitail'; | |
7 | 8 | |
8 | 9 | const FormItem = Form.Item; |
9 | 10 | |
10 | 11 | interface Props { |
11 | 12 | tripReasonModal: { visible: boolean; current?: Reason }; |
12 | - onClose: (fresh?:boolean)=>void; | |
13 | + onClose: (fresh?: boolean, newData?: API.Reason) => void; | |
13 | 14 | } |
14 | 15 | |
15 | 16 | export default function ModalIndex(props: Props) { |
... | ... | @@ -29,14 +30,14 @@ export default function ModalIndex(props: Props) { |
29 | 30 | function submit(params: any) { |
30 | 31 | const { fieldType = {}, addressType } = params; |
31 | 32 | const res = data.find((item) => item.outsideType === fieldType.value); |
32 | - const _param = { ...res, type: 1, id: current.id, reason: res!.outsideTypeName, addressType }; | |
33 | + const _param: API.AddParams = { ...res, type: 1, id: current.id, reason: res!.outsideTypeName, addressType }; | |
33 | 34 | setLoading(true); |
34 | 35 | API.reasonSaveOrUpdateApi(_param) |
35 | 36 | .then(() => { |
36 | 37 | setLoading(false); |
37 | 38 | form.resetFields(); |
38 | - message.success("保存成功"); | |
39 | - onClose && onClose(true); | |
39 | + message.success('保存成功'); | |
40 | + onClose && onClose(true, _param); | |
40 | 41 | }) |
41 | 42 | .catch((e) => { |
42 | 43 | setLoading(false); |
... | ... | @@ -46,7 +47,7 @@ export default function ModalIndex(props: Props) { |
46 | 47 | |
47 | 48 | return ( |
48 | 49 | <Modal |
49 | - title={`${current.id ? "编辑" : "新增"}外勤类型`} | |
50 | + title={`${current.id ? '编辑' : '新增'}外勤类型`} | |
50 | 51 | open={visible} |
51 | 52 | onOk={form.submit} |
52 | 53 | onCancel={() => { |
... | ... | @@ -59,14 +60,8 @@ export default function ModalIndex(props: Props) { |
59 | 60 | confirmLoading={loading} |
60 | 61 | > |
61 | 62 | <Form form={form} onFinish={submit} labelCol={{ span: 6 }} wrapperCol={{ span: 20 }}> |
62 | - <FormItem name="fieldType" label="外勤类型" rules={[{ required: true, message: "请输入外勤类型" }]}> | |
63 | - <Select | |
64 | - placeholder="请选择外勤类型" | |
65 | - labelInValue | |
66 | - showSearch | |
67 | - optionFilterProp="children" | |
68 | - disabled={!!current.id} | |
69 | - > | |
63 | + <FormItem name="fieldType" label="外勤类型" rules={[{ required: true, message: '请输入外勤类型' }]}> | |
64 | + <Select placeholder="请选择外勤类型" labelInValue showSearch optionFilterProp="children" disabled={!!current.id}> | |
70 | 65 | {data.map((item: any) => ( |
71 | 66 | <Select.Option value={item.outsideType} key={item.outsideType}> |
72 | 67 | {item.outsideTypeName} |
... | ... | @@ -74,7 +69,7 @@ export default function ModalIndex(props: Props) { |
74 | 69 | ))} |
75 | 70 | </Select> |
76 | 71 | </FormItem> |
77 | - <FormItem name="addressType" label="外勤地址类型" rules={[{ required: true, message: "请选择外勤地址类型" }]}> | |
72 | + <FormItem name="addressType" label="外勤地址类型" rules={[{ required: true, message: '请选择外勤地址类型' }]}> | |
78 | 73 | <Select placeholder="请选择外勤地址类型"> |
79 | 74 | {addrData.map((item: any) => ( |
80 | 75 | <Select.Option value={item.id} key={item.id}> | ... | ... |
src/pages/attendance/FieldService/subpages/WorkAddress/index.tsx
... | ... | @@ -95,10 +95,14 @@ function WorkKnowledgeBase() { |
95 | 95 | setReasonParams({ reason: e }, true); |
96 | 96 | } |
97 | 97 | |
98 | - function onClose(fresh?: boolean) { | |
98 | + function onClose(fresh?: boolean, newData?: API.Reason) { | |
99 | 99 | setTripReasonModal({ visible: false, current: {} }); |
100 | 100 | if (fresh) { |
101 | + if (newData) { | |
102 | + setSelectedRows(newData); | |
103 | + } | |
101 | 104 | setReasonParams({ ...reasonParams }, true); |
105 | + setParams({}, true); | |
102 | 106 | } |
103 | 107 | } |
104 | 108 | ... | ... |
src/pages/capital/ReceiveRules/component/AddAuthItems.tsx
... | ... | @@ -84,7 +84,20 @@ function CreateModal(props: Props) { |
84 | 84 | )} |
85 | 85 | {!postDimension ? ( |
86 | 86 | <FormItem name="shopIds" label="适用门店" rules={[{ required: true }]}> |
87 | - <ShopSelectNew onChange={(v) => v && setShopIds(v.map((i) => Number(i.value)))} multiple={multiple} disabled={disabled} /> | |
87 | + <ShopSelectNew | |
88 | + defaultOptions={{ bizTypes: '1,2,5' }} | |
89 | + diyOptions={{ | |
90 | + bizList: [ | |
91 | + { type: 1, name: '新车销售' }, | |
92 | + { type: 2, name: '售后' }, | |
93 | + { type: 5, name: '交付中心' }, | |
94 | + ] | |
95 | + }} | |
96 | + onDefaultOptionsChangeFetch | |
97 | + onChange={(v) => v && setShopIds(v.map((i) => Number(i.value)))} | |
98 | + multiple={multiple} | |
99 | + disabled={disabled} | |
100 | + /> | |
88 | 101 | </FormItem> |
89 | 102 | ) : null} |
90 | 103 | {!postDimension ? ( | ... | ... |
src/pages/capital/ReceiveRules/subPages/GoodsDimension/components/PageAuthEdit/index.tsx
... | ... | @@ -169,6 +169,14 @@ export default function SpecConfig(props: Props) { |
169 | 169 | <Row justify="space-between" style={{ marginBottom: 10 }}> |
170 | 170 | <Row> |
171 | 171 | <ShopSelectNew |
172 | + defaultOptions={{ bizTypes: '1,2,5' }} | |
173 | + diyOptions={{ | |
174 | + bizList: [ | |
175 | + { type: 1, name: '新车销售' }, | |
176 | + { type: 2, name: '售后' }, | |
177 | + { type: 5, name: '交付中心' }, | |
178 | + ] | |
179 | + }} | |
172 | 180 | value={innerParams.shopId ? [{ value: innerParams.shopId, label: innerParams.shopName }] : undefined} |
173 | 181 | style={{ width: 200, marginRight: 15 }} |
174 | 182 | onChange={(v: Value) => onFilter({ shopId: v && v[0] ? v[0].value : undefined, shopName: v && v[0] ? v[0].label : undefined })} | ... | ... |
src/pages/capital/ReceiveRules/subPages/ShopsDimension/components/Filter.tsx
... | ... | @@ -23,7 +23,17 @@ const AdvancedSearchForm = ({ onFilter }: Props) => { |
23 | 23 | }, |
24 | 24 | ]} |
25 | 25 | > |
26 | - <ShopSelectNew onChange={form.submit} /> | |
26 | + <ShopSelectNew | |
27 | + defaultOptions={{ bizTypes: '1,2,5' }} | |
28 | + diyOptions={{ | |
29 | + bizList: [ | |
30 | + { type: 1, name: '新车销售' }, | |
31 | + { type: 2, name: '售后' }, | |
32 | + { type: 5, name: '交付中心' }, | |
33 | + ], | |
34 | + }} | |
35 | + onChange={form.submit} | |
36 | + /> | |
27 | 37 | </Form.Item> |
28 | 38 | </Col> |
29 | 39 | <Col span={8}> |
... | ... | @@ -41,10 +51,7 @@ const AdvancedSearchForm = ({ onFilter }: Props) => { |
41 | 51 | </Form.Item> |
42 | 52 | </Col> |
43 | 53 | <Col span={6}> |
44 | - <Form.Item | |
45 | - name="keywords" | |
46 | - label="搜索" | |
47 | - > | |
54 | + <Form.Item name="keywords" label="搜索"> | |
48 | 55 | <Input allowClear placeholder="物品名称/规格型号" /> |
49 | 56 | </Form.Item> |
50 | 57 | </Col> |
... | ... | @@ -63,13 +70,10 @@ const AdvancedSearchForm = ({ onFilter }: Props) => { |
63 | 70 | }; |
64 | 71 | |
65 | 72 | return ( |
66 | - <Form | |
67 | - form={form} | |
68 | - name="advanced_search" | |
69 | - className="ant-advanced-search-form" | |
70 | - onFinish={onFinish} | |
71 | - > | |
72 | - <Row style={{ height: 45 }} gutter={24}>{getFields()}</Row> | |
73 | + <Form form={form} name="advanced_search" className="ant-advanced-search-form" onFinish={onFinish}> | |
74 | + <Row style={{ height: 45 }} gutter={24}> | |
75 | + {getFields()} | |
76 | + </Row> | |
73 | 77 | {/* <Row> |
74 | 78 | <Col span={24} style={{ textAlign: 'right' }}> |
75 | 79 | <Button type="primary" htmlType="submit"> |
... | ... | @@ -87,4 +91,4 @@ const Filter: React.FC<Props> = (props) => ( |
87 | 91 | </div> |
88 | 92 | ); |
89 | 93 | |
90 | -export default Filter; | |
91 | 94 | \ No newline at end of file |
95 | +export default Filter; | ... | ... |
src/pages/carinsur/insureSaleconfig/components/CreateModal.tsx
1 | 1 | import React, { useState, useEffect } from 'react'; |
2 | 2 | import '@ant-design/compatible/assets/index.css'; |
3 | -import { Select, Modal, Form, message, InputNumber, Switch, Input } from 'antd'; | |
3 | +import { Select, Modal, Form, message, InputNumber, Input, Radio } from 'antd'; | |
4 | 4 | import { getCompanyList, saveData } from '../api'; |
5 | 5 | |
6 | 6 | const FormItem = Form.Item; |
7 | 7 | const Option = Select.Option; |
8 | +const RadioGroup = Radio.Group; | |
8 | 9 | |
9 | 10 | interface Props { |
10 | 11 | record: InsurRepair.listItem; |
... | ... | @@ -108,13 +109,13 @@ export default function CreateModal({ onCancel, record, onRrfreshing, visible }: |
108 | 109 | <Input placeholder="出保占比" /> |
109 | 110 | </Form.Item> |
110 | 111 | </Form.Item> |
111 | - <Form.Item | |
112 | - name="controlMonthlySaleAmount" | |
113 | - valuePropName="checked" | |
114 | - rules={[{ required: true, message: '该选项为必填项' }]} | |
115 | - label="是否控制月出保金额" | |
116 | - > | |
117 | - <Switch /> | |
112 | + <Form.Item name="controlMonthlySaleAmount" rules={[{ required: true, message: '该选项为必填项' }]} label="是否控制月出保金额"> | |
113 | + <RadioGroup | |
114 | + options={[ | |
115 | + { value: true, label: '是' }, | |
116 | + { value: false, label: '否' }, | |
117 | + ]} | |
118 | + /> | |
118 | 119 | </Form.Item> |
119 | 120 | <FormItem |
120 | 121 | label="月出保金额浮动比例≤" | ... | ... |
src/pages/cas/ClaimConfirmation/components/SpecialFeeConfirm.tsx
... | ... | @@ -227,6 +227,9 @@ export default function SpecialFeeDetail({ current, visible, setVisible, setLoad |
227 | 227 | <DescriptionItem label="故障描述" span={3}> |
228 | 228 | {(detail && detail.consultantDesc) || '--'} |
229 | 229 | </DescriptionItem> |
230 | + <DescriptionItem label="特情原因" span={3}> | |
231 | + {(detail && detail.remark) || '--'} | |
232 | + </DescriptionItem> | |
230 | 233 | <DescriptionItem label="附件" span={3}> |
231 | 234 | <ImageModal title="查看附件" fids={detail?.attachment ? detail?.attachment.split(',') : []} /> |
232 | 235 | </DescriptionItem> | ... | ... |
src/pages/cas/ClaimFiling/components/CustomerCareModal.tsx
... | ... | @@ -93,7 +93,7 @@ export default function CustomerCareModal({ current, visible, setVisible, setLoa |
93 | 93 | function submit(item: any) { |
94 | 94 | const params: any = { |
95 | 95 | claimId: detail?.claimId, |
96 | - claimNo: item.claimNo, | |
96 | + claimNo: item.claimNo?.trim(), | |
97 | 97 | submitDealerId: item.submitDealer.value, |
98 | 98 | tradeCompId: item.tradeComp.value, |
99 | 99 | tradeCompName: item.tradeComp.label, | ... | ... |
src/pages/cas/ClaimFiling/components/DetailModal.tsx
... | ... | @@ -241,7 +241,7 @@ export default function DetailMOdal({ current, visible, setVisible, setLoading: |
241 | 241 | function submit(item: any) { |
242 | 242 | const params = { |
243 | 243 | claimId: detail?.claimId, |
244 | - claimNo: item.claimNo, | |
244 | + claimNo: item.claimNo?.trim(), | |
245 | 245 | submitDealerId: item.submitDealer.value, |
246 | 246 | tradeCompId: item.tradeComp.value, |
247 | 247 | tradeCompName: item.tradeComp.label, | ... | ... |
src/pages/cas/ClaimFiling/components/SpecialFeeSubmit.tsx
... | ... | @@ -225,7 +225,7 @@ export default function DetailMOdal({ current, visible, setVisible, setLoading: |
225 | 225 | |
226 | 226 | function submit(item: any) { |
227 | 227 | const params = { |
228 | - claimNo: item.claimNo, | |
228 | + claimNo: item.claimNo?.trim(), | |
229 | 229 | claimId: detail?.claimOrderId, |
230 | 230 | submitDealerId: item.submitDealer.value, |
231 | 231 | tradeCompId: item.tradeComp.value, | ... | ... |
src/pages/cas/ClaimFiling/subpages/OldPart/components/EditModal.tsx
... | ... | @@ -112,7 +112,7 @@ export default function EditModal({ current, visible, onClose, onSuccess }: Prop |
112 | 112 | submitDealerName: values.submitDealer.label, |
113 | 113 | settlementUnit: values.settlementUnit.value, |
114 | 114 | settlementUnitName: values.settlementUnit.label, |
115 | - claimNo: values.claimNo, | |
115 | + claimNo: values.claimNo?.trim(), | |
116 | 116 | appendix: fids.join(','), |
117 | 117 | }; |
118 | 118 | ... | ... |
src/pages/coupon/CouponConfig/components/FullReduce.tsx
... | ... | @@ -43,6 +43,7 @@ export default function FullReduce({ info, readonly, form, getCouponType, confNo |
43 | 43 | form.setFieldsValue({ |
44 | 44 | aliasName: currentItems.type == 1 ? currentItems.name : undefined, |
45 | 45 | settlementType: 1, |
46 | + superimposed: false, | |
46 | 47 | settlementCalType: v.value === 'xjdhq' ? 1 : undefined, |
47 | 48 | }); |
48 | 49 | getCouponType && getCouponType(currentItems.type); |
... | ... | @@ -153,8 +154,11 @@ export default function FullReduce({ info, readonly, form, getCouponType, confNo |
153 | 154 | </Form.Item> |
154 | 155 | )} |
155 | 156 | {/* 全部默认不叠加false,立减券允许修改类型 */} |
156 | - <Form.Item label="可与其他同类型优惠券叠加使用" name="superimposed" valuePropName="checked"> | |
157 | - <Switch checkedChildren="是" unCheckedChildren="否" disabled={readonly || info.discountsType != 1} /> | |
157 | + <Form.Item label="可与其他同类型优惠券叠加使用" name="superimposed" > | |
158 | + <Radio.Group disabled={readonly || !!confNo || info.discountsType != 1}> | |
159 | + <Radio key={1} value={true}>可叠加</Radio> | |
160 | + <Radio key={0} value={false}>不可叠加</Radio> | |
161 | + </Radio.Group> | |
158 | 162 | </Form.Item> |
159 | 163 | <Form.Item label="优惠券券面金额" name="amount" rules={[{ required: true, message: '请输入优惠券销售价格' }]}> |
160 | 164 | <InputNumber disabled={readonly || !!confNo} style={{ width: '100%' }} placeholder="请输入" /> | ... | ... |
src/pages/ehr/GroupMobileRecord/api.ts
... | ... | @@ -3,14 +3,12 @@ |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | 4 | * @LastEditTime: 2023-02-24 09:17:40 |
5 | 5 | */ |
6 | -import request from "@/utils/request"; | |
7 | -import { ARCHIVES_HOST, EHR_HOST, FINANCE2_HOST } from "@/utils/host"; | |
8 | -import { http } from "@/typing/http"; | |
6 | +import request from '@/utils/request'; | |
7 | +import { ARCHIVES_HOST, EHR_HOST, FINANCE2_HOST } from '@/utils/host'; | |
8 | +import type { http } from '@/typing/http'; | |
9 | 9 | |
10 | 10 | /** 获取手机号列表 */ |
11 | -export function getMobileListApi( | |
12 | - params: GroupMobileRecord.QueryParams | |
13 | -): http.PromisePageResp<GroupMobileRecord.List> { | |
11 | +export function getMobileListApi(params: GroupMobileRecord.QueryParams): http.PromisePageResp<GroupMobileRecord.List> { | |
14 | 12 | return request.get(`${ARCHIVES_HOST}/mobile/list`, { params }); |
15 | 13 | } |
16 | 14 | |
... | ... | @@ -78,3 +76,12 @@ export function enableGroupMobileApi(id: number): http.PromiseResp<string> { |
78 | 76 | params: { id }, |
79 | 77 | }); |
80 | 78 | } |
79 | + | |
80 | +/** | |
81 | + * @description: 发放集团手机号 | |
82 | + * @param {GroupMobileRecord.ProvideParams} params | |
83 | + * @return {http.PromiseResp<string>} | |
84 | + */ | |
85 | +export function provideGroupMobileApi(params: GroupMobileRecord.ProvideParams): http.PromiseResp<string> { | |
86 | + return request.get(`${ARCHIVES_HOST}/mobile/provide`, { params }); | |
87 | +} | ... | ... |
src/pages/ehr/GroupMobileRecord/components/GroupMobileProvideModal.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { useStore } from '../index'; | |
3 | +import { Form, Modal, message } from 'antd'; | |
4 | +import MemberSelectNew from '@/components/MemberSelectNew'; | |
5 | +import { provideGroupMobileApi } from '@/pages/ehr/GroupMobileRecord/api'; | |
6 | + | |
7 | +export default function GroupMobileProvideModal() { | |
8 | + const { currentItem, setCurrentItem, provideMobileOpen, setProvideMobileOpen, pagination } = useStore(); | |
9 | + const [form] = Form.useForm(); | |
10 | + const [confirmLoading, setConfirmLoading] = useState(false); | |
11 | + | |
12 | + useEffect(() => { | |
13 | + if (!provideMobileOpen) { | |
14 | + form.resetFields(); | |
15 | + setCurrentItem(undefined); | |
16 | + } | |
17 | + }, [provideMobileOpen]); | |
18 | + | |
19 | + function onOk(val: any) { | |
20 | + const params = { | |
21 | + id: currentItem?.id, | |
22 | + staffId: val.staff?.[0]?.value, | |
23 | + }; | |
24 | + console.log(params); | |
25 | + setConfirmLoading(true); | |
26 | + const hide = message.loading('保存发放中...', 0); | |
27 | + provideGroupMobileApi(params) | |
28 | + .then((res) => { | |
29 | + hide(); | |
30 | + setConfirmLoading(false); | |
31 | + message.success(res.result); | |
32 | + pagination.setLoading(true); | |
33 | + setProvideMobileOpen(false); | |
34 | + }) | |
35 | + .catch((error) => { | |
36 | + hide(); | |
37 | + setConfirmLoading(false); | |
38 | + message.error(error.message ?? '保存发放失败'); | |
39 | + }); | |
40 | + } | |
41 | + | |
42 | + return ( | |
43 | + <Modal | |
44 | + title="发放集团手机号" | |
45 | + open={provideMobileOpen} | |
46 | + maskClosable={false} | |
47 | + onOk={form.submit} | |
48 | + onCancel={() => setProvideMobileOpen(false)} | |
49 | + confirmLoading={confirmLoading} | |
50 | + > | |
51 | + <Form form={form} onFinish={onOk}> | |
52 | + <Form.Item label="集团手机号"> | |
53 | + <span>{currentItem?.mobile ?? '-'}</span> | |
54 | + </Form.Item> | |
55 | + <Form.Item name="staff" label="发放人员" rules={[{ required: true, message: '请选择发放集团手机号人员' }]}> | |
56 | + <MemberSelectNew /> | |
57 | + </Form.Item> | |
58 | + </Form> | |
59 | + </Modal> | |
60 | + ); | |
61 | +} | ... | ... |
src/pages/ehr/GroupMobileRecord/components/GroupMobileRecordList.tsx
... | ... | @@ -3,20 +3,11 @@ |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | 4 | * @LastEditTime: 2023-05-11 14:06:10 |
5 | 5 | */ |
6 | -import React, { useState } from "react"; | |
7 | -import { | |
8 | - Table, | |
9 | - Divider, | |
10 | - Popconfirm, | |
11 | - message, | |
12 | - Popover, | |
13 | - Badge, | |
14 | - Modal, | |
15 | - Button, | |
16 | -} from "antd"; | |
17 | -import { CheckCircleFilled, CloseCircleFilled } from "@ant-design/icons"; | |
18 | -import { useStore } from "../index"; | |
19 | -import { deleteMobileApi } from "../api"; | |
6 | +import React, { useState } from 'react'; | |
7 | +import { Table, Divider, Popconfirm, message, Popover, Badge, Modal, Button } from 'antd'; | |
8 | +import { CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons'; | |
9 | +import { useStore } from '../index'; | |
10 | +import { deleteMobileApi } from '../api'; | |
20 | 11 | import { formatNumber } from '@/utils/utils'; |
21 | 12 | |
22 | 13 | const { Column } = Table; |
... | ... | @@ -32,28 +23,22 @@ export default function GroupMobileRecordList() { |
32 | 23 | setEditSubject, |
33 | 24 | disableGroupMobile, |
34 | 25 | enableGroupMobile, |
26 | + setProvideMobileOpen, | |
35 | 27 | } = useStore(); |
36 | - const { | |
37 | - list, | |
38 | - loading, | |
39 | - setLoading, | |
40 | - innerParams, | |
41 | - setParams, | |
42 | - paginationConfig, | |
43 | - } = pagination; | |
28 | + const { list, loading, setLoading, innerParams, setParams, paginationConfig } = pagination; | |
44 | 29 | const [modal, setModal] = useState<{ |
45 | 30 | visible: boolean; |
46 | - type?: "post" | "shop"; | |
31 | + type?: 'post' | 'shop'; | |
47 | 32 | }>({ |
48 | 33 | visible: false, |
49 | 34 | }); |
50 | 35 | |
51 | 36 | const deleteMobile = (id: number) => { |
52 | - const hide = message.loading("删除中,请稍后...", 0); | |
37 | + const hide = message.loading('删除中,请稍后...', 0); | |
53 | 38 | deleteMobileApi(id) |
54 | 39 | .then((res) => { |
55 | 40 | hide(); |
56 | - message.success("删除成功"); | |
41 | + message.success('删除成功'); | |
57 | 42 | if (list.length === 1 && (innerParams.current || 1) > 1) { |
58 | 43 | setParams({ current: innerParams.current! - 1 }, true); |
59 | 44 | } else { |
... | ... | @@ -66,15 +51,14 @@ export default function GroupMobileRecordList() { |
66 | 51 | }); |
67 | 52 | }; |
68 | 53 | |
54 | + function provideMobile(record: GroupMobileRecord.List) { | |
55 | + setCurrentItem(record); | |
56 | + setProvideMobileOpen(true); | |
57 | + } | |
58 | + | |
69 | 59 | return ( |
70 | 60 | <> |
71 | - <Table | |
72 | - dataSource={list} | |
73 | - rowKey="id" | |
74 | - loading={loading} | |
75 | - pagination={paginationConfig} | |
76 | - className="FWStickyTableHeader" | |
77 | - > | |
61 | + <Table dataSource={list} rowKey="id" loading={loading} pagination={paginationConfig} className="FWStickyTableHeader"> | |
78 | 62 | <Column |
79 | 63 | title="手机号信息" |
80 | 64 | align="left" |
... | ... | @@ -85,178 +69,142 @@ export default function GroupMobileRecordList() { |
85 | 69 | content={ |
86 | 70 | <span> |
87 | 71 | <span> |
88 | - <span style={{ color: "#999" }}>手机号:</span> | |
89 | - <span style={{ color: "#333" }}> | |
90 | - {record.mobile || "-"} | |
91 | - </span> | |
72 | + <span style={{ color: '#999' }}>手机号:</span> | |
73 | + <span style={{ color: '#333' }}>{record.mobile || '-'}</span> | |
92 | 74 | <Divider type="vertical" /> |
93 | - <span style={{ color: "#999" }}> | |
75 | + <span style={{ color: '#999' }}> | |
94 | 76 | 录音: |
95 | - {record.recording ? ( | |
96 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
97 | - ) : ( | |
98 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
99 | - )} | |
77 | + {record.recording ? <CheckCircleFilled style={{ color: '#52c41a' }} /> : <CloseCircleFilled style={{ color: '#ff4d4f' }} />} | |
100 | 78 | </span> |
101 | 79 | <Divider type="vertical" /> |
102 | - <span style={{ color: "#999" }}> | |
80 | + <span style={{ color: '#999' }}> | |
103 | 81 | 云转写: |
104 | 82 | <span> |
105 | 83 | {record.recordingTranslate ? ( |
106 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
84 | + <CheckCircleFilled style={{ color: '#52c41a' }} /> | |
107 | 85 | ) : ( |
108 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
86 | + <CloseCircleFilled style={{ color: '#ff4d4f' }} /> | |
109 | 87 | )} |
110 | 88 | </span> |
111 | 89 | </span> |
112 | 90 | <Divider type="vertical" /> |
113 | - <span style={{ color: "#999" }}> | |
91 | + <span style={{ color: '#999' }}> | |
114 | 92 | 云名片: |
115 | 93 | <span> |
116 | 94 | {record.businessCard ? ( |
117 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
95 | + <CheckCircleFilled style={{ color: '#52c41a' }} /> | |
118 | 96 | ) : ( |
119 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
97 | + <CloseCircleFilled style={{ color: '#ff4d4f' }} /> | |
120 | 98 | )} |
121 | 99 | </span> |
122 | 100 | </span> |
123 | 101 | <Divider type="vertical" /> |
124 | - <span style={{ color: "#999" }}> | |
102 | + <span style={{ color: '#999' }}> | |
125 | 103 | 最低月租: |
126 | 104 | <span> |
127 | - {record.monthRent ? ( | |
128 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
129 | - ) : ( | |
130 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
131 | - )} | |
105 | + {record.monthRent ? <CheckCircleFilled style={{ color: '#52c41a' }} /> : <CloseCircleFilled style={{ color: '#ff4d4f' }} />} | |
132 | 106 | </span> |
133 | 107 | </span> |
134 | 108 | </span> |
135 | 109 | <br /> |
136 | 110 | <span> |
137 | - <span style={{ color: "#999" }}>当前保管门店:</span> | |
138 | - <span style={{ color: "#333" }}> | |
139 | - {record.custodyShopName || "-"} | |
140 | - </span> | |
111 | + <span style={{ color: '#999' }}>当前保管门店:</span> | |
112 | + <span style={{ color: '#333' }}>{record.custodyShopName || '-'}</span> | |
141 | 113 | </span> |
142 | 114 | <br /> |
143 | 115 | <span> |
144 | - <span style={{ color: "#999" }}>往来单位:</span> | |
145 | - <span style={{ color: "#333" }}> | |
146 | - {record.subjectName || "-"} | |
147 | - </span> | |
116 | + <span style={{ color: '#999' }}>往来单位:</span> | |
117 | + <span style={{ color: '#333' }}>{record.subjectName || '-'}</span> | |
148 | 118 | </span> |
149 | 119 | </span> |
150 | 120 | } |
151 | 121 | > |
152 | 122 | <span> |
153 | 123 | <span className="span_limit_1"> |
154 | - <span style={{ color: "#999" }}>手机号:</span> | |
155 | - <span style={{ color: "#333" }}>{record.mobile || "-"}</span> | |
124 | + <span style={{ color: '#999' }}>手机号:</span> | |
125 | + <span style={{ color: '#333' }}>{record.mobile || '-'}</span> | |
156 | 126 | <Divider type="vertical" /> |
157 | - <span style={{ color: "#999" }}> | |
127 | + <span style={{ color: '#999' }}> | |
158 | 128 | 录音: |
159 | - {record.recording ? ( | |
160 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
161 | - ) : ( | |
162 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
163 | - )} | |
129 | + {record.recording ? <CheckCircleFilled style={{ color: '#52c41a' }} /> : <CloseCircleFilled style={{ color: '#ff4d4f' }} />} | |
164 | 130 | </span> |
165 | 131 | <Divider type="vertical" /> |
166 | - <span style={{ color: "#999" }}> | |
132 | + <span style={{ color: '#999' }}> | |
167 | 133 | 云转写: |
168 | 134 | <span> |
169 | 135 | {record.recordingTranslate ? ( |
170 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
136 | + <CheckCircleFilled style={{ color: '#52c41a' }} /> | |
171 | 137 | ) : ( |
172 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
138 | + <CloseCircleFilled style={{ color: '#ff4d4f' }} /> | |
173 | 139 | )} |
174 | 140 | </span> |
175 | 141 | </span> |
176 | 142 | <Divider type="vertical" /> |
177 | - <span style={{ color: "#999" }}> | |
143 | + <span style={{ color: '#999' }}> | |
178 | 144 | 云名片: |
179 | 145 | <span> |
180 | - {record.businessCard ? ( | |
181 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
182 | - ) : ( | |
183 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
184 | - )} | |
146 | + {record.businessCard ? <CheckCircleFilled style={{ color: '#52c41a' }} /> : <CloseCircleFilled style={{ color: '#ff4d4f' }} />} | |
185 | 147 | </span> |
186 | 148 | </span> |
187 | 149 | <Divider type="vertical" /> |
188 | - <span style={{ color: "#999" }}> | |
150 | + <span style={{ color: '#999' }}> | |
189 | 151 | 最低月租: |
190 | 152 | <span> |
191 | - {record.monthRent ? ( | |
192 | - <CheckCircleFilled style={{ color: "#52c41a" }} /> | |
193 | - ) : ( | |
194 | - <CloseCircleFilled style={{ color: "#ff4d4f" }} /> | |
195 | - )} | |
153 | + {record.monthRent ? <CheckCircleFilled style={{ color: '#52c41a' }} /> : <CloseCircleFilled style={{ color: '#ff4d4f' }} />} | |
196 | 154 | </span> |
197 | 155 | </span> |
198 | 156 | </span> |
199 | 157 | <span className="span_limit_1"> |
200 | - <span style={{ color: "#999" }}>运营商:</span> | |
201 | - <span style={{ color: "#333" }}> | |
202 | - {record.operatorName || "-"} | |
203 | - </span> | |
158 | + <span style={{ color: '#999' }}>运营商:</span> | |
159 | + <span style={{ color: '#333' }}>{record.operatorName || '-'}</span> | |
204 | 160 | <Divider type="vertical" /> |
205 | - <span style={{ color: "#999" }}>归属地:</span> | |
206 | - <span style={{ color: "#333" }}>{record.address || "-"}</span> | |
161 | + <span style={{ color: '#999' }}>归属地:</span> | |
162 | + <span style={{ color: '#333' }}>{record.address || '-'}</span> | |
207 | 163 | <Divider type="vertical" /> |
208 | - <span style={{ color: "#999" }}>预充金额:</span> | |
209 | - <span style={{ color: "#333" }}> | |
210 | - {record.preChargeAmount | |
211 | - ? formatNumber(record.preChargeAmount) | |
212 | - : "-"} | |
213 | - </span> | |
164 | + <span style={{ color: '#999' }}>预充金额:</span> | |
165 | + <span style={{ color: '#333' }}>{record.preChargeAmount ? formatNumber(record.preChargeAmount) : '-'}</span> | |
214 | 166 | </span> |
215 | 167 | <span className="span_limit_1"> |
216 | - <span style={{ color: "#999" }}>归属门店:</span> | |
217 | - <span style={{ color: "#333" }}> | |
168 | + <span style={{ color: '#999' }}>归属门店:</span> | |
169 | + <span style={{ color: '#333' }}> | |
218 | 170 | {(record?.shopList || []).length > 0 ? ( |
219 | 171 | <a |
220 | 172 | onClick={() => { |
221 | 173 | setCurrentItem(record); |
222 | - setModal({ visible: true, type: "shop" }); | |
174 | + setModal({ visible: true, type: 'shop' }); | |
223 | 175 | }} |
224 | 176 | > |
225 | 177 | 查看 |
226 | 178 | </a> |
227 | 179 | ) : ( |
228 | - "-" | |
180 | + '-' | |
229 | 181 | )} |
230 | 182 | </span> |
231 | 183 | <Divider type="vertical" /> |
232 | - <span style={{ color: "#999" }}>适用岗位:</span> | |
233 | - <span style={{ color: "#333" }}> | |
184 | + <span style={{ color: '#999' }}>适用岗位:</span> | |
185 | + <span style={{ color: '#333' }}> | |
234 | 186 | {(record?.postList || []).length > 0 ? ( |
235 | 187 | <a |
236 | 188 | onClick={() => { |
237 | 189 | setCurrentItem(record); |
238 | - setModal({ visible: true, type: "post" }); | |
190 | + setModal({ visible: true, type: 'post' }); | |
239 | 191 | }} |
240 | 192 | > |
241 | 193 | 查看 |
242 | 194 | </a> |
243 | 195 | ) : ( |
244 | - "-" | |
196 | + '-' | |
245 | 197 | )} |
246 | 198 | </span> |
247 | 199 | </span> |
248 | 200 | <span className="span_limit_1"> |
249 | - <span style={{ color: "#999" }}>当前保管门店:</span> | |
250 | - <span style={{ color: "#333" }}> | |
251 | - {record.custodyShopName || "-"} | |
252 | - </span> | |
201 | + <span style={{ color: '#999' }}>当前保管门店:</span> | |
202 | + <span style={{ color: '#333' }}>{record.custodyShopName || '-'}</span> | |
253 | 203 | </span> |
254 | 204 | <span className="span_limit_1"> |
255 | - <span style={{ color: "#999" }}>往来单位:</span> | |
256 | - <span style={{ color: "#333" }}> | |
257 | - {record.subjectName || "-"} | |
258 | - </span> | |
259 | - {record.status === StatusText["空闲"] ? null : ( | |
205 | + <span style={{ color: '#999' }}>往来单位:</span> | |
206 | + <span style={{ color: '#333' }}>{record.subjectName || '-'}</span> | |
207 | + {record.status === StatusText['空闲'] ? null : ( | |
260 | 208 | <> |
261 | 209 | |
262 | 210 | <a |
... | ... | @@ -279,60 +227,50 @@ export default function GroupMobileRecordList() { |
279 | 227 | title="人员信息" |
280 | 228 | align="left" |
281 | 229 | width="30%" |
282 | - render={(record: GroupMobileRecord.List) => (record.staffName ? ( | |
283 | - <Popover | |
284 | - placement="topLeft" | |
285 | - content={ | |
286 | - <> | |
287 | - <span> | |
230 | + render={(record: GroupMobileRecord.List) => | |
231 | + record.staffName ? ( | |
232 | + <Popover | |
233 | + placement="topLeft" | |
234 | + content={ | |
235 | + <> | |
288 | 236 | <span> |
289 | - <span style={{ color: "#999" }}>员工姓名:</span> | |
290 | - <span style={{ color: "#333" }}> | |
291 | - {record.staffName || "-"} | |
237 | + <span> | |
238 | + <span style={{ color: '#999' }}>员工姓名:</span> | |
239 | + <span style={{ color: '#333' }}>{record.staffName || '-'}</span> | |
292 | 240 | </span> |
293 | - </span> | |
294 | - <br /> | |
295 | - <span> | |
296 | - <span style={{ color: "#999" }}>在职门店:</span> | |
297 | - <span style={{ color: "#333" }}> | |
298 | - {record.staffShopName || "-"} | |
241 | + <br /> | |
242 | + <span> | |
243 | + <span style={{ color: '#999' }}>在职门店:</span> | |
244 | + <span style={{ color: '#333' }}>{record.staffShopName || '-'}</span> | |
299 | 245 | </span> |
300 | - </span> | |
301 | - <br /> | |
302 | - <span> | |
303 | - <span style={{ color: "#999" }}>人员岗位:</span> | |
304 | - <span style={{ color: "#333" }}> | |
305 | - {record.staffPostName || "-"} | |
246 | + <br /> | |
247 | + <span> | |
248 | + <span style={{ color: '#999' }}>人员岗位:</span> | |
249 | + <span style={{ color: '#333' }}>{record.staffPostName || '-'}</span> | |
306 | 250 | </span> |
307 | 251 | </span> |
308 | - </span> | |
309 | - </> | |
252 | + </> | |
310 | 253 | } |
311 | - > | |
312 | - <span> | |
313 | - <span className="span_limit_1"> | |
314 | - <span style={{ color: "#999" }}>员工姓名:</span> | |
315 | - <span style={{ color: "#333" }}> | |
316 | - {record.staffName || "-"} | |
254 | + > | |
255 | + <span> | |
256 | + <span className="span_limit_1"> | |
257 | + <span style={{ color: '#999' }}>员工姓名:</span> | |
258 | + <span style={{ color: '#333' }}>{record.staffName || '-'}</span> | |
317 | 259 | </span> |
318 | - </span> | |
319 | - <span className="span_limit_1"> | |
320 | - <span style={{ color: "#999" }}>在职门店:</span> | |
321 | - <span style={{ color: "#333" }}> | |
322 | - {record.staffShopName || "-"} | |
260 | + <span className="span_limit_1"> | |
261 | + <span style={{ color: '#999' }}>在职门店:</span> | |
262 | + <span style={{ color: '#333' }}>{record.staffShopName || '-'}</span> | |
323 | 263 | </span> |
324 | - </span> | |
325 | - <span className="span_limit_1"> | |
326 | - <span style={{ color: "#999" }}>人员岗位:</span> | |
327 | - <span style={{ color: "#333" }}> | |
328 | - {record.staffPostName || "-"} | |
264 | + <span className="span_limit_1"> | |
265 | + <span style={{ color: '#999' }}>人员岗位:</span> | |
266 | + <span style={{ color: '#333' }}>{record.staffPostName || '-'}</span> | |
329 | 267 | </span> |
330 | 268 | </span> |
331 | - </span> | |
332 | - </Popover> | |
269 | + </Popover> | |
333 | 270 | ) : ( |
334 | - <span style={{ color: "#999" }}>暂未使用</span> | |
335 | - ))} | |
271 | + <span style={{ color: '#999' }}>暂未使用</span> | |
272 | + ) | |
273 | + } | |
336 | 274 | /> |
337 | 275 | <Column |
338 | 276 | title="状态" |
... | ... | @@ -350,8 +288,7 @@ export default function GroupMobileRecordList() { |
350 | 288 | align="left" |
351 | 289 | render={(record: GroupMobileRecord.List) => ( |
352 | 290 | <> |
353 | - {record.status !== StatusText.待停用 && | |
354 | - record.status !== StatusText.停用 ? ( | |
291 | + {record.status !== StatusText.待停用 && record.status !== StatusText.停用 ? ( | |
355 | 292 | <> |
356 | 293 | <a |
357 | 294 | onClick={() => { |
... | ... | @@ -362,21 +299,21 @@ export default function GroupMobileRecordList() { |
362 | 299 | 编辑 |
363 | 300 | </a> |
364 | 301 | <Divider type="vertical" /> |
365 | - <Popconfirm | |
366 | - title={`确定停用【${record.mobile}】`} | |
367 | - onConfirm={() => disableGroupMobile(record.id!)} | |
368 | - > | |
369 | - <a style={{ color: "red" }}>停用</a> | |
302 | + <Popconfirm title={`确定停用【${record.mobile}】`} onConfirm={() => disableGroupMobile(record.id!)}> | |
303 | + <a style={{ color: 'red' }}>停用</a> | |
370 | 304 | </Popconfirm> |
371 | 305 | </> |
372 | 306 | ) : ( |
373 | - <Popconfirm | |
374 | - title={`确定启用【${record.mobile}】`} | |
375 | - onConfirm={() => enableGroupMobile(record.id!)} | |
376 | - > | |
307 | + <Popconfirm title={`确定启用【${record.mobile}】`} onConfirm={() => enableGroupMobile(record.id!)}> | |
377 | 308 | <a>启用</a> |
378 | 309 | </Popconfirm> |
379 | 310 | )} |
311 | + {record.status === StatusText.空闲 ? ( | |
312 | + <> | |
313 | + <Divider type="vertical" /> | |
314 | + <a onClick={() => provideMobile(record)}>发放</a> | |
315 | + </> | |
316 | + ) : null} | |
380 | 317 | </> |
381 | 318 | )} |
382 | 319 | /> |
... | ... | @@ -395,7 +332,7 @@ export default function GroupMobileRecordList() { |
395 | 332 | } |
396 | 333 | |
397 | 334 | interface ShopModalProps { |
398 | - type?: "post" | "shop"; | |
335 | + type?: 'post' | 'shop'; | |
399 | 336 | visible: boolean; |
400 | 337 | onCancel: () => void; |
401 | 338 | data?: GroupMobileRecord.List; |
... | ... | @@ -404,9 +341,7 @@ interface ShopModalProps { |
404 | 341 | function ShopModal({ type, visible, onCancel, data }: ShopModalProps) { |
405 | 342 | return ( |
406 | 343 | <Modal |
407 | - title={`${data?.mobile}-${ | |
408 | - type ? (type == "post" ? "适用岗位" : "归属门店") : "" | |
409 | - }`} | |
344 | + title={`${data?.mobile}-${type ? (type == 'post' ? '适用岗位' : '归属门店') : ''}`} | |
410 | 345 | visible={visible} |
411 | 346 | maskClosable={false} |
412 | 347 | onOk={onCancel} |
... | ... | @@ -418,10 +353,8 @@ function ShopModal({ type, visible, onCancel, data }: ShopModalProps) { |
418 | 353 | ]} |
419 | 354 | // afterClose={() => setCurrentPostItem(undefined)} |
420 | 355 | > |
421 | - {type === "shop" && | |
422 | - data?.shopList?.map((shop) => <p key={shop.shopId}>{shop.shopName}</p>)} | |
423 | - {type === "post" && | |
424 | - data?.postList?.map((post) => <p key={post.postId}>{post.postName}</p>)} | |
356 | + {type === 'shop' && data?.shopList?.map((shop) => <p key={shop.shopId}>{shop.shopName}</p>)} | |
357 | + {type === 'post' && data?.postList?.map((post) => <p key={post.postId}>{post.postName}</p>)} | |
425 | 358 | </Modal> |
426 | 359 | ); |
427 | 360 | } | ... | ... |
src/pages/ehr/GroupMobileRecord/index.tsx
1 | 1 | /* |
2 | 2 | * @Date: 2021-01-05 14:24:23 |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | - * @LastEditTime: 2023-09-02 16:16:24 | |
4 | + * @LastEditTime: 2024-04-15 11:11:53 | |
5 | 5 | */ |
6 | 6 | import React from 'react'; |
7 | 7 | import { Card, Button, Row, Input, ConfigProvider, Select } from 'antd'; |
... | ... | @@ -10,6 +10,7 @@ import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
10 | 10 | import { PlusOutlined } from '@ant-design/icons'; |
11 | 11 | import List from './components/GroupMobileRecordList'; |
12 | 12 | import Modal from './components/GroupMobileRecordModal'; |
13 | +import ProvideMobileModal from './components/GroupMobileProvideModal'; | |
13 | 14 | import { createStore } from '@/hooks/moz'; |
14 | 15 | import store from './store'; |
15 | 16 | import { debounce } from 'lodash'; |
... | ... | @@ -267,6 +268,7 @@ function GroupMobileRecord() { |
267 | 268 | <List /> |
268 | 269 | </Card> |
269 | 270 | <Modal /> |
271 | + <ProvideMobileModal /> | |
270 | 272 | </ConfigProvider> |
271 | 273 | </PageHeaderWrapper> |
272 | 274 | ); | ... | ... |
src/pages/ehr/GroupMobileRecord/interface.d.ts
src/pages/ehr/GroupMobileRecord/store.ts
... | ... | @@ -3,9 +3,9 @@ |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | 4 | * @LastEditTime: 2023-02-24 09:30:52 |
5 | 5 | */ |
6 | -import usePagination from "@/hooks/usePagination"; | |
7 | -import useInitail from "@/hooks/useInitail"; | |
8 | -import { useState } from "react"; | |
6 | +import usePagination from '@/hooks/usePagination'; | |
7 | +import useInitail from '@/hooks/useInitail'; | |
8 | +import { useState } from 'react'; | |
9 | 9 | import { |
10 | 10 | getMobileListApi, |
11 | 11 | getPostListApi, |
... | ... | @@ -13,9 +13,9 @@ import { |
13 | 13 | getCanRecordOperatorIdListApi, |
14 | 14 | disableGroupMobileApi, |
15 | 15 | enableGroupMobileApi, |
16 | -} from "./api"; | |
17 | -import { getStaffApi, getUnitCompanyListApi } from "@/common/api"; | |
18 | -import useMenuElement from "@/hooks/useMenuElement"; | |
16 | +} from './api'; | |
17 | +import { getStaffApi, getUnitCompanyListApi } from '@/common/api'; | |
18 | +import useMenuElement from '@/hooks/useMenuElement'; | |
19 | 19 | import { message } from 'antd'; |
20 | 20 | |
21 | 21 | export default function useStore() { |
... | ... | @@ -26,46 +26,46 @@ export default function useStore() { |
26 | 26 | const { list: posts } = usePagination(getPostListApi); |
27 | 27 | const staffPagination = usePagination<CommonApi.StaffListVO>(getStaffApi, {}); |
28 | 28 | const unitCompanyInitail = useInitail(getUnitCompanyListApi, [], { |
29 | - types: "131", // 默认查询 集团手机号往来单位 | |
29 | + types: '131', // 默认查询 集团手机号往来单位 | |
30 | 30 | }); |
31 | 31 | const operatorListInitail = useInitail(getOperatorListApi, [], undefined); |
32 | - const { data: canRecordOperatorIdList = [] } = useInitail( | |
33 | - getCanRecordOperatorIdListApi, | |
34 | - [], | |
35 | - undefined | |
36 | - ); | |
32 | + const { data: canRecordOperatorIdList = [] } = useInitail(getCanRecordOperatorIdListApi, [], undefined); | |
37 | 33 | const [editSubject, setEditSubject] = useState(false); |
38 | 34 | |
35 | + const [provideMobileOpen, setProvideMobileOpen] = useState(false); | |
36 | + | |
39 | 37 | enum StatusText { |
40 | - "空闲" = 1, | |
41 | - "待领取", | |
42 | - "使用中", | |
38 | + '空闲' = 1, | |
39 | + '待领取', | |
40 | + '使用中', | |
43 | 41 | '待停用', |
44 | 42 | '停用', |
45 | 43 | } |
46 | 44 | |
47 | 45 | enum Status { |
48 | - "default" = 1, | |
49 | - "warning", | |
50 | - "processing", | |
51 | - "success", | |
52 | - "error", | |
46 | + 'default' = 1, | |
47 | + 'warning', | |
48 | + 'processing', | |
49 | + 'success', | |
50 | + 'error', | |
53 | 51 | } |
54 | 52 | |
55 | 53 | const disableGroupMobile = (id: number) => { |
56 | 54 | const hide = message.loading('停用中,请稍后...', 0); |
57 | - disableGroupMobileApi(id).then(res => { | |
58 | - hide(); | |
59 | - message.success(res.result); | |
60 | - pagination.setLoading(true); | |
61 | - }).catch(error => { | |
62 | - hide(); | |
63 | - message.error(error.message || '停用手机号失败'); | |
64 | - }); | |
55 | + disableGroupMobileApi(id) | |
56 | + .then((res) => { | |
57 | + hide(); | |
58 | + message.success(res.result); | |
59 | + pagination.setLoading(true); | |
60 | + }) | |
61 | + .catch((error) => { | |
62 | + hide(); | |
63 | + message.error(error.message || '停用手机号失败'); | |
64 | + }); | |
65 | 65 | }; |
66 | 66 | |
67 | 67 | const enableGroupMobile = (id: number) => { |
68 | - const hide = message.loading("启用中,请稍后...", 0); | |
68 | + const hide = message.loading('启用中,请稍后...', 0); | |
69 | 69 | enableGroupMobileApi(id) |
70 | 70 | .then((res) => { |
71 | 71 | hide(); |
... | ... | @@ -74,7 +74,7 @@ export default function useStore() { |
74 | 74 | }) |
75 | 75 | .catch((error) => { |
76 | 76 | hide(); |
77 | - message.error(error.message || "启用手机号失败"); | |
77 | + message.error(error.message || '启用手机号失败'); | |
78 | 78 | }); |
79 | 79 | }; |
80 | 80 | |
... | ... | @@ -94,6 +94,8 @@ export default function useStore() { |
94 | 94 | canRecordOperatorIdList, |
95 | 95 | editSubject, |
96 | 96 | setEditSubject, |
97 | + provideMobileOpen, | |
98 | + setProvideMobileOpen, | |
97 | 99 | disableGroupMobile, |
98 | 100 | enableGroupMobile, |
99 | 101 | }; | ... | ... |
src/pages/ehr/PeriodRoleSetting/components/SettingItem.tsx
1 | 1 | /* |
2 | 2 | * @Date: 2021-02-03 10:42:42 |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | - * @LastEditTime: 2021-02-21 11:42:47 | |
4 | + * @LastEditTime: 2024-04-17 15:34:22 | |
5 | 5 | */ |
6 | -import React, { useEffect, useState } from 'react'; | |
7 | -import { Collapse, Card, Form, Input, Button, Row, message } from 'antd'; | |
6 | +import React, { useEffect, useMemo, useState } from 'react'; | |
7 | +import { Collapse, Card, Form, Input, Button, Row, message, Select } from 'antd'; | |
8 | +import { getPriodRoleSettingDetailApi, savePriodRoleSettingDetailApi } from '../api'; | |
9 | +import '../style.less'; | |
10 | +import useInitail from '@/hooks/useInitail'; | |
11 | +import { getAllRoleCodeApi } from '@/common/api'; | |
12 | +import { RoleTypeEnum } from '@/pages/admin/Role/entity'; | |
13 | +import { CommonUseType } from '@/common/utils'; | |
14 | +import { validatorNumberMinAndMax } from '@/utils/validate'; | |
15 | +import TableArrayColumnFormat from '@/pages/ehr/components/TableArrayColumnFormat'; | |
8 | 16 | import { useStore } from '../index'; |
9 | -import { savePriodRoleSettingDetailApi } from '../api'; | |
10 | -import "../style.less"; | |
11 | 17 | |
12 | 18 | export default function SettingItem() { |
13 | - const { settingDetail } = useStore(); | |
14 | - const { data, loading, setLoading } = settingDetail; | |
19 | + const { setPriodRoleListLoading, elements } = useStore(); | |
20 | + const canEditRoleList = elements.includes('period:roleList:setting'); | |
21 | + const { data, loading, setLoading } = useInitail(getPriodRoleSettingDetailApi, {}, null); | |
22 | + const { data: roleList } = useInitail(getAllRoleCodeApi, [], { roleType: RoleTypeEnum.流程角色 }); | |
23 | + const roles = useMemo(() => roleList.filter((role) => [CommonUseType.业务].includes(role.useType!)), [roleList]); | |
15 | 24 | const [form] = Form.useForm(); |
16 | 25 | const [edit, setEdit] = useState(false); |
17 | 26 | const [confirmLoading, setConfirmLoading] = useState(false); |
18 | 27 | |
28 | + const showRoleList = useMemo(() => { | |
29 | + if (roles.length && data.roleList?.length) { | |
30 | + return roles.filter((role) => data.roleList?.includes(role.roleCode)); | |
31 | + } | |
32 | + return []; | |
33 | + }, [roles, data]); | |
34 | + | |
19 | 35 | useEffect(() => { |
20 | - if (!loading) { | |
21 | - form.setFieldsValue({ ...data }); | |
36 | + if (!loading && data) { | |
37 | + form.setFieldsValue({ ...data, roleList: data.roleList ?? [] }); | |
22 | 38 | } |
23 | - }, [loading]); | |
39 | + }, [loading, data]); | |
24 | 40 | |
25 | 41 | const cancel = () => { |
26 | 42 | setEdit(false); |
27 | - form.setFieldsValue({ ...data }); | |
28 | - } | |
43 | + setLoading(true); | |
44 | + }; | |
29 | 45 | |
30 | 46 | const ok = () => { |
31 | 47 | setConfirmLoading(true); |
32 | - form.validateFields().then(val => { | |
33 | - savePriodRoleSettingDetailApi(val).then(res => { | |
34 | - message.success(res.result); | |
35 | - setLoading(true); | |
36 | - setConfirmLoading(false); | |
37 | - setEdit(false); | |
38 | - }).catch(error => { | |
48 | + form | |
49 | + .validateFields() | |
50 | + .then((val) => { | |
51 | + const hide = message.loading('保存中...', 0); | |
52 | + savePriodRoleSettingDetailApi({ ...val, roleList: canEditRoleList ? val.roleList : data.roleList }) | |
53 | + .then((res) => { | |
54 | + hide(); | |
55 | + message.success(res.result); | |
56 | + setLoading(true); | |
57 | + setPriodRoleListLoading(true); | |
58 | + setConfirmLoading(false); | |
59 | + setEdit(false); | |
60 | + }) | |
61 | + .catch((error) => { | |
62 | + hide(); | |
63 | + message.error(error.message); | |
64 | + setConfirmLoading(false); | |
65 | + }); | |
66 | + }) | |
67 | + .catch((error) => { | |
39 | 68 | message.error(error.message); |
40 | 69 | setConfirmLoading(false); |
41 | - }) | |
42 | - }).catch(error => { | |
43 | - message.error(error.message); | |
44 | - setConfirmLoading(false); | |
45 | - }); | |
46 | - } | |
70 | + }); | |
71 | + }; | |
47 | 72 | |
48 | 73 | return ( |
49 | 74 | <Collapse defaultActiveKey="时效角色配置"> |
... | ... | @@ -52,24 +77,59 @@ export default function SettingItem() { |
52 | 77 | <Row justify="end"> |
53 | 78 | {edit ? ( |
54 | 79 | <> |
55 | - <Button type="link" onClick={() => form.submit()} loading={confirmLoading}>确定</Button> | |
56 | - <Button type="link" danger onClick={cancel} loading={confirmLoading}>取消</Button> | |
80 | + <Button type="link" onClick={() => form.submit()} loading={confirmLoading}> | |
81 | + 确定 | |
82 | + </Button> | |
83 | + <Button type="link" danger onClick={cancel} loading={confirmLoading}> | |
84 | + 取消 | |
85 | + </Button> | |
57 | 86 | </> |
58 | - ) : <Button type="link" onClick={() => setEdit(true)}>编辑</Button>} | |
87 | + ) : ( | |
88 | + <Button type="link" onClick={() => setEdit(true)}> | |
89 | + 编辑 | |
90 | + </Button> | |
91 | + )} | |
59 | 92 | </Row> |
60 | 93 | <Form form={form} size="small" onFinish={ok}> |
61 | - <Form.Item label="时效角色最长授权时间" name="maxDay"> | |
94 | + <Form.Item | |
95 | + label="时效角色最长授权时间" | |
96 | + name="maxDay" | |
97 | + rules={[{ required: edit, validator: validatorNumberMinAndMax({ min: 0, required: edit, decimal: 0 }) }]} | |
98 | + > | |
62 | 99 | <Input suffix="天" bordered={edit} readOnly={!edit} style={{ width: 70 }} /> |
63 | 100 | </Form.Item> |
64 | - <Form.Item label="取消时效角色时间" name="extraDay"> | |
101 | + <Form.Item | |
102 | + label="取消时效角色时间" | |
103 | + name="extraDay" | |
104 | + rules={[{ required: edit, validator: validatorNumberMinAndMax({ min: 0, required: edit, decimal: 0 }) }]} | |
105 | + > | |
65 | 106 | <Input prefix="申请时效角色的截止日期加上" suffix="天" bordered={edit} readOnly={!edit} style={{ width: 240 }} /> |
66 | 107 | </Form.Item> |
67 | - <Form.Item label="时效角色月度授权次数" name="authNum"> | |
108 | + <Form.Item | |
109 | + label="时效角色月度授权次数" | |
110 | + name="authNum" | |
111 | + rules={[{ required: edit, validator: validatorNumberMinAndMax({ min: 0, required: edit, decimal: 0 }) }]} | |
112 | + > | |
68 | 113 | <Input suffix="次" bordered={edit} readOnly={!edit} style={{ width: 70 }} /> |
69 | 114 | </Form.Item> |
115 | + {canEditRoleList ? ( | |
116 | + <Form.Item label="时效角色最大范围" name="roleList" rules={[{ required: edit, message: '请选择时效角色最大范围' }]}> | |
117 | + {edit ? ( | |
118 | + <Select allowClear placeholder="请选择时效角色最大范围" mode="multiple"> | |
119 | + {roles.map((role) => ( | |
120 | + <Select.Option key={role.roleCode} value={role.roleCode}> | |
121 | + {role.roleName} | |
122 | + </Select.Option> | |
123 | + ))} | |
124 | + </Select> | |
125 | + ) : ( | |
126 | + <span>{<TableArrayColumnFormat data={showRoleList} showKey="roleName" key="roleCode" unit="个角色" maxCount={5} />}</span> | |
127 | + )} | |
128 | + </Form.Item> | |
129 | + ) : null} | |
70 | 130 | </Form> |
71 | 131 | </Card> |
72 | 132 | </Collapse.Panel> |
73 | 133 | </Collapse> |
74 | 134 | ); |
75 | -} | |
76 | 135 | \ No newline at end of file |
136 | +} | ... | ... |
src/pages/ehr/PeriodRoleSetting/interface.d.ts
1 | 1 | /* |
2 | 2 | * @Date: 2020-12-15 16:05:51 |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | - * @LastEditTime: 2020-12-16 09:26:16 | |
4 | + * @LastEditTime: 2024-04-17 14:41:23 | |
5 | 5 | */ |
6 | 6 | declare namespace PeriodRoleSetting { |
7 | 7 | interface QueryParams { |
8 | - keyword?: string // 搜索员工名或角色名 | |
8 | + keyword?: string; // 搜索员工名或角色名 | |
9 | 9 | } |
10 | 10 | |
11 | 11 | interface Item { |
12 | - id?: number | |
13 | - staffId?: number, | |
14 | - staffName?: string, | |
15 | - roleCode?: string, | |
16 | - roleName?: string, | |
17 | - periodRoleShopList?: ShopItem[] | |
12 | + id?: number; | |
13 | + staffId?: number; | |
14 | + staffName?: string; | |
15 | + roleCode?: string; | |
16 | + roleName?: string; | |
17 | + periodRoleShopList?: ShopItem[]; | |
18 | 18 | } |
19 | 19 | |
20 | 20 | interface ShopItem { |
21 | - shopId?: number, | |
22 | - shopName?: string | |
21 | + shopId?: number; | |
22 | + shopName?: string; | |
23 | 23 | } |
24 | 24 | |
25 | 25 | interface SettingDetail { |
26 | - maxDay?: 5, // 最大授权天数 | |
27 | - extraDay?: 3, // 取消额外新增天数 | |
28 | - authNum?: 3 // 最多授权次数 | |
26 | + maxDay?: number; // 最大授权天数 | |
27 | + extraDay?: number; // 取消额外新增天数 | |
28 | + authNum?: number; // 最多授权次数 | |
29 | + roleList?: string[]; // 最大范围 | |
29 | 30 | } |
30 | 31 | |
31 | 32 | interface RoleItem { |
32 | - roleCode?: string, //角色编码 | |
33 | - roleName?: string //角色名 | |
33 | + roleCode?: string; //角色编码 | |
34 | + roleName?: string; //角色名 | |
34 | 35 | } |
35 | 36 | |
36 | 37 | interface UserParams { |
37 | - keywords?: string | |
38 | + keywords?: string; | |
38 | 39 | } |
39 | 40 | |
40 | 41 | interface User { |
41 | - id?: number | |
42 | - name?: string | |
43 | - mobile?: string | |
42 | + id?: number; | |
43 | + name?: string; | |
44 | + mobile?: string; | |
44 | 45 | } |
45 | -} | |
46 | 46 | \ No newline at end of file |
47 | +} | ... | ... |
src/pages/ehr/PeriodRoleSetting/store.ts
... | ... | @@ -12,8 +12,7 @@ import useMenuElement from '@/hooks/useMenuElement'; |
12 | 12 | export default function useStore() { |
13 | 13 | const { elements } = useMenuElement(); |
14 | 14 | const pagination = usePagination(getListApi); |
15 | - const settingDetail = useInitail(getPriodRoleSettingDetailApi, {}, null); | |
16 | - const { data: roleList = [] } = useInitail(getPriodRoleListApi, [], null); | |
15 | + const { data: roleList = [], setLoading: setPriodRoleListLoading } = useInitail(getPriodRoleListApi, [], null); | |
17 | 16 | const { data: shopList = [] } = useInitail(getShopListApi, [], null); |
18 | 17 | const [visible, setVisible] = useState(false); |
19 | 18 | const [currentItem, setCurrentItem] = useState<PeriodRoleSetting.Item>(); |
... | ... | @@ -22,8 +21,8 @@ export default function useStore() { |
22 | 21 | return { |
23 | 22 | elements, |
24 | 23 | pagination, |
25 | - settingDetail, | |
26 | 24 | roleList, |
25 | + setPriodRoleListLoading, | |
27 | 26 | shopList, |
28 | 27 | visible, |
29 | 28 | setVisible, | ... | ... |
src/pages/finance/CompanyRelationAuth/index.tsx
... | ... | @@ -50,6 +50,7 @@ function CompanyRelationAuth() { |
50 | 50 | ...rowSelection, |
51 | 51 | }} |
52 | 52 | > |
53 | + <Column title="单位ID" dataIndex="compId" width={'10%'}/> | |
53 | 54 | <Column title="单位名称" dataIndex="compName" /> |
54 | 55 | <Column title="简称" dataIndex="compShortName" /> |
55 | 56 | <Column title="往来单位业务类型" dataIndex="compTypeName" /> | ... | ... |
src/pages/finance/SpecialAccount/FinancingCompany/components/List.tsx
... | ... | @@ -24,9 +24,14 @@ enum CarRepaymentAccountTypeEnum { |
24 | 24 | } |
25 | 25 | enum DraftModeEnum { |
26 | 26 | '未配置' = -1, |
27 | - '中信模式' = 100, | |
28 | - '光大模式' = 200, | |
29 | - '兵财模式' = 300 | |
27 | + '模式A' = 100, | |
28 | + '模式B' = 200, | |
29 | + '模式C' = 300 | |
30 | +} | |
31 | +enum DraftModeTip { | |
32 | + '每张票支付保证金,按票据已还总金额清票' = 100, | |
33 | + '每张票支付保证金,按单票到期金额清票' = 200, | |
34 | + '前期一次性支付保证金' = 300 | |
30 | 35 | } |
31 | 36 | export default function SalesFinanceList() { |
32 | 37 | const { setCurrent, setVisible, companyList, loading } = useStore(); |
... | ... | @@ -164,8 +169,13 @@ export default function SalesFinanceList() { |
164 | 169 | <Column |
165 | 170 | title="票据模式" |
166 | 171 | dataIndex="draftMode" |
167 | - render={(draftMode, row: any) => (DraftModeEnum[draftMode])} | |
168 | - width={120} | |
172 | + render={(draftMode, row: any) => ( | |
173 | + <div> | |
174 | + {DraftModeEnum[draftMode]}: | |
175 | + <span style={{color:"#999"}}>{DraftModeTip[draftMode]}</span> | |
176 | + </div> | |
177 | + )} | |
178 | + width={200} | |
169 | 179 | /> |
170 | 180 | <Column |
171 | 181 | title="操作" | ... | ... |
src/pages/finance/TradeCompany/components/List.tsx
... | ... | @@ -72,6 +72,7 @@ export default function AccountList() { |
72 | 72 | return ( |
73 | 73 | <> |
74 | 74 | <Table dataSource={comAccountList} pagination={paginationConfig} rowKey="id" loading={loading}> |
75 | + <Column title="单位ID" dataIndex="id" width="5%" /> | |
75 | 76 | <Column title="名称" dataIndex="compName" width="15%" /> |
76 | 77 | {/* <Column title="单位主体类型" dataIndex="subjectType" width="15%" /> */} |
77 | 78 | <Column title="简称" dataIndex="compShortName" width="15%" /> | ... | ... |
src/pages/finance/ViewCompanyRelationAuth/index.tsx
... | ... | @@ -50,6 +50,7 @@ function CompanyRelationAuth() { |
50 | 50 | // ...rowSelection, |
51 | 51 | // }} |
52 | 52 | > |
53 | + <Column title="单位ID" dataIndex="compId" /> | |
53 | 54 | <Column title="单位名称" dataIndex="compName" /> |
54 | 55 | <Column title="简称" dataIndex="compShortName" /> |
55 | 56 | <Column title="往来单位业务类型" dataIndex="compTypeName" /> | ... | ... |
src/pages/finance/ViewTradeCompany/components/List.tsx
... | ... | @@ -72,6 +72,7 @@ export default function AccountList() { |
72 | 72 | return ( |
73 | 73 | <> |
74 | 74 | <Table dataSource={comAccountList} pagination={paginationConfig} rowKey="id" loading={loading}> |
75 | + <Column title="单位ID" dataIndex="id" width="6%" /> | |
75 | 76 | <Column title="名称" dataIndex="compName" width="15%" /> |
76 | 77 | {/* <Column title="单位主体类型" dataIndex="subjectType" width="15%" /> */} |
77 | 78 | <Column title="简称" dataIndex="compShortName" width="15%" /> | ... | ... |
src/pages/mkt/ActivityCreate/BasicInformation/components/ImageUploader/index.tsx
... | ... | @@ -72,7 +72,7 @@ export default function Detail({ form, readOnly, bizType }: Props) { |
72 | 72 | return []; |
73 | 73 | } |
74 | 74 | if (status == 'removed' && response) { |
75 | - COS.cosDelete({ filePath: response.data }); | |
75 | + // COS.cosDelete({ filePath: response.data }); | |
76 | 76 | } |
77 | 77 | return e?.fileList; |
78 | 78 | } | ... | ... |
src/pages/mkt/ActivityCreate/ExternalPromotion/api.ts
... | ... | @@ -162,4 +162,9 @@ export function saveChangeAwardName(params: { giftId: number; awardName: string |
162 | 162 | /** 根据车系id查询门店信息 */ |
163 | 163 | export function getSeriesToShopList(params: { seriesIds: string }): http.PromiseResp<ExternalPromotion.ShopList[]> { |
164 | 164 | return request.post(`${FVM_HOST}/select/sales/series/shop`, params, { contentType: 'form-urlencoded' }); |
165 | +} | |
166 | + | |
167 | +/** 授权配置促销范围门店查询(门店) */ | |
168 | +export function getScopeShopAuthList(params: { bizType?: number }): http.PromiseResp<CommonApi.OptionVO[]> { | |
169 | + return request.get(`${MKT_HOST}/erp/activity/get/scope/shop/auth`, { params }); | |
165 | 170 | } |
166 | 171 | \ No newline at end of file | ... | ... |
src/pages/mkt/ActivityCreate/ExternalPromotion/components/ActivityFlow/SignUp.tsx
1 | 1 | import React, { useState, useEffect } from 'react'; |
2 | -import { Button, Form, InputNumber, message, Space, Spin, Divider, Radio, Row } from 'antd'; | |
2 | +import { Button, Form, InputNumber, message, Space, Spin, Divider, Radio, Row, Alert } from 'antd'; | |
3 | 3 | import useInitial from '@/hooks/useInitail'; |
4 | 4 | import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons'; |
5 | 5 | import { saveSignUpApi, getSignUpDetail, saveChangeSignUpApi } from '../../api'; //保存报名有礼 |
... | ... | @@ -163,6 +163,25 @@ export default function Index() { |
163 | 163 | <Radio value={1}>按报名顺序不同赠送不同优惠券</Radio> |
164 | 164 | </Radio.Group> |
165 | 165 | </Form.Item> |
166 | + {changeEnable ? ( | |
167 | + <Alert | |
168 | + message="提示" | |
169 | + type="warning" | |
170 | + showIcon | |
171 | + closable | |
172 | + style={{ marginBottom: 10 }} | |
173 | + description={ | |
174 | + <div> | |
175 | + <p style={{ margin: 0, fontSize: 12, color: '#999' }}> | |
176 | + 1.优惠券编辑变更:范围只能扩大不能缩小,变更前所发优惠券与变更后所发优惠券的限制范围一致 | |
177 | + </p> | |
178 | + <p style={{ margin: 0, fontSize: 12, color: '#999' }}> | |
179 | + 2.优惠券删除-新增变更:不限制优惠券变更范围,变更前所发优惠券使用范围不变,变更后所发优惠券限制范围变更 | |
180 | + </p> | |
181 | + </div> | |
182 | + } | |
183 | + /> | |
184 | + ) : null} | |
166 | 185 | <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.ladderReward !== currentValues.ladderReward}> |
167 | 186 | {({ getFieldValue }) => { |
168 | 187 | return ( | ... | ... |
src/pages/mkt/ActivityCreate/index.tsx
... | ... | @@ -10,7 +10,6 @@ import { createStore } from '@/hooks/moz'; |
10 | 10 | import store from './store'; |
11 | 11 | import { ActivityStatusEnums } from '@/pages/mkt/entity'; |
12 | 12 | import { saveChangeApply } from '@/pages/mkt/ActivityCreate/ExternalPromotion/api'; |
13 | -import { useLocation } from 'umi'; | |
14 | 13 | |
15 | 14 | export const { Provider, useStore } = createStore(store); |
16 | 15 | type Props = common.ConnectProps |
... | ... | @@ -88,7 +87,7 @@ const ActivityCreate = (props: Props) => { |
88 | 87 | } |
89 | 88 | return ( |
90 | 89 | <PageHeaderWrapper |
91 | - title="活动配置" | |
90 | + title={`活动配置${change ? '变更' : ''}`} | |
92 | 91 | content={ |
93 | 92 | <> |
94 | 93 | {activityNo && (<div>活动编号:{activityNo} | {ActivityStatusEnums[Number(status)]}</div>)} |
... | ... | @@ -96,6 +95,7 @@ const ActivityCreate = (props: Props) => { |
96 | 95 | </> |
97 | 96 | } |
98 | 97 | > |
98 | + | |
99 | 99 | {baseInfo.changeEnable && ( |
100 | 100 | <Card style={{ marginBottom: 15 }}> |
101 | 101 | <Row justify="space-between"> | ... | ... |
src/pages/mkt/ActivityManage/components/Operation.tsx
... | ... | @@ -45,7 +45,7 @@ export default function Oparetion(props: Props) { |
45 | 45 | } |
46 | 46 | }); |
47 | 47 | } |
48 | - /** 变更信息 */ | |
48 | + /** 变更操作 */ | |
49 | 49 | function changeBaseInfo() { |
50 | 50 | history.push({ |
51 | 51 | pathname: '/mkt/manage/create', |
... | ... | @@ -134,7 +134,7 @@ export default function Oparetion(props: Props) { |
134 | 134 | /* 审核成功、待发布 ;未开始,进行中*/ |
135 | 135 | if ([4, 5].includes(status) && record.changeStatus !== 2) { |
136 | 136 | menus.push( |
137 | - <Button type="primary" ghost size="small" onClick={changeBaseInfo}>变更信息</Button>, | |
137 | + <Button type="primary" ghost size="small" onClick={changeBaseInfo}>变更操作</Button>, | |
138 | 138 | <Button type="primary" ghost size="small" onClick={changeRecords}>变更记录</Button>, |
139 | 139 | // <Button danger ghost size="small" onClick={endActivity}>终止</Button>, |
140 | 140 | ); | ... | ... |
src/pages/oop/CarAlias/SpecCode/components/CarList.tsx
1 | 1 | import React from 'react'; |
2 | -import { Table } from 'antd'; | |
2 | +import { Button, Table } from 'antd'; | |
3 | 3 | import { useStore } from '../index'; |
4 | 4 | import style from '../index.less'; |
5 | 5 | import { EnergyTypeEnum } from '../carData'; |
... | ... | @@ -51,6 +51,12 @@ export default function CarList() { |
51 | 51 | dataIndex: 'specCode', |
52 | 52 | }, |
53 | 53 | { |
54 | + title: '配置代码', | |
55 | + dataIndex: 'specCodeList', | |
56 | + align: "center", | |
57 | + render: (text: any, record: any) => (text ? text.map((res: any, index: any) => <div key={`item_${index}`}>{res}</div>) : '——'), | |
58 | + }, | |
59 | + { | |
54 | 60 | title: '能源类型', |
55 | 61 | dataIndex: 'energyType', |
56 | 62 | render: (text: number) => EnergyTypeEnum[text] || '--', |
... | ... | @@ -73,8 +79,8 @@ export default function CarList() { |
73 | 79 | align: 'center', |
74 | 80 | render: (text: any, row: any) => ( |
75 | 81 | <React.Fragment key="key"> |
76 | - <a | |
77 | - href="#" | |
82 | + <Button | |
83 | + type='link' | |
78 | 84 | onClick={(e) => { |
79 | 85 | e.preventDefault(); |
80 | 86 | setCurrentItem(row); |
... | ... | @@ -82,7 +88,7 @@ export default function CarList() { |
82 | 88 | }} |
83 | 89 | > |
84 | 90 | 编辑别名 |
85 | - </a> | |
91 | + </Button> | |
86 | 92 | </React.Fragment> |
87 | 93 | ), |
88 | 94 | }, | ... | ... |
src/pages/oop/CarAlias/SpecCode/components/CarModal.tsx
... | ... | @@ -62,8 +62,8 @@ export default function CarModal() { |
62 | 62 | > |
63 | 63 | <Form |
64 | 64 | form={form} |
65 | - labelCol={{ span: 6 }} | |
66 | - wrapperCol={{ span: 15 }} | |
65 | + labelCol={{ span: 8 }} | |
66 | + wrapperCol={{ span: 12 }} | |
67 | 67 | > |
68 | 68 | <FormItem style={{ width: 400 }} name="brandName" label="品牌"> |
69 | 69 | <Input style={{ width: '100%' }} disabled bordered={false} /> | ... | ... |
src/pages/oop/CarbasicInfo/comps/Filter.tsx
1 | 1 | import React, { useState, useEffect } from 'react'; |
2 | 2 | import '@ant-design/compatible/assets/index.css'; |
3 | 3 | import { Cascader, message } from 'antd'; |
4 | -import { CascaderOptionType } from 'antd/lib/cascader'; | |
4 | +import type { BaseOptionType, DefaultOptionType } from 'antd/lib/cascader'; | |
5 | 5 | import { getBrandApi, getSeriesApi, getSpecApi } from '../api'; |
6 | 6 | import { getSpecCodeList } from '@/pages/oop/Car/api'; |
7 | 7 | |
... | ... | @@ -21,23 +21,23 @@ export default function Filter(props: FilterProps) { |
21 | 21 | |
22 | 22 | useEffect(() => { |
23 | 23 | getBrandApi() |
24 | - .then(res => { | |
24 | + .then((res) => { | |
25 | 25 | const { data = [] } = res; |
26 | - const brandList = data.map(brand => ({ ...brand, isLeaf: false })); | |
26 | + const brandList = data.map((brand) => ({ ...brand, isLeaf: false })); | |
27 | 27 | setSpecOptions(brandList); |
28 | 28 | }) |
29 | - .catch(e => { | |
29 | + .catch((e) => { | |
30 | 30 | message.error(e.message); |
31 | 31 | }); |
32 | 32 | }, []); |
33 | 33 | |
34 | - function loadData(selectedOptions: CascaderOptionType) { | |
34 | + function loadData(selectedOptions: BaseOptionType) { | |
35 | 35 | const length = selectedOptions.length; |
36 | 36 | const targetOption = selectedOptions[length - 1]; |
37 | 37 | targetOption.loading = true; |
38 | 38 | if (length === 1) { |
39 | 39 | getSeriesApi(targetOption.id) |
40 | - .then(res => { | |
40 | + .then((res) => { | |
41 | 41 | const { data = [] } = res; |
42 | 42 | targetOption.loading = false; |
43 | 43 | targetOption.children = []; |
... | ... | @@ -50,32 +50,33 @@ export default function Filter(props: FilterProps) { |
50 | 50 | }); |
51 | 51 | setSpecOptions([...specOptions]); |
52 | 52 | }) |
53 | - .catch(e => { | |
53 | + .catch((e) => { | |
54 | 54 | message.error(e.message); |
55 | 55 | }); |
56 | 56 | } |
57 | 57 | if (length === 2) { |
58 | 58 | const fetchList = specCode ? getSpecCodeList({ seriesId: targetOption.id }) : getSpecApi(targetOption.id); |
59 | 59 | // getSpecCodeList({ seriesId: targetOption.id }) |
60 | - fetchList.then(res => { | |
61 | - const { data = [] } = res; | |
62 | - targetOption.loading = false; | |
63 | - targetOption.children = []; | |
64 | - data.forEach((list: any) => { | |
65 | - targetOption.children.push({ | |
66 | - id: specCode ? list.specCode : list.id, | |
67 | - name: specCode ? `${list.specCode}[${list.specCodeName}]` : list.name, | |
60 | + fetchList | |
61 | + .then((res) => { | |
62 | + const { data = [] } = res; | |
63 | + targetOption.loading = false; | |
64 | + targetOption.children = []; | |
65 | + data.forEach((list: any) => { | |
66 | + targetOption.children.push({ | |
67 | + id: specCode ? list.specCode : list.id, | |
68 | + name: specCode ? `${list.specCode}[${list.specCodeName}]` : list.name, | |
69 | + }); | |
68 | 70 | }); |
69 | - }); | |
70 | - setSpecOptions([...specOptions]); | |
71 | - }) | |
72 | - .catch(e => { | |
71 | + setSpecOptions([...specOptions]); | |
72 | + }) | |
73 | + .catch((e) => { | |
73 | 74 | message.error(e.message); |
74 | 75 | }); |
75 | 76 | } |
76 | 77 | } |
77 | 78 | |
78 | - function filterByCar(value: any, options?: CascaderOptionType[]) { | |
79 | + function filterByCar(value: any, options?: BaseOptionType[]) { | |
79 | 80 | const carFilter = { |
80 | 81 | brandId: value ? value[0] : undefined, |
81 | 82 | seriesId: value ? value[1] : undefined, |
... | ... | @@ -84,6 +85,9 @@ export default function Filter(props: FilterProps) { |
84 | 85 | onChange(carFilter); |
85 | 86 | } |
86 | 87 | |
88 | + const filter = (inputValue: string, path: DefaultOptionType[]) => | |
89 | + path.some((option) => (option.name as string).toLowerCase().indexOf(inputValue.toLowerCase()) > -1); | |
90 | + | |
87 | 91 | return ( |
88 | 92 | <Cascader |
89 | 93 | allowClear |
... | ... | @@ -94,6 +98,8 @@ export default function Filter(props: FilterProps) { |
94 | 98 | onChange={filterByCar} |
95 | 99 | fieldNames={{ value: 'id', label: 'name' }} |
96 | 100 | notFoundContent="暂无数据" |
101 | + showSearch={{ filter }} | |
102 | + onSearch={(value) => console.log(value)} | |
97 | 103 | style={{ minWidth: 200, flex: 1 }} |
98 | 104 | /> |
99 | 105 | ); | ... | ... |
src/pages/order3/RebateCommission/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { ORDER3 } from '@/utils/host'; | |
4 | +import { PageParams } from '@/typing/common'; | |
5 | + | |
6 | +type Page<T> = http.PromisePageResp<T>; | |
7 | + | |
8 | +export interface RequestParams extends PageParams {} | |
9 | + | |
10 | +export interface SaveParams { | |
11 | + id?: number; // id | |
12 | + financialCompanyId?: number; // 金融公司id | |
13 | + financialCompanyName?: string; // 金融公司名称 | |
14 | + productName?: string; // 金融公司产品名称 | |
15 | + loanRate?: number; // 贷款利率 | |
16 | + applyShopType?: number; // 适用门店类型(1.全部门店2.部分门店) | |
17 | + shopList?: ShopList[]; // 门店列表 | |
18 | +} | |
19 | + | |
20 | +export interface ShopList { | |
21 | + shopId?: number; // 门店id | |
22 | + shopName?: string; // 门店名称 | |
23 | +} | |
24 | + | |
25 | +export interface ListResult { | |
26 | + id?: number; // id | |
27 | + financialCompanyId?: number; // 金融公司id | |
28 | + financialCompanyName?: string; // 金融公司名称 | |
29 | + productName?: string; // 产品名称 | |
30 | + loanRate?: number; // 贷款利率 | |
31 | + applyShopList?: ApplyShopList[]; // 适用门店 | |
32 | + applyShopType?: number; // 适用门店类型(1.全部门店2.部分门店) | |
33 | +} | |
34 | + | |
35 | +interface ApplyShopList { | |
36 | + id?: number; // id | |
37 | + createTime?: number; // 创建时间 | |
38 | + updateTime?: number; // 修改时间 | |
39 | + financialProductsConfigId?: number; // 分期条件配置id | |
40 | + shopId?: number; // 门店id | |
41 | + shopName?: string; // 门店名称 | |
42 | +} | |
43 | + | |
44 | +/** | |
45 | + * 查询金融产品配置列表 | |
46 | + * @param params | |
47 | + * @returns | |
48 | + */ | |
49 | +export function getListApi(params: RequestParams): Page<ListResult> { | |
50 | + return request.get(`${ORDER3}/erp/financial/loan/config/products/page`, { params }); | |
51 | +} | |
52 | + | |
53 | +/** | |
54 | + * 查询金融产品详情 | |
55 | + * @param id | |
56 | + * @returns | |
57 | + */ | |
58 | +export function getFinancialDetailApi(id?: number): http.PromiseResp<ListResult> { | |
59 | + return request.get(`${ORDER3}/erp/financial/loan/config/products/queryInfo`, { params: {id} }); | |
60 | +} | |
61 | + | |
62 | +/** | |
63 | + * 新增、编辑金融产品配置 | |
64 | + * @param params | |
65 | + * @returns | |
66 | + */ | |
67 | +export function saveConfigApi(params: SaveParams) { | |
68 | + return request.post(`${ORDER3}/erp/financial/loan/config/products/saveOrUpdate`, params); | |
69 | +} | |
70 | + | |
71 | +/** | |
72 | + * 删除金融产品配置 | |
73 | + * @param params | |
74 | + * @returns | |
75 | + */ | |
76 | +export function deleteConfigApi(params?: {id?: number}) { | |
77 | + return request.post(`${ORDER3}/erp/financial/loan/config/products/delete`, params, { contentType: 'form-urlencoded' }); | |
78 | +} | ... | ... |
src/pages/order3/RebateCommission/components/EditModal.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import FeeweeUploadAttachment from '@/components/FeeweeUploadAttachment'; | |
3 | +import { Button, Card, Form, Input, message, Modal, Radio, Row, Select, Space } from 'antd'; | |
4 | +import { debounce } from 'lodash'; | |
5 | +import moment from 'moment'; | |
6 | +import { SaveParams, saveConfigApi } from '../api'; | |
7 | +import { useStore } from '../index'; | |
8 | +import SelectorWithFull from '@/components/SelectorWithFull'; | |
9 | + | |
10 | +export default function EditModal() { | |
11 | + const [form] = Form.useForm(); | |
12 | + const { editModal, setEditModal, companyList, shopList, setLoading: setPageLoading } = useStore(); | |
13 | + const [confirmLoading, setConfirmLoading] = useState<boolean>(false); | |
14 | + | |
15 | + useEffect(() => { | |
16 | + if (editModal.visible && editModal.data?.id) { | |
17 | + form.setFieldsValue({ | |
18 | + financialCompany: { label: editModal.data?.financialCompanyName, value: editModal.data?.financialCompanyId }, | |
19 | + productName: editModal.data?.productName, | |
20 | + loanRate: editModal.data?.loanRate, | |
21 | + applyShopType: editModal.data?.applyShopType, | |
22 | + shopList: editModal.data.applyShopList?.map(v => ({name: v.shopName, id: v.shopId})), | |
23 | + }); | |
24 | + } | |
25 | + }, [editModal.visible]); | |
26 | + | |
27 | + function handleCancle() { | |
28 | + setEditModal({ visible: false, data: undefined, title: '' }); | |
29 | + form.resetFields(); | |
30 | + } | |
31 | + | |
32 | + async function handleSubmit() { | |
33 | + const params = await form.validateFields(); | |
34 | + const _params: SaveParams = { | |
35 | + financialCompanyId: params.financialCompany?.value, | |
36 | + financialCompanyName: params.financialCompany?.label, | |
37 | + productName: params.productName, | |
38 | + loanRate: params.loanRate, | |
39 | + applyShopType: params.applyShopType, | |
40 | + }; | |
41 | + if (params.applyShopType === 2) { | |
42 | + _params.shopList = params.shopList?.map((v: any) => ({shopId: v.id, shopName: v.name})) | |
43 | + } | |
44 | + if (editModal.data?.id) { | |
45 | + _params.id = editModal.data.id; | |
46 | + } | |
47 | + setConfirmLoading(true); | |
48 | + saveConfigApi(_params) | |
49 | + .then(res => { | |
50 | + message.success(res.result); | |
51 | + setConfirmLoading(false); | |
52 | + setPageLoading(true); | |
53 | + handleCancle(); | |
54 | + }) | |
55 | + .catch(e => { | |
56 | + message.error(e.message); | |
57 | + setConfirmLoading(false); | |
58 | + }) | |
59 | + } | |
60 | + | |
61 | + return ( | |
62 | + <Modal | |
63 | + title={editModal.title} | |
64 | + open={editModal.visible} | |
65 | + onCancel={handleCancle} | |
66 | + width="60%" | |
67 | + maskClosable={false} | |
68 | + footer={false} | |
69 | + destroyOnClose | |
70 | + afterClose={() => form.resetFields()} | |
71 | + > | |
72 | + <Card bordered={false}> | |
73 | + <Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 15 }}> | |
74 | + <Form.Item label="车贷银行" name="financialCompany" rules={[{ required: true, message: '请选择' }]}> | |
75 | + <Select | |
76 | + labelInValue | |
77 | + showSearch | |
78 | + allowClear | |
79 | + filterOption | |
80 | + optionFilterProp='label' | |
81 | + options={companyList.map(v => ({label: v.name, value: v.id}))} | |
82 | + placeholder="请选择" | |
83 | + /> | |
84 | + </Form.Item> | |
85 | + <Form.Item label="金融产品" name="productName" rules={[{ required: true, message: '请输入' }]}> | |
86 | + <Input placeholder="请输入" /> | |
87 | + </Form.Item> | |
88 | + <Form.Item | |
89 | + label="促销利率" | |
90 | + name="loanRate" | |
91 | + rules={[ | |
92 | + { | |
93 | + required: true, | |
94 | + pattern: /^(\d+|\d+\.\d{1,2})$/, | |
95 | + message: '请输入正确的促销利率', | |
96 | + }, | |
97 | + ({ getFieldValue }) => ({ | |
98 | + validator(_, value) { | |
99 | + if (value && +value <= 100 && +value >= 0) { | |
100 | + return Promise.resolve(); | |
101 | + } | |
102 | + return Promise.reject(new Error('比例范围应在0~100!')); | |
103 | + }, | |
104 | + }), | |
105 | + ]} | |
106 | + > | |
107 | + <Input placeholder='请输入' style={{ width: '100%' }} suffix="%" /> | |
108 | + </Form.Item> | |
109 | + <Form.Item label="适用门店类型" name="applyShopType" rules={[{ required: true, message: '请选择' }]}> | |
110 | + <Radio.Group> | |
111 | + <Radio value={1}>全部门店</Radio> | |
112 | + <Radio value={2}>部分门店</Radio> | |
113 | + </Radio.Group> | |
114 | + </Form.Item> | |
115 | + <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.applyShopType != currentValues.applyShopType}> | |
116 | + {({ getFieldValue }) => { | |
117 | + const value = getFieldValue('applyShopType'); | |
118 | + if (value !== 2) { | |
119 | + return; | |
120 | + } | |
121 | + return ( | |
122 | + <Form.Item label="适用门店" name="shopList" rules={[{ required: true, message: '请选择' }]}> | |
123 | + <SelectorWithFull | |
124 | + placeholder="请选择" | |
125 | + multiple | |
126 | + showSearch | |
127 | + allowClear | |
128 | + labelInValue | |
129 | + treeNodeFilterProp='label' | |
130 | + data={shopList || []} | |
131 | + fieldKeyNames={{ keyName: 'id', valueName: 'id', labelName: 'name' }} | |
132 | + /> | |
133 | + </Form.Item> | |
134 | + ); | |
135 | + }} | |
136 | + </Form.Item> | |
137 | + </Form> | |
138 | + | |
139 | + <Row justify="center"> | |
140 | + <Space> | |
141 | + <Button loading={confirmLoading} disabled={confirmLoading} onClick={handleCancle} type="default"> | |
142 | + 取消 | |
143 | + </Button> | |
144 | + <Button loading={confirmLoading} disabled={confirmLoading} onClick={debounce(handleSubmit, 380)} type="primary"> | |
145 | + 确定 | |
146 | + </Button> | |
147 | + </Space> | |
148 | + </Row> | |
149 | + </Card> | |
150 | + </Modal> | |
151 | + ); | |
152 | +} | ... | ... |
src/pages/order3/RebateCommission/components/List.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { message, Popconfirm, Space, Table, Typography, Divider } from 'antd'; | |
3 | +import * as api from '../api'; | |
4 | +import { useStore } from '../index'; | |
5 | +import TextWithMore from '@/components/TextWithMore'; | |
6 | + | |
7 | +const Column = Table.Column; | |
8 | + | |
9 | +export default function List() { | |
10 | + const { list, | |
11 | + paginationConfig, | |
12 | + loading, setLoading, | |
13 | + setEditModal, setSelectedItem, | |
14 | + setSelectKey, selectKey } = useStore(); | |
15 | + const [pageLoading, setPageLoading] = useState<boolean>(false); | |
16 | + | |
17 | + /** | |
18 | + * 删除配置 | |
19 | + * @param id | |
20 | + */ | |
21 | + function onDelete(id?: number) { | |
22 | + setPageLoading(true); | |
23 | + api.deleteConfigApi({id}) | |
24 | + .then(res => { | |
25 | + setPageLoading(false); | |
26 | + setLoading(true); | |
27 | + message.success(res.result); | |
28 | + }) | |
29 | + .catch(e => { | |
30 | + setPageLoading(false); | |
31 | + message.error(e.message); | |
32 | + }) | |
33 | + } | |
34 | + | |
35 | + function onEdit(record?: api.ListResult) { | |
36 | + setEditModal({visible: true, title: '编辑', data: record}) | |
37 | + } | |
38 | + | |
39 | + const rowSelection = { | |
40 | + onChange: (selectedRowKeys: React.Key[], selectedRows: api.ListResult[]) => { | |
41 | + if (selectedRows.length) { | |
42 | + setSelectedItem(selectedRows[0]); | |
43 | + setSelectKey(selectedRowKeys); | |
44 | + } else { | |
45 | + setSelectedItem(undefined); | |
46 | + setSelectKey([]); | |
47 | + } | |
48 | + }, | |
49 | + // getCheckboxProps: (record: api.ListResult) => ({ | |
50 | + // disabled: record.name === 'Disabled User', // Column configuration not to be checked | |
51 | + // name: record.name, | |
52 | + // }), | |
53 | + }; | |
54 | + | |
55 | + return ( | |
56 | + <div> | |
57 | + <Table | |
58 | + dataSource={list} | |
59 | + pagination={paginationConfig} | |
60 | + loading={loading || pageLoading} | |
61 | + rowKey="id" | |
62 | + rowSelection={{ | |
63 | + type: 'radio', | |
64 | + ...rowSelection, | |
65 | + selectedRowKeys: selectKey, | |
66 | + // defaultSelectedRowKeys: list.length ? [list[0].id] : undefined, | |
67 | + }} | |
68 | + > | |
69 | + <Column title="车贷银行" dataIndex="financialCompanyName" /> | |
70 | + <Column title="金融产品" align="center" dataIndex="productName" /> | |
71 | + <Column title="利率" align="center" dataIndex="loanRate" render={(_text) => <span>{(_text ?? '--') + '%'}</span>} /> | |
72 | + <Column | |
73 | + title="适用门店" | |
74 | + align="center" | |
75 | + dataIndex="applyShopList" | |
76 | + render={(_text, record: api.ListResult) => | |
77 | + record.applyShopType === 1 ? '全部门店' : _text && _text.length ? <TextWithMore unit="个门店" title="适用门店" dataIndex="shopName" list={record.applyShopList || []} /> : '--' | |
78 | + } | |
79 | + /> | |
80 | + <Column | |
81 | + title="操作" | |
82 | + dataIndex="option" | |
83 | + align="center" | |
84 | + render={(_text, record: api.ListResult) => ( | |
85 | + <Space wrap split={<Divider type="vertical" />}> | |
86 | + <Popconfirm title="确定删除?" onConfirm={() => onDelete(record.id)}> | |
87 | + <Typography.Link style={{ color: '#666' }}>删除</Typography.Link> | |
88 | + </Popconfirm> | |
89 | + <Typography.Link onClick={() => onEdit(record)} style={{ color: '#4189FD' }}> | |
90 | + 编辑 | |
91 | + </Typography.Link> | |
92 | + </Space> | |
93 | + )} | |
94 | + /> | |
95 | + </Table> | |
96 | + </div> | |
97 | + ); | |
98 | +} | ... | ... |
src/pages/order3/RebateCommission/entity.ts
0 → 100644
1 | +export const ConditionData = [ | |
2 | + { label: '=', value: 1 }, | |
3 | + { label: '>', value: 2 }, | |
4 | + { label: '≥', value: 3 }, | |
5 | + { label: '<', value: 4 }, | |
6 | + { label: '≤', value: 5 }, | |
7 | +]; | |
8 | + | |
9 | +export enum ConditionEnum { | |
10 | + '=' = 1, | |
11 | + '>', | |
12 | + '≥', | |
13 | + '<', | |
14 | + '≤', | |
15 | +} | |
16 | + | |
17 | +export enum RebateTypeEnum { | |
18 | + "固定金额" = 1, | |
19 | + "按比例" | |
20 | +} | |
21 | + | |
22 | +export enum CommissionTypeEnum { | |
23 | + "计提成" = 1, | |
24 | + "计附加值" | |
25 | +} | |
0 | 26 | \ No newline at end of file | ... | ... |
src/pages/order3/RebateCommission/index.tsx
0 → 100644
1 | +import { createStore } from '@/hooks/moz'; | |
2 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
3 | +import { Button, Card, Col, Input, Row, Space } from 'antd'; | |
4 | +import { debounce } from 'lodash'; | |
5 | +import React, { useEffect } from 'react'; | |
6 | +import List from './components/List'; | |
7 | +import store from './store'; | |
8 | +import EditMOdal from './components/EditModal'; | |
9 | +import { PlusOutlined } from '@ant-design/icons'; | |
10 | +import LoanConditionPage from '@/pages/order3/RebateCommission/subpages/LoanCondition'; | |
11 | + | |
12 | +export const { Provider, useStore } = createStore(store); | |
13 | + | |
14 | +function RebateCommission() { | |
15 | + const { setParams, innerParams, setEditModal, selectItem, selectKey } = useStore(); | |
16 | + | |
17 | + function onFinancialSearch(value?: string) { | |
18 | + setParams({ ...innerParams, current: 1, financialCompanyName: value || null }, true); | |
19 | + } | |
20 | + | |
21 | + function onProductSearch(value?: string) { | |
22 | + setParams({ ...innerParams, current: 1, productName: value || null }, true); | |
23 | + } | |
24 | + | |
25 | + function onAdd() { | |
26 | + setEditModal({ visible: true, title: '新增' }); | |
27 | + } | |
28 | + | |
29 | + return ( | |
30 | + <PageHeaderWrapper title="车贷银行返利和提成配置"> | |
31 | + <Card> | |
32 | + <Row> | |
33 | + <Col span={selectKey.length ? 12 : 24}> | |
34 | + <Row justify="space-between" style={{ marginBottom: '15px' }}> | |
35 | + <Space> | |
36 | + <Input.Search allowClear onSearch={debounce(onFinancialSearch, 380)} placeholder="请输入车贷银行名称" /> | |
37 | + <Input.Search allowClear onSearch={debounce(onProductSearch, 380)} placeholder="请输入金融产品名称" /> | |
38 | + </Space> | |
39 | + <Button onClick={onAdd} type="primary"> | |
40 | + <PlusOutlined /> 新增 | |
41 | + </Button> | |
42 | + </Row> | |
43 | + <List /> | |
44 | + <EditMOdal /> | |
45 | + </Col> | |
46 | + {selectKey.length ? ( | |
47 | + <Col span={12}> | |
48 | + <LoanConditionPage id={selectItem?.id} financialCompanyName={selectItem?.financialCompanyName} productName={selectItem?.productName} /> | |
49 | + </Col> | |
50 | + ) : null} | |
51 | + </Row> | |
52 | + </Card> | |
53 | + </PageHeaderWrapper> | |
54 | + ); | |
55 | +} | |
56 | + | |
57 | +export default () => ( | |
58 | + <Provider> | |
59 | + <RebateCommission /> | |
60 | + </Provider> | |
61 | +); | ... | ... |
src/pages/order3/RebateCommission/store.ts
0 → 100644
1 | +import usePagination from '@/hooks/usePagination'; | |
2 | +import { useState } from 'react'; | |
3 | +import { getListApi, ListResult } from './api'; | |
4 | +import { getUnitCompanyListApi, fetchShopListByRangeTypeApi } from '@/common/api'; | |
5 | +import useInitial from '@/hooks/useInitail'; | |
6 | + | |
7 | +interface EditModal { | |
8 | + visible?: boolean; | |
9 | + data?: ListResult; | |
10 | + title: string; | |
11 | +} | |
12 | + | |
13 | +export default function useStore() { | |
14 | + const pagination = usePagination(getListApi, { current: 1, pageSize: 10 }); | |
15 | + const [editModal, setEditModal] = useState<EditModal>({visible: false, title: ''}); | |
16 | + const { data: companyList } = useInitial(getUnitCompanyListApi, [], { types: '20' }); | |
17 | + const { data: shopList } = useInitial(fetchShopListByRangeTypeApi, [], { bizTypeList: '1' }); | |
18 | + const [delay, setDelay] = useState<boolean>(true); | |
19 | + const [selectItem, setSelectedItem] = useState<ListResult>(); | |
20 | + const [selectKey, setSelectKey] = useState<React.Key[]>([]); | |
21 | + return { | |
22 | + ...pagination, | |
23 | + editModal, | |
24 | + setEditModal, | |
25 | + companyList, | |
26 | + shopList, | |
27 | + delay, | |
28 | + setDelay, | |
29 | + selectItem, | |
30 | + setSelectedItem, | |
31 | + selectKey, | |
32 | + setSelectKey | |
33 | + }; | |
34 | +} | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { ORDER3 } from '@/utils/host'; | |
4 | +import { PageParams } from '@/typing/common'; | |
5 | + | |
6 | +type Page<T> = http.PromisePageResp<T>; | |
7 | + | |
8 | +export interface RequestParams extends PageParams {} | |
9 | + | |
10 | +export interface SaveParams { | |
11 | + id?: number; // id | |
12 | + financialProductsConfigId?: number; // 金融产品id | |
13 | + loanPeriods?: number; // 贷款期数 | |
14 | + periodsJudgeCondition?: number; // 贷款期数判断条件(1:小于,2:小于等于,3:大于,4:大于等于) | |
15 | + loanAmount?: number; // 贷款金额 | |
16 | + amountJudgeCondition?: number; // 贷款金额判断条件(1:小于,2:小于等于,3:大于,4:大于等于) | |
17 | + rebateType?: number; // 车贷银行返利类型(1:固定金额,2:按比例) | |
18 | + rebateValue?: number; // 车贷银行返利标准(根据返利类型确定) | |
19 | + applyCarList?: [ | |
20 | + // 适用车系列表 | |
21 | + { | |
22 | + brandId?: number; // 品牌id | |
23 | + brandName?: string; // 品牌名称 | |
24 | + seriesId?: number; // 车系id | |
25 | + seriesName?: string; // 车系名称 | |
26 | + applyCarType?: number; // 适用车辆类型(1:全部车系,2:全部车型,3,部分车型) | |
27 | + specId?: number; // 车型id | |
28 | + specName?: string; // 车型名称 | |
29 | + }, | |
30 | + ]; | |
31 | + roleCommissionList?: RoleCommissionList[]; // 角色提成设置 | |
32 | +} | |
33 | + | |
34 | +export interface ListResult { | |
35 | + id?: number; // id | |
36 | + financialProductsConfigId?: number; // 金融产品id | |
37 | + brandId?: number; // 品牌id | |
38 | + brandName?: string; // 品牌名称 | |
39 | + loanPeriods?: number; // 贷款期数 | |
40 | + periodsJudgeCondition?: number; // 贷款期数判断条件(1:小于,2:小于等于,3:大于,4:大于等于) | |
41 | + loanAmount?: number; // 贷款金额 | |
42 | + amountJudgeCondition?: number; // 贷款金额判断条件(1:小于,2:小于等于,3:大于,4:大于等于) | |
43 | + rebateType?: number; // 车贷银行返利类型(1:固定金额,2:按比例) | |
44 | + rebateValue?: number; // 车贷银行返利值(根据返利类型确定) | |
45 | + applyCarList?: ApplyCarList[]; // 适用车辆 | |
46 | + roleCommissionList?: RoleCommissionList[]; // 角色提成 | |
47 | +} | |
48 | + | |
49 | +export interface RoleCommissionList { | |
50 | + roleCode?: string; // 角色编码 | |
51 | + roleName?: string; // 角色名称 | |
52 | + rebateType?: number; // 返利类型(1.固定金额2.按比例) | |
53 | + rebateValue?: number; // 返利值(根据返利类型确定) | |
54 | + commissionType?: number; // 提成类型(1:计提成,2:计附加值) | |
55 | +} | |
56 | + | |
57 | +export interface ApplyCarList { | |
58 | + configId?: number; // id | |
59 | + brandId?: number; // 品牌id | |
60 | + brandName?: string; // 品牌名称 | |
61 | + seriesList?: SeriesList[]; // 车系列表 | |
62 | +} | |
63 | + | |
64 | +interface SeriesList { | |
65 | + configId?: number; // id | |
66 | + seriesId?: number; // 车系id | |
67 | + seriesName?: string; // 车系名称 | |
68 | + specList?: SpecList[]; // 车型列表 | |
69 | +} | |
70 | + | |
71 | +interface SpecList { | |
72 | + configId?: number; // 补贴配置id | |
73 | + specId?: number; // 车型id | |
74 | + specName?: string; // 车型名称 | |
75 | +} | |
76 | + | |
77 | +/** | |
78 | + * 查询金融贷款条件配置列表 | |
79 | + * @param params | |
80 | + * @returns | |
81 | + */ | |
82 | +export function getListApi(params: RequestParams): Page<ListResult> { | |
83 | + return request.get(`${ORDER3}/erp/financial/loan/config/condition/page`, { params }); | |
84 | +} | |
85 | + | |
86 | +/** | |
87 | + * 查询金融贷款条件详情 | |
88 | + * @param id | |
89 | + * @returns | |
90 | + */ | |
91 | +export function getLoanConditionApi(id?: number): http.PromiseResp<ListResult> { | |
92 | + return request.get(`${ORDER3}/erp/financial/loan/config/condition/queryInfo`, { params: { id } }); | |
93 | +} | |
94 | + | |
95 | +/** | |
96 | + * 新增、编辑金融贷款条件配置 | |
97 | + * @param params | |
98 | + * @returns | |
99 | + */ | |
100 | +export function saveConfigApi(params: SaveParams) { | |
101 | + return request.post(`${ORDER3}/erp/financial/loan/config/condition/saveOrUpdate`, params); | |
102 | +} | |
103 | + | |
104 | +/** | |
105 | + * 删除金融贷款条件配置 | |
106 | + * @param id 配置id | |
107 | + * @returns | |
108 | + */ | |
109 | +export function deleteConfigApi(params: {id?: number}) { | |
110 | + return request.post(`${ORDER3}/erp/financial/loan/config/condition/delete`, params, { contentType: 'form-urlencoded' }); | |
111 | +} | |
112 | + | |
113 | + | |
114 | +export interface RoleList { | |
115 | + roleCode?: string; // 角色代码 | |
116 | + roleName?: string; // 角色名称 | |
117 | +} | |
118 | +/** | |
119 | + * 查询角色 | |
120 | + * @param params | |
121 | + * @returns | |
122 | + */ | |
123 | +export function getRoleListApi(): http.PromiseResp<RoleList[]> { | |
124 | + return request.get(`${ORDER3}/erp/financial/loan/config/condition/queryRole`); | |
125 | +} | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/components/CarModal.tsx
0 → 100644
1 | +import React, { useState, useEffect } from 'react'; | |
2 | +import { Modal } from 'antd'; | |
3 | +import CarTableTreeAuth from '@/components/CarTableTreeAuth'; | |
4 | +import { ApplyCarList } from '../api'; | |
5 | +import { handleCarTreeTransform } from '@/pages/order3/Common/util'; | |
6 | + | |
7 | +interface CarModal { | |
8 | + visible: boolean, | |
9 | + data?: ApplyCarList[]; | |
10 | +} | |
11 | + | |
12 | +interface Props { | |
13 | + carModal: CarModal; | |
14 | + setCarModal: (value: CarModal) => void; | |
15 | +} | |
16 | + | |
17 | +const ShowModal = ({ carModal, setCarModal }: Props) => { | |
18 | + const [carData, setCarData] = useState<any>([]); | |
19 | + | |
20 | + useEffect(() => { | |
21 | + if (carModal.visible) { | |
22 | + const data = handleCarTreeTransform(carModal.data || []); | |
23 | + setCarData(data); | |
24 | + } | |
25 | + }, [carModal.visible]); | |
26 | + | |
27 | + function handleCancel() { | |
28 | + setCarModal({ visible: false, data: undefined }); | |
29 | + }; | |
30 | + | |
31 | + return ( | |
32 | + <Modal | |
33 | + destroyOnClose | |
34 | + forceRender | |
35 | + open={carModal.visible} | |
36 | + title="适用车辆" | |
37 | + maskClosable={false} | |
38 | + onCancel={handleCancel} | |
39 | + onOk={handleCancel} | |
40 | + footer={null} | |
41 | + > | |
42 | + <CarTableTreeAuth value={carData} disabled brandMultiple={false} /> | |
43 | + </Modal> | |
44 | + ); | |
45 | +}; | |
46 | +export default ShowModal; | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/components/ConditionModal.tsx
0 → 100644
1 | +import React from 'react'; | |
2 | +import { Modal, Table } from 'antd'; | |
3 | +import { RoleCommissionList } from '../api'; | |
4 | +import { CommissionTypeEnum } from '@/pages/order3/RebateCommission/entity'; | |
5 | + | |
6 | +interface ConditionModal { | |
7 | + visible: boolean; | |
8 | + data?: RoleCommissionList[]; | |
9 | +} | |
10 | + | |
11 | +interface Props { | |
12 | + conditionModal: ConditionModal; | |
13 | + setConditionModal: (value: ConditionModal) => void; | |
14 | +} | |
15 | + | |
16 | +const Index = ({conditionModal, setConditionModal }: Props) => { | |
17 | + | |
18 | + function handleCancel() { | |
19 | + setConditionModal({ visible: false, data: undefined }); | |
20 | + } | |
21 | + | |
22 | + return ( | |
23 | + <Modal footer={null} destroyOnClose forceRender open={conditionModal.visible} title="角色提成" maskClosable={false} onCancel={handleCancel} onOk={handleCancel}> | |
24 | + <Table rowKey="roleCode" pagination={false} dataSource={conditionModal.data || []}> | |
25 | + <Table.Column title="角色" dataIndex="roleName" /> | |
26 | + <Table.Column | |
27 | + title="提成标准" | |
28 | + dataIndex="rebateType" | |
29 | + render={(_text, record: RoleCommissionList) => { | |
30 | + let str = ''; | |
31 | + if (!_text) { | |
32 | + str = '--'; | |
33 | + } else if (_text === 2) { | |
34 | + str = `贷款额*期数*${record.rebateValue}%`; | |
35 | + } else if (_text === 1) { | |
36 | + str = `${record.rebateValue ?? '--'}元`; | |
37 | + } | |
38 | + return str; | |
39 | + }} | |
40 | + /> | |
41 | + <Table.Column title="提成类型" dataIndex="commissionType" render={(_text) => (_text && CommissionTypeEnum[_text]) || '--'} /> | |
42 | + </Table> | |
43 | + </Modal> | |
44 | + ); | |
45 | +}; | |
46 | +export default Index; | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/components/List.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { message, Popconfirm, Space, Table, Typography, Divider } from 'antd'; | |
3 | +import * as api from '../api'; | |
4 | +import CarModal from './CarModal'; | |
5 | +import ConditionModal from './ConditionModal'; | |
6 | +import { history } from 'umi'; | |
7 | +import { ConditionEnum } from '@/pages/order3/RebateCommission/entity'; | |
8 | +import TextWithMore from '@/components/TextWithMore'; | |
9 | + | |
10 | +interface CarDetailModal { | |
11 | + visible: boolean; | |
12 | + data?: api.ApplyCarList[]; | |
13 | +} | |
14 | + | |
15 | +interface ConditionDetailModal { | |
16 | + visible: boolean; | |
17 | + data?: api.RoleCommissionList[]; | |
18 | +} | |
19 | + | |
20 | +interface Props { | |
21 | + id?: number; | |
22 | + list?: api.ListResult[] | |
23 | + paginationConfig: any; | |
24 | + loading: boolean; | |
25 | + setLoading: (bool: boolean) => void; | |
26 | +} | |
27 | + | |
28 | +const Column = Table.Column; | |
29 | + | |
30 | +export default function List({ id, list, paginationConfig, loading, setLoading }: Props) { | |
31 | + const [pageLoading, setPageLoading] = useState<boolean>(false); | |
32 | + const [carModal, setCarModal] = useState<CarDetailModal>({ visible: false, data: undefined }); | |
33 | + const [conditionModal, setConditionModal] = useState<ConditionDetailModal>({ visible: false, data: undefined }); | |
34 | + | |
35 | + /** | |
36 | + * 删除配置 | |
37 | + * @param id | |
38 | + */ | |
39 | + function onDelete(configId?: number) { | |
40 | + setPageLoading(true); | |
41 | + api | |
42 | + .deleteConfigApi({ id: configId }) | |
43 | + .then((res) => { | |
44 | + setPageLoading(false); | |
45 | + setLoading(true); | |
46 | + message.success(res.result); | |
47 | + }) | |
48 | + .catch((e) => { | |
49 | + setPageLoading(false); | |
50 | + message.error(e.message); | |
51 | + }); | |
52 | + } | |
53 | + | |
54 | + function onEdit(record: api.ListResult, type: number) { | |
55 | + history.push(`/order3/rebateCommission/loanCondition/edit?financialProductsConfigId=${id}&id=${record.id}&type=${type}`); | |
56 | + } | |
57 | + | |
58 | + function handleBrand(value?: api.ApplyCarList[]) { | |
59 | + const brand = value?.map((v) => ({ brandId: v.brandId, brandName: v.brandName })); | |
60 | + return brand || []; | |
61 | + } | |
62 | + | |
63 | + return ( | |
64 | + <div> | |
65 | + <Table dataSource={list} pagination={paginationConfig} loading={loading || pageLoading} rowKey="id" scroll={{ x: 1000 }}> | |
66 | + <Column | |
67 | + title="品牌" | |
68 | + dataIndex="brandName" | |
69 | + render={(_text, record: api.ListResult) => <TextWithMore dataIndex="brandName" list={handleBrand(record.applyCarList)} unit="个品牌" />} | |
70 | + /> | |
71 | + <Column | |
72 | + title="适用车辆" | |
73 | + align="center" | |
74 | + dataIndex="applyCarList" | |
75 | + render={(_text) => ( | |
76 | + <span style={{ color: '#4189FD' }} onClick={() => setCarModal({ visible: true, data: _text })}> | |
77 | + 查看 | |
78 | + </span> | |
79 | + )} | |
80 | + /> | |
81 | + <Column | |
82 | + title="分期条件" | |
83 | + align="center" | |
84 | + dataIndex="loanPeriods" | |
85 | + render={(_text, record: api.ListResult) => ( | |
86 | + <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}> | |
87 | + <span> | |
88 | + 分期期数{(record.periodsJudgeCondition && ConditionEnum[record.periodsJudgeCondition]) || '--'} | |
89 | + {record.loanPeriods}期; | |
90 | + </span> | |
91 | + <span> | |
92 | + 贷款额{(record.amountJudgeCondition && ConditionEnum[record.amountJudgeCondition]) || '--'} | |
93 | + {record.loanAmount}元 | |
94 | + </span> | |
95 | + </div> | |
96 | + )} | |
97 | + /> | |
98 | + <Column | |
99 | + title="车贷银行返利标准" | |
100 | + align="center" | |
101 | + dataIndex="rebateType" | |
102 | + render={(_text, record: api.ListResult) => { | |
103 | + if (_text === 1) { | |
104 | + return `${record.rebateValue}元/单`; | |
105 | + } else if (_text === 2) { | |
106 | + return `${record.rebateValue}%`; | |
107 | + } | |
108 | + return '--'; | |
109 | + }} | |
110 | + /> | |
111 | + <Column | |
112 | + title="角色提成" | |
113 | + align="center" | |
114 | + dataIndex="roleCommissionList" | |
115 | + render={(_text) => ( | |
116 | + <span style={{ color: '#4189FD' }} onClick={() => setConditionModal({ visible: true, data: _text })}> | |
117 | + 查看 | |
118 | + </span> | |
119 | + )} | |
120 | + /> | |
121 | + | |
122 | + <Column | |
123 | + title="操作" | |
124 | + dataIndex="option" | |
125 | + align="center" | |
126 | + fixed="right" | |
127 | + render={(_text, record: api.ListResult) => ( | |
128 | + <Space wrap split={<Divider type="vertical" />}> | |
129 | + <Popconfirm title="确定删除?" onConfirm={() => onDelete(record.id)}> | |
130 | + <Typography.Link style={{ color: '#666' }}>删除</Typography.Link> | |
131 | + </Popconfirm> | |
132 | + <Typography.Link onClick={() => onEdit(record, 2)} style={{ color: '#4189FD' }}> | |
133 | + 复制 | |
134 | + </Typography.Link> | |
135 | + <Typography.Link onClick={() => onEdit(record, 1)} style={{ color: '#4189FD' }}> | |
136 | + 编辑 | |
137 | + </Typography.Link> | |
138 | + </Space> | |
139 | + )} | |
140 | + /> | |
141 | + </Table> | |
142 | + <CarModal carModal={carModal} setCarModal={setCarModal} /> | |
143 | + <ConditionModal conditionModal={conditionModal} setConditionModal={setConditionModal} /> | |
144 | + </div> | |
145 | + ); | |
146 | +} | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/index.tsx
0 → 100644
1 | +import { Button, Card, Input, Row, Space } from 'antd'; | |
2 | +import React, { useEffect, useState } from 'react'; | |
3 | +import { PlusOutlined } from '@ant-design/icons'; | |
4 | +import List from './components/List'; | |
5 | +import { history } from 'umi'; | |
6 | +import { getListApi } from '@/pages/order3/RebateCommission/subpages/LoanCondition/api'; | |
7 | +import usePagination from '@/hooks/usePagination'; | |
8 | + | |
9 | +interface Props { | |
10 | + id?: number; // id | |
11 | + financialCompanyName?: string; // 金融公司名称 | |
12 | + productName?: string; // 产品名称 | |
13 | +} | |
14 | + | |
15 | +const Index = ({ id, financialCompanyName, productName }: Props) => { | |
16 | + const [delay, setDelay] = useState<boolean>(true); | |
17 | + const { list, paginationConfig, loading, setLoading, setParams, innerParams } = usePagination(getListApi, { current: 1, pageSize: 10, financialProductsConfigId: id }, {delay}); | |
18 | + | |
19 | + useEffect(() => { | |
20 | + if (id) { | |
21 | + setParams({ ...innerParams, financialProductsConfigId: id }, true); | |
22 | + setDelay(false); | |
23 | + } | |
24 | + }, [id]) | |
25 | + | |
26 | + function onFinancialSearch(value?: string) { | |
27 | + setParams({ ...innerParams, current: 1, financialCompanyName: value }, true); | |
28 | + } | |
29 | + | |
30 | + function onAdd() { | |
31 | + history.push(`/order3/rebateCommission/loanCondition/edit?financialProductsConfigId=${id}&type=1`); | |
32 | + } | |
33 | + | |
34 | + return ( | |
35 | + <Card style={{backgroundColor: '#f4f4f4'}}> | |
36 | + <Row style={{ marginBottom: '15px' }}> | |
37 | + <span style={{fontSize: '16px', color: '#333', fontWeight: '600'}}> | |
38 | + 当前选择:{financialCompanyName},{productName} | |
39 | + </span> | |
40 | + </Row> | |
41 | + <Row justify="end" style={{ marginBottom: '15px' }}> | |
42 | + <Button onClick={onAdd} type="primary"> | |
43 | + <PlusOutlined /> 新增 | |
44 | + </Button> | |
45 | + </Row> | |
46 | + <List list={list} paginationConfig={paginationConfig} loading={loading} setLoading={setLoading} id={id} /> | |
47 | + </Card> | |
48 | + ); | |
49 | +} | |
50 | + | |
51 | +export default Index; | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/subpages/LoanConditionEdit/components/EditModal.tsx
0 → 100644
1 | +import React, { useEffect } from 'react'; | |
2 | +import { Button, Card, Form, Input, Modal, Radio, Row, Select, Space } from 'antd'; | |
3 | +import { debounce } from 'lodash'; | |
4 | +import { RoleCommissionList, RoleList } from '../../../api'; | |
5 | +import { EditModal } from '../index'; | |
6 | + | |
7 | +interface Props { | |
8 | + editStatus: EditModal; | |
9 | + setEditStatus: (value: EditModal) => void; | |
10 | + roleCommissionList: RoleCommissionList[]; | |
11 | + setRoleCommissionList: (value: RoleCommissionList[]) => void; | |
12 | + roleList?: RoleList[]; | |
13 | +} | |
14 | + | |
15 | +export default function Index({ editStatus, setEditStatus, roleCommissionList, setRoleCommissionList, roleList }: Props) { | |
16 | + const [form] = Form.useForm(); | |
17 | + | |
18 | + useEffect(() => { | |
19 | + if (editStatus.visible && editStatus.data?.roleCode) { | |
20 | + form.setFieldsValue({ | |
21 | + role: { label: editStatus.data.roleName, value: editStatus.data.roleCode }, | |
22 | + rebateType: editStatus.data.rebateType, | |
23 | + rebateValue: editStatus.data.rebateValue, | |
24 | + commissionType: editStatus.data.commissionType, | |
25 | + }); | |
26 | + } | |
27 | + }, [editStatus.visible, editStatus.data?.roleCode]) | |
28 | + | |
29 | + function handleCancle() { | |
30 | + form.resetFields(); | |
31 | + setEditStatus({visible: false, data: undefined}); | |
32 | + } | |
33 | + | |
34 | + function handleRoleList() { | |
35 | + const codeList = roleCommissionList?.map(v => v.roleCode); | |
36 | + const _roleList = JSON.parse(JSON.stringify(roleList || [])); | |
37 | + const data = _roleList.map((v: any) => { | |
38 | + if (codeList?.includes(v.roleCode)) { | |
39 | + v.disabled = true; | |
40 | + } | |
41 | + return {...v, label: v.roleName, value: v.roleCode} | |
42 | + }); | |
43 | + return data || []; | |
44 | + } | |
45 | + | |
46 | + async function handleSubmit() { | |
47 | + const value = await form.validateFields(); | |
48 | + const list = roleCommissionList || []; | |
49 | + if (editStatus.data?.roleCode) { | |
50 | + const result = list.map((v: RoleCommissionList) => { | |
51 | + const item = {...v}; | |
52 | + if (editStatus.data?.roleCode == v.roleCode) { | |
53 | + item.roleCode = value?.role?.value; | |
54 | + item.roleName = value?.role?.label; | |
55 | + item.commissionType = value.commissionType; | |
56 | + item.rebateType = value.rebateType; | |
57 | + item.rebateValue = value.rebateValue; | |
58 | + } | |
59 | + return {...item}; | |
60 | + }) | |
61 | + setRoleCommissionList(result || []); | |
62 | + } else { | |
63 | + const item = { | |
64 | + roleCode: value?.role?.value, | |
65 | + roleName: value?.role?.label, | |
66 | + commissionType: value.commissionType, | |
67 | + rebateType: value.rebateType, | |
68 | + rebateValue: value.rebateValue, | |
69 | + } | |
70 | + setRoleCommissionList([...roleCommissionList, item]); | |
71 | + } | |
72 | + handleCancle(); | |
73 | + } | |
74 | + | |
75 | + return ( | |
76 | + <Modal | |
77 | + title={editStatus.data?.roleCode ? '编辑角色提成' : '新增角色提成'} | |
78 | + open={editStatus.visible} | |
79 | + onCancel={handleCancle} | |
80 | + width="50%" | |
81 | + maskClosable={false} | |
82 | + footer={false} | |
83 | + destroyOnClose | |
84 | + afterClose={() => form.resetFields()} | |
85 | + > | |
86 | + <Card bordered={false}> | |
87 | + <Form form={form}> | |
88 | + <Form.Item label="角色" name="role" rules={[{ required: true, message: '请输入' }]}> | |
89 | + <Select placeholder="请选择" labelInValue filterOption optionFilterProp="children" options={handleRoleList()} /> | |
90 | + </Form.Item> | |
91 | + | |
92 | + <Form.Item label="提成类型" name="rebateType" rules={[{ required: true, message: '请输入' }]}> | |
93 | + <Radio.Group onChange={() => form.setFieldValue('rebateValue', undefined)}> | |
94 | + <Radio value={1}>固定金额</Radio> | |
95 | + <Radio value={2}>固定比例</Radio> | |
96 | + </Radio.Group> | |
97 | + </Form.Item> | |
98 | + <Form.Item noStyle shouldUpdate> | |
99 | + {({ getFieldValue }) => { | |
100 | + const value = getFieldValue('rebateType'); | |
101 | + if (!value) { | |
102 | + return null; | |
103 | + } | |
104 | + return value == 1 ? ( | |
105 | + <Form.Item | |
106 | + label="提成标准" | |
107 | + name="rebateValue" | |
108 | + rules={[ | |
109 | + { | |
110 | + required: true, | |
111 | + pattern: /^(\d+|\d+\.\d{1,2})$/, | |
112 | + message: '请输入正确的提成标准', | |
113 | + }, | |
114 | + ]} | |
115 | + > | |
116 | + <Input placeholder="请输入" suffix="元" /> | |
117 | + </Form.Item> | |
118 | + ) : ( | |
119 | + <Form.Item | |
120 | + label="提成标准" | |
121 | + name="rebateValue" | |
122 | + rules={[ | |
123 | + { | |
124 | + required: true, | |
125 | + pattern: /^(\d+|\d+\.\d{1,4})$/, | |
126 | + message: '请输入正确的提成标准', | |
127 | + }, | |
128 | + ({ getFieldValue }) => ({ | |
129 | + validator(_, value) { | |
130 | + if (value && +value <= 100 && +value >= 0) { | |
131 | + return Promise.resolve(); | |
132 | + } | |
133 | + return Promise.reject(new Error('比例范围应在0~100!')); | |
134 | + }, | |
135 | + }), | |
136 | + ]} | |
137 | + > | |
138 | + <Input placeholder="请输入" suffix="%" /> | |
139 | + </Form.Item> | |
140 | + ); | |
141 | + }} | |
142 | + </Form.Item> | |
143 | + <Form.Item label="计提成类型" name="commissionType" rules={[{ required: true, message: '请输入' }]}> | |
144 | + <Radio.Group> | |
145 | + <Radio value={1}>计提成</Radio> | |
146 | + <Radio value={2}>计附加值</Radio> | |
147 | + </Radio.Group> | |
148 | + </Form.Item> | |
149 | + </Form> | |
150 | + | |
151 | + <Row style={{ marginTop: '30px' }} justify="center"> | |
152 | + <Space> | |
153 | + <Button onClick={handleCancle} type="default"> | |
154 | + 取消 | |
155 | + </Button> | |
156 | + <Button onClick={debounce(handleSubmit, 380)} type="primary"> | |
157 | + 确定 | |
158 | + </Button> | |
159 | + </Space> | |
160 | + </Row> | |
161 | + </Card> | |
162 | + </Modal> | |
163 | + ); | |
164 | +} | ... | ... |
src/pages/order3/RebateCommission/subpages/LoanCondition/subpages/LoanConditionEdit/index.tsx
0 → 100644
1 | +import React, { useState, useEffect } from 'react'; | |
2 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
3 | +import { Button, Card, Col, Input, Row, Typography, Form, Space, Select, Divider, InputNumber, Radio, Table, message, Popconfirm } from 'antd'; | |
4 | +import { debounce } from 'lodash'; | |
5 | +import { PlusOutlined, PlusSquareOutlined } from '@ant-design/icons'; | |
6 | +import { ConditionData } from '@/pages/order3/RebateCommission/entity'; | |
7 | +import { LoanPeriod } from '@/pages/order3/Common/entity'; | |
8 | +import EditModal from './components/EditModal'; | |
9 | +import { RoleCommissionList, getRoleListApi, getLoanConditionApi, saveConfigApi, ListResult } from '../../api'; | |
10 | +import { getFinancialDetailApi } from '@/pages/order3/RebateCommission/api'; | |
11 | +import useInitial from '@/hooks/useInitail'; | |
12 | +import { history } from 'umi'; | |
13 | +import SelectorWithFull from '@/components/SelectorWithFull'; | |
14 | +import CarTableTreeAuth from '@/components/CarTableTreeAuth'; | |
15 | +import { getUnitCompanyListApi, fetchShopListByRangeTypeApi } from '@/common/api'; | |
16 | +import { CommissionTypeEnum } from '@/pages/order3/RebateCommission/entity'; | |
17 | +import { handleCarTreeFlat, handleCarTreeTransform } from '@/pages/order3/Common/util'; | |
18 | + | |
19 | +export interface EditModalSatus { | |
20 | + visible: boolean; | |
21 | + data?: RoleCommissionList; | |
22 | +} | |
23 | + | |
24 | +interface State { | |
25 | + id?: number; | |
26 | + financialProductsConfigId?: number; | |
27 | + type?: number, | |
28 | +} | |
29 | + | |
30 | +export default function Index() { | |
31 | + const { id, financialProductsConfigId, type } = history.location.query as State; | |
32 | + const [form] = Form.useForm(); | |
33 | + const [roleCommissionList, setRoleCommissionList] = useState<RoleCommissionList[]>([]); | |
34 | + const [roleModal, setRoleModal] = useState<EditModalSatus>({ visible: false }); | |
35 | + const { data: roleList } = useInitial(getRoleListApi, [], null); | |
36 | + const [loading, setLoading] = useState<boolean>(false); | |
37 | + const { data: companyList } = useInitial(getUnitCompanyListApi, [], { types: '20' }); | |
38 | + const { data: shopList } = useInitial(fetchShopListByRangeTypeApi, [], { bizTypeList: '1' }); | |
39 | + const { data: product, loading: productLoading } = useInitial(getFinancialDetailApi, {}, financialProductsConfigId); | |
40 | + const [cofrimLoading, setConfirmLoading] = useState<boolean>(false); | |
41 | + | |
42 | + useEffect(() => { | |
43 | + if (product?.id) { | |
44 | + form.setFieldsValue({ | |
45 | + financialCompany: { label: product?.financialCompanyName, value: product?.financialCompanyId }, | |
46 | + productName: product?.productName, | |
47 | + loanRate: product?.loanRate, | |
48 | + applyShopType: product?.applyShopType, | |
49 | + shopList: product?.applyShopList?.map((v) => ({ id: v.shopId, name: v.shopName })), | |
50 | + }); | |
51 | + } | |
52 | + }, [product]) | |
53 | + | |
54 | + useEffect(() => { | |
55 | + // initial(); | |
56 | + if (id) { | |
57 | + setLoading(true); | |
58 | + getLoanConditionApi(id) | |
59 | + .then(res => { | |
60 | + const financial = res.data || {}; | |
61 | + form.setFieldsValue({ | |
62 | + loanPeriods: financial.loanPeriods, | |
63 | + periodsJudgeCondition: financial.periodsJudgeCondition, | |
64 | + loanAmount: financial.loanAmount, | |
65 | + amountJudgeCondition: financial.amountJudgeCondition, | |
66 | + rebateType: financial.rebateType, | |
67 | + rebateValue: financial.rebateValue, | |
68 | + optionalAuth: handleCarTreeTransform(financial.applyCarList || []), | |
69 | + }); | |
70 | + setRoleCommissionList(financial.roleCommissionList || []); | |
71 | + setLoading(false); | |
72 | + }) | |
73 | + .catch(e => { | |
74 | + message.error(e.message); | |
75 | + setLoading(false); | |
76 | + }) | |
77 | + .finally(() => { | |
78 | + setLoading(false); | |
79 | + }) | |
80 | + } | |
81 | + }, []); | |
82 | + | |
83 | + const initial = async () => { | |
84 | + try { | |
85 | + setLoading(true); | |
86 | + const { data: product } = await getFinancialDetailApi(financialProductsConfigId); | |
87 | + let financial: ListResult = {}; | |
88 | + if (id) { | |
89 | + const _data = await getLoanConditionApi(id); | |
90 | + financial = _data?.data || {}; | |
91 | + } | |
92 | + form.setFieldsValue({ | |
93 | + financialCompany: { label: product?.financialCompanyName, value: product?.financialCompanyId }, | |
94 | + productName: product?.productName, | |
95 | + loanRate: product?.loanRate, | |
96 | + applyShopType: product?.applyShopType, | |
97 | + shopList: product?.applyShopList?.map((v) => ({ id: v.shopId, name: v.shopName })), | |
98 | + loanPeriods: financial.loanPeriods, | |
99 | + periodsJudgeCondition: financial.periodsJudgeCondition, | |
100 | + loanAmount: financial.loanAmount, | |
101 | + amountJudgeCondition: financial.amountJudgeCondition, | |
102 | + rebateType: financial.rebateType, | |
103 | + rebateValue: financial.rebateValue, | |
104 | + optionalAuth: handleCarTreeTransform(financial.applyCarList || []), | |
105 | + }); | |
106 | + setRoleCommissionList(financial.roleCommissionList || []); | |
107 | + setLoading(false); | |
108 | + } catch (e: any) { | |
109 | + setLoading(false); | |
110 | + message.error(e.message); | |
111 | + } | |
112 | + } | |
113 | + | |
114 | + function onBack() { | |
115 | + history.goBack(); | |
116 | + } | |
117 | + | |
118 | + /** | |
119 | + * 添加提成角色设置 | |
120 | + */ | |
121 | + function onAddRole() { | |
122 | + setRoleModal({ visible: true, data: undefined }); | |
123 | + } | |
124 | + /** | |
125 | + * 删除提成角色设置 | |
126 | + * @param code | |
127 | + */ | |
128 | + function onDeleteRoleCommission(code?: string) { | |
129 | + const list = roleCommissionList.filter(v => v.roleCode !== code); | |
130 | + setRoleCommissionList(list || []); | |
131 | + } | |
132 | + | |
133 | + /** | |
134 | + * 编辑提成角色设置 | |
135 | + * @param record | |
136 | + */ | |
137 | + function onEditRoleCommission(record?: RoleCommissionList) { | |
138 | + setRoleModal({visible: true, data: record}); | |
139 | + } | |
140 | + | |
141 | + async function onSure() { | |
142 | + const value = await form.validateFields(); | |
143 | + const params = { | |
144 | + loanPeriods: value.loanPeriods, | |
145 | + periodsJudgeCondition: value.periodsJudgeCondition, | |
146 | + loanAmount: value.loanAmount, | |
147 | + amountJudgeCondition: value.amountJudgeCondition, | |
148 | + rebateType: value.rebateType, | |
149 | + rebateValue: value.rebateValue, | |
150 | + applyCarList: handleCarTreeFlat(value.optionalAuth || []), | |
151 | + roleCommissionList, | |
152 | + id: type == 1 ? id : undefined, | |
153 | + financialProductsConfigId, | |
154 | + }; | |
155 | + setConfirmLoading(true); | |
156 | + saveConfigApi(params) | |
157 | + .then(res => { | |
158 | + message.success(res.result); | |
159 | + history.goBack(); | |
160 | + }) | |
161 | + .catch(e => { | |
162 | + message.error(e.message); | |
163 | + setConfirmLoading(false); | |
164 | + }) | |
165 | + .finally(() => { | |
166 | + setConfirmLoading(false); | |
167 | + }) | |
168 | + } | |
169 | + | |
170 | + return ( | |
171 | + <PageHeaderWrapper title="车贷银行返利和提成配置"> | |
172 | + <Card loading={loading || productLoading}> | |
173 | + <Form form={form}> | |
174 | + <Row justify="center"> | |
175 | + <Col span={14}> | |
176 | + <Form.Item label="车贷银行" name="financialCompany"> | |
177 | + <Select | |
178 | + labelInValue | |
179 | + showSearch | |
180 | + allowClear | |
181 | + disabled | |
182 | + filterOption | |
183 | + optionFilterProp="label" | |
184 | + options={companyList.map((v) => ({ label: v.name, value: v.id }))} | |
185 | + placeholder="请选择" | |
186 | + /> | |
187 | + </Form.Item> | |
188 | + | |
189 | + <Form.Item label="金融产品" name="productName"> | |
190 | + <Input disabled placeholder="请输入" /> | |
191 | + </Form.Item> | |
192 | + | |
193 | + <Form.Item label="适用门店类型" name="applyShopType"> | |
194 | + <Radio.Group disabled> | |
195 | + <Radio value={1}>全部门店</Radio> | |
196 | + <Radio value={2}>部分门店</Radio> | |
197 | + </Radio.Group> | |
198 | + </Form.Item> | |
199 | + | |
200 | + <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.applyShopType != currentValues.applyShopType}> | |
201 | + {({ getFieldValue }) => { | |
202 | + const value = getFieldValue('applyShopType'); | |
203 | + if (value !== 2) { | |
204 | + return; | |
205 | + } | |
206 | + return ( | |
207 | + <Form.Item label="适用门店" name="shopList"> | |
208 | + <SelectorWithFull | |
209 | + placeholder="请选择" | |
210 | + multiple | |
211 | + disabled | |
212 | + labelInValue | |
213 | + data={shopList} | |
214 | + fieldKeyNames={{ keyName: 'id', valueName: 'id', labelName: 'name' }} | |
215 | + /> | |
216 | + </Form.Item> | |
217 | + ); | |
218 | + }} | |
219 | + </Form.Item> | |
220 | + | |
221 | + <Form.Item | |
222 | + label="促销利率" | |
223 | + name="loanRate" | |
224 | + > | |
225 | + <Input disabled placeholder="请输入" style={{ width: '100%' }} suffix="%" /> | |
226 | + </Form.Item> | |
227 | + | |
228 | + <Form.Item | |
229 | + name="optionalAuth" | |
230 | + label="适用车辆" | |
231 | + rules={[{ required: true, message: '选择车辆' }]} | |
232 | + tooltip={ | |
233 | + <span style={{ color: '#ccc', fontSize: 12 }}> | |
234 | + *点击图标 | |
235 | + <PlusSquareOutlined /> | |
236 | + 展开详情 | |
237 | + </span> | |
238 | + } | |
239 | + > | |
240 | + <CarTableTreeAuth /> | |
241 | + </Form.Item> | |
242 | + </Col> | |
243 | + </Row> | |
244 | + | |
245 | + <Divider orientation="left">分期规则</Divider> | |
246 | + <Row justify="center"> | |
247 | + <Col span={14}> | |
248 | + <Card headStyle={{ backgroundColor: '#eee', color: '#4189FD', fontSize: 14 }} title="分期条件"> | |
249 | + <Form.Item> | |
250 | + <Form.Item label="分期期数" style={{ marginBottom: 0 }} required> | |
251 | + <Form.Item | |
252 | + name="periodsJudgeCondition" | |
253 | + rules={[{ required: true, message: '请选择' }]} | |
254 | + style={{ display: 'inline-block', width: 'calc(30% - 8px)' }} | |
255 | + > | |
256 | + <Select placeholder="请选择" allowClear options={ConditionData} /> | |
257 | + </Form.Item> | |
258 | + <Form.Item | |
259 | + name="loanPeriods" | |
260 | + rules={[{ required: true, message: '请选择' }]} | |
261 | + style={{ display: 'inline-block', width: 'calc(30% - 8px)', margin: '0 8px' }} | |
262 | + > | |
263 | + <Select placeholder="请选择" allowClear options={LoanPeriod} /> | |
264 | + </Form.Item> | |
265 | + </Form.Item> | |
266 | + | |
267 | + <Form.Item label="贷款额度" style={{ marginBottom: 0 }} required> | |
268 | + <Form.Item | |
269 | + name="amountJudgeCondition" | |
270 | + rules={[{ required: true, message: '请选择' }]} | |
271 | + style={{ display: 'inline-block', width: 'calc(30% - 8px)' }} | |
272 | + > | |
273 | + <Select placeholder="请选择" allowClear options={ConditionData} /> | |
274 | + </Form.Item> | |
275 | + <Form.Item | |
276 | + name="loanAmount" | |
277 | + rules={[ | |
278 | + { | |
279 | + required: true, | |
280 | + pattern: /^(\d+|\d+\.\d{1,2})$/, | |
281 | + message: '请输入正确的金额', | |
282 | + }, | |
283 | + ]} | |
284 | + style={{ display: 'inline-block', width: 'calc(30% - 8px)', margin: '0 8px' }} | |
285 | + > | |
286 | + <Input style={{ width: '100%' }} suffix="元" placeholder="请输入" /> | |
287 | + </Form.Item> | |
288 | + </Form.Item> | |
289 | + | |
290 | + <Form.Item label="返利类型" name="rebateType" rules={[{ required: true, message: '请选择' }]}> | |
291 | + <Radio.Group onChange={() => form.setFieldValue('rebateValue', undefined)}> | |
292 | + <Radio value={1}>固定金额</Radio> | |
293 | + <Radio value={2}>固定比例</Radio> | |
294 | + </Radio.Group> | |
295 | + </Form.Item> | |
296 | + | |
297 | + <Form.Item | |
298 | + noStyle | |
299 | + shouldUpdate={(prevValues, currValues) => { | |
300 | + return prevValues.rebateType !== currValues.rebateType; | |
301 | + }} | |
302 | + > | |
303 | + {({ getFieldValue }) => { | |
304 | + const value = getFieldValue('rebateType'); | |
305 | + if (!value) { | |
306 | + return; | |
307 | + } | |
308 | + return value == 1 ? ( | |
309 | + <Form.Item label="返利标准" style={{ marginBottom: 0 }} required> | |
310 | + <Form.Item | |
311 | + name="rebateValue" | |
312 | + rules={[ | |
313 | + { | |
314 | + required: true, | |
315 | + pattern: /^(\d+|\d+\.\d{1,2})$/, | |
316 | + message: '请输入正确的返利标准', | |
317 | + }, | |
318 | + ]} | |
319 | + style={{ display: 'inline-block', width: 'calc(30% - 8px)' }} | |
320 | + > | |
321 | + <Input style={{ width: '100%' }} placeholder="请输入" suffix="元/单" /> | |
322 | + </Form.Item> | |
323 | + </Form.Item> | |
324 | + ) : ( | |
325 | + <Form.Item label="返利标准" style={{ marginBottom: 0 }} required> | |
326 | + <Form.Item | |
327 | + name="rebateValue" | |
328 | + rules={[ | |
329 | + { | |
330 | + required: true, | |
331 | + pattern: /^(\d+|\d+\.\d{1,2})$/, | |
332 | + message: '请输入正确的返利标准', | |
333 | + }, | |
334 | + ({ getFieldValue }) => ({ | |
335 | + validator(_, value) { | |
336 | + if (value && +value <= 100 && +value >= 0) { | |
337 | + return Promise.resolve(); | |
338 | + } | |
339 | + return Promise.reject(new Error('比例范围应在0~100!')); | |
340 | + }, | |
341 | + }), | |
342 | + ]} | |
343 | + style={{ display: 'inline-block', width: 'calc(30% - 8px)' }} | |
344 | + > | |
345 | + <Input style={{ width: '100%' }} placeholder="请输入" suffix="%" /> | |
346 | + </Form.Item> | |
347 | + </Form.Item> | |
348 | + ); | |
349 | + }} | |
350 | + </Form.Item> | |
351 | + | |
352 | + <div style={{ width: '100%' }}> | |
353 | + <Row style={{ marginBottom: '10px' }} justify="space-between"> | |
354 | + <span>角色提成设置:</span> | |
355 | + <Typography.Link style={{ color: '#4189FD' }} onClick={onAddRole}> | |
356 | + <PlusOutlined /> | |
357 | + 添加角色 | |
358 | + </Typography.Link> | |
359 | + </Row> | |
360 | + <Table pagination={false} dataSource={roleCommissionList} rowKey="roleCode"> | |
361 | + <Table.Column title="角色" dataIndex="roleName" /> | |
362 | + <Table.Column | |
363 | + title="提成标准" | |
364 | + dataIndex="rebateType" | |
365 | + render={(_text, record: RoleCommissionList) => { | |
366 | + let str = ''; | |
367 | + if (!_text) { | |
368 | + str = '--'; | |
369 | + } else if (_text === 2) { | |
370 | + str = `贷款额*期数*${record.rebateValue}%`; | |
371 | + } else if (_text === 1) { | |
372 | + str = `${record.rebateValue ?? '--'}元`; | |
373 | + } | |
374 | + return str; | |
375 | + }} | |
376 | + /> | |
377 | + <Table.Column title="提成类型" dataIndex="commissionType" render={(_text) => (_text && CommissionTypeEnum[_text]) || '--'} /> | |
378 | + <Table.Column | |
379 | + title="操作" | |
380 | + dataIndex="option" | |
381 | + render={(_text, record: RoleCommissionList) => ( | |
382 | + <Space> | |
383 | + <Popconfirm title="确定删除?" onConfirm={() => onDeleteRoleCommission(record.roleCode)}> | |
384 | + <Typography.Link style={{ color: '#999' }}>删除</Typography.Link> | |
385 | + </Popconfirm> | |
386 | + <Typography.Link onClick={() => onEditRoleCommission(record)} style={{ color: '#4189FD' }}> | |
387 | + 编辑 | |
388 | + </Typography.Link> | |
389 | + </Space> | |
390 | + )} | |
391 | + /> | |
392 | + </Table> | |
393 | + </div> | |
394 | + </Form.Item> | |
395 | + </Card> | |
396 | + </Col> | |
397 | + </Row> | |
398 | + </Form> | |
399 | + | |
400 | + <EditModal | |
401 | + roleCommissionList={roleCommissionList} | |
402 | + setRoleCommissionList={setRoleCommissionList} | |
403 | + editStatus={roleModal} | |
404 | + setEditStatus={setRoleModal} | |
405 | + roleList={roleList} | |
406 | + /> | |
407 | + <Row style={{ marginTop: '30px' }} justify="center"> | |
408 | + <Space> | |
409 | + <Button loading={cofrimLoading} onClick={onBack} type="default"> | |
410 | + 取消 | |
411 | + </Button> | |
412 | + <Button loading={cofrimLoading} onClick={debounce(onSure, 380)} type="primary"> | |
413 | + 确定 | |
414 | + </Button> | |
415 | + </Space> | |
416 | + </Row> | |
417 | + </Card> | |
418 | + </PageHeaderWrapper> | |
419 | + ); | |
420 | +} | |
0 | 421 | \ No newline at end of file | ... | ... |
src/pages/performance/DataImport/api.ts
0 → 100644
1 | +import request from '@/utils/request'; | |
2 | +import { MORAX_HOST } from '@/utils/host'; | |
3 | +import type { Page } from '@/typing/common'; | |
4 | +import type { Data } from 'ahooks/lib/useAntdTable/types'; | |
5 | + | |
6 | +/** | |
7 | + * 展厅美化导入记录分页查询 | |
8 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/showroom-page | |
9 | + */ | |
10 | +export async function DataImportAPi(params: MDataImport.DataImportListParams) { | |
11 | + const res = await request.get<Page<MDataImport.DataImportList>>(`${MORAX_HOST}/erp/eval-indicator-import/showroom-page`, { | |
12 | + params, | |
13 | + }); | |
14 | + const data = res?.data || { total: 0, list: [], data: [] }; | |
15 | + if (data) { | |
16 | + const d = data.data || []; | |
17 | + data.data = d; | |
18 | + data.list = d; | |
19 | + } | |
20 | + return data as Data; | |
21 | +} | |
22 | + | |
23 | +/** | |
24 | + * 数据导入指标列表 | |
25 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/indicators | |
26 | + */ | |
27 | +export async function IndicatorListApi() { | |
28 | + const res = await request.get<MDataImport.IndicatorList[]>(`${MORAX_HOST}/erp/eval-indicator-import/indicators`); | |
29 | + return res.data ?? []; | |
30 | +} | |
31 | + | |
32 | +/** | |
33 | + * 展厅美化导入清单查询 | |
34 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/showroom-detail | |
35 | + */ | |
36 | + | |
37 | +export async function DetailedListAPi(params: MDataImport.DataImportListParams) { | |
38 | + const res = await request.get<Page<MDataImport.DetailedList>>(`${MORAX_HOST}/erp/eval-indicator-import/showroom-detail`, { | |
39 | + params, | |
40 | + }); | |
41 | + const data = res?.data || { total: 0, list: [], data: [] }; | |
42 | + if (data) { | |
43 | + const d = data.data || []; | |
44 | + data.data = d; | |
45 | + data.list = d; | |
46 | + } | |
47 | + return data as Data; | |
48 | +} | |
49 | +/** | |
50 | + * 展厅美化导入记录详情查询 | |
51 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/showroom-import-detail | |
52 | + */ | |
53 | + | |
54 | +export async function ImportListDetailApi(id?: number) { | |
55 | + const res = await request.get<MDataImport.DataImportList>(`${MORAX_HOST}/erp/eval-indicator-import/showroom-import-detail`, { params: { id } }); | |
56 | + return res.data ?? {}; | |
57 | +} | |
58 | + | |
59 | +/** | |
60 | + * 上传展厅美化数据 | |
61 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/analysis/showroom-shop | |
62 | + */ | |
63 | + | |
64 | +export async function UploadImportApi(fid?: string, indicatorCode?: string) { | |
65 | + const res = await request.get<MDataImport.DataImportList>(`${MORAX_HOST}/erp/eval-indicator-import/analysis/showroom-shop`, { | |
66 | + params: { fid, indicatorCode }, | |
67 | + }); | |
68 | + return res.data ?? {}; | |
69 | +} | |
70 | + | |
71 | +/** | |
72 | + * 下载展厅美化数据 | |
73 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/template-file | |
74 | + */ | |
75 | + | |
76 | +export async function DownloadApi( indicatorCode?: string) { | |
77 | + const res = await request.get<any>(`${MORAX_HOST}/erp/eval-indicator-import/template-file`, { | |
78 | + params: { indicatorCode }, | |
79 | + }); | |
80 | + return res.data ?? {}; | |
81 | +} | |
82 | + | |
83 | +/** | |
84 | + * 删除导入审批 | |
85 | + * http://testgate.feewee.cn/morax/erp/eval-indicator/del-import | |
86 | + */ | |
87 | +export function deleteApi(params: { id: number }) { | |
88 | + return request.get(`${MORAX_HOST}/erp/eval-indicator/del-import`, { params }); | |
89 | +} | |
90 | +/** | |
91 | + * 撤销审批 | |
92 | + * http://testgate.feewee.cn/morax/erp/eval-indicator/cancel | |
93 | + */ | |
94 | +export function revokeApi(params: { id: number }) { | |
95 | + return request.get(`${MORAX_HOST}/erp/eval-indicator/cancel`, { params }); | |
96 | +} | |
97 | + | |
98 | +/** | |
99 | + * 保存展厅美化数据 | |
100 | + * http://testgate.feewee.cn/morax/erp/eval-indicator-import/save-showroom-import | |
101 | + */ | |
102 | +export function SaveDataApi(params: { key: string }) { | |
103 | + return request.get(`${MORAX_HOST}/erp/eval-indicator-import/save-showroom-import`, { params }); | |
104 | +} | |
0 | 105 | \ No newline at end of file | ... | ... |
src/pages/performance/DataImport/components/DetailList.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Table, message, DatePicker, Select } from 'antd'; | |
3 | +import type { ColumnsType } from 'antd/es/table'; | |
4 | +import type { DatePickerProps } from 'antd'; | |
5 | +import { DetailedListAPi } from '../api'; | |
6 | +import { useAntdTable } from 'ahooks'; | |
7 | +import moment from 'moment'; | |
8 | +import useInitial from '@/hooks/useInitail'; | |
9 | +import { getShopApi } from '@/common/api'; | |
10 | + | |
11 | +type Props = { | |
12 | + indicator?: MDataImport.IndicatorList; | |
13 | + onChange?: (value?: any) => void; | |
14 | +}; | |
15 | +interface DataType { | |
16 | + key: string; | |
17 | + name: string; | |
18 | +} | |
19 | +export default function TableList({ indicator }: Props) { | |
20 | + const [monthly, setMonthly] = useState<number>(); | |
21 | + const [shopId, setShopId] = useState<number>(); | |
22 | + const { data } = useInitial(getShopApi, [], {}); | |
23 | + const pickMonth: DatePickerProps['onChange'] = (date, _dateString) => { | |
24 | + setMonthly(date?.valueOf() ?? 0); | |
25 | + }; | |
26 | + function shopChange(value: any) { | |
27 | + setShopId(value); | |
28 | + } | |
29 | + //@ts-ignore | |
30 | + const { tableProps, run } = useAntdTable<any, MDataImport.DataImportListParams[]>(DetailedListAPi, { | |
31 | + manual: true, | |
32 | + defaultParams: [ | |
33 | + { | |
34 | + pageSize: 10, | |
35 | + current: 1, | |
36 | + shopId: undefined, | |
37 | + monthly: Date.now(), | |
38 | + indicatorCode: indicator?.code || '', | |
39 | + }, | |
40 | + ], | |
41 | + onError: (e, _) => { | |
42 | + message.error(e.message); | |
43 | + }, | |
44 | + }); | |
45 | + const columns: ColumnsType<DataType> = [ | |
46 | + { | |
47 | + title: '月度', | |
48 | + dataIndex: 'dataDate', | |
49 | + align: 'center', | |
50 | + width: 200, | |
51 | + key: 'dataDate', | |
52 | + render: (time: number) => (time ? moment(time).format('YYYY-MM') : '--'), | |
53 | + }, | |
54 | + { | |
55 | + title: '门店', | |
56 | + dataIndex: 'shopName', | |
57 | + width: 300, | |
58 | + align: 'center', | |
59 | + key: 'shopName', | |
60 | + render: (name) => <span>{name || '--'}</span>, | |
61 | + }, | |
62 | + { | |
63 | + title: '打分', | |
64 | + dataIndex: 'score', | |
65 | + width: 100, | |
66 | + align: 'center', | |
67 | + key: 'score', | |
68 | + render: (name) => <span>{name || '--'}</span>, | |
69 | + }, | |
70 | + { | |
71 | + title: '总分', | |
72 | + key: 'totalScore', | |
73 | + width: 100, | |
74 | + align: 'center', | |
75 | + dataIndex: 'totalScore', | |
76 | + render: (name) => <span>{name || '--'}</span>, | |
77 | + }, | |
78 | + { | |
79 | + title: '打分人员', | |
80 | + key: 'graderStaffName', | |
81 | + width: 200, | |
82 | + align: 'center', | |
83 | + dataIndex: 'graderStaffName', | |
84 | + render: (name) => <span>{name || '--'}</span>, | |
85 | + }, | |
86 | + ]; | |
87 | + useEffect(() => { | |
88 | + if (indicator?.code) { | |
89 | + run({ | |
90 | + pageSize: 10, | |
91 | + current: 1, | |
92 | + monthly: monthly || Date.now(), | |
93 | + indicatorCode: indicator?.code || '', | |
94 | + shopId: shopId || undefined, | |
95 | + }); | |
96 | + } | |
97 | + }, [indicator?.code, monthly, shopId]); | |
98 | + return ( | |
99 | + <> | |
100 | + <div style={{ display: 'flex' }}> | |
101 | + <DatePicker | |
102 | + value={monthly ? moment(monthly) : undefined} | |
103 | + disabledDate={(currentDate) => moment().startOf('month').valueOf() < currentDate.startOf('month').valueOf()} | |
104 | + onChange={pickMonth} | |
105 | + picker="month" | |
106 | + style={{ marginRight: 20 }} | |
107 | + /> | |
108 | + <Select allowClear style={{ width: 200, marginRight: 20 }} placeholder="请选择门店" onChange={shopChange}> | |
109 | + {(data || []).map((shop) => ( | |
110 | + <Select.Option value={shop.id} key={shop.id}> | |
111 | + {shop.name} | |
112 | + </Select.Option> | |
113 | + ))} | |
114 | + </Select> | |
115 | + </div> | |
116 | + <Table columns={columns} {...tableProps} rowKey="id" style={{ marginTop: 20 }} /> | |
117 | + </> | |
118 | + ); | |
119 | +} | ... | ... |
src/pages/performance/DataImport/components/ExcelTable.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Table, message, Modal } from 'antd'; | |
3 | +import { UploadImportApi, SaveDataApi } from '../api'; | |
4 | +import { useRequest } from 'ahooks'; | |
5 | +import { ErrorType } from '../entity'; | |
6 | + | |
7 | +import moment from 'moment'; | |
8 | +interface Props { | |
9 | + fid?: string; | |
10 | + show?: boolean; | |
11 | + indicator?: MDataImport.IndicatorList; | |
12 | + setExcelvisible?: (bool: boolean) => void; | |
13 | + refresh?: () => void; | |
14 | +} | |
15 | +export default function ExcelTable({ fid, show, indicator, setExcelvisible, refresh }: Props) { | |
16 | + const { data, run, loading } = useRequest<MDataImport.DataImportList, string[]>(UploadImportApi, { | |
17 | + manual: true, | |
18 | + onError: (e, _) => { | |
19 | + message.error(e.message); | |
20 | + }, | |
21 | + }); | |
22 | + | |
23 | + useEffect(() => { | |
24 | + if (show) { | |
25 | + run(fid || '', indicator?.code || ''); | |
26 | + } | |
27 | + }, [show, fid, indicator]); | |
28 | + const savesubmit = () => { | |
29 | + SaveDataApi({ key: data?.key || '' }) | |
30 | + .then(() => { | |
31 | + message.success('操作成功'); | |
32 | + setExcelvisible?.(false); | |
33 | + refresh?.(); | |
34 | + }) | |
35 | + .catch((error) => { | |
36 | + message.error(error.message); | |
37 | + setExcelvisible?.(false); | |
38 | + }); | |
39 | + }; | |
40 | + const tableItem: any = [ | |
41 | + { | |
42 | + title: '月度', | |
43 | + align: 'center', | |
44 | + width: 100, | |
45 | + dataIndex: 'dataDate', | |
46 | + key: 'dataDate', | |
47 | + render: (time: number) => (time ? moment(time).format('YYYY-MM') : '--'), | |
48 | + }, | |
49 | + { | |
50 | + title: '门店', | |
51 | + dataIndex: 'shopName', | |
52 | + align: 'center', | |
53 | + key: 'shopName', | |
54 | + render: (name: any) => <span>{name || '--'}</span>, | |
55 | + }, | |
56 | + { | |
57 | + title: '打分', | |
58 | + width: 100, | |
59 | + dataIndex: 'score', | |
60 | + align: 'center', | |
61 | + key: 'score', | |
62 | + render: (name: any) => <span>{name || '--'}</span>, | |
63 | + }, | |
64 | + { | |
65 | + title: '总分', | |
66 | + width: 100, | |
67 | + dataIndex: 'totalScore', | |
68 | + align: 'center', | |
69 | + key: 'totalScore', | |
70 | + render: (name: any) => <span>{name || '--'}</span>, | |
71 | + }, | |
72 | + { | |
73 | + title: '打分人员', | |
74 | + width: 100, | |
75 | + dataIndex: 'graderStaffName', | |
76 | + align: 'center', | |
77 | + key: 'graderStaffName', | |
78 | + render: (name: any) => <span>{name || '--'}</span>, | |
79 | + }, | |
80 | + { | |
81 | + title: '是否识别', | |
82 | + width: 100, | |
83 | + dataIndex: 'errorType', | |
84 | + align: 'center', | |
85 | + render: (_: any, record: any) => (record.errorType ? <div>未识别</div> : <div>已识别</div>), | |
86 | + }, | |
87 | + { | |
88 | + title: '未识别原因', | |
89 | + width: 150, | |
90 | + dataIndex: 'errorType', | |
91 | + align: 'center', | |
92 | + render: (_: any, record: any) => (record.errorType ? ErrorType[record.errorType] : '--'), | |
93 | + }, | |
94 | + ]; | |
95 | + return ( | |
96 | + <Modal | |
97 | + open={show} | |
98 | + destroyOnClose | |
99 | + onCancel={() => { | |
100 | + setExcelvisible?.(false); | |
101 | + }} | |
102 | + width="70%" | |
103 | + keyboard | |
104 | + onOk={savesubmit} | |
105 | + > | |
106 | + <Table loading={loading} dataSource={data?.details} columns={tableItem} pagination={{ pageSizeOptions: [10, 20, 50] }} /> | |
107 | + <div> | |
108 | + 成功条数: <span style={{ color: '#20c688' }}>{data?.successNum}</span> 条 | |
109 | + </div> | |
110 | + <div> | |
111 | + 失败条数: <span style={{ color: '#f4333c' }}>{data?.errorNum}</span> 条 | |
112 | + </div> | |
113 | + </Modal> | |
114 | + ); | |
115 | +} | ... | ... |
src/pages/performance/DataImport/components/ImportList.tsx
0 → 100644
1 | +import React, { useEffect, useState, useRef } from 'react'; | |
2 | +import { Table, Button, Tag, message, DatePicker, Select, Modal, Upload, Space, Divider, Popconfirm, Typography } from 'antd'; | |
3 | +import type { UploadProps } from 'antd'; | |
4 | +import type { ColumnsType } from 'antd/es/table'; | |
5 | +import { DataImportAPi, ImportListDetailApi, DownloadApi, deleteApi, revokeApi } from '../api'; | |
6 | +import { useAntdTable } from 'ahooks'; | |
7 | +import moment from 'moment'; | |
8 | +import type { DatePickerProps } from 'antd'; | |
9 | +import useInitial from '@/hooks/useInitail'; | |
10 | +import { getShopApi } from '@/common/api'; | |
11 | +import { SelectStatus } from '../entity'; | |
12 | +import { DownloadOutlined, PlusOutlined } from '@ant-design/icons'; | |
13 | +import { useRequest } from 'ahooks'; | |
14 | +import ApprovalProgressModal from '@/components/ApprovalProgressModal'; | |
15 | +import type { ApprovalProgressModalRef } from '@/components/ApprovalProgressModal'; | |
16 | +import dowloader from '@/utils/downloader'; | |
17 | +import { IMGURL } from '@/utils'; | |
18 | +import ExcelTable from './ExcelTable'; | |
19 | + | |
20 | +type Props = { | |
21 | + indicator?: MDataImport.IndicatorList; | |
22 | +}; | |
23 | +interface DataType { | |
24 | + key: string; | |
25 | + name: string; | |
26 | +} | |
27 | +export default function TableList({ indicator }: Props) { | |
28 | + const [monthly, setMonthly] = useState<number>(); | |
29 | + const [shopId, setShopId] = useState<number>(); | |
30 | + const [status, setStatus] = useState<number>(); | |
31 | + const [fid, setFid] = useState<string>(''); | |
32 | + const [dataVisible, setDataVisible] = useState<boolean>(false); | |
33 | + const [excelvisible, setExcelvisible] = useState<boolean>(false); | |
34 | + const tagColorArr = ['', 'warning', 'processing', 'error', 'success', 'warning']; | |
35 | + | |
36 | + const approvalProgressRef = useRef<ApprovalProgressModalRef | null>(null); | |
37 | + | |
38 | + const upload: UploadProps = { | |
39 | + name: 'file', | |
40 | + action: '/api2/file/upload', | |
41 | + accept: '.xlsx,.xls', | |
42 | + maxCount: 1, | |
43 | + showUploadList: false, | |
44 | + onChange(info) { | |
45 | + if (info.file.status !== 'uploading') { | |
46 | + } | |
47 | + if (info.file.status === 'done') { | |
48 | + setFid(info.file.response.data); | |
49 | + setExcelvisible(true); | |
50 | + } else if (info.file.status === 'error') { | |
51 | + message.error(`${info.file.name} 上传失败`); | |
52 | + } | |
53 | + }, | |
54 | + }; | |
55 | + const viewProcess = (record: MDataImport.DetailedList) => { | |
56 | + approvalProgressRef.current?.setApprovalProgressModalInfo({ | |
57 | + visible: true, | |
58 | + orderNo: record?.approvalNo, | |
59 | + }); | |
60 | + }; | |
61 | + const pickMonth: DatePickerProps['onChange'] = (date, _dateString) => { | |
62 | + setMonthly(date?.valueOf() ?? 0); | |
63 | + }; | |
64 | + function shopChange(value: any) { | |
65 | + setShopId(value); | |
66 | + } | |
67 | + function statusChange(value: any) { | |
68 | + setStatus(value); | |
69 | + } | |
70 | + const { data } = useInitial(getShopApi, [], {}); | |
71 | + //@ts-ignore | |
72 | + const { tableProps, run, refresh } = useAntdTable<any, MDataImport.DataImportListParams[]>(DataImportAPi, { | |
73 | + manual: true, | |
74 | + defaultParams: [ | |
75 | + { | |
76 | + pageSize: 10, | |
77 | + current: 1, | |
78 | + monthly: Date.now(), | |
79 | + indicatorCode: indicator?.code || '', | |
80 | + }, | |
81 | + ], | |
82 | + | |
83 | + onError: (e, _) => { | |
84 | + message.error(e.message); | |
85 | + }, | |
86 | + }); | |
87 | + const { | |
88 | + run: running, | |
89 | + mutate, | |
90 | + loading, | |
91 | + data: list, | |
92 | + } = useRequest<MDataImport.DataImportList, (number | undefined)[]>(ImportListDetailApi, { | |
93 | + manual: true, | |
94 | + onError: (e, _) => { | |
95 | + message.error(e.message); | |
96 | + }, | |
97 | + }); | |
98 | + const deleteData = async (id: number) => { | |
99 | + const param = { id }; | |
100 | + try { | |
101 | + const { success } = await deleteApi(param); | |
102 | + if (success) { | |
103 | + message.success('删除成功'); | |
104 | + refresh(); | |
105 | + } | |
106 | + } catch (error: any) { | |
107 | + message.error(error.message); | |
108 | + } | |
109 | + }; | |
110 | + const revoke = async (id: number) => { | |
111 | + const param = { id }; | |
112 | + try { | |
113 | + const { success } = await revokeApi(param); | |
114 | + if (success) { | |
115 | + message.success('删除成功'); | |
116 | + refresh(); | |
117 | + } | |
118 | + } catch (error: any) { | |
119 | + message.error(error.message); | |
120 | + } | |
121 | + }; | |
122 | + const detailColumns: ColumnsType<DataType> = [ | |
123 | + { | |
124 | + title: '月度', | |
125 | + align: 'center', | |
126 | + dataIndex: 'dataDate', | |
127 | + width: 200, | |
128 | + key: 'dataDate', | |
129 | + render: (time: number) => (time ? moment(time).format('YYYY-MM') : '--'), | |
130 | + }, | |
131 | + { | |
132 | + title: '门店', | |
133 | + align: 'center', | |
134 | + dataIndex: 'shopName', | |
135 | + width: 300, | |
136 | + key: 'shopName', | |
137 | + render: (name) => <span>{name || '--'}</span>, | |
138 | + }, | |
139 | + { | |
140 | + title: '打分', | |
141 | + align: 'center', | |
142 | + dataIndex: 'score', | |
143 | + width: 100, | |
144 | + key: 'score', | |
145 | + render: (name) => <span>{name || '--'}</span>, | |
146 | + }, | |
147 | + { | |
148 | + title: '总分', | |
149 | + align: 'center', | |
150 | + key: 'totalScore', | |
151 | + width: 100, | |
152 | + dataIndex: 'totalScore', | |
153 | + render: (name) => <span>{name || '--'}</span>, | |
154 | + }, | |
155 | + { | |
156 | + title: '打分人员', | |
157 | + align: 'center', | |
158 | + key: 'graderStaffName', | |
159 | + width: 200, | |
160 | + dataIndex: 'graderStaffName', | |
161 | + render: (name) => <span>{name || '--'}</span>, | |
162 | + }, | |
163 | + ]; | |
164 | + const columns: ColumnsType<MDataImport.DetailedList> = [ | |
165 | + { | |
166 | + title: '导入时间', | |
167 | + align: 'center', | |
168 | + width: 300, | |
169 | + dataIndex: 'createTime', | |
170 | + key: 'createTime', | |
171 | + render: (time: number) => (time ? moment(time).format('YYYY-MM-DD hh:mm:ss') : '--'), | |
172 | + }, | |
173 | + { | |
174 | + title: '导入人员', | |
175 | + align: 'center', | |
176 | + width: 300, | |
177 | + dataIndex: 'importUserName', | |
178 | + key: 'importUserName', | |
179 | + render: (name) => <span>{name || '--'}</span>, | |
180 | + }, | |
181 | + | |
182 | + { | |
183 | + title: '导入数据', | |
184 | + align: 'center', | |
185 | + width: 100, | |
186 | + key: 'num', | |
187 | + dataIndex: 'num', | |
188 | + render: (name) => <span>{name + '条' || '--'}</span>, | |
189 | + }, | |
190 | + { | |
191 | + title: '成功', | |
192 | + align: 'center', | |
193 | + width: 100, | |
194 | + key: 'successNum', | |
195 | + dataIndex: 'successNum', | |
196 | + render: (name) => <span>{name + '条' || '--'}</span>, | |
197 | + }, | |
198 | + { | |
199 | + title: '失败', | |
200 | + align: 'center', | |
201 | + width: 100, | |
202 | + key: 'errorNum', | |
203 | + dataIndex: 'errorNum', | |
204 | + render: (name) => <span>{name + '条' || '--'}</span>, | |
205 | + }, | |
206 | + { | |
207 | + title: '数据清单', | |
208 | + align: 'center', | |
209 | + width: 200, | |
210 | + key: 'importUserId', | |
211 | + render: (value, record: MDataImport.DetailedList) => { | |
212 | + return ( | |
213 | + <Button | |
214 | + type="link" | |
215 | + onClick={() => { | |
216 | + { | |
217 | + setDataVisible(true); | |
218 | + running(record?.id); | |
219 | + } | |
220 | + }} | |
221 | + > | |
222 | + 查看 | |
223 | + </Button> | |
224 | + ); | |
225 | + }, | |
226 | + }, | |
227 | + { | |
228 | + title: '状态', | |
229 | + width: 100, | |
230 | + align: 'center', | |
231 | + key: 'status', | |
232 | + dataIndex: 'status', | |
233 | + render: (text: number) => <Tag color={tagColorArr[text]}>{text ? SelectStatus[text] : '--'}</Tag>, | |
234 | + }, | |
235 | + { | |
236 | + title: '操作', | |
237 | + align: 'center', | |
238 | + width: 300, | |
239 | + key: 'tags', | |
240 | + render: (_: any, record: MDataImport.DetailedList) => { | |
241 | + return ( | |
242 | + <Space split={<Divider type="vertical" />}> | |
243 | + {(record.status == 1 || record.status == 3 || record.status == 5) && ( | |
244 | + <Popconfirm title="确定删除,提交后不可更改?" onConfirm={() => deleteData(record?.id || 0)} okText="确定" cancelText="取消"> | |
245 | + <Typography.Link>删除</Typography.Link> | |
246 | + </Popconfirm> | |
247 | + )} | |
248 | + {(record.status == 2 || record.status == 3) && ( | |
249 | + <> | |
250 | + {record.status == 2 && ( | |
251 | + <Popconfirm title="确定撤销,提交后不可更改?" onConfirm={() => revoke(record?.id || 0)} okText="确定" cancelText="取消"> | |
252 | + <Typography.Link>撤销</Typography.Link> | |
253 | + </Popconfirm> | |
254 | + )} | |
255 | + <Typography.Link | |
256 | + onClick={() => { | |
257 | + viewProcess(record); | |
258 | + }} | |
259 | + > | |
260 | + 流程进度 | |
261 | + </Typography.Link> | |
262 | + </> | |
263 | + )} | |
264 | + {record.status == 4 && <div>--</div>} | |
265 | + </Space> | |
266 | + ); | |
267 | + }, | |
268 | + }, | |
269 | + ]; | |
270 | + | |
271 | + useEffect(() => { | |
272 | + if (indicator?.code) { | |
273 | + run({ | |
274 | + pageSize: 10, | |
275 | + current: 1, | |
276 | + monthly: monthly || Date.now(), | |
277 | + indicatorCode: indicator?.code || '', | |
278 | + shopId: shopId || undefined, | |
279 | + status: status || undefined, | |
280 | + }); | |
281 | + } | |
282 | + }, [indicator?.code, monthly, shopId, status]); | |
283 | + return ( | |
284 | + <> | |
285 | + <div style={{ display: 'flex' }}> | |
286 | + <DatePicker | |
287 | + value={monthly ? moment(monthly) : undefined} | |
288 | + disabledDate={(currentDate) => moment().startOf('month').valueOf() < currentDate.startOf('month').valueOf()} | |
289 | + onChange={pickMonth} | |
290 | + picker="month" | |
291 | + style={{ marginRight: 20 }} | |
292 | + /> | |
293 | + <Select allowClear style={{ width: 245, marginRight: 20 }} placeholder="请选择门店" onChange={shopChange}> | |
294 | + {(data || []).map((shop) => ( | |
295 | + <Select.Option value={shop.id} key={shop.id}> | |
296 | + {shop.name} | |
297 | + </Select.Option> | |
298 | + ))} | |
299 | + </Select> | |
300 | + <Select allowClear style={{ width: 120 }} placeholder="状态筛选" onChange={statusChange}> | |
301 | + {[2, 3, 4, 5].map((text: number) => ( | |
302 | + <Select.Option value={text} key={text}> | |
303 | + {SelectStatus[text]} | |
304 | + </Select.Option> | |
305 | + ))} | |
306 | + </Select> | |
307 | + <div style={{ marginLeft: 'auto' }}> | |
308 | + <Button | |
309 | + icon={<DownloadOutlined rev="" />} | |
310 | + type="primary" | |
311 | + onClick={() => { | |
312 | + DownloadApi(indicator?.code) | |
313 | + .then((res) => { | |
314 | + dowloader.downloadFile({ fileUrl: IMGURL.showImage(res) }); | |
315 | + }) | |
316 | + .catch((e) => { | |
317 | + message.error(e.message); | |
318 | + }); | |
319 | + }} | |
320 | + > | |
321 | + 下载模版 | |
322 | + </Button> | |
323 | + <Upload {...upload}> | |
324 | + <Button style={{ marginLeft: 10 }} icon={<PlusOutlined rev="" />} type="primary"> | |
325 | + 导入 | |
326 | + </Button> | |
327 | + </Upload> | |
328 | + </div> | |
329 | + </div> | |
330 | + | |
331 | + <Table rowKey="id" columns={columns} {...tableProps} style={{ marginTop: 20 }} /> | |
332 | + <Modal | |
333 | + title="数据清单" | |
334 | + open={dataVisible} | |
335 | + footer={null} | |
336 | + destroyOnClose | |
337 | + onCancel={() => { | |
338 | + setDataVisible(false); | |
339 | + mutate(undefined); | |
340 | + }} | |
341 | + width="70%" | |
342 | + keyboard | |
343 | + > | |
344 | + <Table | |
345 | + rowKey="id" | |
346 | + loading={loading} | |
347 | + dataSource={list?.details ?? []} | |
348 | + columns={detailColumns} | |
349 | + pagination={{ pageSizeOptions: [10, 20, 50] }} | |
350 | + /> | |
351 | + </Modal> | |
352 | + <ExcelTable refresh={refresh} setExcelvisible={setExcelvisible} show={excelvisible} fid={fid} indicator={indicator} /> | |
353 | + <ApprovalProgressModal ref={approvalProgressRef} /> | |
354 | + </> | |
355 | + ); | |
356 | +} | ... | ... |
src/pages/performance/DataImport/components/exhibitionHallFour.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { Radio, Empty } from 'antd'; | |
3 | +import ImportList from './ImportList'; | |
4 | +import DetailList from './DetailList'; | |
5 | + | |
6 | +type Props = { | |
7 | + indicator?: MDataImport.IndicatorList; | |
8 | + onChange?: (value?: any) => void; | |
9 | +}; | |
10 | + | |
11 | +export default function ExhibitionHallFour({ indicator }: Props) { | |
12 | + const [tableType, setTableType] = useState<number>(0); | |
13 | + | |
14 | + return ( | |
15 | + <div style={{ flex: 1, overflowX: 'hidden', marginLeft: 20 }}> | |
16 | + {indicator?.code ? ( | |
17 | + <div> | |
18 | + <div style={{ fontSize: 18, fontWeight: 'bold' }}>{`指标:${indicator?.name ?? '-'}`}</div> | |
19 | + <Radio.Group defaultValue="a" buttonStyle="solid" style={{ marginTop: 15, marginBottom: 20 }}> | |
20 | + <Radio.Button | |
21 | + value="a" | |
22 | + style={{ marginRight: 10 }} | |
23 | + onClick={() => { | |
24 | + setTableType(0); | |
25 | + }} | |
26 | + > | |
27 | + 导入记录 | |
28 | + </Radio.Button> | |
29 | + | |
30 | + <Radio.Button | |
31 | + value="b" | |
32 | + onClick={() => { | |
33 | + setTableType(1); | |
34 | + }} | |
35 | + > | |
36 | + 数据清单 | |
37 | + </Radio.Button> | |
38 | + </Radio.Group> | |
39 | + {tableType === 0 ? <ImportList indicator={indicator} /> : <DetailList indicator={indicator} />} | |
40 | + </div> | |
41 | + ) : ( | |
42 | + <div style={{ marginTop: '25%', display: 'flex', justifyContent: 'center' }}> | |
43 | + <Empty description={'请选择指标'} /> | |
44 | + </div> | |
45 | + )} | |
46 | + </div> | |
47 | + ); | |
48 | +} | ... | ... |
src/pages/performance/DataImport/components/truckloadBank.tsx
0 → 100644
1 | +import React from 'react'; | |
2 | +import { Table, message } from 'antd'; | |
3 | +import { IndicatorListApi } from '../api'; | |
4 | +import { useRequest } from 'ahooks'; | |
5 | + | |
6 | +type Props = { | |
7 | + value?: MDataImport.IndicatorList; | |
8 | + onChange?: (value?: any) => void; | |
9 | +}; | |
10 | +export default function TruckloadBank({ value, onChange }: Props) { | |
11 | + const Column = Table.Column; | |
12 | + const { data } = useRequest<MDataImport.IndicatorList[], never[]>(IndicatorListApi, { | |
13 | + onSuccess: (data, _params) => { | |
14 | + onChange?.(data?.[0]); | |
15 | + }, | |
16 | + onError: (e, _) => { | |
17 | + message.error(e.message); | |
18 | + }, | |
19 | + }); | |
20 | + | |
21 | + return ( | |
22 | + <div style={{ width: 200 }}> | |
23 | + <Table | |
24 | + rowKey="code" | |
25 | + pagination={false} | |
26 | + rowSelection={{ | |
27 | + type: 'radio', | |
28 | + selectedRowKeys: value?.code ? [value.code] : [], | |
29 | + onSelect: (record) => onChange?.(record), | |
30 | + }} | |
31 | + dataSource={data || []} | |
32 | + > | |
33 | + <Column title="指标" dataIndex="name" align="center" render={(text) => text ?? '-'} fixed /> | |
34 | + </Table> | |
35 | + </div> | |
36 | + ); | |
37 | +} | ... | ... |
src/pages/performance/DataImport/entity.ts
0 → 100644
src/pages/performance/DataImport/index.css
0 → 100644
src/pages/performance/DataImport/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
3 | +import { Card } from 'antd'; | |
4 | +import TruckloadBank from './components/truckloadBank'; | |
5 | +import ExhibitionHallFour from './components/exhibitionHallFour'; | |
6 | + | |
7 | +export default () => { | |
8 | + const [indicator, setIndicator] = useState<MDataImport.IndicatorList>(); | |
9 | + const onChange = (value?: MDataImport.IndicatorList) => { | |
10 | + setIndicator(value); | |
11 | + }; | |
12 | + return ( | |
13 | + <PageHeaderWrapper title="自定义数据导入"> | |
14 | + <Card> | |
15 | + <div style={{ display: 'flex' }}> | |
16 | + <TruckloadBank value={indicator} onChange={onChange} /> | |
17 | + <ExhibitionHallFour indicator={indicator} onChange={onChange} /> | |
18 | + </div> | |
19 | + </Card> | |
20 | + </PageHeaderWrapper> | |
21 | + ); | |
22 | +}; | ... | ... |
src/pages/performance/DataImport/interface.d.ts
0 → 100644
1 | +declare namespace MDataImport { | |
2 | + /** | |
3 | + * 展厅美化导入记录分页查询参数 | |
4 | + */ | |
5 | + interface DataImportListParams { | |
6 | + current: number; | |
7 | + pageSize: number; | |
8 | + indicatorCode?: string; | |
9 | + shopId?: number; | |
10 | + monthly?: number; | |
11 | + sorter?: any; | |
12 | + filter?: any; | |
13 | + extra?: any; | |
14 | + [key: string]: any; | |
15 | + } | |
16 | + | |
17 | + /** | |
18 | + * 展厅美化导入记录分页查询数据 | |
19 | + */ | |
20 | + interface DataImportList { | |
21 | + id?: number; | |
22 | + importUserId?: number; | |
23 | + importUserName?: string; | |
24 | + shopId?: number; | |
25 | + shopName?: string; | |
26 | + dimensionType?: string; | |
27 | + indicatorCode?: string; | |
28 | + indicatorName?: string; | |
29 | + valueType?: number; | |
30 | + dataDate?: string; | |
31 | + num?: number; | |
32 | + successNum?: number; | |
33 | + errorNum?: number; | |
34 | + groupId?: number; | |
35 | + createTime?: string; | |
36 | + key?: string; | |
37 | + status?: string; | |
38 | + approvalNo?: string; | |
39 | + dataTimeType?: string; | |
40 | + details?: []; | |
41 | + } | |
42 | + /** | |
43 | + * 数据导入指标列表数据 | |
44 | + */ | |
45 | + interface IndicatorList { | |
46 | + id?: number; | |
47 | + code?: string; | |
48 | + name?: 'melda.sanford'; | |
49 | + } | |
50 | + /** | |
51 | + * 数据清单列表数据 | |
52 | + */ | |
53 | + interface DetailedList { | |
54 | + id?: number; | |
55 | + recordId?: number; | |
56 | + indicatorName?: string; | |
57 | + indicatorCode?: string; | |
58 | + shopId?: number; | |
59 | + shopName?: string; | |
60 | + score?: number; | |
61 | + totalScore?: number; | |
62 | + graderStaffName?: string; | |
63 | + graderStaffId?: number; | |
64 | + stageStartDataDate?: string; | |
65 | + stageEndDataDate?: string; | |
66 | + dataDate?: string; | |
67 | + errorType?: string; | |
68 | + valid?: boolean; | |
69 | + yn?: boolean; | |
70 | + approvalNo?: string; | |
71 | + status: number; | |
72 | + } | |
73 | +} | ... | ... |
src/pages/performance/EvaDataImport/index.tsx
... | ... | @@ -51,7 +51,7 @@ export default () => { |
51 | 51 | } |
52 | 52 | const uploadPerson: UploadProps = { |
53 | 53 | name: 'file', |
54 | - action: '/api/morax/erp/eval-indicator/analysis-staff', | |
54 | + action: '/api/morax/erp/eval-indicator/analysis-staff', | |
55 | 55 | maxCount: 1, |
56 | 56 | showUploadList: false, |
57 | 57 | // 设置headers里的token |
... | ... | @@ -62,6 +62,7 @@ export default () => { |
62 | 62 | } |
63 | 63 | if (info.file.status === 'done') { |
64 | 64 | setFileData(info.file.response.data); |
65 | + | |
65 | 66 | setVisible(true); |
66 | 67 | } else if (info.file.status === 'error') { |
67 | 68 | message.error(`${info.file.name} 上传失败`); | ... | ... |
src/pages/performance/EvaSetting/components/EditModal.tsx
... | ... | @@ -29,6 +29,7 @@ export default function EditModal({ onClose, item, roleList, customIndicatorList |
29 | 29 | const [customIndicator, setCustomIndicator] = useState<any[]>([]); |
30 | 30 | const [codeType, setCodeType] = useState<number>(0); |
31 | 31 | const [isOriginCode, setIsOriginCode] = useState<boolean>(!!currentItem.originCode); |
32 | + const [pa, setPa] = useState(); | |
32 | 33 | useEffect(() => { |
33 | 34 | setIsOriginCode(!!item.currentItem?.originCode); |
34 | 35 | }, [item]); |
... | ... | @@ -57,6 +58,12 @@ export default function EditModal({ onClose, item, roleList, customIndicatorList |
57 | 58 | setCodeType(currentItem.codeType); |
58 | 59 | if (currentItem.codeType == 2) { |
59 | 60 | const result = transformFormData(currentItem, roleList, list); |
61 | + console.log(pa, 'asada'); | |
62 | + | |
63 | + if (currentItem.roleCodes && currentItem.roleCodes.length > 0) { | |
64 | + result.roles = currentItem?.roleCodes?.map((item: any) => ({ value: item })); | |
65 | + } | |
66 | + | |
60 | 67 | form.setFieldsValue({ ...result }); |
61 | 68 | } else { |
62 | 69 | setDetailsParams({ id: currentItem.id }, true); |
... | ... | @@ -110,6 +117,12 @@ export default function EditModal({ onClose, item, roleList, customIndicatorList |
110 | 117 | if (currentItem.combineCode) { |
111 | 118 | pa.combineCode = currentItem.combineCode; |
112 | 119 | } |
120 | + const roles = values.roles ?? []; | |
121 | + | |
122 | + pa.roleCodes = roles.map((role: any) => role.value); | |
123 | + pa.roleNames = roles.map((role: any) => role.label); | |
124 | + console.log(pa.roleCodes, pa.roleNames, 'wwe333333'); | |
125 | + setPa(pa); | |
113 | 126 | console.log('提交指标pa', pa); |
114 | 127 | setSaveLoading(true); |
115 | 128 | if (pa.codeType == 2 || currentItem.codeType == 2) { |
... | ... | @@ -442,6 +455,17 @@ export default function EditModal({ onClose, item, roleList, customIndicatorList |
442 | 455 | </Select> |
443 | 456 | </FormItem> |
444 | 457 | )} |
458 | + {!isOriginCode && currentItem.id && currentItem.codeType !== 3 && ( | |
459 | + <Form.Item name="roles" label="适用角色" rules={[{ required: true }]}> | |
460 | + <Select placeholder="请选择角色" showSearch allowClear mode="multiple" optionFilterProp="children" disabled={isOriginCode} labelInValue> | |
461 | + {roleList.map((item) => ( | |
462 | + <Option value={item.roleCode} key={item.roleCode}> | |
463 | + {item.roleName} | |
464 | + </Option> | |
465 | + ))} | |
466 | + </Select> | |
467 | + </Form.Item> | |
468 | + )} | |
445 | 469 | </Form> |
446 | 470 | </Spin> |
447 | 471 | </Modal> | ... | ... |
src/pages/performance/EvaSetting/components/EditModalOne.tsx
... | ... | @@ -111,6 +111,9 @@ export default function EditModal({ onClose, item, roleList, customIndicatorList |
111 | 111 | pa.combineCode = currentItem.combineCode; |
112 | 112 | } |
113 | 113 | console.log('提交指标pa', pa); |
114 | + const roles = values.roles ?? []; | |
115 | + pa.roleCodes = roles.map((role: any) => role.value); | |
116 | + pa.roleNames = roles.map((role: any) => role.label); | |
114 | 117 | setSaveLoading(true); |
115 | 118 | if (pa.codeType == 2 || currentItem.codeType == 2) { |
116 | 119 | saveEvaIndicators(pa) |
... | ... | @@ -442,6 +445,25 @@ export default function EditModal({ onClose, item, roleList, customIndicatorList |
442 | 445 | </Select> |
443 | 446 | </FormItem> |
444 | 447 | )} |
448 | + {!isOriginCode && currentItem.codeType !== 3 && ( | |
449 | + <Form.Item name="roles" label="适用角色" rules={[{ required: true }]}> | |
450 | + <Select | |
451 | + placeholder="请选择角色" | |
452 | + showSearch | |
453 | + allowClear | |
454 | + mode="multiple" | |
455 | + optionFilterProp="children" | |
456 | + disabled={isOriginCode} | |
457 | + labelInValue | |
458 | + > | |
459 | + {roleList.map((item) => ( | |
460 | + <Option value={item.roleCode} key={item.roleCode}> | |
461 | + {item.roleName} | |
462 | + </Option> | |
463 | + ))} | |
464 | + </Select> | |
465 | + </Form.Item> | |
466 | + )} | |
445 | 467 | </Form> |
446 | 468 | </Spin> |
447 | 469 | </Modal> | ... | ... |
src/pages/performance/EvaSetting/interface.ts
src/pages/performance/KpiGroupSetting/EditComfirm/components/IndivatorsTable.tsx
... | ... | @@ -199,7 +199,7 @@ const IndivatorsTable = ({ value, onChange, personModal }: Props) => { |
199 | 199 | return _columns; |
200 | 200 | }; |
201 | 201 | const onChangePag = (page: number, pageSize: number) => { |
202 | - console.log(page, pageSize, value); | |
202 | + console.log(page, pageSize, value,'0000000'); | |
203 | 203 | setPage(page - 1); |
204 | 204 | }; |
205 | 205 | return ( | ... | ... |
src/pages/performance/KpiSetting/components/EditModal.tsx
... | ... | @@ -44,6 +44,7 @@ export default function EditModal({ onClose, setItem, item, roleList }: Props) { |
44 | 44 | useEffect(() => { |
45 | 45 | if (visible && currentItem) { |
46 | 46 | const result = transformFormData(currentItem, roleList, list); |
47 | + console.log({...result},'1111dwewwwwwew') | |
47 | 48 | form.setFieldsValue({ ...result }); |
48 | 49 | } |
49 | 50 | }, [visible]); |
... | ... | @@ -209,7 +210,7 @@ export default function EditModal({ onClose, setItem, item, roleList }: Props) { |
209 | 210 | > |
210 | 211 | {({ getFieldValue }) => { |
211 | 212 | return getFieldValue('roleType') === 3 ? ( |
212 | - <Form.Item name="roles" label="适用角色" rules={[{ required: true }]}> | |
213 | + <Form.Item name="roles" label="适用角色1" rules={[{ required: true }]}> | |
213 | 214 | <Select |
214 | 215 | placeholder="请选择角色" |
215 | 216 | showSearch | ... | ... |
src/pages/performance/Portfolio/interface.d.ts
1 | -import Enum from "@/utils/enum"; | |
1 | +import Enum from '@/utils/enum'; | |
2 | 2 | |
3 | 3 | declare namespace ComIndicatorSetting { |
4 | 4 | /** |
... | ... | @@ -83,6 +83,7 @@ declare namespace ComIndicatorSetting { |
83 | 83 | roleType: number[]; |
84 | 84 | roleNames: string[]; |
85 | 85 | unit: string; |
86 | + roleCodes: string; | |
86 | 87 | } |
87 | 88 | interface ComSaveParams { |
88 | 89 | id?: number; | ... | ... |
src/pages/promotion/proengine/components/List.tsx
... | ... | @@ -33,7 +33,7 @@ export default function List(props: Props) { |
33 | 33 | render={(text, row: IF.ListVo) => ( |
34 | 34 | <div> |
35 | 35 | <p>{text || '-'}</p> |
36 | - <p>{`(${row.proId || ''})`}</p> | |
36 | + <p style={{ margin: 0, color: '#666' }}>{`(${row.proId || ''})`}</p> | |
37 | 37 | </div> |
38 | 38 | )} |
39 | 39 | /> |
... | ... | @@ -89,6 +89,7 @@ export default function List(props: Props) { |
89 | 89 | /> |
90 | 90 | <Column |
91 | 91 | title="操作" |
92 | + width={100} | |
92 | 93 | render={(text, record: IF.ListVo) => ( |
93 | 94 | //@ts-ignore |
94 | 95 | <Operation record={record} onRefreshing={() => onRefreshing()} /> | ... | ... |
src/pages/promotion/proengine/components/Operation.tsx
1 | 1 | import React from 'react'; |
2 | 2 | import { Button, Divider, Popconfirm, Tooltip, message, Modal } from 'antd'; |
3 | 3 | import { history } from 'umi'; |
4 | -import * as common from '@/typing/common'; | |
4 | +import type * as common from '@/typing/common'; | |
5 | 5 | import * as API from '../api'; |
6 | -import * as IF from '../interface.d'; | |
6 | +import type * as IF from '../interface.d'; | |
7 | 7 | import { PromotionStatus } from '../entity'; |
8 | 8 | |
9 | 9 | const { confirm } = Modal; |
... | ... | @@ -107,53 +107,46 @@ export default function Oparetion(props: Props) { |
107 | 107 | <React.Fragment> |
108 | 108 | {record.proStatus == PromotionStatus['草稿'] && ( |
109 | 109 | <span> |
110 | - <Button type="primary" ghost size="small" onClick={() => commitAudit(record)}>提审</Button> | |
111 | - <Divider type="vertical" /> | |
110 | + <Button type="link" size="small" onClick={() => commitAudit(record)}>提审</Button> | |
111 | + {/* <Divider type="vertical" /> */} | |
112 | 112 | <Popconfirm placement="top" title="确定删除?" onConfirm={() => deleteItem(record)}> |
113 | - <Button type="danger" ghost size="small">删除</Button> | |
113 | + <Button type="link" danger size="small">删除</Button> | |
114 | 114 | </Popconfirm> |
115 | - <Divider type="vertical" /> | |
116 | - <Button type="primary" ghost size="small" onClick={() => copyDetail(record)}>复制</Button> | |
117 | - <Divider type="vertical" /> | |
118 | - <Button type="primary" ghost size="small" onClick={() => viewDetail(record)}>编辑</Button> | |
115 | + {/* <Divider type="vertical" /> */} | |
116 | + <Button type="link" size="small" onClick={() => copyDetail(record)}>复制</Button> | |
117 | + {/* <Divider type="vertical" /> */} | |
118 | + <Button type="link" size="small" onClick={() => viewDetail(record)}>编辑</Button> | |
119 | 119 | </span> |
120 | 120 | )} |
121 | 121 | {record.proStatus == PromotionStatus['待审核'] && ( |
122 | 122 | <span> |
123 | 123 | <Popconfirm placement="top" title="确定删除?" onConfirm={() => deleteItem(record)}> |
124 | - <Button type="danger" ghost size="small">删除</Button> | |
124 | + <Button type="link" danger size="small">删除</Button> | |
125 | 125 | </Popconfirm> |
126 | - <Divider type="vertical" /> | |
127 | - <Button type="primary" ghost size="small" onClick={() => copyDetail(record)}>复制</Button> | |
128 | - <Divider type="vertical" /> | |
129 | - <Button type="primary" ghost size="small" onClick={() => viewDetail(record)}>查看</Button> | |
126 | + <Button type="link" size="small" onClick={() => copyDetail(record)}>复制</Button> | |
127 | + <Button type="link" size="small" onClick={() => viewDetail(record)}>查看</Button> | |
130 | 128 | </span> |
131 | 129 | )} |
132 | 130 | {record.proStatus == PromotionStatus['待发布'] && ( |
133 | 131 | <span> |
134 | 132 | <Tooltip key="save" title="活动发布后,才能正常使用"> |
135 | - <Button type="primary" ghost size="small" onClick={() => publishActivity(record)}>发布</Button> | |
133 | + <Button type="link" size="small" onClick={() => publishActivity(record)}>发布</Button> | |
136 | 134 | </Tooltip> |
137 | - <Divider type="vertical" /> | |
138 | - <Button type="primary" ghost size="small" onClick={() => copyDetail(record)}>复制</Button> | |
139 | - <Divider type="vertical" /> | |
140 | - <Button type="primary" ghost size="small" onClick={() => viewDetail(record)}>查看</Button> | |
135 | + <Button type="link" size="small" onClick={() => copyDetail(record)}>复制</Button> | |
136 | + <Button type="link" size="small" onClick={() => viewDetail(record)}>查看</Button> | |
141 | 137 | </span> |
142 | 138 | )} |
143 | 139 | {[PromotionStatus['未开始'], PromotionStatus['进行中']].includes(record.proStatus) && ( |
144 | 140 | <span> |
145 | - <Button type="danger" ghost size="small" onClick={() => endActivity(record)}>结束</Button> | |
146 | - <Divider type="vertical" /> | |
147 | - <Button type="primary" ghost size="small" onClick={() => copyDetail(record)}>复制</Button> | |
148 | - <Divider type="vertical" /> | |
149 | - <Button type="primary" ghost size="small" onClick={() => viewDetail(record)}>查看</Button> | |
141 | + <Button type="link" danger size="small" onClick={() => endActivity(record)}>结束</Button> | |
142 | + <Button type="link" size="small" onClick={() => copyDetail(record)}>复制</Button> | |
143 | + <Button type="link" size="small" onClick={() => viewDetail(record)}>查看</Button> | |
150 | 144 | </span> |
151 | 145 | )} |
152 | 146 | {record.proStatus == PromotionStatus['已结束'] && ( |
153 | 147 | <span> |
154 | - <Button type="primary" ghost size="small" onClick={() => copyDetail(record)}>复制</Button> | |
155 | - <Divider type="vertical" /> | |
156 | - <Button type="primary" ghost size="small" onClick={() => viewDetail(record)}>查看</Button> | |
148 | + <Button type="link" size="small" onClick={() => copyDetail(record)}>复制</Button> | |
149 | + <Button type="link" size="small" onClick={() => viewDetail(record)}>查看</Button> | |
157 | 150 | </span> |
158 | 151 | )} |
159 | 152 | </React.Fragment> | ... | ... |
src/pages/promotion/proengineCreate/components/DealerSelector/api.ts
1 | -import { OOP_HOST } from '@/utils/host'; | |
2 | -import { http } from '@/typing/http'; | |
1 | +import { OOP_HOST, MKT_HOST } from '@/utils/host'; | |
2 | +import type { http } from '@/typing/http'; | |
3 | 3 | import request from '@/utils/request'; |
4 | 4 | |
5 | 5 | export interface DealerItem { |
... | ... | @@ -21,5 +21,5 @@ export function getDealerApi(brandId: number): http.PromiseResp<DealerItem[]> { |
21 | 21 | |
22 | 22 | /** 根据当前登录人信息获取商家门店树 */ |
23 | 23 | export function getDealerTreeApi(params: { bizType: number; brandId?: number }): http.PromiseRespA<DealersShop> { |
24 | - return request.get(`${OOP_HOST}/select/dealers/shops`, { params }); | |
24 | + return request.get(`${MKT_HOST}/erp/activity/get/scope/auth`, { params }); | |
25 | 25 | } | ... | ... |
src/pages/promotion/proengineCreate/components/DealerSelector/index.tsx
1 | -import React, { useEffect, useState, Ref, forwardRef } from 'react'; | |
1 | +import type { Ref } from 'react'; | |
2 | +import React, { useEffect, useState, forwardRef } from 'react'; | |
2 | 3 | import { Radio, message, Select, TreeSelect } from 'antd'; |
3 | 4 | import type { DefaultOptionType } from 'antd/es/select'; |
4 | 5 | import { DealerItem, getDealerApi, getDealerTreeApi } from './api'; |
... | ... | @@ -32,8 +33,8 @@ const defaultValue: Value = { |
32 | 33 | |
33 | 34 | function DealerSelector(props: DealerSelectorProps, ref?: Ref<any>) { |
34 | 35 | const { brandId, value = defaultValue, bizType, joinDealerIds, onChange, disabled } = props; |
35 | - const { type = 1, selected = [] } = value; | |
36 | - const [innerValue, setValue] = useState<Value>({ type, selected }); | |
36 | + const { type = 2, selected = [] } = value; | |
37 | + const [innerValue, setValue] = useState<Value>({ type: 2, selected }); | |
37 | 38 | const [treeData, setTreeData] = useState<Omit<DefaultOptionType, 'label'>[]>([]); |
38 | 39 | const [loading, setLoading] = useState(false); |
39 | 40 | |
... | ... | @@ -105,39 +106,39 @@ function DealerSelector(props: DealerSelectorProps, ref?: Ref<any>) { |
105 | 106 | |
106 | 107 | return ( |
107 | 108 | <div> |
108 | - <RadioGroup value={innerValue.type} disabled={disabled} onChange={typeChange}> | |
109 | + {/* <RadioGroup value={innerValue.type} disabled={disabled} onChange={typeChange}> | |
109 | 110 | <Radio value={1}>全部商家</Radio> |
110 | 111 | <Radio value={2}>部分商家</Radio> |
111 | 112 | </RadioGroup> |
112 | 113 | {innerValue.type === 2 && ( |
113 | - // <TreeSelect | |
114 | - // showSearch | |
115 | - // allowClear | |
116 | - // disabled={disabled} | |
117 | - // treeCheckable | |
118 | - // loading={loading} | |
119 | - // placeholder="请选择商家/门店" | |
120 | - // style={{ width: '100%' }} | |
121 | - // value={innerValue.selected} | |
122 | - // treeExpandAction="click" | |
123 | - // multiple | |
124 | - // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} | |
125 | - // onChange={treeOnChange} | |
126 | - // treeData={treeData} | |
127 | - // /> | |
128 | - <SelectorWithFull | |
129 | - data={treeData} | |
114 | + <TreeSelect | |
115 | + showSearch | |
130 | 116 | allowClear |
117 | + disabled={disabled} | |
118 | + treeCheckable | |
131 | 119 | loading={loading} |
132 | 120 | placeholder="请选择商家/门店" |
133 | - value={innerValue.selected} | |
134 | 121 | style={{ width: '100%' }} |
135 | - dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} | |
122 | + value={innerValue.selected} | |
123 | + treeExpandAction="click" | |
136 | 124 | multiple |
137 | - fieldKeyNames={{ keyName: 'key', valueName: 'value', labelName: 'title', childrenName: 'children' }} | |
125 | + dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} | |
138 | 126 | onChange={treeOnChange} |
127 | + treeData={treeData} | |
139 | 128 | /> |
140 | - )} | |
129 | + )} */} | |
130 | + <SelectorWithFull | |
131 | + data={treeData} | |
132 | + allowClear | |
133 | + loading={loading} | |
134 | + placeholder="请选择商家/门店" | |
135 | + value={innerValue.selected} | |
136 | + style={{ width: '100%' }} | |
137 | + dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} | |
138 | + multiple | |
139 | + fieldKeyNames={{ keyName: 'key', valueName: 'value', labelName: 'title', childrenName: 'children' }} | |
140 | + onChange={treeOnChange} | |
141 | + /> | |
141 | 142 | </div> |
142 | 143 | ); |
143 | 144 | } | ... | ... |
src/pages/promotion/proengineCreate/entity.ts
1 | 1 | import moment from 'moment'; |
2 | 2 | import _ from 'lodash'; |
3 | -import { BaseInfoDto } from './interface'; | |
3 | +import type { BaseInfoDto } from './interface'; | |
4 | 4 | |
5 | 5 | export const formItemLayout = { |
6 | 6 | labelCol: { |
... | ... | @@ -176,7 +176,7 @@ export function setRules(config: BaseInfoDto) { |
176 | 176 | |
177 | 177 | /** 将管理UI状态的数据,转化为store中存储的数据 */ |
178 | 178 | export function stateTransforToStore(formState) { |
179 | - let store = { ...base }; | |
179 | + const store = { ...base }; | |
180 | 180 | |
181 | 181 | _.each(formState, (value, key) => { |
182 | 182 | switch (key) { |
... | ... | @@ -196,11 +196,11 @@ export function stateTransforToStore(formState) { |
196 | 196 | case 'joinDealer': |
197 | 197 | const dealersIds: string[] = []; |
198 | 198 | const shopIds: string[] = []; |
199 | - value.selected.forEach((item:string) => { | |
199 | + value.selected.forEach((item: string) => { | |
200 | 200 | dealersIds.push(item.split("-")[0]); |
201 | 201 | shopIds.push(item.split("-")[1]); |
202 | 202 | }); |
203 | - store.joinDealerType = value.type; | |
203 | + store.joinDealerType = 2; | |
204 | 204 | store.joinDealerIds = [...new Set(dealersIds)].join(","); |
205 | 205 | store.joinShopIds = shopIds.join(","); |
206 | 206 | break; | ... | ... |