Commit 5fd4d7fc948ddee569bdc9bf85de9c4405ca4d07
Merge remote-tracking branch 'origin/master' into bug_fix
Showing
54 changed files
with
1605 additions
and
1208 deletions
config/routers/angel.ts
... | ... | @@ -10,8 +10,8 @@ export default [ |
10 | 10 | component: './carinsur/PurchaseConfig', |
11 | 11 | }, |
12 | 12 | { |
13 | - path: '/angel/loan/client/config', //贷款客户保险要求配置 | |
14 | - component: './carinsur/LoanClientConfig', | |
13 | + path: '/angel/loanClientRequires', // 贷款期客户保险配置 | |
14 | + component: './carinsur/LoanClientRequires', | |
15 | 15 | }, |
16 | 16 | |
17 | 17 | { | ... | ... |
config/routers/contract.ts
src/components/Condition/BrandToSeries/index.tsx
... | ... | @@ -5,47 +5,50 @@ import * as API from './api'; |
5 | 5 | |
6 | 6 | interface BrandToSeriesProps extends CascaderProps { |
7 | 7 | /** 第一层 品牌列表 */ |
8 | - brandList?: API.Brand[] | API.optionItem[], | |
9 | - labelInValue?: boolean, | |
10 | - value?: any[], | |
11 | - onChange?: (value: any, ...other: any) => any, | |
8 | + brandList?: API.Brand[] | API.optionItem[]; | |
9 | + labelInValue?: boolean; | |
10 | + value?: any[]; | |
11 | + onChange?: (value: any, ...other: any) => any; | |
12 | 12 | /** 是否授权品牌(授权品牌接口是admin,非授权品牌接口是oop) */ |
13 | - authBrand?: boolean | |
13 | + authBrand?: boolean; | |
14 | + placeholder?: string; | |
14 | 15 | } |
15 | 16 | |
16 | 17 | /** |
17 | 18 | * 基于Cascader封装的品牌车系级联选择框 |
18 | 19 | */ |
19 | 20 | export default function BrandToSeries(props: BrandToSeriesProps) { |
20 | - const { value = [], onChange, labelInValue, brandList, placeholder = "请选择品牌/车系", authBrand, ...other } = props; | |
21 | + const { value = [], onChange, labelInValue, brandList, placeholder = '请选择品牌/车系', authBrand, ...other } = props; | |
21 | 22 | const [options, setOptions] = useState<any[]>([]); |
22 | 23 | const [selected, setSelected] = useState<any[]>([]); |
23 | 24 | |
24 | 25 | useEffect(() => { |
25 | 26 | if (!brandList) { |
26 | 27 | const brandApi: any = authBrand ? API.authBrandsApi : API.brandByOopApi; |
27 | - brandApi().then(res => { | |
28 | - const { data = [] } = res; | |
29 | - const _data = data.map(brand => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false })); | |
30 | - setOptions([..._data]); | |
31 | - }).catch(e => { | |
32 | - message.error(e.message); | |
33 | - }); | |
28 | + brandApi() | |
29 | + .then((res) => { | |
30 | + const { data = [] } = res; | |
31 | + const _data = data.map((brand) => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false })); | |
32 | + setOptions([..._data]); | |
33 | + }) | |
34 | + .catch((e) => { | |
35 | + message.error(e.message); | |
36 | + }); | |
34 | 37 | } else { |
35 | - setOptions(brandList.map(brand => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false }))) | |
38 | + setOptions(brandList.map((brand) => ({ id: brand.brandId || brand.id, name: brand.brandName || brand.name, isLeaf: false }))); | |
36 | 39 | } |
37 | - }, []) | |
40 | + }, []); | |
38 | 41 | |
39 | 42 | useEffect(() => { |
40 | 43 | if (selected.length === 0 && value.length > 0) { |
41 | 44 | const valueBrandId = labelInValue ? value[0].id : value[0]; |
42 | - loadData(options.filter(item => item.id === valueBrandId)); | |
45 | + loadData(options.filter((item) => item.id === valueBrandId)); | |
43 | 46 | } |
44 | 47 | if (value[1] !== selected[1]) { |
45 | - const _value = labelInValue ? value.map(item => item.id) : value; | |
48 | + const _value = labelInValue ? value.map((item) => item.id) : value; | |
46 | 49 | setSelected(_value); |
47 | 50 | } |
48 | - }, [value[1]]) | |
51 | + }, [value[1]]); | |
49 | 52 | |
50 | 53 | function loadData(selectedOptions?: CascaderOptionType[]) { |
51 | 54 | if (selectedOptions && selectedOptions.length > 0) { |
... | ... | @@ -53,23 +56,25 @@ export default function BrandToSeries(props: BrandToSeriesProps) { |
53 | 56 | const targetOption = selectedOptions[length - 1]; |
54 | 57 | targetOption.loading = true; |
55 | 58 | if (length === 1) { |
56 | - API.getSeriesApi(targetOption.id).then(res => { | |
57 | - const { data = [] } = res; | |
58 | - targetOption.loading = false; | |
59 | - targetOption.children = data.map((list, index) => ({ | |
60 | - id: list.id, | |
61 | - name: list.name, | |
62 | - })); | |
63 | - setOptions([...options]) | |
64 | - }).catch(e => { | |
65 | - message.error(e.message); | |
66 | - }); | |
59 | + API.getSeriesApi(targetOption.id) | |
60 | + .then((res) => { | |
61 | + const { data = [] } = res; | |
62 | + targetOption.loading = false; | |
63 | + targetOption.children = data.map((list, index) => ({ | |
64 | + id: list.id, | |
65 | + name: list.name, | |
66 | + })); | |
67 | + setOptions([...options]); | |
68 | + }) | |
69 | + .catch((e) => { | |
70 | + message.error(e.message); | |
71 | + }); | |
67 | 72 | } |
68 | 73 | } |
69 | 74 | } |
70 | 75 | |
71 | 76 | function _onChange(value: string[], selectedOptions: any[] = []) { |
72 | - const _value = labelInValue ? selectedOptions.map(item => ({ id: item.id, name: item.name })) : value; | |
77 | + const _value = labelInValue ? selectedOptions.map((item) => ({ id: item.id, name: item.name })) : value; | |
73 | 78 | setSelected(value || []); |
74 | 79 | onChange && onChange(_value || [], selectedOptions); |
75 | 80 | } |
... | ... | @@ -82,9 +87,8 @@ export default function BrandToSeries(props: BrandToSeriesProps) { |
82 | 87 | loadData={loadData} |
83 | 88 | value={selected.length <= 0 ? undefined : selected} |
84 | 89 | onChange={_onChange} |
85 | - fieldNames={{ value: 'id', label: 'name', }} | |
90 | + fieldNames={{ value: 'id', label: 'name' }} | |
86 | 91 | notFoundContent="暂无数据" |
87 | 92 | /> |
88 | - | |
89 | 93 | ); |
90 | 94 | } | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/CommonSettingForm.tsx
... | ... | @@ -17,7 +17,7 @@ interface TableRoleItem { |
17 | 17 | |
18 | 18 | interface Props { |
19 | 19 | small?: boolean; |
20 | - shopBizTypes: string[]; | |
20 | + shopBizTypes: number[]; // 从预设条件为门店的选项值中提取 bizType 交集 | |
21 | 21 | roles: ApprovalSetting.ApprovalRoleItem[][]; |
22 | 22 | setRoles: (value: ApprovalSetting.ApprovalRoleItem[][]) => void; |
23 | 23 | groupRoot?: boolean; |
... | ... | @@ -99,7 +99,7 @@ export default function CommonSettingForm({ small = false, shopBizTypes, roles, |
99 | 99 | roleListHook |
100 | 100 | .run({ |
101 | 101 | configuredRoleCodes: ids.join(','), |
102 | - shopBizTypes: shopBizTypes.join(','), | |
102 | + // shopBizTypes: shopBizTypes.join(','), // 门店业态和门店预设条件去掉后,审批配置此接口不传此参数 | |
103 | 103 | }) |
104 | 104 | .then((res) => { |
105 | 105 | setRoleList(res ?? []); | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/DefaultFlowNewOrEdit.tsx
... | ... | @@ -16,7 +16,6 @@ import { |
16 | 16 | BrandSelector, |
17 | 17 | RPTypesSelector, |
18 | 18 | BizTypeSelector, |
19 | - ShopBizTypeSelector, | |
20 | 19 | OfficeWordTypeSelector, |
21 | 20 | ContractTypeSelector, |
22 | 21 | } from './Selectors'; |
... | ... | @@ -81,6 +80,17 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
81 | 80 | } |
82 | 81 | }); |
83 | 82 | const newCondVals = (data?.conditionValues ?? []).concat(essVals); |
83 | + // idOrCode to idOrCode--bizType | |
84 | + newCondVals.forEach((n) => { | |
85 | + if (n.flowTriggerDto.type === TriggerType.门店) { | |
86 | + const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ | |
87 | + idOrCode: `${i.idOrCode}--${i.bizType}`, | |
88 | + name: i.name, | |
89 | + bizType: i.bizType, | |
90 | + })); | |
91 | + n.value = JSON.stringify(value); | |
92 | + } | |
93 | + }); | |
84 | 94 | setConditionVals(newCondVals); |
85 | 95 | |
86 | 96 | setRoles(data?.approvalRoles ?? []); |
... | ... | @@ -101,17 +111,36 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
101 | 111 | } |
102 | 112 | }, [visible, data]); |
103 | 113 | |
104 | - // 获取已配置的门店业态条件值 | |
114 | + // 从已选择门店中自动计算 bizType 交集 | |
105 | 115 | const shopBizTypes = useMemo(() => { |
106 | - const currType = conditionVals.find((i) => i.flowTriggerDto.type === TriggerType.门店业态); | |
107 | - if (!currType) return []; | |
108 | - try { | |
109 | - const options = JSON.parse(currType.value); | |
110 | - return options.map((i: FlowSetting.CondValItem) => i.idOrCode); | |
111 | - } catch { | |
112 | - return []; | |
113 | - } | |
116 | + const shopCondVals = conditionVals.filter((i) => i.flowTriggerDto.type === TriggerType.门店); | |
117 | + if (!shopCondVals.length) return []; | |
118 | + const bizTypeSet = new Set<number>(); | |
119 | + shopCondVals.forEach((s) => { | |
120 | + try { | |
121 | + const options = JSON.parse(s.value); | |
122 | + options.forEach((o: FlowSetting.CondValItem) => { | |
123 | + bizTypeSet.add(o.bizType!); | |
124 | + }); | |
125 | + } catch {} | |
126 | + }); | |
127 | + return Array.from(bizTypeSet.values()); | |
114 | 128 | }, [conditionVals]); |
129 | + // 计算最新 bizType 交集 | |
130 | + const getShopBizTypes = (cVals: ApprovalSetting.ConditionVal[]) => { | |
131 | + const shopCondVals = cVals.filter((i) => i.flowTriggerDto.type === TriggerType.门店); | |
132 | + if (!shopCondVals.length) return []; | |
133 | + const bizTypeSet = new Set<number>(); | |
134 | + shopCondVals.forEach((s) => { | |
135 | + try { | |
136 | + const options = JSON.parse(s.value); | |
137 | + options.forEach((o: FlowSetting.CondValItem) => { | |
138 | + bizTypeSet.add(o.bizType!); | |
139 | + }); | |
140 | + } catch {} | |
141 | + }); | |
142 | + return Array.from(bizTypeSet.values()); | |
143 | + }; | |
115 | 144 | |
116 | 145 | const hide = () => { |
117 | 146 | onCancel && onCancel(); |
... | ... | @@ -128,6 +157,17 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
128 | 157 | message.error('请填写全部触发条件的对应值'); |
129 | 158 | return; |
130 | 159 | } |
160 | + // idOrCode--bizType to idOrCode | |
161 | + conditionVals.forEach((n) => { | |
162 | + if (n.flowTriggerDto.type === TriggerType.门店) { | |
163 | + const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ | |
164 | + idOrCode: i.idOrCode.split('--')[0]!, | |
165 | + name: i.name, | |
166 | + bizType: i.bizType, | |
167 | + })); | |
168 | + n.value = JSON.stringify(value); | |
169 | + } | |
170 | + }); | |
131 | 171 | form.validateFields().then((values) => { |
132 | 172 | const { seniorApprove } = values; |
133 | 173 | if (!seniorApprove && roles.length === 0) { |
... | ... | @@ -146,35 +186,39 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
146 | 186 | }); |
147 | 187 | }; |
148 | 188 | |
149 | - // 门店业态值只要变化则清空已添加审批角色列表 | |
150 | - const clearRoles = () => { | |
151 | - setRoles([]); | |
152 | - }; | |
153 | - | |
154 | - // 选择|取消选择门店业态 | |
155 | - const handleShopBizTypeChange = (value: number) => { | |
156 | - const currType = (selectList.find((i) => i.value === value) ?? {}).extral; | |
157 | - if (currType?.type === TriggerType.门店业态) { | |
158 | - clearRoles(); | |
159 | - } | |
189 | + // 门店业态值减少时交互:旧业态值不存在于新业态值数组 | |
190 | + const clearRoles = (newCondVals: ApprovalSetting.ConditionVal[]) => { | |
191 | + const oldShopBizTypes = [...shopBizTypes]; | |
192 | + const newShopBizTypes = getShopBizTypes(newCondVals); | |
193 | + oldShopBizTypes.forEach((i) => { | |
194 | + if (!newShopBizTypes.includes(i)) { | |
195 | + // 清空已添加审批角色列表 | |
196 | + setRoles([]); | |
197 | + } | |
198 | + }); | |
160 | 199 | }; |
161 | 200 | |
162 | 201 | const onConditionChange = (item: ApprovalSetting.ConditionVal, values: any, index: number) => { |
163 | - if (item.flowTriggerDto.type === TriggerType.门店业态) { | |
164 | - // 审批角色清空 | |
165 | - clearRoles(); | |
166 | - // 门店组件清空 | |
167 | - const shopValIdx = conditionVals.findIndex((i) => i.flowTriggerDto.type === TriggerType.门店); | |
168 | - if (shopValIdx > -1) { | |
169 | - conditionVals[shopValIdx].value = ''; | |
170 | - } | |
171 | - } | |
172 | - const newValue = Array.isArray(values) ? values.map((i) => ({ idOrCode: i.value, name: i.label })) : values; | |
173 | 202 | const { value, flowTriggerDto } = item; |
203 | + | |
204 | + // idOrCode--bizType | |
205 | + let newValue; | |
206 | + if (flowTriggerDto.type === TriggerType.门店) { | |
207 | + newValue = Array.isArray(values) | |
208 | + ? values.map((i) => { | |
209 | + const currBizType = i.value.split('--')[1]!; | |
210 | + return { idOrCode: i.value, name: i.label, bizType: Number(currBizType) }; | |
211 | + }) | |
212 | + : values; | |
213 | + } else { | |
214 | + newValue = Array.isArray(values) ? values.map((i) => ({ idOrCode: i.value, name: i.label })) : values; | |
215 | + } | |
216 | + | |
217 | + // 计算新条件值 | |
218 | + const newCondVals = [...conditionVals]; | |
174 | 219 | if (flowTriggerDto && [2, 3, 4, 5, 6, 7, 8].includes(flowTriggerDto.judgeRule ?? 0)) { |
175 | 220 | const _item = { ...item, value: JSON.stringify(newValue) }; |
176 | - conditionVals[index] = _item; | |
177 | - setConditionVals([...conditionVals]); | |
221 | + newCondVals[index] = _item; | |
178 | 222 | } else { |
179 | 223 | const _item = { |
180 | 224 | ...item, |
... | ... | @@ -183,9 +227,16 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
183 | 227 | ...newValue, |
184 | 228 | }), |
185 | 229 | }; |
186 | - conditionVals[index] = _item; | |
187 | - setConditionVals([...conditionVals]); | |
230 | + newCondVals[index] = _item; | |
231 | + } | |
232 | + | |
233 | + // 门店业态值减少时交互 | |
234 | + if (flowTriggerDto.type === TriggerType.门店) { | |
235 | + clearRoles(newCondVals); | |
188 | 236 | } |
237 | + | |
238 | + // 更新条件值 | |
239 | + setConditionVals(newCondVals); | |
189 | 240 | }; |
190 | 241 | |
191 | 242 | // 选择需要配置的预设条件 |
... | ... | @@ -194,6 +245,10 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
194 | 245 | const currVal = conditionVals.find((c) => c.flowTriggerDto.id === i); |
195 | 246 | return { value: currVal ? currVal.value : '', flowTriggerDto: preCondition.find((p) => p.id === i)! }; |
196 | 247 | }); |
248 | + | |
249 | + // 门店业态值减少时交互 | |
250 | + clearRoles(tempVals); | |
251 | + | |
197 | 252 | setConditionVals(tempVals); |
198 | 253 | }; |
199 | 254 | |
... | ... | @@ -207,6 +262,7 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
207 | 262 | cancelButtonProps={{ disabled: loading }} |
208 | 263 | onCancel={hide} |
209 | 264 | onOk={onSave} |
265 | + destroyOnClose | |
210 | 266 | > |
211 | 267 | <Form form={form}> |
212 | 268 | <Form.Item name="id" hidden /> |
... | ... | @@ -214,15 +270,7 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
214 | 270 | <Input placeholder="请输入" maxLength={64} /> |
215 | 271 | </Form.Item> |
216 | 272 | <Form.Item label="触发条件" name="conditions" rules={[{ required: false, message: '请选择需要配置的条件' }]}> |
217 | - <Select | |
218 | - mode="multiple" | |
219 | - style={{ width: '100%' }} | |
220 | - allowClear | |
221 | - placeholder="请选择" | |
222 | - onChange={onSelectCondition} | |
223 | - onSelect={handleShopBizTypeChange} | |
224 | - onDeselect={handleShopBizTypeChange} | |
225 | - > | |
273 | + <Select mode="multiple" style={{ width: '100%' }} allowClear placeholder="请选择" onChange={onSelectCondition}> | |
226 | 274 | {selectList.map((item: SelectItem) => ( |
227 | 275 | <Option value={item.value} key={item.value} extral={item.extral} disabled={item.extral.essential}> |
228 | 276 | {item.label} |
... | ... | @@ -290,7 +338,6 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
290 | 338 | labelInValue |
291 | 339 | multiple |
292 | 340 | initType={1} |
293 | - bizTypes={shopBizTypes.join(',')} | |
294 | 341 | value={ |
295 | 342 | originalData.length > 0 |
296 | 343 | ? originalData.map((i: any) => ({ |
... | ... | @@ -371,9 +418,6 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
371 | 418 | {type === TriggerType['报销类型'] && ( |
372 | 419 | <BizTypeSelector visible={type === TriggerType['报销类型']} index={index} item={item} onChange={onConditionChange} /> |
373 | 420 | )} |
374 | - {type === TriggerType['门店业态'] && ( | |
375 | - <ShopBizTypeSelector visible={type === TriggerType['门店业态']} index={index} item={item} onChange={onConditionChange} /> | |
376 | - )} | |
377 | 421 | {type === TriggerType['工作类型'] && ( |
378 | 422 | <OfficeWordTypeSelector visible={type === TriggerType['工作类型']} index={index} item={item} onChange={onConditionChange} /> |
379 | 423 | )} | ... | ... |
src/pages/approval/FlowSetting/interface.d.ts
src/pages/approval/FlowSetting/subpages/ConditionSetting/components/CustomFlowNewOrEdit.tsx
... | ... | @@ -16,7 +16,6 @@ import { |
16 | 16 | BrandSelector, |
17 | 17 | RPTypesSelector, |
18 | 18 | BizTypeSelector, |
19 | - ShopBizTypeSelector, | |
20 | 19 | OfficeWordTypeSelector, |
21 | 20 | ContractTypeSelector, |
22 | 21 | } from '@/pages/approval/ApprovalSetting/subpages/components/Selectors'; |
... | ... | @@ -52,7 +51,7 @@ export default function CustomFlowNewOrEdit(props: Props) { |
52 | 51 | const [form] = Form.useForm(); |
53 | 52 | |
54 | 53 | // 触发条件对应表单值 |
55 | - const [conditionVals, setConditionVals] = useState<ApprovalSetting.ConditionVal[]>([]); | |
54 | + const [conditionVals, setConditionVals] = useState<FlowSetting.ConditionVal[]>([]); | |
56 | 55 | // 条件审批配置-->默认审批流程-->附加审批角色 |
57 | 56 | const [roles, setRoles] = useState<FlowSetting.ApprovalRoleItem[][]>([]); |
58 | 57 | |
... | ... | @@ -86,7 +85,7 @@ export default function CustomFlowNewOrEdit(props: Props) { |
86 | 85 | setSelectList(tempData); |
87 | 86 | |
88 | 87 | // 主要条件要必选 |
89 | - const essVals: ApprovalSetting.ConditionVal[] = []; | |
88 | + const essVals: FlowSetting.ConditionVal[] = []; | |
90 | 89 | preCondition.forEach((i) => { |
91 | 90 | const currVal = (data?.conditionValues ?? []).find((c) => c.flowTriggerDto.id === i.id); |
92 | 91 | if (i.essential && !currVal) { |
... | ... | @@ -98,6 +97,17 @@ export default function CustomFlowNewOrEdit(props: Props) { |
98 | 97 | } |
99 | 98 | }); |
100 | 99 | const newCondVals = (data?.conditionValues ?? []).concat(essVals); |
100 | + // idOrCode to idOrCode--bizType | |
101 | + newCondVals.forEach((n) => { | |
102 | + if (n.flowTriggerDto.type === TriggerType.门店) { | |
103 | + const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ | |
104 | + idOrCode: `${i.idOrCode}--${i.bizType}`, | |
105 | + name: i.name, | |
106 | + bizType: i.bizType, | |
107 | + })); | |
108 | + n.value = JSON.stringify(value); | |
109 | + } | |
110 | + }); | |
101 | 111 | setConditionVals(newCondVals); |
102 | 112 | |
103 | 113 | setRoles(data?.approvalRoles ?? []); |
... | ... | @@ -119,17 +129,36 @@ export default function CustomFlowNewOrEdit(props: Props) { |
119 | 129 | } |
120 | 130 | }, [visible, data]); |
121 | 131 | |
122 | - // 获取已配置的门店业态条件值 | |
132 | + // 从已选择门店中自动计算 bizType 交集 | |
123 | 133 | const shopBizTypes = useMemo(() => { |
124 | - const currType = conditionVals.find((i) => i.flowTriggerDto.type === TriggerType.门店业态); | |
125 | - if (!currType) return []; | |
126 | - try { | |
127 | - const options = JSON.parse(currType.value); | |
128 | - return options.map((i: FlowSetting.CondValItem) => i.idOrCode); | |
129 | - } catch { | |
130 | - return []; | |
131 | - } | |
134 | + const shopCondVals = conditionVals.filter((i) => i.flowTriggerDto.type === TriggerType.门店); | |
135 | + if (!shopCondVals.length) return []; | |
136 | + const bizTypeSet = new Set<number>(); | |
137 | + shopCondVals.forEach((s) => { | |
138 | + try { | |
139 | + const options = JSON.parse(s.value); | |
140 | + options.forEach((o: FlowSetting.CondValItem) => { | |
141 | + bizTypeSet.add(o.bizType!); | |
142 | + }); | |
143 | + } catch {} | |
144 | + }); | |
145 | + return Array.from(bizTypeSet.values()); | |
132 | 146 | }, [conditionVals]); |
147 | + // 计算最新 bizType 交集 | |
148 | + const getShopBizTypes = (cVals: FlowSetting.ConditionVal[]) => { | |
149 | + const shopCondVals = cVals.filter((i) => i.flowTriggerDto.type === TriggerType.门店); | |
150 | + if (!shopCondVals.length) return []; | |
151 | + const bizTypeSet = new Set<number>(); | |
152 | + shopCondVals.forEach((s) => { | |
153 | + try { | |
154 | + const options = JSON.parse(s.value); | |
155 | + options.forEach((o: FlowSetting.CondValItem) => { | |
156 | + bizTypeSet.add(o.bizType!); | |
157 | + }); | |
158 | + } catch {} | |
159 | + }); | |
160 | + return Array.from(bizTypeSet.values()); | |
161 | + }; | |
133 | 162 | |
134 | 163 | const hide = () => { |
135 | 164 | onCancel && onCancel(); |
... | ... | @@ -147,6 +176,17 @@ export default function CustomFlowNewOrEdit(props: Props) { |
147 | 176 | message.error('请填写全部触发条件的对应值'); |
148 | 177 | return; |
149 | 178 | } |
179 | + // idOrCode--bizType to idOrCode | |
180 | + conditionVals.forEach((n) => { | |
181 | + if (n.flowTriggerDto.type === TriggerType.门店) { | |
182 | + const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ | |
183 | + idOrCode: i.idOrCode.split('--')[0]!, | |
184 | + name: i.name, | |
185 | + bizType: i.bizType, | |
186 | + })); | |
187 | + n.value = JSON.stringify(value); | |
188 | + } | |
189 | + }); | |
150 | 190 | form.validateFields().then((values) => { |
151 | 191 | const params = { |
152 | 192 | ...values, |
... | ... | @@ -159,35 +199,39 @@ export default function CustomFlowNewOrEdit(props: Props) { |
159 | 199 | }); |
160 | 200 | }; |
161 | 201 | |
162 | - // 门店业态值只要变化则清空已添加审批角色列表 | |
163 | - const clearRoles = () => { | |
164 | - setRoles([]); | |
165 | - }; | |
166 | - | |
167 | - // 选择|取消选择门店业态 | |
168 | - const handleShopBizTypeChange = (value: number) => { | |
169 | - const currType = (selectList.find((i) => i.value === value) ?? {}).extral; | |
170 | - if (currType?.type === TriggerType.门店业态) { | |
171 | - clearRoles(); | |
172 | - } | |
202 | + // 门店业态值减少时交互:旧业态值不存在于新业态值数组 | |
203 | + const clearRoles = (newCondVals: FlowSetting.ConditionVal[]) => { | |
204 | + const oldShopBizTypes = [...shopBizTypes]; | |
205 | + const newShopBizTypes = getShopBizTypes(newCondVals); | |
206 | + oldShopBizTypes.forEach((i) => { | |
207 | + if (!newShopBizTypes.includes(i)) { | |
208 | + // 清空已添加审批角色列表 | |
209 | + setRoles([]); | |
210 | + } | |
211 | + }); | |
173 | 212 | }; |
174 | 213 | |
175 | - const onConditionChange = (item: ApprovalSetting.ConditionVal, values: any, index: number) => { | |
214 | + const onConditionChange = (item: FlowSetting.ConditionVal, values: any, index: number) => { | |
176 | 215 | const { value, flowTriggerDto } = item; |
177 | - if (item.flowTriggerDto.type === TriggerType.门店业态) { | |
178 | - // 审批角色清空 | |
179 | - clearRoles(); | |
180 | - // 门店组件清空 | |
181 | - const shopValIdx = conditionVals.findIndex((i) => i.flowTriggerDto.type === TriggerType.门店); | |
182 | - if (shopValIdx > -1) { | |
183 | - conditionVals[shopValIdx].value = ''; | |
184 | - } | |
216 | + | |
217 | + // idOrCode--bizType | |
218 | + let newValue; | |
219 | + if (flowTriggerDto.type === TriggerType.门店) { | |
220 | + newValue = Array.isArray(values) | |
221 | + ? values.map((i) => { | |
222 | + const currBizType = i.value.split('--')[1]!; | |
223 | + return { idOrCode: i.value, name: i.label, bizType: Number(currBizType) }; | |
224 | + }) | |
225 | + : values; | |
226 | + } else { | |
227 | + newValue = Array.isArray(values) ? values.map((i) => ({ idOrCode: i.value, name: i.label })) : values; | |
185 | 228 | } |
186 | - const newValue = Array.isArray(values) ? values.map((i) => ({ idOrCode: i.value, name: i.label })) : values; | |
229 | + | |
230 | + // 计算新条件值 | |
231 | + const newCondVals = [...conditionVals]; | |
187 | 232 | if (flowTriggerDto && [2, 3, 4, 5, 6, 7, 8].includes(flowTriggerDto.judgeRule ?? 0)) { |
188 | 233 | const _item = { ...item, value: JSON.stringify(newValue) }; |
189 | - conditionVals[index] = _item; | |
190 | - setConditionVals([...conditionVals]); | |
234 | + newCondVals[index] = _item; | |
191 | 235 | } else { |
192 | 236 | const _item = { |
193 | 237 | ...item, |
... | ... | @@ -196,9 +240,16 @@ export default function CustomFlowNewOrEdit(props: Props) { |
196 | 240 | ...newValue, |
197 | 241 | }), |
198 | 242 | }; |
199 | - conditionVals[index] = _item; | |
200 | - setConditionVals([...conditionVals]); | |
243 | + newCondVals[index] = _item; | |
201 | 244 | } |
245 | + | |
246 | + // 门店业态值减少时交互 | |
247 | + if (flowTriggerDto.type === TriggerType.门店) { | |
248 | + clearRoles(newCondVals); | |
249 | + } | |
250 | + | |
251 | + // 更新条件值 | |
252 | + setConditionVals(newCondVals); | |
202 | 253 | }; |
203 | 254 | |
204 | 255 | // 选择需要配置的预设条件 |
... | ... | @@ -207,6 +258,10 @@ export default function CustomFlowNewOrEdit(props: Props) { |
207 | 258 | const currVal = conditionVals.find((c) => c.flowTriggerDto?.id == i); |
208 | 259 | return { value: currVal ? currVal.value : '', flowTriggerDto: preCondition.find((p) => p.id === i)! }; |
209 | 260 | }); |
261 | + | |
262 | + // 门店业态值减少时交互 | |
263 | + clearRoles(tempVals); | |
264 | + | |
210 | 265 | setConditionVals(tempVals); |
211 | 266 | }; |
212 | 267 | |
... | ... | @@ -220,6 +275,7 @@ export default function CustomFlowNewOrEdit(props: Props) { |
220 | 275 | cancelButtonProps={{ disabled: loading }} |
221 | 276 | onCancel={hide} |
222 | 277 | onOk={handleSaveFlow} |
278 | + destroyOnClose | |
223 | 279 | > |
224 | 280 | <Form form={form}> |
225 | 281 | <Form.Item name="id" hidden /> |
... | ... | @@ -227,15 +283,7 @@ export default function CustomFlowNewOrEdit(props: Props) { |
227 | 283 | <Input placeholder="请输入" maxLength={64} /> |
228 | 284 | </Form.Item> |
229 | 285 | <Form.Item label="触发条件" name="conditions" rules={[{ required: true, message: '请选择需要配置的条件' }]}> |
230 | - <Select | |
231 | - mode="multiple" | |
232 | - allowClear | |
233 | - style={{ width: '100%' }} | |
234 | - placeholder="请选择" | |
235 | - onChange={handleSelectCondition} | |
236 | - onSelect={handleShopBizTypeChange} | |
237 | - onDeselect={handleShopBizTypeChange} | |
238 | - > | |
286 | + <Select mode="multiple" allowClear style={{ width: '100%' }} placeholder="请选择" onChange={handleSelectCondition}> | |
239 | 287 | {selectList.map((item: SelectItem) => ( |
240 | 288 | <Option value={item.value} key={item.value} extral={item.extral} disabled={item.extral.essential}> |
241 | 289 | {item.label} |
... | ... | @@ -244,7 +292,7 @@ export default function CustomFlowNewOrEdit(props: Props) { |
244 | 292 | </Select> |
245 | 293 | </Form.Item> |
246 | 294 | |
247 | - {conditionVals.map((item: ApprovalSetting.ConditionVal, index: number) => { | |
295 | + {conditionVals.map((item: FlowSetting.ConditionVal, index: number) => { | |
248 | 296 | const { flowTriggerDto, value } = item; |
249 | 297 | const originalData = JSON.parse(value || '{}'); // 触发的条件选的值 |
250 | 298 | const { name, judgeRule = 0, type, id } = flowTriggerDto ?? {}; // 触发条件信息 |
... | ... | @@ -303,7 +351,6 @@ export default function CustomFlowNewOrEdit(props: Props) { |
303 | 351 | labelInValue |
304 | 352 | multiple |
305 | 353 | initType={1} |
306 | - bizTypes={shopBizTypes.join(',')} | |
307 | 354 | value={ |
308 | 355 | originalData.length > 0 |
309 | 356 | ? originalData.map((i: any) => ({ |
... | ... | @@ -384,9 +431,6 @@ export default function CustomFlowNewOrEdit(props: Props) { |
384 | 431 | {type === TriggerType['报销类型'] && ( |
385 | 432 | <BizTypeSelector visible={type === TriggerType['报销类型']} index={index} item={item} onChange={onConditionChange} /> |
386 | 433 | )} |
387 | - {type === TriggerType['门店业态'] && ( | |
388 | - <ShopBizTypeSelector visible={type === TriggerType['门店业态']} index={index} item={item} onChange={onConditionChange} /> | |
389 | - )} | |
390 | 434 | {type === TriggerType['工作类型'] && ( |
391 | 435 | <OfficeWordTypeSelector visible={type === TriggerType['工作类型']} index={index} item={item} onChange={onConditionChange} /> |
392 | 436 | )} | ... | ... |
src/pages/approval/FlowSetting/subpages/ConditionSetting/components/RolesSettingForm.tsx
... | ... | @@ -15,7 +15,7 @@ interface TableRoleItem { |
15 | 15 | } |
16 | 16 | |
17 | 17 | interface Props { |
18 | - shopBizTypes: number[]; // 预设条件门店业态-联动 | |
18 | + shopBizTypes: number[]; // 从预设条件为门店的选项值中提取 bizType 交集 | |
19 | 19 | roles: FlowSetting.ApprovalRoleItem[][]; |
20 | 20 | setRoles: (value: FlowSetting.ApprovalRoleItem[][]) => void; |
21 | 21 | } | ... | ... |
src/pages/approval/components/ShopSelectByBizType/api.ts
1 | 1 | import type { http } from '@/typing/http'; |
2 | 2 | import request from '@/utils/request'; |
3 | -import { OOP_HOST, } from '@/utils/host'; | |
3 | +import { OOP_HOST } from '@/utils/host'; | |
4 | 4 | |
5 | 5 | type P<T> = http.PromiseResp<T>; |
6 | 6 | |
7 | 7 | export interface QueryParams { |
8 | - groupId?: number // 集团id | |
9 | - keyword?: string // 查询门店 | |
10 | - bizTypes?: string // 门店业态筛选 | |
8 | + groupId?: number; // 集团id | |
9 | + keyword?: string; // 查询门店 | |
10 | + bizTypes?: string; // 门店业态筛选 | |
11 | + allType?: boolean; // 是否为全业态 | |
11 | 12 | } |
12 | 13 | |
13 | 14 | export interface ShopItem { |
14 | - value?: number, | |
15 | - label?: string, | |
16 | - bizType?: number, | |
17 | - children?: ShopItem[] | |
15 | + value?: number; | |
16 | + label?: string; | |
17 | + bizType?: number; | |
18 | + children?: ShopItem[]; | |
18 | 19 | } |
19 | 20 | |
20 | 21 | /** |
... | ... | @@ -33,4 +34,4 @@ export function getShopListByBizTypeApi(params: QueryParams): P<ShopItem[]> { |
33 | 34 | */ |
34 | 35 | export function getShopListByDealerApi(params: QueryParams): P<ShopItem[]> { |
35 | 36 | return request.get(`${OOP_HOST}/select/dealers/shops`, { params }); |
36 | -} | |
37 | 37 | \ No newline at end of file |
38 | +} | ... | ... |
src/pages/approval/components/ShopSelectByBizType/index.tsx
... | ... | @@ -16,7 +16,6 @@ interface Props { |
16 | 16 | multiple?: boolean; |
17 | 17 | labelInValue?: boolean; |
18 | 18 | initType?: 1 | 2; |
19 | - bizTypes?: string; // 支持门店业态筛选 | |
20 | 19 | disabled?: boolean; |
21 | 20 | /** 📢 以下2个属性 仅同时使用一个 📢 */ |
22 | 21 | showIds?: number[]; // 仅显示项目ID列表 |
... | ... | @@ -44,16 +43,15 @@ export interface ShopSelectRef { |
44 | 43 | export default forwardRef(ShopSelectByBizType); |
45 | 44 | |
46 | 45 | function ShopSelectByBizType( |
47 | - { value = [], onChange, multiple = false, labelInValue = false, initType = 1, bizTypes, disabled = false, showIds, hiddenIds, disabledIds }: Props, | |
46 | + { value = [], onChange, multiple = false, labelInValue = false, initType = 1, disabled = false, showIds, hiddenIds, disabledIds }: Props, | |
48 | 47 | ref: Ref<ShopSelectRef>, |
49 | 48 | ) { |
50 | 49 | if (showIds?.length && hiddenIds?.length) { |
51 | 50 | console.error(`(<ShopSelectByBizType>):\`showIds\` 和 \`hiddenIds\` 不能同时传入。`); |
52 | 51 | } |
53 | 52 | |
54 | - const [delay, setDelay] = useState(true); | |
55 | - const { data: byBizTypeList, loading: byBizTypeLoading, setParams: setBizTypeParams } = useInitail(getShopListByBizTypeApi, [], {}, delay); | |
56 | - const { data: byDealerList, loading: byDealerLoading, setParams: setDealerParams } = useInitail(getShopListByDealerApi, [], {}, delay); | |
53 | + const { data: byBizTypeList, loading: byBizTypeLoading } = useInitail(getShopListByBizTypeApi, [], { allType: true }); | |
54 | + const { data: byDealerList, loading: byDealerLoading } = useInitail(getShopListByDealerApi, [], {}); | |
57 | 55 | const [type, setType] = useState<1 | 2>(initType); |
58 | 56 | const [values, setValues] = useState<LabeledValue[]>(value); |
59 | 57 | const [checkInfo, setCheckInfo] = useState({ |
... | ... | @@ -63,12 +61,6 @@ function ShopSelectByBizType( |
63 | 61 | const allValues = useRef<LabeledValue[]>([]); // 为了方便全选按钮被点击时赋值,将所有人员再计算list的时候,顺便赋值给该变量 |
64 | 62 | |
65 | 63 | useEffect(() => { |
66 | - setDelay(false); | |
67 | - setBizTypeParams({ bizTypes }, true); | |
68 | - setDealerParams({ bizTypes }, true); | |
69 | - }, [bizTypes]); | |
70 | - | |
71 | - useEffect(() => { | |
72 | 64 | if (value.length > 0) { |
73 | 65 | setValues(value); |
74 | 66 | setCheckInfo({ |
... | ... | @@ -115,8 +107,8 @@ function ShopSelectByBizType( |
115 | 107 | (children || []) |
116 | 108 | .filter((child) => !child.disabled) |
117 | 109 | .map((shop) => ({ |
118 | - label: `${shop.shopName}`, | |
119 | - value: shop.shopId, | |
110 | + label: shop.title, | |
111 | + value: shop.value, | |
120 | 112 | })), |
121 | 113 | ); |
122 | 114 | if (index === byBizTypeList.length - 1) { |
... | ... | @@ -143,8 +135,8 @@ function ShopSelectByBizType( |
143 | 135 | // 将商家下的门店赋值给allValues |
144 | 136 | allValues.current = allValues.current.concat( |
145 | 137 | (children || []).map((shop) => ({ |
146 | - label: shop.shopName, | |
147 | - value: shop.shopId, | |
138 | + label: shop.title, | |
139 | + value: shop.value, | |
148 | 140 | })), |
149 | 141 | ); |
150 | 142 | if (index === byDealerList.length - 1) { |
... | ... | @@ -228,6 +220,7 @@ function ShopSelectByBizType( |
228 | 220 | } |
229 | 221 | |
230 | 222 | function processingChildrenData(data: ShopItem, showIds?: number[], hiddenIds?: number[], disabledIds?: number[]): DataItem[] | undefined { |
223 | + // todo hiddenIds 需要拼接 bizType 处理 | |
231 | 224 | let _data: ShopItem[] | undefined, _children: DataItem[] | undefined; |
232 | 225 | |
233 | 226 | if (showIds?.length) { |
... | ... | @@ -244,8 +237,9 @@ function processingChildrenData(data: ShopItem, showIds?: number[], hiddenIds?: |
244 | 237 | return { |
245 | 238 | pid: data.value, |
246 | 239 | title: shop.label, |
247 | - value: shop.value, | |
248 | - key: shop.value, | |
240 | + // value: idOrCode to idOrCode--bizType | |
241 | + value: `${shop.value}--${shop.bizType}`, | |
242 | + key: `${shop.value}--${shop.bizType}`, | |
249 | 243 | isLeaf: true, |
250 | 244 | level: 2, |
251 | 245 | disabled: disabledIds?.includes(shop.value || -1), | ... | ... |
src/pages/attendance/Attend/subpages/Roster/api.ts
... | ... | @@ -18,6 +18,21 @@ export interface SettingItem { |
18 | 18 | posts: Post[]; |
19 | 19 | month: string[]; |
20 | 20 | effectMonth: string; |
21 | + confirmType?: number; // 确认类型(-1:待办未推送, 0:未确认, 1:主动确认, 2:到期系统自动确认) | |
22 | +} | |
23 | + | |
24 | +export enum ConfirmType { | |
25 | + 待办未推送 = -1, | |
26 | + 未确认 = 0, | |
27 | + 主动确认 = 1, | |
28 | + 到期系统自动确认 = 2, | |
29 | +} | |
30 | + | |
31 | +export enum ConfirmTypeColor { | |
32 | + '#999' = -1, | |
33 | + '#FF921C' = 0, | |
34 | + '#4189FD' = 1, | |
35 | + '#F4333C' = 2, | |
21 | 36 | } |
22 | 37 | |
23 | 38 | export interface Shop { |
... | ... | @@ -61,6 +76,7 @@ export interface SepcialSettingsItem { |
61 | 76 | shops?: Shop[]; |
62 | 77 | posts?: Post[]; |
63 | 78 | restMode?: number[]; |
79 | + confirmType?: number; // 确认类型(-1:待办未推送, 0:未确认, 1:主动确认, 2:到期系统自动确认) | |
64 | 80 | } |
65 | 81 | |
66 | 82 | export enum RestMode { |
... | ... | @@ -102,3 +118,21 @@ export function deleteSpecialItemApi(id: number): http.PromiseResp<string> { |
102 | 118 | export function deleteSettingItemApi(id: number): http.PromiseResp<string> { |
103 | 119 | return request.get(`${ATTENDANCE_HOST}/erp/schedule/setting/del`, { params: { id } }); |
104 | 120 | } |
121 | + | |
122 | +/** | |
123 | + * @description: 确认排班配置 | |
124 | + * @param {number} id | |
125 | + * @return {http.PromiseResp<string>} | |
126 | + */ | |
127 | +export function confirmSettingItemApi(id: number): http.PromiseResp<string> { | |
128 | + return request.get(`${ATTENDANCE_HOST}/erp/schedule/setting/confirmConfig`, { params: { id } }); | |
129 | +} | |
130 | + | |
131 | +/** | |
132 | + * @description: 确认特殊排班配置 | |
133 | + * @param {number} id | |
134 | + * @return {http.PromiseResp<string>} | |
135 | + */ | |
136 | +export function confirmSpecialSettingItemApi(id: number): http.PromiseResp<string> { | |
137 | + return request.get(`${ATTENDANCE_HOST}/erp/schedule/special/setting/confirmConfig`, { params: { id } }); | |
138 | +} | ... | ... |
src/pages/attendance/Attend/subpages/Roster/components/Settings/index.tsx
... | ... | @@ -2,7 +2,7 @@ import usePagination from '@/hooks/usePagination'; |
2 | 2 | import moment from 'moment'; |
3 | 3 | import React, { useState } from 'react'; |
4 | 4 | import * as API from '../../api'; |
5 | -import { Button, Popconfirm, Select, Table, message } from 'antd'; | |
5 | +import { Badge, Button, Divider, Popconfirm, Select, Table, message } from 'antd'; | |
6 | 6 | import SaveModal from './SaveModal'; |
7 | 7 | import DetailModal from './DetailModal'; |
8 | 8 | import TableArrayColumnFormat from '@/pages/ehr/components/TableArrayColumnFormat'; |
... | ... | @@ -37,6 +37,20 @@ export default function Settings() { |
37 | 37 | }); |
38 | 38 | } |
39 | 39 | |
40 | + function confirmItem(id: number) { | |
41 | + const hide = message.loading('确认中,请稍后...', 0); | |
42 | + API.confirmSettingItemApi(id) | |
43 | + .then((res) => { | |
44 | + hide(); | |
45 | + message.success(res.result); | |
46 | + setLoading(true); | |
47 | + }) | |
48 | + .catch((error) => { | |
49 | + hide(); | |
50 | + message.error(error.message ?? '确认失败'); | |
51 | + }); | |
52 | + } | |
53 | + | |
40 | 54 | return ( |
41 | 55 | <> |
42 | 56 | <div |
... | ... | @@ -71,72 +85,81 @@ export default function Settings() { |
71 | 85 | </Button> |
72 | 86 | </div> |
73 | 87 | <Table loading={loading} dataSource={list} pagination={paginationConfig} rowKey="id"> |
74 | - <Column | |
75 | - title="适用门店" | |
76 | - dataIndex="shops" | |
77 | - render={(shops?: API.Shop[]) => <TableArrayColumnFormat data={shops ?? []} key="shopId" showKey="shopName" unit="个门店" />} | |
78 | - /> | |
79 | - <Column | |
80 | - title="适用岗位" | |
81 | - dataIndex="posts" | |
82 | - render={(posts?: API.Post[]) => <TableArrayColumnFormat data={posts ?? []} key="postId" showKey="postName" unit="个岗位" />} | |
83 | - /> | |
84 | - <Column title="月休息天数" dataIndex="monthRestCnt" width="10%" align="center" render={(text, row: any) => <div>{row.monthRestCnt}天</div>} /> | |
85 | - <Column | |
86 | - title="最大连续休息天数" | |
87 | - dataIndex="restContinuousCnt" | |
88 | - width="10%" | |
89 | - align="center" | |
90 | - render={(text, row: any) => ( | |
91 | - <div> | |
92 | - {row.restContinuousCnt | |
93 | - ? row.continuousType === 0 | |
94 | - ? `${row.restContinuousCnt}天` | |
95 | - : `${Math.floor((row.restContinuousCnt * row.monthRestCnt) / 100)}天(百分比计算)` | |
96 | - : '--'} | |
97 | - </div> | |
88 | + <Table.Column | |
89 | + title="适用范围" | |
90 | + render={(record: API.SettingItem) => ( | |
91 | + <span> | |
92 | + <span className="span_limit_1"> | |
93 | + <span style={{ color: '#999' }}>适用门店:</span> | |
94 | + <TableArrayColumnFormat data={record.shops ?? []} key="shopId" showKey="shopName" unit="个门店" /> | |
95 | + </span> | |
96 | + <span className="span_limit_1"> | |
97 | + <span style={{ color: '#999' }}>适用岗位:</span> | |
98 | + <TableArrayColumnFormat data={record.posts ?? []} key="postId" showKey="postName" unit="个岗位" /> | |
99 | + </span> | |
100 | + </span> | |
98 | 101 | )} |
99 | 102 | /> |
100 | - <Column | |
101 | - title={`排班表设置时间(${moment(date).subtract(1, 'M').format('YYYY年MM月')}倒数后多少天)`} | |
102 | - dataIndex="scheduleDays" | |
103 | - width="16%" | |
104 | - align="center" | |
105 | - render={(text, row: any) => <div>{row.scheduleDays}天</div>} | |
103 | + <Table.Column | |
104 | + title="配置" | |
105 | + render={(record: API.SettingItem) => ( | |
106 | + <span> | |
107 | + <span className="span_limit_1"> | |
108 | + <span style={{ color: '#999' }}>月休息天数:</span> | |
109 | + <span style={{ color: '#333' }}>{record.monthRestCnt || '-'}天</span> | |
110 | + </span> | |
111 | + <span className="span_limit_1"> | |
112 | + <span style={{ color: '#999' }}>最大连续休息天数:</span> | |
113 | + <span style={{ color: '#333' }}> | |
114 | + {record.restContinuousCnt | |
115 | + ? record.continuousType === 0 | |
116 | + ? `${record.restContinuousCnt}天` | |
117 | + : `${Math.floor((record.restContinuousCnt * record.monthRestCnt) / 100)}天(百分比计算)` | |
118 | + : '--'} | |
119 | + </span> | |
120 | + </span> | |
121 | + <span className="span_limit_1"> | |
122 | + <span style={{ color: '#999' }}>{`排班表设置时间(${moment(date).subtract(1, 'M').format('YYYY年MM月')}倒数后多少天)`}:</span> | |
123 | + <span style={{ color: '#333' }}>{record.scheduleDays || '-'}天</span> | |
124 | + </span> | |
125 | + <span className="span_limit_1"> | |
126 | + <span style={{ color: '#999' }}>每月可主动调休次数:</span> | |
127 | + <span style={{ color: '#333' }}>{record.changeRestCnt || '-'}次</span> | |
128 | + </span> | |
129 | + </span> | |
130 | + )} | |
106 | 131 | /> |
107 | 132 | <Column |
108 | - title="每月可主动调休次数" | |
109 | - dataIndex="changeRestCnt" | |
110 | - width="16%" | |
111 | - align="center" | |
112 | - render={(text, row: any) => <div>{row.changeRestCnt ? `${row.changeRestCnt}次` : '--'}</div>} | |
133 | + title="状态" | |
134 | + dataIndex="confirmType" | |
135 | + render={(confirmType: number) => | |
136 | + Number.isFinite(confirmType) ? <Badge color={API.ConfirmTypeColor[confirmType]} text={API.ConfirmType[confirmType]} /> : '-' | |
137 | + } | |
113 | 138 | /> |
114 | - {/* <Column | |
115 | - title="最大连续上班天数(可跨月)" | |
116 | - dataIndex="restFrequency" | |
117 | - width="16%" | |
118 | - align="center" | |
119 | - render={(text, row: any) => <div>{row.restFrequency ? `${row.restFrequency}天/次` : '--'}</div>} | |
120 | - /> */} | |
121 | 139 | <Column |
122 | - width="10%" | |
123 | 140 | title="操作" |
124 | 141 | align="center" |
125 | 142 | render={(text, record: API.SettingItem) => ( |
126 | 143 | <> |
127 | - <Button | |
128 | - type="link" | |
144 | + {record.confirmType === API.ConfirmType.未确认 ? ( | |
145 | + <> | |
146 | + <Popconfirm placement="top" title="确定确认?" onConfirm={() => confirmItem(record.id)}> | |
147 | + <a>确认</a> | |
148 | + </Popconfirm> | |
149 | + <Divider type="vertical" /> | |
150 | + </> | |
151 | + ) : null} | |
152 | + <a | |
129 | 153 | onClick={() => { |
130 | 154 | setItem(record); |
131 | 155 | setVisible(true); |
132 | 156 | }} |
133 | 157 | > |
134 | 158 | 编辑 |
135 | - </Button> | |
159 | + </a> | |
160 | + <Divider type="vertical" /> | |
136 | 161 | <Popconfirm placement="top" title="确认删除?" onConfirm={() => deleteItem(record.id)}> |
137 | - <Button type="link" danger> | |
138 | - 删除 | |
139 | - </Button> | |
162 | + <a style={{ color: 'red' }}>删除</a> | |
140 | 163 | </Popconfirm> |
141 | 164 | </> |
142 | 165 | )} | ... | ... |
src/pages/attendance/Attend/subpages/Roster/components/SpecialSettings/index.tsx
1 | 1 | import React, { useEffect, useState } from 'react'; |
2 | 2 | import * as API from '../../api'; |
3 | 3 | import usePagination from '@/hooks/usePagination'; |
4 | -import { Button, Divider, Form, Modal, Popconfirm, Popover, Select, Spin, Table, message } from 'antd'; | |
4 | +import { Badge, Button, Divider, Form, Modal, Popconfirm, Popover, Select, Spin, Table, message } from 'antd'; | |
5 | 5 | import { formatObjText } from '@/utils/utils'; |
6 | 6 | import ShopSelectNew from '@/components/ShopSelectNew'; |
7 | 7 | import PostSelectNew from '@/components/PostSelectNew'; |
... | ... | @@ -46,6 +46,20 @@ export default function SpecialSettings() { |
46 | 46 | }); |
47 | 47 | } |
48 | 48 | |
49 | + function confirmItem(id: number) { | |
50 | + const hide = message.loading('确认中,请稍后...', 0); | |
51 | + API.confirmSpecialSettingItemApi(id) | |
52 | + .then((res) => { | |
53 | + hide(); | |
54 | + message.success(res.result); | |
55 | + pagination.setLoading(true); | |
56 | + }) | |
57 | + .catch((error) => { | |
58 | + hide(); | |
59 | + message.error(error.message ?? '确认失败'); | |
60 | + }); | |
61 | + } | |
62 | + | |
49 | 63 | function closeModal() { |
50 | 64 | setOpen(false); |
51 | 65 | setCurrent(undefined); |
... | ... | @@ -106,9 +120,24 @@ export default function SpecialSettings() { |
106 | 120 | render={(restMode: number[]) => (restMode?.length ? restMode.map((mode) => API.RestMode[mode]).join(' + ') : '-')} |
107 | 121 | /> |
108 | 122 | <Table.Column |
123 | + title="状态" | |
124 | + dataIndex="confirmType" | |
125 | + render={(confirmType: number) => | |
126 | + Number.isFinite(confirmType) ? <Badge color={API.ConfirmTypeColor[confirmType]} text={API.ConfirmType[confirmType]} /> : '-' | |
127 | + } | |
128 | + /> | |
129 | + <Table.Column | |
109 | 130 | title="操作" |
110 | 131 | render={(record: API.SepcialSettingsItem) => ( |
111 | 132 | <> |
133 | + {record.confirmType === API.ConfirmType.未确认 ? ( | |
134 | + <> | |
135 | + <Popconfirm placement="top" title="确定确认?" onConfirm={() => confirmItem(record.id ?? -1)}> | |
136 | + <a>确认</a> | |
137 | + </Popconfirm> | |
138 | + <Divider type="vertical" /> | |
139 | + </> | |
140 | + ) : null} | |
112 | 141 | <a onClick={() => openModal(record)}>编辑</a> |
113 | 142 | <Divider type="vertical" /> |
114 | 143 | <Popconfirm title="确定删除该配置?" onConfirm={() => deleteItem(record.id ?? -1)}> | ... | ... |
src/pages/carinsur/LoanClientConfig/api.ts deleted
1 | -import { http } from '@/typing/http'; | |
2 | -import request from '@/utils/request'; | |
3 | -import { ANGEL_Host, FVM_HOST } from "@/utils/host"; | |
4 | -import * as IF from './interface'; | |
5 | - | |
6 | -/** | |
7 | - * 查询列表 | |
8 | - */ | |
9 | -export function getPageListApi(brandId?: IF.QueryParams): http.PromisePageResp<IF.Item> { | |
10 | - return request.get(`${ANGEL_Host}/loancusinsureqconfig/page`, { params: brandId }); | |
11 | -} | |
12 | -/**查询配置授权车型 */ | |
13 | -export function getSpecListApi(additionalId?: number): http.PromiseResp<IF.Option[]> { | |
14 | - return request.get(`${FVM_HOST}/erp/subsidy/additional/auth/spec/list`, { params: { additionalId } }); | |
15 | -} | |
16 | - | |
17 | -/** | |
18 | - * 保存 | |
19 | - */ | |
20 | -export function saveApi(params: IF.SaveParams): http.PromiseResp<void> { | |
21 | - return request.post(`${ANGEL_Host}/loancusinsureqconfig/save`, params); | |
22 | -} | |
23 | - | |
24 | -// 配置删除 | |
25 | -export function deleteApi(id: number): http.PromiseResp<null> { | |
26 | - return request.post(`${ANGEL_Host}/loancusinsureqconfig/delete`, {id}); | |
27 | -} |
src/pages/carinsur/LoanClientConfig/components/EditModal.tsx deleted
1 | -import React, { useState, useEffect } from "react"; | |
2 | -import { message, Modal, Select, Form, DatePicker, InputNumber, Spin, Space, Radio } from "antd"; | |
3 | -import { saveApi } from "../api"; | |
4 | -import moment from "moment"; | |
5 | -import { getSeriesApi } from "@/common/api"; | |
6 | -import * as IF from "../interface"; | |
7 | - | |
8 | -const RangePicker = DatePicker.RangePicker; | |
9 | -interface Props { | |
10 | - visible: boolean; | |
11 | - onCancel: Function; | |
12 | - item: IF.Item; | |
13 | - fetchList: () => any; | |
14 | - brandList: CommonApi.OptionVO[]; | |
15 | -} | |
16 | - | |
17 | -const formItemLayout = { | |
18 | - labelCol: { | |
19 | - xs: { span: 24 }, | |
20 | - sm: { span: 6 }, | |
21 | - md: { span: 6 }, | |
22 | - }, | |
23 | - wrapperCol: { | |
24 | - xs: { span: 24 }, | |
25 | - sm: { span: 15 }, | |
26 | - md: { span: 15 }, | |
27 | - }, | |
28 | -}; | |
29 | - | |
30 | -const Item = Form.Item; | |
31 | - | |
32 | -function SaveModal(props: Props) { | |
33 | - const { item, onCancel, fetchList, visible, brandList } = props; | |
34 | - const [loading, setLoading] = useState(false); | |
35 | - const [initLoading, setInitLoading] = useState(false); | |
36 | - const [form] = Form.useForm(); | |
37 | - const [seriesList, setSeriesList] = useState<CommonApi.OptionVO[]>([]); | |
38 | - // const [seriesId, setSeriesId] = useState<number>(); | |
39 | - // const [specData, setSpecData] = useState<IF.Option[]>([]); | |
40 | - | |
41 | - useEffect(() => { | |
42 | - if (visible && item.id) { | |
43 | - form.setFieldsValue({ | |
44 | - startDate: [item.startDate && moment(item.startDate), item.endDate && moment(item.endDate)], | |
45 | - brandId: { value: item.brandId, label: item.brandName, key: item.brandId }, | |
46 | - seriesId: item.series?.map((item) => ({ value: item.seriesId, label: item.seriesName, key: item.seriesId })), | |
47 | - subsidyType: item.subsidyType, | |
48 | - needBuyTci: item.needBuyTci, | |
49 | - needBuyVci: item.needBuyVci, | |
50 | - vciReqAmount: item.vciReqAmount && item.vciReqAmount, | |
51 | - }); | |
52 | - | |
53 | - item.brandId && getSeries(item.brandId); | |
54 | - // setInitLoading(true); | |
55 | - } else { | |
56 | - // setSpecData([]); | |
57 | - // setSeriesId(undefined); | |
58 | - setSeriesList([]); | |
59 | - } | |
60 | - }, [visible]); | |
61 | - | |
62 | - function getSeries(brandId: number) { | |
63 | - getSeriesApi(brandId) | |
64 | - .then((res) => { | |
65 | - setSeriesList(res.data || []); | |
66 | - }) | |
67 | - .catch((err) => { | |
68 | - message.error(err.message); | |
69 | - }); | |
70 | - } | |
71 | - | |
72 | - function submit() { | |
73 | - form.validateFields().then((fields) => { | |
74 | - // 车系 | |
75 | - const series = fields.seriesId.map((item:any) => ({ seriesId: item.key, seriesName: item.label })); | |
76 | - const params: IF.SaveParams = { | |
77 | - id: item && item.id, | |
78 | - ...fields, | |
79 | - brandId: fields.brandId.value, | |
80 | - brandName: fields.brandId.label, | |
81 | - series, | |
82 | - startDate: fields.startDate[0].valueOf(), | |
83 | - endDate: fields.startDate[1].valueOf(), | |
84 | - }; | |
85 | - setLoading(true); | |
86 | - saveApi(params) | |
87 | - .then(() => { | |
88 | - message.success("保存成功"); | |
89 | - fetchList(); | |
90 | - onCancel(); | |
91 | - setLoading(false); | |
92 | - }) | |
93 | - .catch((e) => { | |
94 | - setLoading(false); | |
95 | - message.error(e.message); | |
96 | - }); | |
97 | - }); | |
98 | - } | |
99 | - | |
100 | - return ( | |
101 | - <Modal title={item.id ? "编辑" : "新增"} width={700} visible={visible} maskClosable={false} afterClose={() => form.resetFields()} onCancel={() => onCancel()} onOk={() => form.submit()} confirmLoading={loading}> | |
102 | - <Spin spinning={initLoading}> | |
103 | - <Form form={form} {...formItemLayout} onFinish={submit}> | |
104 | - <Item label="有效期" name="startDate" rules={[{ required: true, message: "请选择生效时间" }]}> | |
105 | - <RangePicker disabledDate={(current) => !!current && current < moment().startOf("day")} style={{ width: "100%" }} format="YYYY-MM-DD" /> | |
106 | - </Item> | |
107 | - <Item label="适用品牌" name="brandId" rules={[{ required: true, message: "请选择品牌" }]}> | |
108 | - <Select | |
109 | - optionFilterProp="children" | |
110 | - placeholder="请选择品牌" | |
111 | - labelInValue | |
112 | - showSearch | |
113 | - onChange={(v: any) => { | |
114 | - getSeries(v.value); | |
115 | - form.setFieldsValue({ seriesId: undefined, specList: undefined }); | |
116 | - }} | |
117 | - > | |
118 | - {brandList.map((i) => ( | |
119 | - <Select.Option value={i.id} key={i.id}> | |
120 | - {i.name} | |
121 | - </Select.Option> | |
122 | - ))} | |
123 | - </Select> | |
124 | - </Item> | |
125 | - | |
126 | - <Item label="适用车系" name="seriesId" rules={[{ required: true, message: "请选择车系" }]}> | |
127 | - <Select | |
128 | - mode="multiple" | |
129 | - optionFilterProp="children" | |
130 | - placeholder="请选择车系" | |
131 | - notFoundContent="暂无数据" | |
132 | - labelInValue | |
133 | - showSearch | |
134 | - onChange={(v: any) => { | |
135 | - // setSeriesId(v.value); | |
136 | - // form.setFieldsValue({ specList: undefined }); | |
137 | - }} | |
138 | - > | |
139 | - {seriesList.map((i) => ( | |
140 | - <Select.Option value={i.id} key={i.id}> | |
141 | - {i.name} | |
142 | - </Select.Option> | |
143 | - ))} | |
144 | - </Select> | |
145 | - </Item> | |
146 | - {/* 交强险 */} | |
147 | - <Item name="needBuyTci" label="要求购买交强险" rules={[{ required: true, message: "请选择是否要求购买交强险" }]}> | |
148 | - <Radio.Group | |
149 | - options={[ | |
150 | - { label: "是", value: true }, | |
151 | - { label: "否", value: false }, | |
152 | - ]} | |
153 | - /> | |
154 | - </Item> | |
155 | - {/* 商业险 */} | |
156 | - <Item name="needBuyVci" label="要求购买商业险" rules={[{ required: true, message: "请选择是否要求购买交强险" }]}> | |
157 | - <Radio.Group | |
158 | - options={[ | |
159 | - { label: "是", value: true }, | |
160 | - { label: "否", value: false }, | |
161 | - ]} | |
162 | - /> | |
163 | - </Item> | |
164 | - | |
165 | - <Item noStyle shouldUpdate={(prevValues, curValues) => prevValues.needBuyVci !== curValues.needBuyVci}> | |
166 | - {({ getFieldValue }) => { | |
167 | - const type = getFieldValue("needBuyVci"); | |
168 | - return type ? ( | |
169 | - <Form.Item label="商业险要求金额(>=)"> | |
170 | - <Space> | |
171 | - <Item | |
172 | - name="vciReqAmount" | |
173 | - noStyle | |
174 | - rules={[ | |
175 | - { required: true, message: "请输入" }, | |
176 | - { pattern: /^(?!(0[0-9]{0,}$))[0-9]{1,}[.]{0,}[0-9]{0,}$/, message: "请输入正数" }, | |
177 | - ]} | |
178 | - > | |
179 | - <InputNumber style={{ width: "100%" }} placeholder="请输入" precision={2} /> | |
180 | - </Item> | |
181 | - <span>元</span> | |
182 | - </Space> | |
183 | - </Form.Item> | |
184 | - ) : null; | |
185 | - }} | |
186 | - </Item> | |
187 | - </Form> | |
188 | - </Spin> | |
189 | - </Modal> | |
190 | - ); | |
191 | -} | |
192 | - | |
193 | -export default SaveModal; |
src/pages/carinsur/LoanClientConfig/components/SpecModal.tsx deleted
1 | -import React, { useState, useEffect } from "react"; | |
2 | -import "@ant-design/compatible/assets/index.css"; | |
3 | -import { Modal, Button, Table } from "antd"; | |
4 | - | |
5 | -import * as IF from "../interface"; | |
6 | - | |
7 | -interface Props { | |
8 | - visible: boolean; | |
9 | - onCancel: () => any; | |
10 | - item: IF.Item; | |
11 | -} | |
12 | - | |
13 | -function SpecModal(props: Props) { | |
14 | - const { visible, onCancel, item } = props; | |
15 | - const [tableList, setTableList] = useState<IF.SeriesItem[]>([]); | |
16 | - useEffect(() => { | |
17 | - let list = []; | |
18 | - if (item.series) { | |
19 | - for (let i = 0; i < item.series.length; i++) { | |
20 | - let obj = { ...item.series[i] }; | |
21 | - obj.brandName = item.brandName; | |
22 | - list.push(obj); | |
23 | - } | |
24 | - setTableList([...tableList, ...list]); | |
25 | - } else { | |
26 | - setTableList([]); | |
27 | - } | |
28 | - }, [item.id]); | |
29 | - const columns = [ | |
30 | - { | |
31 | - title: "品牌", | |
32 | - dataIndex: "brandName", | |
33 | - }, | |
34 | - { | |
35 | - title: "适用车系", | |
36 | - dataIndex: "seriesName", | |
37 | - }, | |
38 | - ]; | |
39 | - | |
40 | - return ( | |
41 | - <Modal | |
42 | - title="车辆信息" | |
43 | - style={{ width: 400 }} | |
44 | - maskClosable={false} | |
45 | - visible={visible} | |
46 | - onCancel={() => onCancel()} | |
47 | - footer={ | |
48 | - <Button type="default" onClick={() => onCancel()}> | |
49 | - 取消 | |
50 | - </Button> | |
51 | - } | |
52 | - > | |
53 | - <Table columns={columns} dataSource={tableList} rowKey={record => record.seriesId} /> | |
54 | - </Modal> | |
55 | - ); | |
56 | -} | |
57 | - | |
58 | -export default React.memo(SpecModal); |
src/pages/carinsur/LoanClientConfig/index.tsx deleted
1 | -import React, { useState } from "react"; | |
2 | -import { PlusOutlined } from "@ant-design/icons"; | |
3 | -import { Button, Card, Divider, message, Popconfirm, Table, Select } from "antd"; | |
4 | -import { PageHeaderWrapper } from "@ant-design/pro-layout"; | |
5 | -import usePagination from "@/hooks/usePagination"; | |
6 | -import SaveModal from "./components/EditModal"; | |
7 | -import SpecModal from "./components/SpecModal"; | |
8 | -import { deleteApi, getPageListApi } from "./api"; | |
9 | -import * as IF from "./interface"; | |
10 | -import useInitial from "@/hooks/useInitail"; | |
11 | -import { getBrandFilterApi } from "@/common/api"; | |
12 | -import moment from "moment"; | |
13 | - | |
14 | -const Column = Table.Column; | |
15 | - | |
16 | -export default function StorageList() { | |
17 | - const { list, paginationConfig, loading, setLoading, setParams, innerParams } = usePagination<StorageMaintain.Item>(getPageListApi, {}); | |
18 | - const [specVisible, setSpecVisible] = useState(false); | |
19 | - const { data: brandList } = useInitial<CommonApi.OptionVO[], {}>(getBrandFilterApi, [], {}); | |
20 | - const [visible, setVisible] = useState(false); | |
21 | - const [item, setItem] = useState<IF.Item>({}); | |
22 | - | |
23 | - /**删除 */ | |
24 | - function handleDelete(item: IF.Item) { | |
25 | - item.id && | |
26 | - deleteApi(item.id) | |
27 | - .then((res) => { | |
28 | - setLoading(true); | |
29 | - message.success("操作成功"); | |
30 | - }) | |
31 | - .catch((e) => { | |
32 | - message.error(e.message); | |
33 | - }); | |
34 | - } | |
35 | - | |
36 | - return ( | |
37 | - <PageHeaderWrapper title="贷款客户保险要求配置"> | |
38 | - <Card> | |
39 | - <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", marginBottom: 20 }}> | |
40 | - <div style={{ display: "flex", flexDirection: "row" }}> | |
41 | - <Select style={{ width: 250 }} placeholder="请选择品牌" value={innerParams.brandId} onChange={(v) => setParams({ ...innerParams, brandId: v }, true)} allowClear> | |
42 | - {brandList.map((item) => ( | |
43 | - <Select.Option value={item.id} key={item.id}> | |
44 | - {item.name} | |
45 | - </Select.Option> | |
46 | - ))} | |
47 | - </Select> | |
48 | - </div> | |
49 | - <Button | |
50 | - type="primary" | |
51 | - icon={<PlusOutlined />} | |
52 | - onClick={() => { | |
53 | - setVisible(true); | |
54 | - setItem({}); | |
55 | - }} | |
56 | - > | |
57 | - 新增 | |
58 | - </Button> | |
59 | - </div> | |
60 | - <Table size="small" loading={loading} pagination={paginationConfig} rowKey={(item) => String(item.id)} dataSource={list} onChange={(_pagination) => setParams({ ..._pagination }, true)}> | |
61 | - <Column title="品牌" width="10%" align="center" dataIndex="brandName" /> | |
62 | - <Column | |
63 | - title="适用车系" | |
64 | - width="10%" | |
65 | - align="center" | |
66 | - render={(text, record: IF.Item) => ( | |
67 | - <Button | |
68 | - type="link" | |
69 | - onClick={() => { | |
70 | - setSpecVisible(true); | |
71 | - setItem(record); | |
72 | - }} | |
73 | - > | |
74 | - 查看 | |
75 | - </Button> | |
76 | - )} | |
77 | - /> | |
78 | - <Column | |
79 | - title="有效期" | |
80 | - width="16%" | |
81 | - align="center" | |
82 | - render={(text, record: IF.Item) => <span>{`${(record.startDate && moment(record.startDate).format("YYYY-MM-DD")) || "——"}~${(record.endDate && moment(record.endDate).format("YYYY-MM-DD")) || "——"}`}</span>} | |
83 | - /> | |
84 | - <Column title="要求购买交强险" dataIndex="needBuyTci" width="10%" align="center" render={(text) => (text ? <span>是</span> : <span>否</span>)} /> | |
85 | - <Column title="要求购买商业险" dataIndex="needBuyVci" width="10%" align="center" render={(text) => (text ? <span>是</span> : <span>否</span>)} /> | |
86 | - <Column | |
87 | - title="商业险要求金额(>=)" | |
88 | - dataIndex="vciReqAmount" | |
89 | - width="10%" | |
90 | - align="center" | |
91 | - render={(text: number) => { | |
92 | - return text > 0? <span>{`${text || 0}元`}</span> :"--"; | |
93 | - }} | |
94 | - /> | |
95 | - | |
96 | - <Column | |
97 | - title="操作" | |
98 | - align="center" | |
99 | - width="15%" | |
100 | - render={(text, record: IF.Item) => ( | |
101 | - <> | |
102 | - <Button | |
103 | - type="link" | |
104 | - style={{ padding: 0 }} | |
105 | - onClick={() => { | |
106 | - setVisible(true); | |
107 | - setItem(record); | |
108 | - }} | |
109 | - > | |
110 | - 编辑 | |
111 | - </Button> | |
112 | - <Divider type="vertical" /> | |
113 | - <Popconfirm placement="top" title="确认删除?" onConfirm={() => handleDelete(record)}> | |
114 | - <Button type="link" style={{ padding: 0 }}> | |
115 | - 删除 | |
116 | - </Button> | |
117 | - </Popconfirm> | |
118 | - </> | |
119 | - )} | |
120 | - /> | |
121 | - </Table> | |
122 | - </Card> | |
123 | - <SaveModal | |
124 | - visible={visible} | |
125 | - brandList={brandList} | |
126 | - item={item} | |
127 | - fetchList={() => setLoading(true)} | |
128 | - onCancel={() => { | |
129 | - setVisible(false); | |
130 | - setItem({}); | |
131 | - }} | |
132 | - /> | |
133 | - {/* {specModal} */} | |
134 | - | |
135 | - <SpecModal | |
136 | - visible={specVisible} | |
137 | - item={item} | |
138 | - onCancel={() => { | |
139 | - setSpecVisible(false); | |
140 | - setItem({}); | |
141 | - }} | |
142 | - /> | |
143 | - </PageHeaderWrapper> | |
144 | - ); | |
145 | -} |
src/pages/carinsur/LoanClientConfig/interface.d.ts deleted
1 | -/** | |
2 | - * 查询参数 | |
3 | - */ | |
4 | -export interface QueryParams { | |
5 | - brandId?: number, | |
6 | - current?: number, | |
7 | - pageSize?: number, | |
8 | -} | |
9 | - | |
10 | -// export interface QueryParams { | |
11 | -// brandId?: number; | |
12 | -// } | |
13 | -/** | |
14 | - * 列表项 | |
15 | - */ | |
16 | -export interface Item { | |
17 | - id?: number; | |
18 | - brandId?: number; | |
19 | - brandName?: string; | |
20 | - seriesName?: string; | |
21 | - startDate?: number; | |
22 | - endDate?: number; | |
23 | - subsidyAmount?: number; | |
24 | - subsidyType?: number; | |
25 | - needBuyTci?: boolean; //是否要求买交强险 | |
26 | - needBuyVci?: boolean; // 是否要求买商业险 | |
27 | - series?: { seriesId: number; seriesName: string; brandName?: string }[]; | |
28 | - vciReqAmount?: number; | |
29 | - name?:string; | |
30 | -} | |
31 | - | |
32 | -export interface SaveParams { | |
33 | - id?: number; | |
34 | - brandId?: number; | |
35 | - brandName?: string; | |
36 | - series?: { seriesId: number; seriesName: string }[]; | |
37 | - startDate?: number; | |
38 | - endDate?: number; | |
39 | - needBuyTci?: boolean; | |
40 | - needBuyVci?: boolean; | |
41 | - vciReqAmount?: number; //商业险补贴金额 | |
42 | - subsidyType?: number; //补贴类型 1增购补贴、2大客户购车补贴、3置换补贴、4最美职业补贴 | |
43 | - subsidyAmount?: number; //补贴金额 | |
44 | -} | |
45 | - | |
46 | -interface SeriesItem { | |
47 | - seriesId: number; | |
48 | - seriesName: string; | |
49 | - brandName?: string; | |
50 | -} | |
51 | - | |
52 | -interface SimilarItem { | |
53 | - brandId: number, | |
54 | - brandName: string, | |
55 | -} | |
56 | -/** | |
57 | - * 授权参数 | |
58 | - */ | |
59 | -export interface ShopItem { | |
60 | - shopId?: number, // 所属门店 | |
61 | - shopName?: string | |
62 | -} | |
63 | - | |
64 | -export interface SelecSpecParams { | |
65 | - seriesId: number, //车系id | |
66 | - startTime: number, // 开始时间 | |
67 | - endTime: number, //结束时间 | |
68 | - additionalId?: number, //配置id(编辑使用) | |
69 | -} | |
70 | -/** | |
71 | - * 选项 | |
72 | - */ | |
73 | -export interface CustomerOption { | |
74 | - customerType: number, | |
75 | - typeName?: string | |
76 | -} | |
77 | - | |
78 | -export interface Option { | |
79 | - specId?: number, | |
80 | - specName?: string | |
81 | -} | |
82 | 0 | \ No newline at end of file |
src/pages/carinsur/LoanClientRequires/api.ts
0 → 100644
1 | +import type { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import type { IdNameOption, ShopOption } from '../entity'; | |
4 | +import { ANGEL_Host } from '@/utils/host'; | |
5 | +import type { Pagination } from '@/typing/common'; | |
6 | + | |
7 | +export interface LoanType { | |
8 | + type: number; | |
9 | + amount: number; | |
10 | +} | |
11 | +export interface brandSeriesItem { | |
12 | + id: number; | |
13 | + name: string; | |
14 | + series: IdNameOption[]; | |
15 | +} | |
16 | +export interface Item { | |
17 | + id?: number; | |
18 | + allBrandSeries: boolean; | |
19 | + brandSeries: brandSeriesItem[]; | |
20 | + useShopIds: ShopOption[]; | |
21 | + newTci: LoanType; | |
22 | + newVci: LoanType; | |
23 | + newTai: LoanType; | |
24 | + reNewTci: LoanType; | |
25 | + reNewVci: LoanType; | |
26 | + reNewTai: LoanType; | |
27 | +} | |
28 | + | |
29 | +export interface PageParams extends Pagination { | |
30 | + shopId?: number; | |
31 | + brandId?: number; | |
32 | + seriesId?: number; | |
33 | +} | |
34 | + | |
35 | +/** | |
36 | + * 分页查询 | |
37 | + */ | |
38 | +export function getLCRPage(params?: PageParams): http.PromisePageResp<Item> { | |
39 | + return request.get(`${ANGEL_Host}/loancusinsureq/page`, { params }); | |
40 | +} | |
41 | + | |
42 | +/** | |
43 | + * 新增/编辑 | |
44 | + */ | |
45 | +export function addLCR(data?: Item): http.PromiseResp<void> { | |
46 | + return request.post(`${ANGEL_Host}/loancusinsureq/add`, data); | |
47 | +} | |
48 | + | |
49 | +/** | |
50 | + * 删除 | |
51 | + */ | |
52 | +export function delLCR(id: number): http.PromisePageResp<void> { | |
53 | + return request.post(`${ANGEL_Host}/loancusinsureq/delete`, { id }); | |
54 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/components/AddModal/index.tsx
0 → 100644
1 | +import React, { useEffect, memo } from 'react'; | |
2 | +import { Modal, Form, message, Radio } from 'antd'; | |
3 | +import * as API from '../../api'; | |
4 | +import { useRequest } from 'umi'; | |
5 | +import BrandSeriesFormItem from '../BrandSeriesFormItem'; | |
6 | +import ShopSelectorByAll from '../ShopSelectorByAll'; | |
7 | +import LoanTypeFormItem from '../LoanTypeFormItem'; | |
8 | +import type { LabeledValue } from 'antd/lib/select'; | |
9 | +import st from './style.less'; | |
10 | + | |
11 | +interface Props { | |
12 | + visible: boolean; | |
13 | + row?: API.Item; | |
14 | + onCancel: () => void; | |
15 | + onRefresh: () => void; | |
16 | +} | |
17 | + | |
18 | +function AddModal({ visible, row, onCancel, onRefresh }: Props) { | |
19 | + const { id } = row ?? {}; | |
20 | + const [form] = Form.useForm(); | |
21 | + | |
22 | + const saveHook = useRequest(API.addLCR, { | |
23 | + manual: true, | |
24 | + throwOnError: true, | |
25 | + }); | |
26 | + | |
27 | + useEffect(() => { | |
28 | + if (visible) { | |
29 | + if (row) { | |
30 | + form.setFieldsValue({ | |
31 | + ...row, | |
32 | + useShopIds: row.useShopIds.map((i) => ({ label: i.shopName, value: i.shopId })), | |
33 | + }); | |
34 | + } else { | |
35 | + form.setFieldsValue({ | |
36 | + allBrandSeries: true, | |
37 | + }); | |
38 | + } | |
39 | + } else { | |
40 | + form.resetFields(); | |
41 | + } | |
42 | + }, [visible, row]); | |
43 | + | |
44 | + const handleSave = (feildValue: any) => { | |
45 | + saveHook | |
46 | + .run({ | |
47 | + ...feildValue, | |
48 | + useShopIds: feildValue.useShopIds.map((i: LabeledValue) => ({ shopId: i.value, shopName: i.label })), | |
49 | + brandSeries: feildValue.allBrandSeries ? [] : feildValue.brandSeries, | |
50 | + }) | |
51 | + .then(() => { | |
52 | + message.success('操作成功'); | |
53 | + onCancel(); | |
54 | + onRefresh(); | |
55 | + }) | |
56 | + .catch((e) => { | |
57 | + message.error(e.message); | |
58 | + }); | |
59 | + }; | |
60 | + | |
61 | + return ( | |
62 | + <Modal title={`${id ? '编辑' : '新增'}`} open={visible} confirmLoading={saveHook.loading} onCancel={onCancel} onOk={form.submit} width={1000}> | |
63 | + <Form form={form} onFinish={handleSave} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }}> | |
64 | + <Form.Item name="id" hidden /> | |
65 | + <Form.Item label="适用品牌车系" name="allBrandSeries" rules={[{ required: true, message: '请选择' }]}> | |
66 | + <Radio.Group> | |
67 | + <Radio value={true}>全部品牌全部车系</Radio> | |
68 | + <Radio value={false}>指定</Radio> | |
69 | + </Radio.Group> | |
70 | + </Form.Item> | |
71 | + <Form.Item | |
72 | + noStyle | |
73 | + shouldUpdate={(prev, curr) => { | |
74 | + // 切换全部|部分时交互未清空部分品牌部分车系数据 | |
75 | + return prev.allBrandSeries !== curr.allBrandSeries; | |
76 | + }} | |
77 | + > | |
78 | + {({ getFieldValue }) => { | |
79 | + const allBrandSeries = getFieldValue('allBrandSeries'); | |
80 | + if (allBrandSeries) { | |
81 | + return null; | |
82 | + } | |
83 | + return ( | |
84 | + <Form.Item className={st.hidden} label={<></>} name="brandSeries" rules={[{ required: true, message: '请至少添加一种适应品牌车系' }]}> | |
85 | + <BrandSeriesFormItem /> | |
86 | + </Form.Item> | |
87 | + ); | |
88 | + }} | |
89 | + </Form.Item> | |
90 | + <Form.Item label="适用门店" name="useShopIds" rules={[{ required: true, message: '请选择' }]}> | |
91 | + <ShopSelectorByAll /> | |
92 | + </Form.Item> | |
93 | + <LoanTypeFormItem form={form} key="newTci" name="newTci" label="新保交强险" /> | |
94 | + <LoanTypeFormItem form={form} key="newVci" name="newVci" label="新保商业险" /> | |
95 | + <LoanTypeFormItem form={form} key="newTai" name="newTai" label="新保驾意险" /> | |
96 | + <LoanTypeFormItem form={form} key="reNewTci" name="reNewTci" label="续保交强险" /> | |
97 | + <LoanTypeFormItem form={form} key="reNewVci" name="reNewVci" label="续保商业险" /> | |
98 | + <LoanTypeFormItem form={form} key="reNewTai" name="reNewTai" label="续保驾意险" /> | |
99 | + </Form> | |
100 | + </Modal> | |
101 | + ); | |
102 | +} | |
103 | + | |
104 | +export default memo(AddModal); | ... | ... |
src/pages/carinsur/LoanClientRequires/components/AddModal/style.less
0 → 100644
src/pages/carinsur/LoanClientRequires/components/BrandSeriesAddModal.tsx
0 → 100644
1 | +import React, { useEffect } from 'react'; | |
2 | +import { Modal, Form, Select } from 'antd'; | |
3 | +import type { brandSeriesItem } from '../api'; | |
4 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | +import SeriesSelectorByAll from './SeriesSelectorByAll'; | |
6 | +import _ from 'lodash'; | |
7 | + | |
8 | +interface Props { | |
9 | + brands?: CommonApi.OptionVO[]; | |
10 | + visible: boolean; | |
11 | + value?: brandSeriesItem; | |
12 | + onCancel: () => void; | |
13 | + onChange: (data: brandSeriesItem) => void; | |
14 | +} | |
15 | +const FormItem = Form.Item; | |
16 | + | |
17 | +export default function Index({ brands, visible, value, onCancel, onChange }: Props) { | |
18 | + const [form] = Form.useForm(); | |
19 | + | |
20 | + useEffect(() => { | |
21 | + if (visible && value) { | |
22 | + const { id, name, series } = value; | |
23 | + form.setFieldsValue({ | |
24 | + brand: { label: name, value: id }, | |
25 | + series: series.map((i) => ({ label: i.name, value: i.id })), | |
26 | + }); | |
27 | + } else { | |
28 | + form.resetFields(); | |
29 | + } | |
30 | + }, [visible]); | |
31 | + | |
32 | + const closeModal = () => { | |
33 | + onCancel(); | |
34 | + form.resetFields(); | |
35 | + }; | |
36 | + | |
37 | + function handleSave(feildValue: any) { | |
38 | + const { brand, series } = feildValue; | |
39 | + onChange && | |
40 | + onChange({ | |
41 | + id: brand.value, | |
42 | + name: brand.label, | |
43 | + series: series.map((i: LabeledValue) => ({ id: i.value, name: i.label })), | |
44 | + }); | |
45 | + closeModal(); | |
46 | + } | |
47 | + | |
48 | + return ( | |
49 | + <Modal title={`${value ? '编辑' : '添加'}适用品牌车系`} style={{ width: 600 }} open={visible} onCancel={closeModal} onOk={form.submit}> | |
50 | + <Form form={form} labelCol={{ span: '6' }} onFinish={handleSave}> | |
51 | + <FormItem label="品牌" name="brand" rules={[{ required: true, message: '请选择品牌' }]}> | |
52 | + <Select | |
53 | + disabled={!!value} // 编辑时不可编辑品牌 | |
54 | + placeholder="请选择" | |
55 | + options={brands} | |
56 | + fieldNames={{ label: 'name', value: 'id' }} | |
57 | + showSearch | |
58 | + labelInValue | |
59 | + optionFilterProp="children" | |
60 | + /> | |
61 | + </FormItem> | |
62 | + <Form.Item | |
63 | + noStyle | |
64 | + shouldUpdate={(prev, curr) => { | |
65 | + if (!_.isEqual(prev.brand, curr.brand)) { | |
66 | + if (value) { | |
67 | + form.setFieldValue('series', value.id === curr.brand.value ? value.series.map((i) => ({ label: i.name, value: i.id })) : []); | |
68 | + } else { | |
69 | + form.setFieldValue('series', []); | |
70 | + } | |
71 | + } | |
72 | + return !_.isEqual(prev.brand, curr.brand); | |
73 | + }} | |
74 | + > | |
75 | + {({ getFieldValue }) => { | |
76 | + const brandId = (getFieldValue('brand') ?? {}).value; | |
77 | + return ( | |
78 | + <FormItem label="车系" name="series" rules={[{ required: true, message: '请选择车系' }]}> | |
79 | + <SeriesSelectorByAll brandId={brandId} disabled={!brandId} disabledTip="请先选择品牌" /> | |
80 | + </FormItem> | |
81 | + ); | |
82 | + }} | |
83 | + </Form.Item> | |
84 | + </Form> | |
85 | + </Modal> | |
86 | + ); | |
87 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/components/BrandSeriesFormItem.tsx
0 → 100644
1 | +import React, { useEffect, useMemo, useState } from 'react'; | |
2 | +import { Table, Divider, Popconfirm, Button, Row } from 'antd'; | |
3 | +import { PlusOutlined } from '@ant-design/icons'; | |
4 | +import BrandSeriesAddModal from './BrandSeriesAddModal'; | |
5 | +import type { brandSeriesItem } from '../api'; | |
6 | +import TextWithMore from '@/components/TextWithMore'; | |
7 | +import useInitial from '@/hooks/useInitail'; | |
8 | +import { getBrandFilterApi } from '@/common/api'; | |
9 | + | |
10 | +const { Column } = Table; | |
11 | + | |
12 | +interface Props { | |
13 | + readOnly?: boolean; | |
14 | + value?: brandSeriesItem[]; | |
15 | + onChange?: (data: brandSeriesItem[]) => void; | |
16 | +} | |
17 | + | |
18 | +export default function Index({ readOnly = false, value = [], onChange }: Props) { | |
19 | + const [delay, setDelay] = useState(true); | |
20 | + const { data: brands, setParams } = useInitial(getBrandFilterApi, [], {}, delay); | |
21 | + | |
22 | + useEffect(() => { | |
23 | + if (!readOnly) { | |
24 | + setDelay(false); | |
25 | + setParams(undefined, true); | |
26 | + } | |
27 | + }, []); | |
28 | + | |
29 | + const theRestBrands = useMemo(() => { | |
30 | + const selectedBrands = value.map((i) => i.id); | |
31 | + return brands.filter((b) => !selectedBrands.includes(b.id!)); | |
32 | + }, [value, brands]); | |
33 | + | |
34 | + // 新增 | 编辑 | |
35 | + const [addModal, setAddModal] = useState<{ | |
36 | + visible: boolean; | |
37 | + row?: brandSeriesItem; | |
38 | + }>({ | |
39 | + visible: false, | |
40 | + }); | |
41 | + | |
42 | + const handleEdit = (row: brandSeriesItem) => { | |
43 | + setAddModal({ | |
44 | + visible: true, | |
45 | + row, | |
46 | + }); | |
47 | + }; | |
48 | + | |
49 | + const handleDelete = (row: brandSeriesItem) => { | |
50 | + const newVal = [...value]; | |
51 | + const currIdx = newVal.findIndex((i) => i.id === row.id); | |
52 | + newVal.splice(currIdx, 1); | |
53 | + onChange && onChange(newVal); | |
54 | + }; | |
55 | + | |
56 | + const handleUpdate = (res: brandSeriesItem) => { | |
57 | + const newVal = [...value]; | |
58 | + const currIdx = newVal.findIndex((i) => i.id === res.id); // 品牌 id | |
59 | + if (currIdx > -1) { | |
60 | + newVal[currIdx] = res; | |
61 | + } else { | |
62 | + newVal.push(res); | |
63 | + } | |
64 | + onChange && onChange(newVal); | |
65 | + }; | |
66 | + | |
67 | + return ( | |
68 | + <> | |
69 | + {!readOnly && ( | |
70 | + <Row align="middle" justify="end" style={{ marginBottom: 20 }}> | |
71 | + <Button | |
72 | + type="primary" | |
73 | + icon={<PlusOutlined />} | |
74 | + onClick={() => { | |
75 | + setAddModal({ | |
76 | + visible: true, | |
77 | + }); | |
78 | + }} | |
79 | + > | |
80 | + 添加 | |
81 | + </Button> | |
82 | + </Row> | |
83 | + )} | |
84 | + <Table dataSource={value} rowKey="id" size="small"> | |
85 | + <Column title="品牌" dataIndex="name" width={200} render={(t) => t || '-'} /> | |
86 | + <Column title="车系" dataIndex="series" width={200} render={(t) => <TextWithMore title="车系" dataIndex="name" list={t} />} /> | |
87 | + {!readOnly && ( | |
88 | + <Column | |
89 | + title="操作" | |
90 | + width={100} | |
91 | + dataIndex="unit" | |
92 | + render={(text, row: brandSeriesItem) => ( | |
93 | + <span> | |
94 | + <a | |
95 | + onClick={() => { | |
96 | + handleEdit(row); | |
97 | + }} | |
98 | + > | |
99 | + 编辑 | |
100 | + </a> | |
101 | + <Divider type="vertical" /> | |
102 | + <Popconfirm title="是否删除?" onConfirm={() => handleDelete(row)} okText="确定" cancelText="取消"> | |
103 | + <a | |
104 | + onClick={(e) => { | |
105 | + e.preventDefault(); | |
106 | + }} | |
107 | + style={{ color: 'red' }} | |
108 | + > | |
109 | + 删除 | |
110 | + </a> | |
111 | + </Popconfirm> | |
112 | + </span> | |
113 | + )} | |
114 | + /> | |
115 | + )} | |
116 | + </Table> | |
117 | + <BrandSeriesAddModal | |
118 | + brands={theRestBrands} | |
119 | + visible={addModal.visible} | |
120 | + value={addModal.row} | |
121 | + onCancel={() => setAddModal({ visible: false })} | |
122 | + onChange={handleUpdate} | |
123 | + /> | |
124 | + </> | |
125 | + ); | |
126 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/components/BrandSeriesModal.tsx
0 → 100644
1 | +import React from 'react'; | |
2 | +import { Modal } from 'antd'; | |
3 | +import BrandSeriesFormItem from './BrandSeriesFormItem'; | |
4 | +import type { brandSeriesItem } from '../api'; | |
5 | + | |
6 | +interface Props { | |
7 | + brandSeriesModal: { visible: boolean; brandSeries?: brandSeriesItem[] }; | |
8 | + onCancel: () => void; | |
9 | +} | |
10 | + | |
11 | +export default function Index({ brandSeriesModal, onCancel }: Props) { | |
12 | + const { visible, brandSeries = [] } = brandSeriesModal; | |
13 | + return ( | |
14 | + <Modal title="适用品牌车系" open={visible} onCancel={() => onCancel()} footer={null} width={600}> | |
15 | + <BrandSeriesFormItem value={brandSeries} readOnly /> | |
16 | + </Modal> | |
17 | + ); | |
18 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/components/Filter/index.tsx
0 → 100644
1 | +import React, { memo } from 'react'; | |
2 | +import { Row, Select } from 'antd'; | |
3 | +import _ from 'lodash'; | |
4 | +import type { PageParams } from '../../api'; | |
5 | +import { getShopApi } from '@/common/api'; | |
6 | +import useInitial from '@/hooks/useInitail'; | |
7 | +import BrandToSeries from '@/components/Condition/BrandToSeries'; | |
8 | + | |
9 | +interface Props { | |
10 | + innerParams?: any; | |
11 | + setParams: (params: PageParams, refreshing: boolean) => void; | |
12 | +} | |
13 | + | |
14 | +function Filter({ innerParams, setParams }: Props) { | |
15 | + const { data: shops } = useInitial<CommonApi.OptionVO[], undefined>(getShopApi, [], undefined); | |
16 | + | |
17 | + const onChange = _.debounce((newParams) => { | |
18 | + setParams({ ...innerParams, ...newParams }, true); | |
19 | + }, 600); | |
20 | + | |
21 | + return ( | |
22 | + <Row style={{ display: 'flex', flex: 1 }}> | |
23 | + <BrandToSeries | |
24 | + //@ts-ignore | |
25 | + style={{ width: 260 }} | |
26 | + placeholder="筛选品牌车系" | |
27 | + onChange={(v) => onChange({ brandId: v[0], seriesId: v && v.length === 2 ? v[1] : undefined })} | |
28 | + /> | |
29 | + <Select | |
30 | + style={{ width: 260, marginLeft: 20 }} | |
31 | + showSearch | |
32 | + allowClear | |
33 | + placeholder="筛选门店" | |
34 | + options={shops} | |
35 | + fieldNames={{ label: 'name', value: 'id' }} | |
36 | + onChange={(value) => { | |
37 | + onChange({ shopId: value }); | |
38 | + }} | |
39 | + /> | |
40 | + </Row> | |
41 | + ); | |
42 | +} | |
43 | + | |
44 | +export default Filter; | ... | ... |
src/pages/carinsur/LoanClientRequires/components/LoanTypeFormItem.tsx
0 → 100644
1 | +import { Form, InputNumber, Radio } from 'antd'; | |
2 | +import React from 'react'; | |
3 | +import { LoanTypeEnum } from '../../entity'; | |
4 | + | |
5 | +interface Props { | |
6 | + form: any; | |
7 | + name: string; | |
8 | + label: string; | |
9 | +} | |
10 | + | |
11 | +export default function Index({ form, name, label }: Props) { | |
12 | + return ( | |
13 | + <Form.Item label={label} name={[name, 'type']} rules={[{ required: true, message: '请选择' }]}> | |
14 | + <Radio.Group> | |
15 | + <Radio value={LoanTypeEnum.无要求}>无要求</Radio> | |
16 | + <Radio value={LoanTypeEnum.购买即可}>购买即可</Radio> | |
17 | + <Radio value={LoanTypeEnum.保费有要求}> | |
18 | + <div style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}> | |
19 | + <span>保费有要求</span> | |
20 | + <Form.Item | |
21 | + noStyle | |
22 | + shouldUpdate={(prev, curr) => { | |
23 | + if (prev[name] && curr[name] && prev[name].type !== curr[name].type && curr[name].type !== LoanTypeEnum.保费有要求) { | |
24 | + form.setFieldValue([name, 'amount'], undefined); | |
25 | + } | |
26 | + return prev[name] !== curr[name]; | |
27 | + }} | |
28 | + > | |
29 | + {({ getFieldValue }) => { | |
30 | + const type = (getFieldValue(name) ?? {}).type; | |
31 | + if (type !== LoanTypeEnum.保费有要求) return null; | |
32 | + return ( | |
33 | + <Form.Item | |
34 | + style={{ marginBottom: 0, marginLeft: 10 }} | |
35 | + name={[name, 'amount']} | |
36 | + required | |
37 | + rules={[{ required: true, message: '请填写金额' }]} | |
38 | + > | |
39 | + <InputNumber addonBefore="≥" addonAfter="元" style={{ width: 200 }} min={0.01} precision={2} placeholder="请填写金额" /> | |
40 | + </Form.Item> | |
41 | + ); | |
42 | + }} | |
43 | + </Form.Item> | |
44 | + </div> | |
45 | + </Radio> | |
46 | + </Radio.Group> | |
47 | + </Form.Item> | |
48 | + ); | |
49 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/components/SeriesSelectorByAll.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Select, Spin } from 'antd'; | |
3 | +import type { LabelInValueType } from 'rc-select/lib/Select'; | |
4 | +import { getSeriesApi } from '@/common/api'; | |
5 | +import useInitial from '@/hooks/useInitail'; | |
6 | + | |
7 | +interface Props { | |
8 | + brandId: number; // 根据品牌 id 筛选车系 | |
9 | + value?: LabelInValueType[]; | |
10 | + onChange?: (value: LabelInValueType[]) => void; | |
11 | + disabled?: boolean; | |
12 | + disabledTip?: string; | |
13 | + defaultTip?: string; | |
14 | + style?: React.CSSProperties; | |
15 | +} | |
16 | + | |
17 | +export default function Index({ | |
18 | + brandId, | |
19 | + value = [], | |
20 | + onChange, | |
21 | + disabled = false, | |
22 | + disabledTip = '请选择车系', | |
23 | + defaultTip = '请选择车系', | |
24 | + style, | |
25 | +}: Props) { | |
26 | + const [delay, setDelay] = useState(true); | |
27 | + const [allList, setAllList] = useState<any[]>([]); | |
28 | + const { data: list, setParams, loading } = useInitial<CommonApi.OptionVO[], number>(getSeriesApi, [], brandId, delay); | |
29 | + | |
30 | + useEffect(() => { | |
31 | + if (brandId) { | |
32 | + setParams(brandId, true); | |
33 | + setDelay(false); | |
34 | + } | |
35 | + }, [brandId]); | |
36 | + | |
37 | + useEffect(() => { | |
38 | + if (list && list.length > 0) { | |
39 | + // @ts-ignore | |
40 | + const newPostList = [{ id: -1, name: '全部车系' }].concat(list); // 前端手动在列表头部增加一个 {id: -1, name: '全部车系'} 的选项 | |
41 | + setAllList(newPostList); | |
42 | + } else { | |
43 | + setAllList([]); | |
44 | + } | |
45 | + }, [list]); | |
46 | + | |
47 | + return ( | |
48 | + <Spin spinning={loading && !disabled}> | |
49 | + <Select | |
50 | + labelInValue | |
51 | + value={value} | |
52 | + mode="multiple" | |
53 | + onChange={(value) => { | |
54 | + if (value && value.findIndex((i) => i.value === -1) > -1) { | |
55 | + onChange && onChange([{ key: '-1', label: '全部车系', value: -1 }]); | |
56 | + } else { | |
57 | + onChange && onChange(value); | |
58 | + } | |
59 | + }} | |
60 | + style={style || { flex: 1 }} | |
61 | + allowClear | |
62 | + placeholder={disabled ? disabledTip : defaultTip} | |
63 | + showSearch | |
64 | + optionFilterProp="children" | |
65 | + disabled={disabled} | |
66 | + // getPopupContainer={(triggerNode) => triggerNode.parentNode} | |
67 | + > | |
68 | + {allList.map((brand) => ( | |
69 | + <Select.Option key={brand.id} value={brand.id!} disabled={value.findIndex((i) => i.value === -1) > -1 && brand.id !== -1}> | |
70 | + {brand.name} | |
71 | + </Select.Option> | |
72 | + ))} | |
73 | + </Select> | |
74 | + </Spin> | |
75 | + ); | |
76 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/components/ShopSelectorByAll.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Select, Spin } from 'antd'; | |
3 | +import type { LabelInValueType } from 'rc-select/lib/Select'; | |
4 | +import { getShopApi } from '@/common/api'; | |
5 | +import useInitial from '@/hooks/useInitail'; | |
6 | + | |
7 | +interface Props { | |
8 | + value?: LabelInValueType[]; | |
9 | + onChange?: (value: LabelInValueType[]) => void; | |
10 | + disabled?: boolean; | |
11 | + disabledTip?: string; | |
12 | + defaultTip?: string; | |
13 | + style?: React.CSSProperties; | |
14 | +} | |
15 | + | |
16 | +export default function Index({ value = [], onChange, disabled = false, disabledTip = '请选择门店', defaultTip = '请选择门店', style }: Props) { | |
17 | + const [delay, setDelay] = useState(true); | |
18 | + const [allList, setAllList] = useState<any[]>([]); | |
19 | + const { data: list, setParams, loading } = useInitial<CommonApi.OptionVO[], undefined>(getShopApi, [], undefined, delay); | |
20 | + | |
21 | + useEffect(() => { | |
22 | + if (list && list.length > 0) { | |
23 | + // @ts-ignore | |
24 | + const newPostList = [{ id: -1, name: '全部门店' }].concat(list); // 前端手动在列表头部增加一个 {id: -1, name: '全部门店'} 的选项 | |
25 | + setAllList(newPostList); | |
26 | + } else { | |
27 | + setAllList([]); | |
28 | + } | |
29 | + }, [list]); | |
30 | + | |
31 | + useEffect(() => { | |
32 | + setParams(undefined, true); | |
33 | + setDelay(false); | |
34 | + }, []); | |
35 | + | |
36 | + return ( | |
37 | + <Spin spinning={loading && !disabled}> | |
38 | + <Select | |
39 | + labelInValue | |
40 | + value={value} | |
41 | + mode="multiple" | |
42 | + onChange={(value) => { | |
43 | + if (value && value.findIndex((i) => i.value === -1) > -1) { | |
44 | + onChange && onChange([{ key: '-1', label: '全部门店', value: -1 }]); | |
45 | + } else { | |
46 | + onChange && onChange(value); | |
47 | + } | |
48 | + }} | |
49 | + style={style || { flex: 1 }} | |
50 | + allowClear | |
51 | + placeholder={disabled ? disabledTip : defaultTip} | |
52 | + showSearch | |
53 | + optionFilterProp="children" | |
54 | + disabled={disabled} | |
55 | + // getPopupContainer={(triggerNode) => triggerNode.parentNode} | |
56 | + > | |
57 | + {allList.map((brand) => ( | |
58 | + <Select.Option key={brand.id} value={brand.id!} disabled={value.findIndex((i) => i.value === -1) > -1 && brand.id !== -1}> | |
59 | + {brand.name} | |
60 | + </Select.Option> | |
61 | + ))} | |
62 | + </Select> | |
63 | + </Spin> | |
64 | + ); | |
65 | +} | ... | ... |
src/pages/carinsur/LoanClientRequires/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { Button, Card, ConfigProvider, Divider, message, Popconfirm, Row, Table } from 'antd'; | |
3 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
4 | +import zhCN from 'antd/lib/locale-provider/zh_CN'; | |
5 | +import usePagination from '@/hooks/usePagination'; | |
6 | +import { PlusOutlined } from '@ant-design/icons'; | |
7 | +import AddModal from './components/AddModal'; | |
8 | +import Filter from './components/Filter'; | |
9 | +import * as API from './api'; | |
10 | +import _ from 'lodash'; | |
11 | +import TextWithMore from '@/components/TextWithMore'; | |
12 | +import { LoanTypeEnum } from '../entity'; | |
13 | +import BrandSeriesModal from './components/BrandSeriesModal'; | |
14 | + | |
15 | +const { Column } = Table; | |
16 | + | |
17 | +export default function Index() { | |
18 | + // 新增 | 编辑 | |
19 | + const [addModal, setAddModal] = useState<{ | |
20 | + visible: boolean; | |
21 | + row?: API.Item; | |
22 | + }>({ | |
23 | + visible: false, | |
24 | + }); | |
25 | + // 查看部分品牌车系 | |
26 | + const [brandSeriesModal, setBrandSeriesModal] = useState<{ | |
27 | + visible: boolean; | |
28 | + brandSeries?: API.brandSeriesItem[]; | |
29 | + }>({ | |
30 | + visible: false, | |
31 | + brandSeries: [], | |
32 | + }); | |
33 | + | |
34 | + const { list, paginationConfig, loading, innerParams, setParams } = usePagination<API.Item>(API.getLCRPage); | |
35 | + | |
36 | + const handleDelete = (row: API.Item) => { | |
37 | + const { id } = row; | |
38 | + API.delLCR(id!) | |
39 | + .then((res) => { | |
40 | + message.success(res.result); | |
41 | + setParams({ ...innerParams }, true); | |
42 | + }) | |
43 | + .catch((e) => { | |
44 | + message.error(e.message); | |
45 | + }); | |
46 | + }; | |
47 | + | |
48 | + const handleEdit = (row: API.Item) => { | |
49 | + setAddModal({ | |
50 | + visible: true, | |
51 | + row, | |
52 | + }); | |
53 | + }; | |
54 | + | |
55 | + const renderLoanTypeEle = (value: API.LoanType) => { | |
56 | + return value ? (value.type !== LoanTypeEnum.保费有要求 ? LoanTypeEnum[value.type] : `保费 ≥ ${value.amount}元`) : '--'; | |
57 | + }; | |
58 | + | |
59 | + return ( | |
60 | + <PageHeaderWrapper title="贷款期客户保险要求"> | |
61 | + <ConfigProvider locale={zhCN}> | |
62 | + <Card> | |
63 | + <Row align="middle" justify="space-between" style={{ marginBottom: 20 }}> | |
64 | + <Filter innerParams={innerParams} setParams={setParams} /> | |
65 | + <Button | |
66 | + type="primary" | |
67 | + icon={<PlusOutlined />} | |
68 | + onClick={() => { | |
69 | + setAddModal({ | |
70 | + visible: true, | |
71 | + }); | |
72 | + }} | |
73 | + > | |
74 | + 新增 | |
75 | + </Button> | |
76 | + </Row> | |
77 | + <Table | |
78 | + loading={loading} | |
79 | + dataSource={list} | |
80 | + pagination={paginationConfig} | |
81 | + scroll={{ y: 800 }} | |
82 | + rowKey="id" | |
83 | + onChange={(_pagination) => setParams({ ..._pagination }, true)} | |
84 | + > | |
85 | + <Column | |
86 | + title="适用品牌车系" | |
87 | + dataIndex="allBrandSeries" | |
88 | + render={(value, row: API.Item) => | |
89 | + value ? ( | |
90 | + '全部品牌全部车系' | |
91 | + ) : ( | |
92 | + <a | |
93 | + onClick={(e) => { | |
94 | + e.preventDefault(); | |
95 | + setBrandSeriesModal({ visible: true, brandSeries: row.brandSeries }); | |
96 | + }} | |
97 | + > | |
98 | + 查看 | |
99 | + </a> | |
100 | + ) | |
101 | + } | |
102 | + /> | |
103 | + <Column | |
104 | + title="适用门店" | |
105 | + dataIndex="useShopIds" | |
106 | + render={(value) => <TextWithMore title="适用门店" dataIndex="shopName" list={value} unit="个门店" />} | |
107 | + /> | |
108 | + <Column title="新保交强险" dataIndex="newTci" render={renderLoanTypeEle} /> | |
109 | + <Column title="新保商业险" dataIndex="newVci" render={renderLoanTypeEle} /> | |
110 | + <Column title="新保驾意险" dataIndex="newTai" render={renderLoanTypeEle} /> | |
111 | + <Column title="续保交强险" dataIndex="reNewTci" render={renderLoanTypeEle} /> | |
112 | + <Column title="续保商业险" dataIndex="reNewVci" render={renderLoanTypeEle} /> | |
113 | + <Column title="续保驾意险" dataIndex="reNewTai" render={renderLoanTypeEle} /> | |
114 | + <Column | |
115 | + title="操作" | |
116 | + dataIndex="btns" | |
117 | + render={(text, row: API.Item) => ( | |
118 | + <span> | |
119 | + <a | |
120 | + onClick={(e) => { | |
121 | + e.preventDefault(); | |
122 | + handleEdit(row); | |
123 | + }} | |
124 | + > | |
125 | + 编辑 | |
126 | + </a> | |
127 | + <Divider type="vertical" /> | |
128 | + <Popconfirm title="是否删除?" onConfirm={() => handleDelete(row)}> | |
129 | + <a | |
130 | + onClick={(e) => { | |
131 | + e.preventDefault(); | |
132 | + }} | |
133 | + style={{ color: 'red' }} | |
134 | + > | |
135 | + 删除 | |
136 | + </a> | |
137 | + </Popconfirm> | |
138 | + </span> | |
139 | + )} | |
140 | + /> | |
141 | + </Table> | |
142 | + </Card> | |
143 | + <AddModal | |
144 | + visible={addModal.visible} | |
145 | + row={addModal.row} | |
146 | + onCancel={() => { | |
147 | + setAddModal({ visible: false }); | |
148 | + }} | |
149 | + onRefresh={() => setParams({ ...innerParams }, true)} | |
150 | + /> | |
151 | + <BrandSeriesModal | |
152 | + brandSeriesModal={brandSeriesModal} | |
153 | + onCancel={() => { | |
154 | + setBrandSeriesModal({ visible: false }); | |
155 | + }} | |
156 | + /> | |
157 | + </ConfigProvider> | |
158 | + </PageHeaderWrapper> | |
159 | + ); | |
160 | +} | ... | ... |
src/pages/carinsur/entity.ts
0 → 100644
src/pages/contract/ExpressLogisticsArticleSetting/components/UserAddModal.tsx
... | ... | @@ -40,7 +40,7 @@ export default function UserAddModal({ visible, value, onCancel, onChange }: Pro |
40 | 40 | name="userName" |
41 | 41 | rules={[ |
42 | 42 | { required: true, message: '请填写姓名' }, |
43 | - { max: 20, message: '输入长度应该小于20' }, | |
43 | + { max: 32, message: '输入长度应该小于32' }, | |
44 | 44 | { whitespace: true, message: '不能输入空白字符' }, |
45 | 45 | ]} |
46 | 46 | > |
... | ... | @@ -55,7 +55,7 @@ export default function UserAddModal({ visible, value, onCancel, onChange }: Pro |
55 | 55 | pattern: /^((\+86)|(86))?(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/, |
56 | 56 | message: '请输入有效的电话号码', |
57 | 57 | }, |
58 | - { max: 20, message: '输入长度应该小于20' }, | |
58 | + { max: 16, message: '输入长度应该小于16' }, | |
59 | 59 | { whitespace: true, message: '不能输入空白字符' }, |
60 | 60 | ]} |
61 | 61 | > | ... | ... |
src/pages/contract/FoodWhiteList/api.ts
0 → 100644
1 | +import type { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { OA_HOST } from '@/utils/host'; | |
4 | +import type { Pagination } from '@/typing/common'; | |
5 | + | |
6 | +export interface Item { | |
7 | + id?: number; | |
8 | + name: string; | |
9 | + mobile: string; | |
10 | + remark: string; | |
11 | +} | |
12 | + | |
13 | +export interface PageParams extends Pagination { | |
14 | + name?: string; | |
15 | + mobile?: string; | |
16 | + remark?: string; | |
17 | +} | |
18 | + | |
19 | +/** | |
20 | + * 分页查询 | |
21 | + */ | |
22 | +export function getFoodWhitePage(params?: PageParams): http.PromisePageResp<Item> { | |
23 | + return request.get(`${OA_HOST}/contract/erp/repast/white/page`, { params }); | |
24 | +} | |
25 | + | |
26 | +/** | |
27 | + * 新增/编辑 | |
28 | + */ | |
29 | +export function addFoodWhite(data?: Item): http.PromiseResp<void> { | |
30 | + return request.post(`${OA_HOST}/contract/erp/repast/white/save`, data); | |
31 | +} | |
32 | + | |
33 | +/** | |
34 | + * 删除 | |
35 | + */ | |
36 | +export function delFoodWhite(id: number): http.PromisePageResp<void> { | |
37 | + return request.post(`${OA_HOST}/contract/erp/repast/white/delete`, { id }); | |
38 | +} | ... | ... |
src/pages/contract/FoodWhiteList/components/AddModal/index.tsx
0 → 100644
1 | +import React, { useEffect, memo } from 'react'; | |
2 | +import { Modal, Form, message, Input } from 'antd'; | |
3 | +import * as API from '../../api'; | |
4 | +import { useRequest } from 'umi'; | |
5 | + | |
6 | +interface Props { | |
7 | + visible: boolean; | |
8 | + row?: API.Item; | |
9 | + onCancel: () => void; | |
10 | + onRefresh: () => void; | |
11 | +} | |
12 | + | |
13 | +function AddModal({ visible, row, onCancel, onRefresh }: Props) { | |
14 | + const { id } = row ?? {}; | |
15 | + const [form] = Form.useForm(); | |
16 | + | |
17 | + const saveHook = useRequest(API.addFoodWhite, { | |
18 | + manual: true, | |
19 | + throwOnError: true, | |
20 | + }); | |
21 | + | |
22 | + useEffect(() => { | |
23 | + if (visible) { | |
24 | + if (row) { | |
25 | + form.setFieldsValue(row); | |
26 | + } | |
27 | + } else { | |
28 | + form.resetFields(); | |
29 | + } | |
30 | + }, [visible, row]); | |
31 | + | |
32 | + const handleSave = (feildValue: any) => { | |
33 | + saveHook | |
34 | + .run(feildValue) | |
35 | + .then(() => { | |
36 | + message.success('操作成功'); | |
37 | + onCancel(); | |
38 | + onRefresh(); | |
39 | + }) | |
40 | + .catch((e) => { | |
41 | + message.error(e.message); | |
42 | + }); | |
43 | + }; | |
44 | + | |
45 | + return ( | |
46 | + <Modal title={`${id ? '编辑' : '新增'}`} open={visible} confirmLoading={saveHook.loading} onCancel={onCancel} onOk={form.submit} width={600}> | |
47 | + <Form form={form} onFinish={handleSave} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }}> | |
48 | + <Form.Item name="id" hidden /> | |
49 | + <Form.Item | |
50 | + label="姓名" | |
51 | + name="name" | |
52 | + rules={[ | |
53 | + { required: true, message: '请填写姓名' }, | |
54 | + { max: 32, message: '输入长度应该小于32' }, | |
55 | + { whitespace: true, message: '不能输入空白字符' }, | |
56 | + ]} | |
57 | + > | |
58 | + <Input placeholder="请填写" /> | |
59 | + </Form.Item> | |
60 | + <Form.Item | |
61 | + label="手机号" | |
62 | + name="mobile" | |
63 | + rules={[ | |
64 | + { required: true, message: '请填写联系电话' }, | |
65 | + { | |
66 | + pattern: /^((\+86)|(86))?(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/, | |
67 | + message: '请输入有效的电话号码', | |
68 | + }, | |
69 | + { max: 16, message: '输入长度应该小于16' }, | |
70 | + { whitespace: true, message: '不能输入空白字符' }, | |
71 | + ]} | |
72 | + > | |
73 | + <Input placeholder="请填写" /> | |
74 | + </Form.Item> | |
75 | + <Form.Item label="备注" name="remark" rules={[{ required: true, message: '请填写' }]}> | |
76 | + <Input.TextArea placeholder="请填写" maxLength={64} /> | |
77 | + </Form.Item> | |
78 | + </Form> | |
79 | + </Modal> | |
80 | + ); | |
81 | +} | |
82 | + | |
83 | +export default memo(AddModal); | ... | ... |
src/pages/contract/FoodWhiteList/components/Filter/index.tsx
0 → 100644
1 | +import React from 'react'; | |
2 | +import { Input, Row } from 'antd'; | |
3 | +import _ from 'lodash'; | |
4 | +import type { PageParams } from '../../api'; | |
5 | + | |
6 | +interface Props { | |
7 | + innerParams?: any; | |
8 | + setParams: (params: PageParams, refreshing: boolean) => void; | |
9 | +} | |
10 | + | |
11 | +function Filter({ innerParams, setParams }: Props) { | |
12 | + const onChange = _.debounce((newParams) => { | |
13 | + setParams({ ...innerParams, ...newParams }, true); | |
14 | + }, 600); | |
15 | + | |
16 | + return ( | |
17 | + <Row style={{ display: 'flex', flex: 1 }}> | |
18 | + <Input | |
19 | + style={{ width: 200 }} | |
20 | + allowClear | |
21 | + placeholder="搜索姓名" | |
22 | + onChange={(e) => { | |
23 | + onChange({ name: e.target.value }); | |
24 | + }} | |
25 | + /> | |
26 | + <Input | |
27 | + style={{ width: 200, marginLeft: 20 }} | |
28 | + allowClear | |
29 | + placeholder="搜索手机号" | |
30 | + onChange={(e) => { | |
31 | + onChange({ mobile: e.target.value }); | |
32 | + }} | |
33 | + /> | |
34 | + </Row> | |
35 | + ); | |
36 | +} | |
37 | + | |
38 | +export default Filter; | ... | ... |
src/pages/contract/FoodWhiteList/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { Button, Card, ConfigProvider, Divider, message, Popconfirm, Row, Table } from 'antd'; | |
3 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
4 | +import zhCN from 'antd/lib/locale-provider/zh_CN'; | |
5 | +import usePagination from '@/hooks/usePagination'; | |
6 | +import { PlusOutlined } from '@ant-design/icons'; | |
7 | +import AddModal from './components/AddModal'; | |
8 | +import Filter from './components/Filter'; | |
9 | +import * as API from './api'; | |
10 | +import _ from 'lodash'; | |
11 | + | |
12 | +const { Column } = Table; | |
13 | + | |
14 | +export default function Index() { | |
15 | + // 新增 | 编辑 | |
16 | + const [addModal, setAddModal] = useState<{ | |
17 | + visible: boolean; | |
18 | + row?: API.Item; | |
19 | + }>({ | |
20 | + visible: false, | |
21 | + }); | |
22 | + | |
23 | + const { list, paginationConfig, loading, innerParams, setParams } = usePagination<API.Item>(API.getFoodWhitePage); | |
24 | + | |
25 | + const handleDelete = (row: API.Item) => { | |
26 | + const { id } = row; | |
27 | + API.delFoodWhite(id!) | |
28 | + .then((res) => { | |
29 | + message.success(res.result); | |
30 | + setParams({ ...innerParams }, true); | |
31 | + }) | |
32 | + .catch((e) => { | |
33 | + message.error(e.message); | |
34 | + }); | |
35 | + }; | |
36 | + | |
37 | + const handleEdit = (row: API.Item) => { | |
38 | + setAddModal({ | |
39 | + visible: true, | |
40 | + row, | |
41 | + }); | |
42 | + }; | |
43 | + | |
44 | + return ( | |
45 | + <PageHeaderWrapper title="就餐白名单"> | |
46 | + <ConfigProvider locale={zhCN}> | |
47 | + <Card> | |
48 | + <Row align="middle" justify="space-between" style={{ marginBottom: 20 }}> | |
49 | + <Filter innerParams={innerParams} setParams={setParams} /> | |
50 | + <Button | |
51 | + type="primary" | |
52 | + icon={<PlusOutlined />} | |
53 | + onClick={() => { | |
54 | + setAddModal({ | |
55 | + visible: true, | |
56 | + }); | |
57 | + }} | |
58 | + > | |
59 | + 新增 | |
60 | + </Button> | |
61 | + </Row> | |
62 | + <Table | |
63 | + loading={loading} | |
64 | + dataSource={list} | |
65 | + pagination={paginationConfig} | |
66 | + rowKey="id" | |
67 | + onChange={(_pagination) => setParams({ ..._pagination }, true)} | |
68 | + > | |
69 | + <Column title="姓名" dataIndex="name" /> | |
70 | + <Column title="手机号" dataIndex="mobile" /> | |
71 | + <Column title="备注" dataIndex="remark" /> | |
72 | + <Column | |
73 | + title="操作" | |
74 | + dataIndex="btns" | |
75 | + render={(text, row: API.Item) => ( | |
76 | + <span> | |
77 | + <a | |
78 | + onClick={(e) => { | |
79 | + e.preventDefault(); | |
80 | + handleEdit(row); | |
81 | + }} | |
82 | + > | |
83 | + 编辑 | |
84 | + </a> | |
85 | + <Divider type="vertical" /> | |
86 | + <Popconfirm title="是否删除?" onConfirm={() => handleDelete(row)}> | |
87 | + <a | |
88 | + onClick={(e) => { | |
89 | + e.preventDefault(); | |
90 | + }} | |
91 | + style={{ color: 'red' }} | |
92 | + > | |
93 | + 删除 | |
94 | + </a> | |
95 | + </Popconfirm> | |
96 | + </span> | |
97 | + )} | |
98 | + /> | |
99 | + </Table> | |
100 | + </Card> | |
101 | + <AddModal | |
102 | + visible={addModal.visible} | |
103 | + row={addModal.row} | |
104 | + onCancel={() => { | |
105 | + setAddModal({ visible: false }); | |
106 | + }} | |
107 | + onRefresh={() => setParams({ ...innerParams }, true)} | |
108 | + /> | |
109 | + </ConfigProvider> | |
110 | + </PageHeaderWrapper> | |
111 | + ); | |
112 | +} | ... | ... |
src/pages/decoration/deco/DecorationPromotion/DecorateFullFree/components/Modal.tsx
... | ... | @@ -8,7 +8,7 @@ import ShopDetail from './ShopDetail'; |
8 | 8 | import AddBrand from './AddBrand'; |
9 | 9 | import AddSerie from './AddSerie'; |
10 | 10 | import AddSpec from './AddSpec'; |
11 | -import ShopSelect from '@/components/ShopSelectNew'; | |
11 | +import ShopSelect from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew'; | |
12 | 12 | |
13 | 13 | const FormItem = Form.Item; |
14 | 14 | const { RangePicker } = DatePicker; |
... | ... | @@ -316,7 +316,7 @@ export default function AddModal(props: Props) { |
316 | 316 | 元(包含) 送 |
317 | 317 | <InputNumber defaultValue={item.expect} onChange={(value) => _changeTwo(value, index)} min={0} /> |
318 | 318 | 元 |
319 | - <DeleteOutlined onClick={() => deleteItem(index)} style={{ color: 'red', fontSize: 16 }} /> | |
319 | + <DeleteOutlined rev={undefined} onClick={() => deleteItem(index)} style={{ color: 'red', fontSize: 16 }} /> | |
320 | 320 | </div> |
321 | 321 | ))} |
322 | 322 | <Button type="primary" style={{ marginTop: 20 }} onClick={addList}> |
... | ... | @@ -328,7 +328,7 @@ export default function AddModal(props: Props) { |
328 | 328 | <RangePicker format="YYYY-MM-DD" disabledDate={(current) => disalbeTime(current)} /> |
329 | 329 | </Form.Item> |
330 | 330 | <FormItem label="适用门店" name="applyShops" rules={[{ required: true, message: '请选择门店' }]}> |
331 | - <ShopSelect multiple /> | |
331 | + <ShopSelect /> | |
332 | 332 | </FormItem> |
333 | 333 | <FormItem name="decos" label="必选装潢"> |
334 | 334 | <Tabs type="card"> | ... | ... |
src/pages/decoration/deco/DecorationPromotion/DecorationPackage/components/Modal.tsx
1 | 1 | import React, { useEffect, useState } from 'react'; |
2 | -import { Modal, Form, Input, DatePicker, Select, InputNumber, Button, message } from 'antd'; | |
2 | +import { Modal, Form, Input, DatePicker, InputNumber, Button, message } from 'antd'; | |
3 | 3 | import { DeleteOutlined } from '@ant-design/icons'; |
4 | 4 | import moment from 'moment'; |
5 | 5 | import { useStore } from '../index'; |
6 | -import { getShopApi } from "@/common/api"; | |
7 | -import useInitial from '@/hooks/useInitail'; | |
8 | 6 | import * as API from '../api'; |
9 | -import ShopSelect from "@/components/ShopSelectNew"; | |
7 | +import ShopSelect from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew'; | |
10 | 8 | |
11 | 9 | const FormItem = Form.Item; |
12 | -const { Option } = Select; | |
13 | 10 | const { RangePicker } = DatePicker; |
14 | 11 | |
15 | 12 | interface Props { |
16 | - setLoading: (value:any) => any | |
13 | + setLoading: (value: any) => any | |
17 | 14 | } |
18 | 15 | |
19 | -export default function AddModal(props:Props) { | |
16 | +export default function AddModal(props: Props) { | |
20 | 17 | const {setLoading} = props; |
21 | - const { data: shopData } = useInitial(getShopApi, [], {}); | |
22 | 18 | const [form] = Form.useForm(); |
23 | - const { visible, setVisible, confirLoading, current = {} } = useStore(); | |
19 | + const { visible, setVisible, confirLoading } = useStore(); | |
24 | 20 | const [discountList, setDiscountList] = useState<any>([]); |
25 | 21 | |
26 | 22 | useEffect(() => { |
... | ... | @@ -122,6 +118,7 @@ export default function AddModal(props:Props) { |
122 | 118 | /> |
123 | 119 | 元 |
124 | 120 | <DeleteOutlined |
121 | + rev={undefined} | |
125 | 122 | onClick={() => deleteItem(index)} |
126 | 123 | style={{ color: "red", fontSize: 16 }} |
127 | 124 | /> |
... | ... | @@ -137,7 +134,7 @@ export default function AddModal(props:Props) { |
137 | 134 | name="applyShops" |
138 | 135 | rules={[{ required: true, message: "请选择门店" }]} |
139 | 136 | > |
140 | - <ShopSelect multiple /> | |
137 | + <ShopSelect /> | |
141 | 138 | </FormItem> |
142 | 139 | </Form> |
143 | 140 | </Modal> | ... | ... |
src/pages/decoration/deco/DecorationPromotion/SPPManage/subPage/AddPage.tsx
1 | 1 | import React, { useState } from 'react'; |
2 | -import { Button, DatePicker, Input, Select, Card, Form, message} from 'antd'; | |
2 | +import { Button, DatePicker, Input, Card, Form, message} from 'antd'; | |
3 | 3 | import moment from 'moment'; |
4 | -import {getShopApi} from '@/common/api'; | |
5 | -import useInitial from '@/hooks/useInitail'; | |
6 | 4 | import ShopDetail from './ShopDetail'; |
7 | 5 | import * as API from '../api'; |
8 | 6 | import { useStore } from "../index"; |
9 | -import ShopSelect from "@/components/ShopSelectNew"; | |
7 | +import ShopSelect from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew'; | |
10 | 8 | |
11 | 9 | const { RangePicker } = DatePicker; |
12 | -const { Option } = Select; | |
13 | - | |
14 | 10 | const FormItem = Form.Item; |
15 | 11 | |
16 | 12 | interface Props { |
... | ... | @@ -19,13 +15,11 @@ interface Props { |
19 | 15 | |
20 | 16 | export default function AddPage({onReturn}: Props) { |
21 | 17 | const { setCurrentBreadcrumb} = useStore(); |
22 | - const {data: shopData} = useInitial(getShopApi, [], {}); | |
23 | 18 | const [specData, setSpecData] = useState<any>([]); |
24 | - | |
25 | 19 | const [form] = Form.useForm(); |
26 | 20 | |
27 | - const onFinish = (value:any) => { | |
28 | - specData.map((res:any) => { | |
21 | + const onFinish = (value: any) => { | |
22 | + specData.map((res: any) => { | |
29 | 23 | res.goodsId = res.id; |
30 | 24 | return res; |
31 | 25 | }); |
... | ... | @@ -47,7 +41,7 @@ export default function AddPage({onReturn}: Props) { |
47 | 41 | }); |
48 | 42 | }; |
49 | 43 | |
50 | - const disalbeTime = (current:any) => { | |
44 | + const disalbeTime = (current: any) => { | |
51 | 45 | return current && current <moment().subtract(1, "days"); //当天之前的不可选,不包括当天 |
52 | 46 | //return current && current < moment().endOf(‘day');当天之前的不可选,包括当天 |
53 | 47 | }; |
... | ... | @@ -82,22 +76,7 @@ export default function AddPage({onReturn}: Props) { |
82 | 76 | name="applyShops" |
83 | 77 | rules={[{ required: true, message: "请选择门店" }]} |
84 | 78 | > |
85 | - <ShopSelect multiple /> | |
86 | - {/* <Select | |
87 | - optionFilterProp="children" | |
88 | - mode="multiple" | |
89 | - labelInValue | |
90 | - allowClear | |
91 | - style={{ width: 300 }} | |
92 | - placeholder="请选择门店" | |
93 | - > | |
94 | - {shopData && | |
95 | - shopData.map((shop: any) => ( | |
96 | - <Option value={shop.id} key={shop.id}> | |
97 | - {shop.name} | |
98 | - </Option> | |
99 | - ))} | |
100 | - </Select> */} | |
79 | + <ShopSelect /> | |
101 | 80 | </FormItem> |
102 | 81 | <FormItem name="goods" label="装潢促销"> |
103 | 82 | <ShopDetail | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/components/AddShop.tsx
1 | -import React, { useEffect, useState } from "react"; | |
2 | -import { | |
3 | - Modal, | |
4 | - Form, | |
5 | - Input, | |
6 | - DatePicker, | |
7 | - Select, | |
8 | - InputNumber, | |
9 | - Button, | |
10 | - message, | |
11 | -} from "antd"; | |
12 | -import { DeleteOutlined } from "@ant-design/icons"; | |
13 | -import moment from "moment"; | |
14 | -import { useStore } from "../index"; | |
15 | -import { getShopApi } from "@/common/api"; | |
1 | +import React, { useEffect } from "react"; | |
2 | +import { Modal, Form, message } from "antd"; | |
16 | 3 | import useInitial from "@/hooks/useInitail"; |
17 | 4 | import * as API from "../api"; |
18 | -import ShopSelect from "@/components/ShopSelectNew"; | |
5 | +import SelectorWithFull from '@/components/SelectorWithFull'; | |
6 | +import { getShops } from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew/api'; | |
19 | 7 | |
20 | 8 | const FormItem = Form.Item; |
21 | 9 | |
... | ... | @@ -29,7 +17,7 @@ export default function AddModal(props: Props) { |
29 | 17 | const { current, setCurrent, setLoading } = props; |
30 | 18 | const [form] = Form.useForm(); |
31 | 19 | |
32 | - const {data: afterList} = useInitial(getShopApi, [], {}) | |
20 | + const { data } = useInitial(getShops, [], {}) | |
33 | 21 | |
34 | 22 | useEffect(() => { |
35 | 23 | form.resetFields(); |
... | ... | @@ -39,11 +27,11 @@ export default function AddModal(props: Props) { |
39 | 27 | const _list = (value.applyShops || []).map((e: any) => { |
40 | 28 | return { |
41 | 29 | goodsId: current.goodsId, |
42 | - shopId: e.shopId | |
30 | + shopId: e.value | |
43 | 31 | } |
44 | 32 | }) |
45 | 33 | API.upListApi({goods: _list }) |
46 | - .then((res) => { | |
34 | + .then(() => { | |
47 | 35 | setCurrent({ visible: false, goodsId: undefined }); |
48 | 36 | setLoading(true); |
49 | 37 | }) |
... | ... | @@ -52,18 +40,26 @@ export default function AddModal(props: Props) { |
52 | 40 | |
53 | 41 | return ( |
54 | 42 | <Modal |
55 | - visible={current.visible} | |
43 | + open={current.visible} | |
56 | 44 | onCancel={() => setCurrent({visible: false, goosId: undefined})} |
57 | 45 | width={800} |
58 | 46 | onOk={() => form.submit()} |
59 | 47 | > |
60 | - <Form form={form} onFinish={handleSave}> | |
48 | + <Form form={form} onFinish={handleSave} labelCol={{span: 3}} wrapperCol={{span: 18}}> | |
61 | 49 | <FormItem |
62 | 50 | label="适用门店" |
63 | 51 | name="applyShops" |
64 | 52 | rules={[{ required: true, message: "请选择门店" }]} |
65 | 53 | > |
66 | - <ShopSelect multiple style={{width: 500}} type={2} shopIds={afterList.map(e => e.id)} /> | |
54 | + <SelectorWithFull | |
55 | + treeNodeFilterProp="label" | |
56 | + labelInValue | |
57 | + data={data} | |
58 | + multiple | |
59 | + allowClear | |
60 | + autoClearSearchValue={false} | |
61 | + placeholder="请选择门店或输入关键词筛选" | |
62 | + /> | |
67 | 63 | </FormItem> |
68 | 64 | </Form> |
69 | 65 | </Modal> | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew/api.ts
0 → 100644
1 | +import type { http } from "@/typing/http"; | |
2 | +import request from "@/utils/request"; | |
3 | +import { DECORATION } from "@/utils/host"; | |
4 | + | |
5 | +export interface Shop { | |
6 | + value: number; | |
7 | + label: string; | |
8 | +} | |
9 | +export function getShops(): http.PromiseResp<Shop[]> { | |
10 | + return request.get(`${DECORATION}/deco/common/get/group/deco/shops`) | |
11 | +} | |
0 | 12 | \ No newline at end of file | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew/index.tsx
0 → 100644
1 | +import useInitial from '@/hooks/useInitail'; | |
2 | +import React from 'react'; | |
3 | +import type { Shop } from './api'; | |
4 | +import { getShops } from './api'; | |
5 | +import SelectorWithFull from '@/components/SelectorWithFull'; | |
6 | +import st from './style.less' | |
7 | + | |
8 | +interface Props { | |
9 | + value?: Shop[] | |
10 | + onChange?: (v: Shop[]) => void | |
11 | +} | |
12 | + | |
13 | +export default function ShopSelect(props: Props) { | |
14 | + const { value, onChange } = props; | |
15 | + const { data } = useInitial(getShops, [], {}) | |
16 | + return ( | |
17 | + <SelectorWithFull | |
18 | + treeNodeFilterProp="label" | |
19 | + value={value} | |
20 | + onChange={onChange} | |
21 | + labelInValue | |
22 | + data={data} | |
23 | + multiple | |
24 | + allowClear | |
25 | + autoClearSearchValue={false} | |
26 | + placeholder="请选择门店或输入关键词筛选" | |
27 | + className={st.select_deco} | |
28 | + /> | |
29 | + ) | |
30 | +} | |
0 | 31 | \ No newline at end of file | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew/style.less
0 → 100644
src/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/components/DecoContent/index.tsx
1 | 1 | import { Button, Checkbox, Popconfirm, Cascader, Divider, Input, message, Radio, Row, Spin, Table } from 'antd'; |
2 | -import { CheckboxChangeEvent } from 'antd/lib/checkbox'; | |
2 | +import type { CheckboxChangeEvent } from 'antd/lib/checkbox'; | |
3 | 3 | import React from 'react'; |
4 | 4 | import { useStore } from '../../index'; |
5 | -import { WorkItem, getSeriesApi, getSpecApi } from '../../../../api'; | |
5 | +import type { WorkItem} from '../../../../api'; | |
6 | +import { getSeriesApi, getSpecApi } from '../../../../api'; | |
6 | 7 | import ShopModal from '../../../../../common/Shop'; |
7 | 8 | |
8 | 9 | const { Search } = Input; |
... | ... | @@ -14,14 +15,13 @@ interface Props { |
14 | 15 | |
15 | 16 | type TableType = '列表' | '选择'; |
16 | 17 | |
17 | -function Deco({ type = 1, multiple = true }: Props) { | |
18 | +function Deco({ multiple = true }: Props) { | |
18 | 19 | const { |
19 | 20 | list, |
20 | 21 | setParams, |
21 | 22 | decoSelected: selected, |
22 | 23 | setDecoSelected: setSelected, |
23 | 24 | loading, |
24 | - paginationConfig, | |
25 | 25 | brandOptions, |
26 | 26 | setBrandOptions, |
27 | 27 | } = useStore(); |
... | ... | @@ -55,7 +55,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
55 | 55 | setParams({ keywords: e }, true); |
56 | 56 | } |
57 | 57 | |
58 | - function filterBySeries(value: any[], selectedOptions: any) { | |
58 | + function filterBySeries(value: any[]) { | |
59 | 59 | if (value.length > 0) { |
60 | 60 | const seriesFilter = { |
61 | 61 | brandId: value[0], |
... | ... | @@ -87,7 +87,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
87 | 87 | getSeriesApi(targetOption.id) |
88 | 88 | .then((res: any) => { |
89 | 89 | const { data = [] } = res; |
90 | - targetOption.children = data.map((list: any, index: any) => ({ | |
90 | + targetOption.children = data.map((list: any) => ({ | |
91 | 91 | id: list.id, |
92 | 92 | name: list.name, |
93 | 93 | isLeaf: false, |
... | ... | @@ -104,7 +104,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
104 | 104 | const { data = [] } = res; |
105 | 105 | targetOption.loading = false; |
106 | 106 | targetOption.children = []; |
107 | - data.forEach((list, index) => { | |
107 | + data.forEach((list) => { | |
108 | 108 | targetOption.children.push({ |
109 | 109 | id: list.id, |
110 | 110 | name: list.name, |
... | ... | @@ -215,7 +215,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
215 | 215 | 当前选择({selected.length} 个) |
216 | 216 | </Radio.Button> |
217 | 217 | </Radio.Group> |
218 | - <Row> | |
218 | + <Row align="middle"> | |
219 | 219 | {multiple ? ( |
220 | 220 | <Checkbox className="ShopSelectNew_checkbox" indeterminate={checkInfo.indeterminate} checked={checkInfo.checkAll} onChange={checkAll}> |
221 | 221 | 全选 | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/components/ShopContent/api.ts deleted
1 | -/* | |
2 | - * @Date: 2021-07-08 16:53:36 | |
3 | - * @LastEditors: wangqiang@feewee.cn | |
4 | - * @LastEditTime: 2022-05-25 11:32:53 | |
5 | - */ | |
6 | -import type { http } from "@/typing/http"; | |
7 | -import request from "@/utils/request"; | |
8 | -import { OOP_HOST } from "@/utils/host"; | |
9 | -import type { LabelValueType } from "rc-tree-select/lib/interface"; | |
10 | - | |
11 | -export interface QueryParams { | |
12 | - type: 1 | 2; // 1 集团维度 2 自定义门店维度 | |
13 | - shops?: string; // 门店集合 ,分割 | |
14 | - keywords?: string; // 门店关键字搜索 | |
15 | - bizTypes?: string; // 业态类型集合 ,分割 | |
16 | - brands?: string; // 品牌id集合 ,分割 | |
17 | - regions?: string; // 区域编码集合 ,分割 | |
18 | - dealers?: string; // 商家id集合 ,分割 | |
19 | -} | |
20 | - | |
21 | -export interface ShopItem { | |
22 | - shopId: number; //门店id | |
23 | - shopFullName?: string; //门店全称 | |
24 | - shopShortName?: string; //门店简称 | |
25 | - casShopId?: number; //对应售后门店id(只有售前业态门店有) | |
26 | - casShopName?: string; //对应售后门店名称 | |
27 | - bizType?: number; //业态类型 | |
28 | - region?: Region; | |
29 | - dealer?: DealerOrBrand; | |
30 | - brandList?: DealerOrBrand[]; //只有售前业态门店有 | |
31 | -} | |
32 | -export interface Value extends ShopItem, LabelValueType {} | |
33 | - | |
34 | -export enum BizType { | |
35 | - "新车销售" = 1, | |
36 | - "售后", | |
37 | - "二手车", | |
38 | - "租车", | |
39 | - "交付中心" | |
40 | -} | |
41 | - | |
42 | -export interface Region { | |
43 | - bh?: string; // 区域编码 | |
44 | - name?: string; // 区域名称 | |
45 | - fullName?: string; // 区域全称 | |
46 | -} | |
47 | - | |
48 | -export interface DealerOrBrand { | |
49 | - id?: number; | |
50 | - name?: string; | |
51 | -} | |
52 | - | |
53 | -/** | |
54 | - * @description: 门店选择列表 | |
55 | - * @param {QueryParams} params | |
56 | - * @return {http.PromiseResp<ShopItem[]>} | |
57 | - */ | |
58 | -export function getShopListApi( | |
59 | - params: QueryParams | |
60 | -): http.PromiseResp<ShopItem[]> { | |
61 | - return request.get(`${OOP_HOST}/select/shop/classify`, { params }); | |
62 | -} | |
63 | - | |
64 | -export interface Option { | |
65 | - bizList?: Biz[]; | |
66 | - regionList?: Region[]; | |
67 | - brandList?: DealerOrBrand[]; | |
68 | - dealerList?: DealerOrBrand[]; | |
69 | -} | |
70 | - | |
71 | -export interface Biz { | |
72 | - type?: number; | |
73 | - name?: string; | |
74 | -} | |
75 | - | |
76 | -/** | |
77 | - * @description: 门店选择条件 | |
78 | - * @param {QueryParams} params | |
79 | - * @return {http.PromiseResp<Option>} | |
80 | - */ | |
81 | -export function getShopListChooseOptionsApi( | |
82 | - params: QueryParams | |
83 | -): http.PromiseResp<Option> { | |
84 | - return request.get(`${OOP_HOST}/select/shop/filters`, { params }); | |
85 | -} |
src/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/components/ShopContent/index.tsx deleted
1 | -import useInitial from '@/hooks/useInitail'; | |
2 | -import { Button, Checkbox, Divider, Input, Popconfirm, Popover, Radio, Row, Select, Spin, Table } from 'antd'; | |
3 | -import type { CheckboxChangeEvent } from 'antd/lib/checkbox'; | |
4 | -import { debounce } from 'lodash'; | |
5 | -import React from 'react'; | |
6 | -import type { ShopItem, DealerOrBrand, Value} from './api'; | |
7 | -import { BizType, getShopListChooseOptionsApi, getShopListApi } from './api'; | |
8 | -import { useStore } from '../../index'; | |
9 | - | |
10 | -interface Props { | |
11 | - type?: 1 | 2; // 1 集团维度 2 自定义门店维度 | |
12 | - multiple?: boolean; | |
13 | -} | |
14 | - | |
15 | -type TableType = '列表' | '选择'; | |
16 | - | |
17 | -function Shop({ type = 1, multiple = true }: Props) { | |
18 | - const { shopSelected: selected, setShopSelected: setSelected } = useStore(); | |
19 | - const optionInitial = useInitial(getShopListChooseOptionsApi, {}, { type }); | |
20 | - const listInitial = useInitial(getShopListApi, [], { | |
21 | - type, | |
22 | - bizTypes: '1,2,3,5', | |
23 | - }); | |
24 | - const [checkInfo, setCheckInfo] = React.useState({ | |
25 | - indeterminate: false, | |
26 | - checkAll: false, | |
27 | - }); | |
28 | - const fetchListByName = debounce((keywords) => { | |
29 | - listInitial.setParams({ type, keywords }, true); | |
30 | - // setCheckInfo({ | |
31 | - // indeterminate: false, | |
32 | - // checkAll: false, | |
33 | - // }); | |
34 | - // setSelected([]); | |
35 | - }, 500); | |
36 | - | |
37 | - const [tableType, setTableType] = React.useState<TableType>('列表'); | |
38 | - | |
39 | - React.useEffect(() => { | |
40 | - setCheckInfo({ | |
41 | - indeterminate: selected.length > 0 && listInitial.data.length !== selected.length, | |
42 | - checkAll: selected.length > 0 && listInitial.data.length === selected.length, | |
43 | - }); | |
44 | - }, [selected, listInitial.data]); | |
45 | - | |
46 | - /** | |
47 | - * @description: 当一个门店被点击时,触发该回调函数。 | |
48 | - * @param {ShopItem} record 当前门店数据 | |
49 | - * @param {boolean} _selected 是否选中 | |
50 | - * @param {Object[]} selectedRows 已被选择的数据 | |
51 | - * @param {Event} nativeEvent 点击事件 | |
52 | - */ | |
53 | - const onSelect = (record: ShopItem, _selected: boolean, selectedRows: Object[], nativeEvent: Event) => { | |
54 | - if (multiple) { | |
55 | - if (_selected) { | |
56 | - // 若被选择,则将该数据处理后,插入已选择列表中 | |
57 | - setSelected([...selected, { ...record, value: record.shopId, label: record.shopShortName }]); | |
58 | - } else { | |
59 | - // 若被取消选择,则将该数据,从已选择列表中删除 | |
60 | - setSelected(selected.filter((item) => item.shopId !== record.shopId)); | |
61 | - } | |
62 | - } else { | |
63 | - true; | |
64 | - if (_selected) { | |
65 | - setSelected([{ ...record, value: record.shopId, label: record.shopShortName }]); | |
66 | - } else { | |
67 | - setSelected([]); | |
68 | - } | |
69 | - } | |
70 | - }; | |
71 | - | |
72 | - /** | |
73 | - * @description: 当全选CheckBox被点击时,调用该回调函数 | |
74 | - * @description: 只有 多选才会调用该全选函数,故起函数内部不需要判断是否多选情况 | |
75 | - * @param {boolean} _selected 是否选中 | |
76 | - * @param {ShopItem[]} selectedRows 已被选择的数据列表 | |
77 | - * @param {ShopItem[]} changeRows 点击全选CheckBox后,受影响的数据列表。该数据与_selected参数共同使用,可以得知是应该将changeRows数据加入已选中数据还是删除 | |
78 | - */ | |
79 | - const onSelectAll = (_selected: boolean, selectedRows: ShopItem[], changeRows: ShopItem[]) => { | |
80 | - if (_selected) { | |
81 | - // 若选中全选CheckBox,则将changeRows中的还未被选入selected中的数据插入 | |
82 | - setSelected( | |
83 | - selected.concat( | |
84 | - changeRows.map((row) => ({ | |
85 | - ...row, | |
86 | - value: row.shopId, | |
87 | - label: row.shopShortName, | |
88 | - })), | |
89 | - ), | |
90 | - ); | |
91 | - } else { | |
92 | - // 若取消选择全选CheckBox,则将changeRows中的数据全部从selected中删除 | |
93 | - const cancelIds = changeRows.map((row) => row.shopId); | |
94 | - // @ts-ignore | |
95 | - setSelected(selected.filter((item) => !cancelIds.includes(item.value))); | |
96 | - } | |
97 | - }; | |
98 | - | |
99 | - const rowClick = (record: Value) => { | |
100 | - if (multiple) { | |
101 | - if (selected.some((item) => item.value === record.shopId)) { | |
102 | - setSelected(selected.filter((item) => item.value !== record.shopId)); | |
103 | - } else { | |
104 | - setSelected( | |
105 | - selected.concat({ | |
106 | - ...record, | |
107 | - value: record.shopId, | |
108 | - label: record.shopShortName, | |
109 | - }), | |
110 | - ); | |
111 | - } | |
112 | - } else { | |
113 | - setSelected([{ ...record, value: record.shopId, label: record.shopShortName }]); | |
114 | - } | |
115 | - }; | |
116 | - | |
117 | - const checkAll = (e: CheckboxChangeEvent) => { | |
118 | - const checked = e.target.checked; | |
119 | - setSelected( | |
120 | - checked | |
121 | - ? listInitial.data.map((item) => ({ | |
122 | - ...item, | |
123 | - value: item.shopId, | |
124 | - label: item.shopShortName, | |
125 | - })) | |
126 | - : [], | |
127 | - ); | |
128 | - }; | |
129 | - | |
130 | - return ( | |
131 | - <div> | |
132 | - <> | |
133 | - <Row justify="space-between"> | |
134 | - <Radio.Group buttonStyle="solid" value={tableType} onChange={(e) => setTableType(e.target.value)}> | |
135 | - <Radio.Button value="列表">列表</Radio.Button> | |
136 | - <Radio.Button value="选择" disabled={!selected.length}> | |
137 | - 当前选择({selected.length} 个) | |
138 | - </Radio.Button> | |
139 | - </Radio.Group> | |
140 | - <Row> | |
141 | - {multiple ? ( | |
142 | - <Checkbox className="ShopSelectNew_checkbox" indeterminate={checkInfo.indeterminate} checked={checkInfo.checkAll} onChange={checkAll}> | |
143 | - 全选 | |
144 | - </Checkbox> | |
145 | - ) : null} | |
146 | - <Popconfirm | |
147 | - title="确定清空已选择门店?" | |
148 | - disabled={!selected.length} | |
149 | - onConfirm={() => { | |
150 | - setSelected([]); | |
151 | - setTableType('列表'); | |
152 | - }} | |
153 | - > | |
154 | - <Button danger type="link" disabled={!selected.length}> | |
155 | - 清空 | |
156 | - </Button> | |
157 | - </Popconfirm> | |
158 | - </Row> | |
159 | - </Row> | |
160 | - <Divider /> | |
161 | - </> | |
162 | - <Spin spinning={optionInitial.loading}> | |
163 | - <Row justify="start" align="middle" style={{ display: tableType === '列表' ? 'flex' : 'none' }} className="ShopSelectNew_Filter_Container"> | |
164 | - <Input | |
165 | - allowClear | |
166 | - placeholder="请输入门店名查询" | |
167 | - // value={listInitial.params.keywords} | |
168 | - onChange={(e) => fetchListByName(e.target.value)} | |
169 | - style={{ maxWidth: 260, marginRight: 10, marginBottom: 10 }} | |
170 | - /> | |
171 | - <Select | |
172 | - allowClear | |
173 | - placeholder="请选择业态" | |
174 | - mode="multiple" | |
175 | - value={listInitial.params.bizTypes ? listInitial.params.bizTypes.split(',') : undefined} | |
176 | - onChange={(bizs) => listInitial.setParams({ type, bizTypes: bizs?.join(',') }, true)} | |
177 | - // value="1" | |
178 | - // disabled | |
179 | - showSearch | |
180 | - optionFilterProp="children" | |
181 | - style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }} | |
182 | - getPopupContainer={(triggerNode) => triggerNode.parentNode} | |
183 | - > | |
184 | - {optionInitial.data.bizList | |
185 | - ?.filter((item) => item.type !== 4) | |
186 | - .map((biz) => ( | |
187 | - <Select.Option key={biz.type} value={'' + biz.type!}> | |
188 | - {biz.name} | |
189 | - </Select.Option> | |
190 | - ))} | |
191 | - </Select> | |
192 | - <Select | |
193 | - allowClear | |
194 | - placeholder="请选择区域" | |
195 | - mode="multiple" | |
196 | - value={listInitial.params.regions ? listInitial.params.regions.split(',') : undefined} | |
197 | - onChange={(regions) => listInitial.setParams({ type, regions: regions?.join(',') }, true)} | |
198 | - showSearch | |
199 | - optionFilterProp="children" | |
200 | - style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }} | |
201 | - getPopupContainer={(triggerNode) => triggerNode.parentNode} | |
202 | - > | |
203 | - {optionInitial.data.regionList?.map((region) => ( | |
204 | - <Select.Option key={region.bh} value={region.bh!}> | |
205 | - {region.fullName} | |
206 | - </Select.Option> | |
207 | - ))} | |
208 | - </Select> | |
209 | - <Select | |
210 | - allowClear | |
211 | - placeholder="请选择品牌" | |
212 | - mode="multiple" | |
213 | - value={listInitial.params.brands ? listInitial.params.brands.split(',') : undefined} | |
214 | - onChange={(brandList) => listInitial.setParams({ type, brands: brandList?.join(',') }, true)} | |
215 | - showSearch | |
216 | - optionFilterProp="children" | |
217 | - style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }} | |
218 | - getPopupContainer={(triggerNode) => triggerNode.parentNode} | |
219 | - > | |
220 | - {optionInitial.data.brandList?.map((brand) => ( | |
221 | - <Select.Option key={brand.id} value={'' + brand.id!}> | |
222 | - {brand.name} | |
223 | - </Select.Option> | |
224 | - ))} | |
225 | - </Select> | |
226 | - <Select | |
227 | - allowClear | |
228 | - placeholder="请选择商家" | |
229 | - mode="multiple" | |
230 | - value={listInitial.params.dealers ? listInitial.params.dealers.split(',') : undefined} | |
231 | - onChange={(dealerList) => listInitial.setParams({ type, dealers: dealerList?.join(',') }, true)} | |
232 | - showSearch | |
233 | - optionFilterProp="children" | |
234 | - style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }} | |
235 | - getPopupContainer={(triggerNode) => triggerNode.parentNode} | |
236 | - > | |
237 | - {optionInitial.data.dealerList?.map((dealer) => ( | |
238 | - <Select.Option key={dealer.id} value={'' + dealer.id!}> | |
239 | - {dealer.name} | |
240 | - </Select.Option> | |
241 | - ))} | |
242 | - </Select> | |
243 | - </Row> | |
244 | - </Spin> | |
245 | - <Table | |
246 | - dataSource={tableType === '列表' ? listInitial.data : selected} | |
247 | - rowKey="shopId" | |
248 | - size="small" | |
249 | - loading={listInitial.loading} | |
250 | - onRow={(record) => ({ | |
251 | - onClick: () => rowClick(record), | |
252 | - })} | |
253 | - rowSelection={{ | |
254 | - type: multiple ? 'checkbox' : 'radio', | |
255 | - selectedRowKeys: selected.map((item) => item.value || item.shopId || -1), | |
256 | - onSelect, | |
257 | - onSelectAll, | |
258 | - }} | |
259 | - > | |
260 | - <Table.Column title="门店名称" dataIndex="shopFullName" align="left" render={(shopFullName) => shopFullName || '-'} /> | |
261 | - <Table.Column title="门店简称" dataIndex="shopShortName" align="left" render={(shopFullName) => shopFullName || '-'} /> | |
262 | - <Table.Column title="门店业态" dataIndex="bizType" align="left" render={(bizType) => (bizType ? BizType[bizType] : '-')} /> | |
263 | - <Table.Column title="归属公司" dataIndex="dealer" align="left" render={(dealer) => dealer?.name || '-'} /> | |
264 | - <Table.Column title="门店区域" dataIndex="region" align="left" render={(region) => region?.fullName || '-'} /> | |
265 | - <Table.Column | |
266 | - title="授权品牌" | |
267 | - dataIndex="brandList" | |
268 | - align="left" | |
269 | - render={(brandList: DealerOrBrand[]) => | |
270 | - brandList?.length ? ( | |
271 | - <Popover | |
272 | - placement="topLeft" | |
273 | - content={ | |
274 | - <span> | |
275 | - {brandList?.map((brand) => ( | |
276 | - <div key={brand.id}>{brand.name}</div> | |
277 | - ))} | |
278 | - </span> | |
279 | - } | |
280 | - > | |
281 | - <span className="span_limit_1">{brandList?.map((brand) => brand.name).join(';')}</span> | |
282 | - </Popover> | |
283 | - ) : ( | |
284 | - '-' | |
285 | - ) | |
286 | - } | |
287 | - /> | |
288 | - <Table.Column title="对应售后门店" dataIndex="casShopName" align="left" render={(casShopName) => casShopName || '-'} /> | |
289 | - </Table> | |
290 | - </div> | |
291 | - ); | |
292 | -} | |
293 | - | |
294 | -export default Shop; |
src/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/components/Step2.tsx
1 | 1 | import React from 'react'; |
2 | 2 | import { Card, Button } from 'antd'; |
3 | -import ShopContent from './ShopContent'; | |
3 | +import ShopContent from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew'; | |
4 | 4 | import DecoContent from './DecoContent'; |
5 | - | |
5 | +import { useStore } from '../index' | |
6 | 6 | interface Props { |
7 | 7 | onNext: () => any; |
8 | 8 | onBack: () => any; |
... | ... | @@ -19,10 +19,10 @@ export default function Step2(props: Props) { |
19 | 19 | disabled, |
20 | 20 | way, |
21 | 21 | } = props; |
22 | - | |
22 | + const { shopSelected, setShopSelected } = useStore(); | |
23 | 23 | return ( |
24 | 24 | <Card bordered={false}> |
25 | - {way === 1 ? <DecoContent /> : <ShopContent />} | |
25 | + {way === 1 ? <DecoContent /> : <ShopContent value={shopSelected} onChange={setShopSelected} />} | |
26 | 26 | |
27 | 27 | <div style={{ display: "flex", justifyContent: "center" }}> |
28 | 28 | <Button loading={loading} style={{ width: 120 }} onClick={onBack}> | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/components/Step3.tsx
1 | 1 | import React from "react"; |
2 | 2 | import { Card, Button } from "antd"; |
3 | -import ShopContent from "./ShopContent"; | |
3 | +import ShopContent from "@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew"; | |
4 | 4 | import DecoContent from "./DecoContent"; |
5 | - | |
5 | +import { useStore } from '../index' | |
6 | 6 | interface Props { |
7 | 7 | onNext: () => any; |
8 | 8 | onBack: () => any; |
... | ... | @@ -13,10 +13,10 @@ interface Props { |
13 | 13 | |
14 | 14 | export default function Step3(props: Props) { |
15 | 15 | const { onNext, onBack, loading, disabled, way} = props; |
16 | - | |
16 | + const { shopSelected, setShopSelected } = useStore(); | |
17 | 17 | return ( |
18 | 18 | <Card bordered={false}> |
19 | - {way === 1 ? <ShopContent /> : <DecoContent />} | |
19 | + {way === 1 ? <ShopContent value={shopSelected} onChange={setShopSelected} /> : <DecoContent />} | |
20 | 20 | |
21 | 21 | <div style={{ display: "flex", justifyContent: "center" }}> |
22 | 22 | <Button loading={loading} style={{ width: 120 }} onClick={onBack}> | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/index.tsx
1 | -import React, { useEffect, useState } from 'react'; | |
1 | +import React, { useState } from 'react'; | |
2 | 2 | import { Card, Steps, message, Tabs, Form } from 'antd'; |
3 | 3 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
4 | 4 | import Step1 from './components/Step1'; |
... | ... | @@ -38,7 +38,7 @@ const Index = () => { |
38 | 38 | } |
39 | 39 | form |
40 | 40 | .validateFields(names) |
41 | - .then((res) => { | |
41 | + .then(() => { | |
42 | 42 | setCurrent(cur); |
43 | 43 | setWay(form.getFieldValue('way')); |
44 | 44 | }) |
... | ... | @@ -57,8 +57,6 @@ const Index = () => { |
57 | 57 | } |
58 | 58 | |
59 | 59 | function _save() { |
60 | - console.log('门店', shopSelected); | |
61 | - console.log('装潢', decoSelected); | |
62 | 60 | if (shopSelected.length === 0) { |
63 | 61 | message.error('请选择门店'); |
64 | 62 | return; |
... | ... | @@ -70,12 +68,12 @@ const Index = () => { |
70 | 68 | const _list = { goods: [] } as API.UpParams; |
71 | 69 | for (let i = 0; i < decoSelected.length; i++) { |
72 | 70 | for (let j = 0; j < shopSelected.length; j++) { |
73 | - _list.goods.push({ goodsId: decoSelected[i].id, shopId: shopSelected[j].shopId }); | |
71 | + _list.goods.push({ goodsId: decoSelected[i].id, shopId: shopSelected[j].value }); | |
74 | 72 | } |
75 | 73 | } |
76 | 74 | setSubmitLoading(true); |
77 | 75 | API.upListApi({ ..._list }) |
78 | - .then((res) => { | |
76 | + .then(() => { | |
79 | 77 | setCurrent(3); |
80 | 78 | setSubmitLoading(false); |
81 | 79 | }) |
... | ... | @@ -98,7 +96,7 @@ const Index = () => { |
98 | 96 | <TabPane key="0"> |
99 | 97 | <Step1 |
100 | 98 | form={form} |
101 | - onValuesChange={(changeValue, values) => { | |
99 | + onValuesChange={(changeValue) => { | |
102 | 100 | setWay(changeValue.way || 1); |
103 | 101 | }} |
104 | 102 | disabled={disabled} | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/putOnShelves/components/DecoContent/index.tsx
1 | 1 | import { Button, Checkbox, Popconfirm, Cascader, Divider, Input, message, Radio, Row, Spin, Table } from 'antd'; |
2 | -import { CheckboxChangeEvent } from 'antd/lib/checkbox'; | |
2 | +import type { CheckboxChangeEvent } from 'antd/lib/checkbox'; | |
3 | 3 | import React from 'react'; |
4 | 4 | import { useStore } from '../../index'; |
5 | -import { WorkItem, getSeriesApi, getSpecApi } from '../../../../api'; | |
5 | +import type { WorkItem} from '../../../../api'; | |
6 | +import { getSeriesApi, getSpecApi } from '../../../../api'; | |
6 | 7 | import ShopModal from '../../../../../common/Shop'; |
7 | 8 | |
8 | 9 | const { Search } = Input; |
... | ... | @@ -21,7 +22,6 @@ function Deco({ type = 1, multiple = true }: Props) { |
21 | 22 | decoSelected: selected, |
22 | 23 | setDecoSelected: setSelected, |
23 | 24 | loading, |
24 | - paginationConfig, | |
25 | 25 | brandOptions, |
26 | 26 | setBrandOptions, |
27 | 27 | } = useStore(); |
... | ... | @@ -54,7 +54,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
54 | 54 | setParams({ keywords: e }, true); |
55 | 55 | } |
56 | 56 | |
57 | - function filterBySeries(value: any[], selectedOptions: any) { | |
57 | + function filterBySeries(value: any[]) { | |
58 | 58 | if (value.length > 0) { |
59 | 59 | const seriesFilter = { |
60 | 60 | brandId: value[0], |
... | ... | @@ -86,7 +86,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
86 | 86 | getSeriesApi(targetOption.id) |
87 | 87 | .then((res: any) => { |
88 | 88 | const { data = [] } = res; |
89 | - targetOption.children = data.map((list: any, index: any) => ({ | |
89 | + targetOption.children = data.map((list: any) => ({ | |
90 | 90 | id: list.id, |
91 | 91 | name: list.name, |
92 | 92 | isLeaf: false, |
... | ... | @@ -103,7 +103,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
103 | 103 | const { data = [] } = res; |
104 | 104 | targetOption.loading = false; |
105 | 105 | targetOption.children = []; |
106 | - data.forEach((list, index) => { | |
106 | + data.forEach((list) => { | |
107 | 107 | targetOption.children.push({ |
108 | 108 | id: list.id, |
109 | 109 | name: list.name, |
... | ... | @@ -214,7 +214,7 @@ function Deco({ type = 1, multiple = true }: Props) { |
214 | 214 | 当前选择({selected.length} 个) |
215 | 215 | </Radio.Button> |
216 | 216 | </Radio.Group> |
217 | - <Row> | |
217 | + <Row align="middle"> | |
218 | 218 | {multiple ? ( |
219 | 219 | <Checkbox className="ShopSelectNew_checkbox" indeterminate={checkInfo.indeterminate} checked={checkInfo.checkAll} onChange={checkAll}> |
220 | 220 | 全选 | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/putOnShelves/components/Step2.tsx
1 | 1 | import React from 'react'; |
2 | 2 | import { Card, Button } from 'antd'; |
3 | -import ShopContent from './ShopContent'; | |
3 | +import ShopContent from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew'; | |
4 | 4 | import DecoContent from './DecoContent'; |
5 | +import { useStore } from '../index' | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | onNext: () => any; |
... | ... | @@ -19,10 +20,11 @@ export default function Step2(props: Props) { |
19 | 20 | disabled, |
20 | 21 | way, |
21 | 22 | } = props; |
23 | + const { shopSelected, setShopSelected } = useStore(); | |
22 | 24 | |
23 | 25 | return ( |
24 | 26 | <Card bordered={false}> |
25 | - {way === 1 ? <DecoContent /> : <ShopContent />} | |
27 | + {way === 1 ? <DecoContent /> : <ShopContent value={shopSelected} onChange={setShopSelected} />} | |
26 | 28 | |
27 | 29 | <div style={{ display: "flex", justifyContent: "center" }}> |
28 | 30 | <Button loading={loading} style={{ width: 120 }} onClick={onBack}> | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/putOnShelves/components/Step3.tsx
1 | 1 | import React from "react"; |
2 | 2 | import { Card, Button } from "antd"; |
3 | -import ShopContent from "./ShopContent"; | |
3 | +import ShopContent from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew'; | |
4 | 4 | import DecoContent from "./DecoContent"; |
5 | +import { useStore } from '../index' | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | onNext: () => any; |
... | ... | @@ -13,10 +14,11 @@ interface Props { |
13 | 14 | |
14 | 15 | export default function Step3(props: Props) { |
15 | 16 | const { onNext, onBack, loading, disabled, way} = props; |
17 | + const { shopSelected, setShopSelected } = useStore(); | |
16 | 18 | |
17 | 19 | return ( |
18 | 20 | <Card bordered={false}> |
19 | - {way === 1 ? <ShopContent /> : <DecoContent />} | |
21 | + {way === 1 ? <ShopContent value={shopSelected} onChange={setShopSelected} /> : <DecoContent />} | |
20 | 22 | |
21 | 23 | <div style={{ display: "flex", justifyContent: "center" }}> |
22 | 24 | <Button loading={loading} style={{ width: 120 }} onClick={onBack}> | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/subpages/putOnShelves/index.tsx
1 | -import React, { useEffect, useState } from 'react'; | |
1 | +import React, { useState } from 'react'; | |
2 | 2 | import { Card, Steps, message, Tabs, Form } from 'antd'; |
3 | 3 | import { PageHeaderWrapper } from '@ant-design/pro-layout'; |
4 | 4 | import Step1 from './components/Step1'; |
... | ... | @@ -38,7 +38,7 @@ const Index = () => { |
38 | 38 | } |
39 | 39 | form |
40 | 40 | .validateFields(names) |
41 | - .then((res) => { | |
41 | + .then(() => { | |
42 | 42 | setCurrent(cur); |
43 | 43 | setWay(form.getFieldValue('way')); |
44 | 44 | }) |
... | ... | @@ -72,13 +72,13 @@ const Index = () => { |
72 | 72 | for (let j = 0; j < shopSelected.length; j++) { |
73 | 73 | _list.goods.push({ |
74 | 74 | goodsId: decoSelected[i].id, |
75 | - shopId: shopSelected[j].shopId, | |
75 | + shopId: shopSelected[j].value, | |
76 | 76 | }); |
77 | 77 | } |
78 | 78 | } |
79 | 79 | setSubmitLoading(true); |
80 | 80 | API.downListApi({ ..._list }) |
81 | - .then((res) => { | |
81 | + .then(() => { | |
82 | 82 | setCurrent(3); |
83 | 83 | setSubmitLoading(false); |
84 | 84 | }) | ... | ... |
src/pages/decoration/deco/DeoGoodsManagement/useStore.ts
1 | +/* | |
2 | + * @Author: jiangwei jiangwei.feewee.cn | |
3 | + * @Date: 2024-03-27 17:14:09 | |
4 | + * @LastEditors: jiangwei jiangwei.feewee.cn | |
5 | + * @LastEditTime: 2024-03-27 17:15:50 | |
6 | + * @FilePath: /fw-cms/src/pages/decoration/deco/DeoGoodsManagement/useStore.ts | |
7 | + * @Description: | |
8 | + * | |
9 | + * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. | |
10 | + */ | |
1 | 11 | import { useState, useEffect } from 'react'; |
2 | 12 | import type { Option } from './interface.d'; |
3 | 13 | import { message } from 'antd'; |
... | ... | @@ -5,7 +15,7 @@ import usePagination from '@/hooks/usePagination'; |
5 | 15 | import useInitial from '@/hooks/useInitail'; |
6 | 16 | import * as api from './api'; |
7 | 17 | import { getGroupCasBrandApi } from '@/common/api'; |
8 | -import type { Value } from '@/pages/decoration/deco/DeoGoodsManagement/subpages/pullOffShelves/components/ShopContent/api'; | |
18 | +import type { Shop } from '@/pages/decoration/deco/DeoGoodsManagement/components/ShopConentNew/api'; | |
9 | 19 | |
10 | 20 | export default function useStore() { |
11 | 21 | const [currentType, setCurrentType] = useState<number>(0); |
... | ... | @@ -16,7 +26,7 @@ export default function useStore() { |
16 | 26 | |
17 | 27 | const pagnation = usePagination(api.getShop, { bizType: 0, pageSize: 9999 }); |
18 | 28 | // 门店选择 |
19 | - const [shopSelected, setShopSelected] = useState<Value[]>([]); | |
29 | + const [shopSelected, setShopSelected] = useState<Shop[]>([]); | |
20 | 30 | // 装潢选择 |
21 | 31 | const [decoSelected, setDecoSelected] = useState<api.WorkItem[]>([]); |
22 | 32 | // 装潢分类 | ... | ... |
src/pages/finance/entitys.ts
... | ... | @@ -222,9 +222,9 @@ export const ExpireRepayRuleObj: { [key: string]: any }[] = [ |
222 | 222 | // 配置类型(不可编辑):1 收入录入,2 付款申请,3 缴费申请,4 事项申请(See: 财务款项配置类型) |
223 | 223 | export enum ConfigTypeEnum { |
224 | 224 | '收入录入' = 1, |
225 | - '付款申请', | |
226 | - '缴费申请', | |
227 | - '事项申请', | |
225 | + // '付款申请', | |
226 | + '缴费申请' = 3, | |
227 | + '付款申请' = 4, | |
228 | 228 | } |
229 | 229 | |
230 | 230 | export const ConfigType = [ |
... | ... | @@ -232,17 +232,17 @@ export const ConfigType = [ |
232 | 232 | label: '收入录入', |
233 | 233 | value: ConfigTypeEnum['收入录入'], |
234 | 234 | }, |
235 | - { | |
236 | - label: '原付款申请', | |
237 | - value: ConfigTypeEnum['付款申请'], | |
238 | - }, | |
235 | + // { | |
236 | + // label: '原付款申请', | |
237 | + // value: ConfigTypeEnum['付款申请'], | |
238 | + // }, | |
239 | 239 | { |
240 | 240 | label: '缴费申请', |
241 | 241 | value: ConfigTypeEnum['缴费申请'], |
242 | 242 | }, |
243 | 243 | { |
244 | 244 | label: '付款申请', |
245 | - value: ConfigTypeEnum['事项申请'], | |
245 | + value: ConfigTypeEnum['付款申请'], | |
246 | 246 | }, |
247 | 247 | ]; |
248 | 248 | /** | ... | ... |