Commit 7d026a35dc7b7aaa6aab2cf8cef96b08d9477cf7
Merge remote-tracking branch 'origin/master' into pms_minratio
# Conflicts: # config/routers/pms.ts
Showing
71 changed files
with
1529 additions
and
588 deletions
config/routers/capital.ts
... | ... | @@ -12,7 +12,7 @@ export default [ |
12 | 12 | component: './capital/SupplySetting' |
13 | 13 | }, |
14 | 14 | { |
15 | - path: '/ams/standardMange', // 编辑管理 | |
15 | + path: '/ams/setting/standardMange', // 编辑管理 | |
16 | 16 | component: './capital/StandardMange' |
17 | 17 | }, |
18 | 18 | { |
... | ... | @@ -24,7 +24,7 @@ export default [ |
24 | 24 | component: './capital/SpecConfig' |
25 | 25 | }, |
26 | 26 | { |
27 | - path: '/ams/standard/name', // 资产分类标准 | |
27 | + path: '/ams/setting/standard/name', // 资产分类标准 | |
28 | 28 | component: './capital/StandardName' |
29 | 29 | }, |
30 | 30 | { | ... | ... |
config/routers/cas.ts
... | ... | @@ -45,6 +45,10 @@ export default [ |
45 | 45 | path: '/cas/baseConfig/workTimeDuration', // 下班可延时时长 |
46 | 46 | component: './cas/baseConfig/WorkTimeDuration', |
47 | 47 | }, |
48 | + { | |
49 | + path: '/cas/baseConfig/ShopRelateBizConfig', // 门店业务关联配置 | |
50 | + component: './cas/baseConfig/ShopRelateBizConfig', | |
51 | + }, | |
48 | 52 | |
49 | 53 | // 毛利目标设置 |
50 | 54 | { |
... | ... | @@ -311,10 +315,7 @@ export default [ |
311 | 315 | path: '/cas/cassetting/manHoursDiscountConfig/create/:id/:brandId?', //工时减免规则配置 |
312 | 316 | component: './cas/afterSaleConfiguration/manHoursDiscountConfig/subpages/ConfigCreate', |
313 | 317 | }, |
314 | - { | |
315 | - path: '/cas/manhoursProportionConfig', // 机修组工时分成比例配置 | |
316 | - component: './cas/afterSaleConfiguration/manhoursProportionConfig', | |
317 | - }, | |
318 | + | |
318 | 319 | // { |
319 | 320 | // path: '/cas/part/plantype', // 备件计划类型 |
320 | 321 | // component: './cas/spareParts/PlanType' |
... | ... | @@ -388,31 +389,31 @@ export default [ |
388 | 389 | }, |
389 | 390 | { |
390 | 391 | //终身质保卡设置 |
391 | - path: '/cas/WarrantyCard/Setting', // 终身质保卡设置 | |
392 | + path: '/cas/promotionConfig/WarrantyCard/Setting', // 终身质保卡设置 | |
392 | 393 | component: './cas/WarrantyCardSetting', |
393 | 394 | }, |
394 | 395 | { |
395 | - path: '/cas/WarrantyCard/Detail/:brandId/:warrantyId?/:isCopy?', //新增、编辑、查看 | |
396 | + path: '/cas/promotionConfig/WarrantyCard/Detail/:brandId/:warrantyId?/:isCopy?', //新增、编辑、查看 | |
396 | 397 | component: './cas/WarrantyCardCreate', |
397 | 398 | }, |
398 | 399 | { |
399 | - path: '/cas/WarrantyCard/UseLog', //使用记录 | |
400 | + path: '/cas/promotionConfig/WarrantyCard/UseLog', //使用记录 | |
400 | 401 | component: './cas/WarrantyCardUseLog', |
401 | 402 | }, |
402 | 403 | { |
403 | - path: '/cas/MaintenancePackageCard/PurchaseRecord', //保养套餐卡->购买记录 | |
404 | + path: '/cas/promotionConfig/MaintenancePackageCard/PurchaseRecord', //保养套餐卡->购买记录 | |
404 | 405 | component: './cas/MaintenanceCard/purchaseRecord', |
405 | 406 | }, |
406 | 407 | { |
407 | - path: '/cas/MaintenancePackageCard/list', //保养套餐卡->列表 | |
408 | + path: '/cas/promotionConfig/MaintenancePackageCard/list', //保养套餐卡->列表 | |
408 | 409 | component: './cas/MaintenanceCard/MPList', |
409 | 410 | }, |
410 | 411 | { |
411 | - path: '/cas/MaintenancePackageCard/list/upsert/:brandId/:maintainId?/:isCopy?', //保养套餐卡->新建编辑 | |
412 | + path: '/cas/promotionConfig/MaintenancePackageCard/list/upsert/:brandId/:maintainId?/:isCopy?', //保养套餐卡->新建编辑 | |
412 | 413 | component: './cas/MaintenanceCard/Upsert', |
413 | 414 | }, |
414 | 415 | { |
415 | - path: '/cas/MaintenancePackageCard/list/oil/:brandId/:maintainId?/:isCopy?', //保养套餐卡->新建编辑机油 | |
416 | + path: '/cas/promotionConfig/MaintenancePackageCard/list/oil/:brandId/:maintainId?/:isCopy?', //保养套餐卡->新建编辑机油 | |
416 | 417 | component: './cas/MaintenanceCard/Oil', |
417 | 418 | }, |
418 | 419 | /** |
... | ... | @@ -444,14 +445,14 @@ export default [ |
444 | 445 | * 市场行动 |
445 | 446 | */ |
446 | 447 | { |
447 | - path: '/cas/marketAction', | |
448 | + path: '/cas/promotionConfig/marketAction', | |
448 | 449 | component: './cas/MarketAction/index', |
449 | 450 | }, |
450 | 451 | /** |
451 | 452 | * 市场行动 => 详情 |
452 | 453 | */ |
453 | 454 | { |
454 | - path: '/cas/marketAction/edit/:id?', | |
455 | + path: '/cas/promotionConfig/marketAction/edit/:id?', | |
455 | 456 | component: './cas/MarketAction/EditComfirm/index', |
456 | 457 | }, |
457 | 458 | |
... | ... | @@ -493,18 +494,25 @@ export default [ |
493 | 494 | * 客户类型结算 |
494 | 495 | */ |
495 | 496 | { |
496 | - path: '/cas/CustomerType/CustomerTypePay', | |
497 | + path: '/cas/ManageConfig/CustomerTypePay', | |
497 | 498 | component: './cas/CustomerTypePay', |
498 | 499 | }, |
499 | 500 | /** |
500 | 501 | * 客户白名单 |
501 | 502 | */ |
502 | 503 | { |
503 | - path: '/cas/CustomerType/CustomerTypeWhiteList', | |
504 | + path: '/cas/ManageConfig/CustomerTypeWhiteList', | |
504 | 505 | component: './cas/CustomerTypeWhiteList', |
505 | 506 | }, |
506 | 507 | { |
507 | - path: '/cas/CustomerType/CustomerTypeWhiteApplyList/:type', //积分商城->商品管理->编辑、新增 | |
508 | + path: '/cas/ManageConfig/CustomerTypeWhiteApplyList/:type', //积分商城->商品管理->编辑、新增 | |
508 | 509 | component: './cas/CustomerTypeWhiteList/subpages/ApplyList', |
509 | 510 | }, |
511 | + /** | |
512 | + * 机修组工时分成比例配置 | |
513 | + */ | |
514 | + { | |
515 | + path: '/cas/ManageConfig/manhoursProportionConfig', | |
516 | + component: './cas/afterSaleConfiguration/manhoursProportionConfig', | |
517 | + }, | |
510 | 518 | ]; | ... | ... |
config/routers/crm_new.ts
... | ... | @@ -74,7 +74,7 @@ export default [ |
74 | 74 | component: './crm_new/OnlineImport', |
75 | 75 | }, |
76 | 76 | { |
77 | - path: '/crm/threePartyPlatformClue', // 三方平台线索配置 | |
77 | + path: '/crm/goalSetting/threePartyPlatformClue', // 三方平台线索配置 | |
78 | 78 | component: './crm_new/ThreePartyPlatformClue', |
79 | 79 | }, |
80 | 80 | { | ... | ... |
config/routers/decoration.ts
... | ... | @@ -16,10 +16,7 @@ export default [ |
16 | 16 | path: '/decoration/decorationGoods/deoGoodsPool', // 装潢商品池 |
17 | 17 | component: './decoration/deco/DeoGoodsPool', |
18 | 18 | }, |
19 | - { | |
20 | - path: '/decoration/retailPriceCoefficient', // 装潢零售价格系数 | |
21 | - component: './pms/part/DecoPriceCoefficient', | |
22 | - }, | |
19 | + | |
23 | 20 | { |
24 | 21 | path: '/decoration/permissiondiscounts', // 装潢权限优惠设置 |
25 | 22 | component: './decoration/deco/PermissionDiscounts', |
... | ... | @@ -28,18 +25,7 @@ export default [ |
28 | 25 | path: '/decoration/workKnowledgeBase', // 装潢作业知识库 |
29 | 26 | component: './decoration/deco/WorkKnowledgeBase', |
30 | 27 | }, |
31 | - { | |
32 | - path: '/decoration/decorationGoods/decorationPromotion/sPPManage', // 特价 | |
33 | - component: './decoration/deco/DecorationPromotion/SPPManage', | |
34 | - }, | |
35 | - { | |
36 | - path: '/decoration/decorationGoods/decorationPromotion/decorationPackage', // 满送 | |
37 | - component: './decoration/deco/DecorationPromotion/DecorationPackage', | |
38 | - }, | |
39 | - { | |
40 | - path: '/decoration/decorationGoods/decorationPromotion/decorateFullFree', // 套餐 | |
41 | - component: './decoration/deco/DecorationPromotion/DecorateFullFree', | |
42 | - }, | |
28 | + | |
43 | 29 | |
44 | 30 | //商品管理 ===> 配件零售 |
45 | 31 | { |
... | ... | @@ -78,4 +64,26 @@ export default [ |
78 | 64 | path: '/decoration/partsGoods/decorationPromotion/decorateFullFree', // 套餐 |
79 | 65 | component: './decoration/parts/DecorationPromotion/DecorateFullFree', |
80 | 66 | }, |
67 | + //促销设置 | |
68 | + { | |
69 | + path: '/decoration/promotionsettings/deoGoodsManagement', // 装潢商品管理 | |
70 | + component: './decoration/deco/DeoGoodsManagement', | |
71 | + }, | |
72 | + { | |
73 | + path: '/decoration/promotionsettings/sPPManage', // 特价 | |
74 | + component: './decoration/deco/DecorationPromotion/SPPManage', | |
75 | + }, | |
76 | + { | |
77 | + path: '/decoration/promotionsettings/decorationPackage', // 满送 | |
78 | + component: './decoration/deco/DecorationPromotion/DecorationPackage', | |
79 | + }, | |
80 | + { | |
81 | + path: '/decoration/promotionsettings/decorateFullFree', // 套餐 | |
82 | + component: './decoration/deco/DecorationPromotion/DecorateFullFree', | |
83 | + }, | |
84 | + //管控 | |
85 | + { | |
86 | + path: '/decoration/controlsettings/retailPriceCoefficient', // 装潢零售价格系数 | |
87 | + component: './pms/part/DecoPriceCoefficient', | |
88 | + }, | |
81 | 89 | ]; |
82 | 90 | \ No newline at end of file | ... | ... |
config/routers/fvm.ts
... | ... | @@ -78,7 +78,7 @@ export default [ |
78 | 78 | }, |
79 | 79 | /**不启票计划提醒 */ |
80 | 80 | { |
81 | - path: '/fvm/plan/noticket', | |
81 | + path: '/fvm/control/noticket', | |
82 | 82 | component: './stock/Plan/NoticketConfig', |
83 | 83 | }, |
84 | 84 | /** 提前输机 */ |
... | ... | @@ -100,7 +100,7 @@ export default [ |
100 | 100 | /** *******系统设置****** */ |
101 | 101 | |
102 | 102 | { |
103 | - path: '/fvm/systems/ticket/price', // 启票价百分比调整设置 | |
103 | + path: '/fvm/control/ticket/price', // 启票价百分比调整设置 | |
104 | 104 | component: './stock/Systems/TicketPercentSetting', |
105 | 105 | }, |
106 | 106 | { |
... | ... | @@ -160,7 +160,7 @@ export default [ |
160 | 160 | component: './stock/Systems/ConcessionConfig', |
161 | 161 | }, |
162 | 162 | { |
163 | - path: '/fvm/addprice', // 车辆加价设置 | |
163 | + path: '/fvm/promotion/addprice', // 车辆加价设置 | |
164 | 164 | component: './stock/CarAddPrice', |
165 | 165 | }, |
166 | 166 | { |
... | ... | @@ -176,7 +176,7 @@ export default [ |
176 | 176 | component: './stock/Systems/TicketIncreaseToBeDone', |
177 | 177 | }, |
178 | 178 | { |
179 | - path: '/fvm/systems/invoice/whitelist', // 开票管控白名单 | |
179 | + path: '/fvm/control/invoice/whitelist', // 开票管控白名单 | |
180 | 180 | component: './stock/Systems/Invoice/WhiteList', |
181 | 181 | }, |
182 | 182 | |
... | ... | @@ -194,7 +194,7 @@ export default [ |
194 | 194 | component: './stock/StoreHouse/ShopStorage', |
195 | 195 | }, |
196 | 196 | { |
197 | - path: '/fvm/storehouse/regionalQuery', // 区域库查询授权 | |
197 | + path: '/fvm/control/regionalQuery', // 区域库查询授权 | |
198 | 198 | component: './stock/StoreHouse/RegionalQueryAuth', |
199 | 199 | }, |
200 | 200 | { |
... | ... | @@ -232,7 +232,7 @@ export default [ |
232 | 232 | }, |
233 | 233 | /**车辆上架管理 */ |
234 | 234 | { |
235 | - path: '/fvm/shop/product/onsale', | |
235 | + path: '/fvm/promotion/onsale', | |
236 | 236 | component: './stock/ProductSetting', |
237 | 237 | }, |
238 | 238 | /**门店维度上架 */ |
... | ... | @@ -324,15 +324,15 @@ export default [ |
324 | 324 | |
325 | 325 | /**厂家补贴 */ |
326 | 326 | { |
327 | - path: '/fvm/subsidy/replace', // 置换补贴 | |
327 | + path: '/fvm/promotion/subsidy/replace', // 置换补贴 | |
328 | 328 | component: './stock/ManufacturerSubsidies/Replace', |
329 | 329 | }, |
330 | 330 | { |
331 | - path: 'fvm/subsidy/keyAccount', // 大客户补贴 | |
331 | + path: 'fvm/promotion/subsidy/keyAccount', // 大客户补贴 | |
332 | 332 | component: './stock/ManufacturerSubsidies/KeyAccount', |
333 | 333 | }, |
334 | 334 | { |
335 | - path: 'fvm/subsidy/addPurchase', // 增购补贴 | |
335 | + path: 'fvm/promotion/subsidy/addPurchase', // 增购补贴 | |
336 | 336 | component: './stock/ManufacturerSubsidies/AddPurchase', |
337 | 337 | }, |
338 | 338 | { |
... | ... | @@ -394,7 +394,7 @@ export default [ |
394 | 394 | }, |
395 | 395 | // 加装车配置 |
396 | 396 | { |
397 | - path: '/fvm/vehicle/additional', | |
397 | + path: '/fvm/promotion/vehicle/additional', | |
398 | 398 | component: './stock/VehicleAdditional', |
399 | 399 | }, |
400 | 400 | ]; | ... | ... |
config/routers/mkt.ts
1 | 1 | /**营销活动 */ |
2 | 2 | export default [ |
3 | 3 | { |
4 | - path: '/mkt/manage', | |
4 | + path: '/mkt/control/manage', | |
5 | 5 | component: './mkt/ActivityManage', |
6 | 6 | }, |
7 | 7 | { |
... | ... | @@ -10,7 +10,7 @@ export default [ |
10 | 10 | }, |
11 | 11 | /**评价有礼配置 */ |
12 | 12 | { |
13 | - path: '/mkt/evaluate/gifts', | |
13 | + path: '/mkt/control/evaluate/gifts', | |
14 | 14 | component: './mkt/EvaluativeGifts', |
15 | 15 | }, |
16 | 16 | /**活动中奖概况运维 */ |
... | ... | @@ -39,15 +39,15 @@ export default [ |
39 | 39 | component: './mkt/PromotionGoal', |
40 | 40 | }, |
41 | 41 | { |
42 | - path: '/mkt/article', // 文章库 | |
42 | + path: '/mkt/control/article', // 文章库 | |
43 | 43 | component: './mkt/articleList', |
44 | 44 | }, |
45 | 45 | { |
46 | - path: '/mkt/original/article', // 原创文章 | |
46 | + path: '/mkt/control/original/article', // 原创文章 | |
47 | 47 | component: './mkt/articleList', |
48 | 48 | }, |
49 | 49 | { |
50 | - path: '/mkt/poster', //海报库列表 | |
50 | + path: '/mkt/control/poster', //海报库列表 | |
51 | 51 | component: './mkt/posterList', |
52 | 52 | }, |
53 | 53 | { |
... | ... | @@ -55,15 +55,15 @@ export default [ |
55 | 55 | component: './mkt/posterCreate', |
56 | 56 | }, |
57 | 57 | { |
58 | - path: '/mkt/video', // 视频库 | |
58 | + path: '/mkt/control/video', // 视频库 | |
59 | 59 | component: './mkt/videoLibrary' |
60 | 60 | }, |
61 | 61 | { |
62 | - path: '/mkt/questions', // 问答项 | |
62 | + path: '/mkt/control/questions', // 问答项 | |
63 | 63 | component: './mkt/questions' |
64 | 64 | }, |
65 | 65 | { |
66 | - path: '/mkt/share/resources', // 文案标准库 | |
66 | + path: '/mkt/control/share/resources', // 文案标准库 | |
67 | 67 | component: './mkt/ShareResources' |
68 | 68 | }, |
69 | 69 | ]; |
70 | 70 | \ No newline at end of file | ... | ... |
config/routers/order3.ts
... | ... | @@ -43,7 +43,7 @@ export default [ |
43 | 43 | }, |
44 | 44 | { |
45 | 45 | //零售任务分配 |
46 | - path: '/order3/saleTask', | |
46 | + path: '/order3/goalSetting/saleTask', | |
47 | 47 | component: './order3/SaleTask', |
48 | 48 | }, |
49 | 49 | { |
... | ... | @@ -77,12 +77,12 @@ export default [ |
77 | 77 | }, |
78 | 78 | { |
79 | 79 | //零售任务设置 |
80 | - path: '/order3/OrderRetailSetting', | |
80 | + path: '/order3/goalSetting/orderRetailSetting', | |
81 | 81 | component: './order3/OrderRetailSetting', |
82 | 82 | }, |
83 | 83 | { |
84 | 84 | //大客户单位设置 |
85 | - path: '/order3/largeBusSetting', | |
85 | + path: '/order3/promotionSettings/largeBusSetting', | |
86 | 86 | component: './order3/LargeBusSetting', |
87 | 87 | }, |
88 | 88 | { |
... | ... | @@ -112,7 +112,7 @@ export default [ |
112 | 112 | }, |
113 | 113 | { |
114 | 114 | //权限优惠设置 |
115 | - path: '/order3/orderSetting/orderPermissionDiscount', | |
115 | + path: '/order3/promotionSettings/orderPermissionDiscount', | |
116 | 116 | component: './order3/OrderSetting/OrderPermissionDiscount', |
117 | 117 | }, |
118 | 118 | { |
... | ... | @@ -132,7 +132,7 @@ export default [ |
132 | 132 | }, |
133 | 133 | { |
134 | 134 | //特价车补贴配置 |
135 | - path: '/order3/orderSetting/specialCarSales', | |
135 | + path: '/order3/promotionSettings/specialCarSales', | |
136 | 136 | component: './order3/SpecialCarSales', |
137 | 137 | }, |
138 | 138 | { |
... | ... | @@ -157,27 +157,27 @@ export default [ |
157 | 157 | }, |
158 | 158 | { |
159 | 159 | //每日送优惠 |
160 | - path: '/order3/dailyGivePreferential', | |
160 | + path: '/order3/promotionSettings/dailyGivePreferential', | |
161 | 161 | component: './order3/DailyGivePreferential', |
162 | 162 | }, |
163 | 163 | { |
164 | 164 | //买车即送 |
165 | - path: '/order3/buyCarGift', | |
165 | + path: '/order3/promotionSettings/buyCarGift', | |
166 | 166 | component: './order3/BuyCarGift', |
167 | 167 | }, |
168 | 168 | { |
169 | 169 | // 置换补贴 |
170 | - path: '/order3/carPurchaseSubsidy/replacementSubsidy', | |
170 | + path: '/order3/promotionSettings/replacementSubsidy', | |
171 | 171 | component: './order3/CarPurchaseSubsidy/ReplacementSubsidy', |
172 | 172 | }, |
173 | 173 | { |
174 | 174 | // 大客户补贴 |
175 | - path: '/order3/carPurchaseSubsidy/keyCustomerSubsidy', | |
175 | + path: '/order3/promotionSettings/keyCustomerSubsidy', | |
176 | 176 | component: './order3/CarPurchaseSubsidy/KeyCustomerSubsidy', |
177 | 177 | }, |
178 | 178 | { |
179 | 179 | // 增购补贴 |
180 | - path: '/order3/carPurchaseSubsidy/additionalSubsidy', | |
180 | + path: '/order3/promotionSettings/additionalSubsidy', | |
181 | 181 | component: './order3/CarPurchaseSubsidy/AdditionalPurchaseSubsidy', |
182 | 182 | }, |
183 | 183 | { |
... | ... | @@ -202,12 +202,12 @@ export default [ |
202 | 202 | }, |
203 | 203 | { |
204 | 204 | // 零售线索占比配置 |
205 | - path: '/order3/retailTaskConfiguration', | |
205 | + path: '/order3/goalSetting/retailTaskConfiguration', | |
206 | 206 | component: './order3/RetailTaskConfiguration', |
207 | 207 | }, |
208 | 208 | { |
209 | 209 | // 附加值任务配置 |
210 | - path: '/order3/addValueTaskConfig', | |
210 | + path: '/order3/goalSetting/addValueTaskConfig', | |
211 | 211 | component: './order3/AddValueTaskConfig', |
212 | 212 | }, |
213 | 213 | { |
... | ... | @@ -257,7 +257,7 @@ export default [ |
257 | 257 | }, |
258 | 258 | { |
259 | 259 | //零售任务白名单设置 |
260 | - path: '/order3/retailTaskWhitelist', | |
260 | + path: '/order3/goalSetting/retailTaskWhitelist', | |
261 | 261 | component: './order3/RetailTaskWhitelist', |
262 | 262 | }, |
263 | 263 | { |
... | ... | @@ -277,7 +277,7 @@ export default [ |
277 | 277 | }, |
278 | 278 | { |
279 | 279 | //交付中心目标 |
280 | - path: '/order3/deliverCentralGoals', | |
280 | + path: '/order3/goalSetting/deliverCentralGoals', | |
281 | 281 | component: './order3/DeliverCentralGoals', |
282 | 282 | }, |
283 | 283 | { |
... | ... | @@ -317,7 +317,7 @@ export default [ |
317 | 317 | }, |
318 | 318 | { |
319 | 319 | // 直营策车厂家促销设置 |
320 | - path: '/order3/directCarPromotion', | |
320 | + path: '/order3/promotionSettings/directCarPromotion', | |
321 | 321 | component: './order3/DirectCarPromotion', |
322 | 322 | }, |
323 | 323 | ]; | ... | ... |
config/routers/pms.ts
1 | +/* | |
2 | + * @Author: jiangwei jiangwei.feewee.cn | |
3 | + * @Date: 2024-04-03 17:42:01 | |
4 | + * @LastEditors: jiangwei jiangwei.feewee.cn | |
5 | + * @LastEditTime: 2024-04-07 10:07:02 | |
6 | + * @FilePath: /fw-cms/config/routers/pms.ts | |
7 | + * @Description: | |
8 | + * | |
9 | + * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. | |
10 | + */ | |
1 | 11 | export default [ |
2 | 12 | { |
3 | 13 | path: '/pms/part/repertory', //备件库标准管理 |
... | ... | @@ -7,10 +17,7 @@ export default [ |
7 | 17 | path: '/pms/part/repertoryCreate/:partNo', // 编辑、新增备件标准 |
8 | 18 | component: './pms/part/RepertoryCreate', |
9 | 19 | }, |
10 | - { | |
11 | - path: '/pms/part/partPriceCoefficient', // 配件价格系数配置 | |
12 | - component: './pms/part/PartPriceCoefficient', | |
13 | - }, | |
20 | + | |
14 | 21 | { |
15 | 22 | path: '/pms/part/decoPriceCoefficient', // 装潢件价格系数配置 |
16 | 23 | component: './pms/part/DecoPriceCoefficient', |
... | ... | @@ -39,18 +46,12 @@ export default [ |
39 | 46 | path: '/pms/part/settlementSetting', // 结算系数设置 |
40 | 47 | component: './pms/part/SettlementSetting', |
41 | 48 | }, |
42 | - { | |
43 | - path: '/pms/partPlan/factoryTask', // 月度任务 | |
44 | - component: './pms/partPlan/FactoryTask', | |
45 | - }, | |
49 | + | |
46 | 50 | { |
47 | 51 | path: '/pms/storage/storageManage', // 仓储管理 -> 仓库管理 |
48 | 52 | component: './pms/storage/StorageManage', |
49 | 53 | }, |
50 | - { | |
51 | - path: '/pms/storage/locationManage', // 仓储管理 -> 库位管理 | |
52 | - component: './pms/storage/LocationManage', | |
53 | - }, | |
54 | + | |
54 | 55 | { |
55 | 56 | path: '/pms/storage/partShop', // 服务站配件 |
56 | 57 | component: './pms/storage/partShop', |
... | ... | @@ -87,10 +88,7 @@ export default [ |
87 | 88 | path: '/pms/partPlan/shipmentfw', // 配件发运单(霏微运维用) |
88 | 89 | component: './pms/partPlan/PlanShipping', |
89 | 90 | }, |
90 | - { | |
91 | - path: '/pms/partPlan/planSupplier', // 采购供应商 | |
92 | - component: './pms/partPlan/PlanSupplier', | |
93 | - }, | |
91 | + | |
94 | 92 | { |
95 | 93 | path: '/pms/partPlan/minRatioPlan', // 最低库销比计划 |
96 | 94 | component: './pms/partPlan/MinRatioPlan', |
... | ... | @@ -155,10 +153,7 @@ export default [ |
155 | 153 | path: '/pms/part/priceSettingTodo', |
156 | 154 | component: './pms/part/PriceSettingTodo', |
157 | 155 | }, |
158 | - { | |
159 | - path: '/pms/part/pickUpAddress', // 提货地址设置 | |
160 | - component: './pms/part/PickUpAddress', | |
161 | - }, | |
156 | + | |
162 | 157 | { |
163 | 158 | path: '/pms/part/partSplit', // 配件拆分设置 |
164 | 159 | component: './pms/part/PartSplit', |
... | ... | @@ -255,4 +250,27 @@ export default [ |
255 | 250 | path: '/pms/setting/minratiowhitelist', // 不纳入库销比计算白名单 |
256 | 251 | component: './pms/setting/MinRatiowhitelist', |
257 | 252 | }, |
253 | + | |
254 | + // 管控设置---配件零售价格 | |
255 | + { | |
256 | + path: '/pms/controlsettings/partPriceCoefficient', // 配件价格系数配置 | |
257 | + component: './pms/part/PartPriceCoefficient', | |
258 | + }, | |
259 | + { | |
260 | + path: '/pms/controlsettings/pickUpAddress', // 提货地址设置 | |
261 | + component: './pms/part/PickUpAddress', | |
262 | + }, | |
263 | + { | |
264 | + path: '/pms/controlsettings/planSupplier', // 采购供应商 | |
265 | + component: './pms/partPlan/PlanSupplier', | |
266 | + }, | |
267 | + { | |
268 | + path: '/pms/controlsettings/locationManage', // 仓储管理 -> 库位管理 | |
269 | + component: './pms/storage/LocationManage', | |
270 | + }, | |
271 | + //目标设置 | |
272 | + { | |
273 | + path: '/pms/targetsetting/factoryTask', // 月度任务 | |
274 | + component: './pms/partPlan/FactoryTask', | |
275 | + }, | |
258 | 276 | ]; | ... | ... |
src/components/SelectorWithFull/MultipleSelector.tsx
... | ... | @@ -99,7 +99,7 @@ export default function MultipleSelector<V = any, T = Record<string, string | nu |
99 | 99 | return ( |
100 | 100 | <div className={classNames(st.wrapper, className)}> |
101 | 101 | <TreeSelect {...other} multiple {...tProps} /> |
102 | - {treeData.length > 1 ? ( | |
102 | + {treeData.length > 1 && !other?.disabled ? ( | |
103 | 103 | <Checkbox className={st.cb} checked={isAllSelect()} onChange={onAllSelect}> |
104 | 104 | 全选 |
105 | 105 | </Checkbox> | ... | ... |
src/pages/admin/employee/api.ts
... | ... | @@ -81,8 +81,8 @@ export function roleRemoveApi(id: string | number) { |
81 | 81 | } |
82 | 82 | |
83 | 83 | // 商家门店树 |
84 | -export function getShopTreeApi(): http.PromiseResp<UserRole.ShopTreeOption[]> { | |
85 | - return request.get(`${host.oop}/select/dealers/shops`); | |
84 | +export function getShopTreeApi(params: { showAll: boolean }): http.PromiseResp<UserRole.ShopTreeOption[]> { | |
85 | + return request.get(`${host.oop}/select/dealers/shops`, { params }); | |
86 | 86 | } |
87 | 87 | |
88 | 88 | //保存用户角色 | ... | ... |
src/pages/admin/employee/components/AddRoleModal.tsx
... | ... | @@ -89,7 +89,7 @@ export default function AddRoleModal({ visible, _onCancel, record = {}, refreshi |
89 | 89 | |
90 | 90 | function fetchRangeData() { |
91 | 91 | setTreeLoading(true); |
92 | - getShopTreeApi() | |
92 | + getShopTreeApi({ showAll: true }) | |
93 | 93 | .then((res) => { |
94 | 94 | const { data = [] } = res; |
95 | 95 | setAllRangeList(data.filter((i) => (i?.children?.length ?? 0) > 0)); |
... | ... | @@ -110,34 +110,34 @@ export default function AddRoleModal({ visible, _onCancel, record = {}, refreshi |
110 | 110 | selectable: false, |
111 | 111 | children: _.compact( |
112 | 112 | item.children && |
113 | - item.children.map((i) => { | |
114 | - // 0为所有业态 | |
115 | - if ( | |
116 | - currentRole && | |
117 | - currentRole.authRange | |
118 | - ?.split(',') | |
119 | - .map((v) => Number(v)) | |
120 | - .includes(0) | |
121 | - ) { | |
122 | - return { | |
123 | - title: i.label, | |
124 | - value: i.value, | |
125 | - key: i.value, | |
126 | - bizType: i.bizType, | |
127 | - isLeaf: true, | |
128 | - }; | |
129 | - } | |
130 | - if ((currentRole ? currentRole.authRange || '' : '').split(',').includes(String(i.bizType))) { | |
131 | - return { | |
132 | - title: i.label, | |
133 | - value: i.value, | |
134 | - key: i.value, | |
135 | - bizType: i.bizType, | |
136 | - isLeaf: true, | |
137 | - }; | |
138 | - } | |
139 | - return null; | |
140 | - }), | |
113 | + item.children.map((i) => { | |
114 | + // 0为所有业态 | |
115 | + if ( | |
116 | + currentRole && | |
117 | + currentRole.authRange | |
118 | + ?.split(',') | |
119 | + .map((v) => Number(v)) | |
120 | + .includes(0) | |
121 | + ) { | |
122 | + return { | |
123 | + title: i.label, | |
124 | + value: i.value, | |
125 | + key: i.value, | |
126 | + bizType: i.bizType, | |
127 | + isLeaf: true, | |
128 | + }; | |
129 | + } | |
130 | + if ((currentRole ? currentRole.authRange || '' : '').split(',').includes(String(i.bizType))) { | |
131 | + return { | |
132 | + title: i.label, | |
133 | + value: i.value, | |
134 | + key: i.value, | |
135 | + bizType: i.bizType, | |
136 | + isLeaf: true, | |
137 | + }; | |
138 | + } | |
139 | + return null; | |
140 | + }), | |
141 | 141 | ), |
142 | 142 | })); |
143 | 143 | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/DefaultFlowNewOrEdit.tsx
... | ... | @@ -24,6 +24,7 @@ import { Condition_Type_Enum as TriggerType } from './PreSettingForm/entity'; |
24 | 24 | import { geneRandomNum } from '@/utils/tools'; |
25 | 25 | import CommonSettingForm from './CommonSettingForm'; |
26 | 26 | import ShopSelectByBizType from '@/pages/approval/components/ShopSelectByBizType'; |
27 | +import type { LabeledValue } from 'antd/lib/select'; | |
27 | 28 | |
28 | 29 | const { Option } = Select; |
29 | 30 | const FormItem = Form.Item; |
... | ... | @@ -80,11 +81,11 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
80 | 81 | } |
81 | 82 | }); |
82 | 83 | const newCondVals = (data?.conditionValues ?? []).concat(essVals); |
83 | - // idOrCode to idOrCode--bizType | |
84 | + // idOrCode to idOrCode__bizType | |
84 | 85 | newCondVals.forEach((n) => { |
85 | 86 | if (n.flowTriggerDto.type === TriggerType.门店) { |
86 | 87 | const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ |
87 | - idOrCode: `${i.idOrCode}--${i.bizType}`, | |
88 | + idOrCode: `${i.idOrCode}__${i.bizType}`, | |
88 | 89 | name: i.name, |
89 | 90 | bizType: i.bizType, |
90 | 91 | })); |
... | ... | @@ -157,11 +158,11 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
157 | 158 | message.error('请填写全部触发条件的对应值'); |
158 | 159 | return; |
159 | 160 | } |
160 | - // idOrCode--bizType to idOrCode | |
161 | + // idOrCode__bizType to idOrCode | |
161 | 162 | conditionVals.forEach((n) => { |
162 | 163 | if (n.flowTriggerDto.type === TriggerType.门店) { |
163 | 164 | const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ |
164 | - idOrCode: i.idOrCode.split('--')[0]!, | |
165 | + idOrCode: i.idOrCode.split('__')[0]!, | |
165 | 166 | name: i.name, |
166 | 167 | bizType: i.bizType, |
167 | 168 | })); |
... | ... | @@ -201,12 +202,12 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
201 | 202 | const onConditionChange = (item: ApprovalSetting.ConditionVal, values: any, index: number) => { |
202 | 203 | const { value, flowTriggerDto } = item; |
203 | 204 | |
204 | - // idOrCode--bizType | |
205 | + // idOrCode__bizType | |
205 | 206 | let newValue; |
206 | 207 | if (flowTriggerDto.type === TriggerType.门店) { |
207 | 208 | newValue = Array.isArray(values) |
208 | 209 | ? values.map((i) => { |
209 | - const currBizType = i.value.split('--')[1]!; | |
210 | + const currBizType = i.value.split('__')[1]!; | |
210 | 211 | return { idOrCode: i.value, name: i.label, bizType: Number(currBizType) }; |
211 | 212 | }) |
212 | 213 | : values; |
... | ... | @@ -286,6 +287,19 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
286 | 287 | |
287 | 288 | const _maxRule = originalData && typeof originalData.max === 'number' ? originalData.max : Infinity; |
288 | 289 | const _minRule = originalData && typeof originalData.min === 'number' ? originalData.min : -Infinity; |
290 | + | |
291 | + let initType = 1; | |
292 | + if (type === TriggerType['门店']) { | |
293 | + const newOriginalData: LabeledValue[] = | |
294 | + originalData.length > 0 | |
295 | + ? originalData.map((i: any) => ({ | |
296 | + value: i.idOrCode, | |
297 | + label: i.name, | |
298 | + })) | |
299 | + : []; | |
300 | + const isTypeAll = newOriginalData.length === 1 && newOriginalData[0].value === '-1__-1'; // 是全部门店 | |
301 | + initType = isTypeAll ? -1 : 1; | |
302 | + } | |
289 | 303 | return ( |
290 | 304 | <FormItem key={id} label={`${index + 1}、${name || ''}(${TriggerAll[judgeRule]})`} style={{ marginBottom: 20 }}> |
291 | 305 | {judgeRule === 1 ? ( |
... | ... | @@ -337,7 +351,7 @@ export default function DefaultSettingNewOrEdit(props: Props) { |
337 | 351 | <ShopSelectByBizType |
338 | 352 | labelInValue |
339 | 353 | multiple |
340 | - initType={1} | |
354 | + initType={initType} | |
341 | 355 | value={ |
342 | 356 | originalData.length > 0 |
343 | 357 | ? originalData.map((i: any) => ({ | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/AbilitySelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getAbilityPage } from '@/pages/approval/FlowSetting/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const AbilitySelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getAbilityPage, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const AbilitySelector = ({ visible, index, item, readOnly, onChange }: Pr |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/AccountSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import usePagination from '@/hooks/usePagination'; |
4 | 4 | import { getAccountApi } from '@/pages/approval/FlowSetting/api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const AccountSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { list, setParams } = usePagination(getAccountApi, {}, { delay }); |
... | ... | @@ -31,9 +33,33 @@ export const AccountSelector = ({ visible, index, item, readOnly, onChange }: Pr |
31 | 33 | } |
32 | 34 | }, [visible]); |
33 | 35 | |
36 | + const getFilteredData = () => { | |
37 | + const oriOptions = list.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
38 | + if (searchValue.trim() === '') { | |
39 | + return oriOptions; | |
40 | + } | |
41 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
42 | + }; | |
43 | + | |
44 | + const handleSelect = (_: LabeledValue, option: any) => { | |
45 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
46 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
47 | + oriNames.push(option.label); | |
48 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
49 | + const filteredData = getFilteredData(); | |
50 | + if (valueMatchArr.length === filteredData.length) { | |
51 | + setSearchValue(''); | |
52 | + } | |
53 | + }; | |
54 | + | |
34 | 55 | return ( |
35 | 56 | <SelectorWithFull |
36 | 57 | showSearch |
58 | + searchValue={searchValue} | |
59 | + onSearch={(value) => { | |
60 | + setSearchValue(value); | |
61 | + }} | |
62 | + onSelect={handleSelect} | |
37 | 63 | treeNodeFilterProp="label" |
38 | 64 | maxTagCount={100} |
39 | 65 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/BacklogSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getBacklogList } from '@/pages/approval/FlowSetting/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const BacklogSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getBacklogList, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const BacklogSelector = ({ visible, index, item, readOnly, onChange }: Pr |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.itemCode, value: item.itemCode, label: item.itemName })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/BizTypeSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import useInitial from '@/hooks/useInitail'; |
4 | 4 | import { queryAllBizType } from '@/common/api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const BizTypeSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(queryAllBizType, [], undefined, delay); |
... | ... | @@ -26,9 +28,33 @@ export const BizTypeSelector = ({ visible, index, item, readOnly, onChange }: Pr |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.value, value: item.value, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/BrandSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import useInitial from '@/hooks/useInitail'; |
4 | 4 | import { getBrandFilterApi } from '@/common/api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const BrandSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getBrandFilterApi, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const BrandSelector = ({ visible, index, item, readOnly, onChange }: Prop |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/ContractTypeSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import usePagination from '@/hooks/usePagination'; |
4 | 4 | import { getContractTypes } from '../../../api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const ContractTypeSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { list, setParams } = usePagination(getContractTypes, {}, { delay }); |
... | ... | @@ -26,9 +28,33 @@ export const ContractTypeSelector = ({ visible, index, item, readOnly, onChange |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = list.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/FittingsSelector.tsx
... | ... | @@ -2,6 +2,8 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getShopListApi } from '@/components/ShopSelectNew/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
6 | + | |
5 | 7 | interface Props { |
6 | 8 | visible: boolean; |
7 | 9 | index: number; |
... | ... | @@ -14,6 +16,7 @@ interface Props { |
14 | 16 | export const FittingsSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
15 | 17 | const { value } = item; |
16 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
17 | 20 | |
18 | 21 | const [delay, setDelay] = useState(true); |
19 | 22 | const { data: list, setParams } = useInitial(getShopListApi, [], { type: 1, bizTypes: '6' }, delay); |
... | ... | @@ -31,9 +34,33 @@ export const FittingsSelector = ({ visible, index, item, readOnly, onChange }: P |
31 | 34 | } |
32 | 35 | }, [visible]); |
33 | 36 | |
37 | + const getFilteredData = () => { | |
38 | + const oriOptions = list.map((item) => ({ key: item.shopId, value: item.shopId, label: item.shopShortName })); | |
39 | + if (searchValue.trim() === '') { | |
40 | + return oriOptions; | |
41 | + } | |
42 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
43 | + }; | |
44 | + | |
45 | + const handleSelect = (_: LabeledValue, option: any) => { | |
46 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
47 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
48 | + oriNames.push(option.label); | |
49 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
50 | + const filteredData = getFilteredData(); | |
51 | + if (valueMatchArr.length === filteredData.length) { | |
52 | + setSearchValue(''); | |
53 | + } | |
54 | + }; | |
55 | + | |
34 | 56 | return ( |
35 | 57 | <SelectorWithFull |
36 | 58 | showSearch |
59 | + searchValue={searchValue} | |
60 | + onSearch={(value) => { | |
61 | + setSearchValue(value); | |
62 | + }} | |
63 | + onSelect={handleSelect} | |
37 | 64 | treeNodeFilterProp="label" |
38 | 65 | maxTagCount={100} |
39 | 66 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/FoundSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getFoundPage } from '@/pages/approval/FlowSetting/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const FoundSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getFoundPage, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const FoundSelector = ({ visible, index, item, readOnly, onChange }: Prop |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.value, value: item.value, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/IndicatorSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getIndicatorList } from '@/pages/approval/FlowSetting/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const IndicatorSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getIndicatorList, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const IndicatorSelector = ({ visible, index, item, readOnly, onChange }: |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.code, value: item.code, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/OfficeWordTypeSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import useInitial from '@/hooks/useInitail'; |
4 | 4 | import { getOfficeWordTypes } from '../../../api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const OfficeWordTypeSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getOfficeWordTypes, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const OfficeWordTypeSelector = ({ visible, index, item, readOnly, onChang |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/PostSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import usePagination from '@/hooks/usePagination'; |
4 | 4 | import { getPost } from '@/pages/approval/FlowSetting/api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const PostSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { list, setParams } = usePagination(getPost, {}, { delay }); |
... | ... | @@ -32,9 +34,33 @@ export const PostSelector = ({ visible, index, item, readOnly, onChange }: Props |
32 | 34 | } |
33 | 35 | }, [visible]); |
34 | 36 | |
37 | + const getFilteredData = () => { | |
38 | + const oriOptions = list.map((item) => ({ key: item.id, value: item.id, label: item.postName })); | |
39 | + if (searchValue.trim() === '') { | |
40 | + return oriOptions; | |
41 | + } | |
42 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
43 | + }; | |
44 | + | |
45 | + const handleSelect = (_: LabeledValue, option: any) => { | |
46 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
47 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
48 | + oriNames.push(option.label); | |
49 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
50 | + const filteredData = getFilteredData(); | |
51 | + if (valueMatchArr.length === filteredData.length) { | |
52 | + setSearchValue(''); | |
53 | + } | |
54 | + }; | |
55 | + | |
35 | 56 | return ( |
36 | 57 | <SelectorWithFull |
37 | 58 | showSearch |
59 | + searchValue={searchValue} | |
60 | + onSearch={(value) => { | |
61 | + setSearchValue(value); | |
62 | + }} | |
63 | + onSelect={handleSelect} | |
38 | 64 | treeNodeFilterProp="label" |
39 | 65 | maxTagCount={100} |
40 | 66 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/PostTypeSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getPostTypeList } from '@/pages/approval/FlowSetting/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const PostTypeSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getPostTypeList, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const PostTypeSelector = ({ visible, index, item, readOnly, onChange }: P |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.type, value: item.type, label: item.typeName })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/RPTypesSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import useInitial from '@/hooks/useInitail'; |
4 | 4 | import { getRPTypes } from '@/common/api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | configType: number; |
... | ... | @@ -16,6 +17,7 @@ interface Props { |
16 | 17 | export const RPTypesSelector = ({ configType, visible, index, item, readOnly, onChange }: Props) => { |
17 | 18 | const { value } = item; |
18 | 19 | const originalData = JSON.parse(value || '{}'); |
20 | + const [searchValue, setSearchValue] = useState(''); | |
19 | 21 | |
20 | 22 | const [delay, setDelay] = useState(true); |
21 | 23 | // @ts-ignore |
... | ... | @@ -28,9 +30,33 @@ export const RPTypesSelector = ({ configType, visible, index, item, readOnly, on |
28 | 30 | } |
29 | 31 | }, [visible]); |
30 | 32 | |
33 | + const getFilteredData = () => { | |
34 | + const oriOptions = data.map((item) => ({ key: item.value, value: item.value, label: item.name })); | |
35 | + if (searchValue.trim() === '') { | |
36 | + return oriOptions; | |
37 | + } | |
38 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
39 | + }; | |
40 | + | |
41 | + const handleSelect = (_: LabeledValue, option: any) => { | |
42 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
43 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
44 | + oriNames.push(option.label); | |
45 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
46 | + const filteredData = getFilteredData(); | |
47 | + if (valueMatchArr.length === filteredData.length) { | |
48 | + setSearchValue(''); | |
49 | + } | |
50 | + }; | |
51 | + | |
31 | 52 | return ( |
32 | 53 | <SelectorWithFull |
33 | 54 | showSearch |
55 | + searchValue={searchValue} | |
56 | + onSearch={(value) => { | |
57 | + setSearchValue(value); | |
58 | + }} | |
59 | + onSelect={handleSelect} | |
34 | 60 | treeNodeFilterProp="label" |
35 | 61 | maxTagCount={100} |
36 | 62 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/RoleSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import { getAllRoleCodeApi } from '@/common/api'; |
3 | 3 | import useInitial from '@/hooks/useInitail'; |
4 | 4 | import SelectorWithFull from '@/components/SelectorWithFull'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const RoleSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getAllRoleCodeApi, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const RoleSelector = ({ visible, index, item, readOnly, onChange }: Props |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.roleCode, value: item.roleCode, label: item.roleName })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/SealSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import usePagination from '@/hooks/usePagination'; |
4 | 4 | import { getList } from '@/pages/contract/StampMatter/api'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const SealSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { list, setParams } = usePagination(getList, {}, { delay }); |
... | ... | @@ -26,9 +28,33 @@ export const SealSelector = ({ visible, index, item, readOnly, onChange }: Props |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = list.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label!.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/ShopBizTypeSelector.tsx
... | ... | @@ -11,7 +11,7 @@ interface Props { |
11 | 11 | onChange: (item: ApprovalSetting.ConditionVal, value: any, index: number) => void; |
12 | 12 | } |
13 | 13 | |
14 | -// 门店业态 | |
14 | +// 门店业态--已废弃 | |
15 | 15 | export const ShopBizTypeSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 16 | const { value } = item; |
17 | 17 | const originalData = JSON.parse(value || '{}'); | ... | ... |
src/pages/approval/ApprovalSetting/subpages/components/Selectors/StorageSelector.tsx
... | ... | @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; |
2 | 2 | import SelectorWithFull from '@/components/SelectorWithFull'; |
3 | 3 | import { getStorageList } from '@/pages/approval/FlowSetting/api'; |
4 | 4 | import useInitial from '@/hooks/useInitail'; |
5 | +import type { LabeledValue } from 'antd/lib/select'; | |
5 | 6 | |
6 | 7 | interface Props { |
7 | 8 | visible: boolean; |
... | ... | @@ -15,6 +16,7 @@ interface Props { |
15 | 16 | export const StorageSelector = ({ visible, index, item, readOnly, onChange }: Props) => { |
16 | 17 | const { value } = item; |
17 | 18 | const originalData = JSON.parse(value || '{}'); |
19 | + const [searchValue, setSearchValue] = useState(''); | |
18 | 20 | |
19 | 21 | const [delay, setDelay] = useState(true); |
20 | 22 | const { data, setParams } = useInitial(getStorageList, [], {}, delay); |
... | ... | @@ -26,9 +28,33 @@ export const StorageSelector = ({ visible, index, item, readOnly, onChange }: Pr |
26 | 28 | } |
27 | 29 | }, [visible]); |
28 | 30 | |
31 | + const getFilteredData = () => { | |
32 | + const oriOptions = data.map((item) => ({ key: item.id, value: item.id, label: item.name })); | |
33 | + if (searchValue.trim() === '') { | |
34 | + return oriOptions; | |
35 | + } | |
36 | + return oriOptions.filter((i) => i.label.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
37 | + }; | |
38 | + | |
39 | + const handleSelect = (_: LabeledValue, option: any) => { | |
40 | + const oriNames = originalData.length > 0 ? originalData.map((i: any) => i.name) : []; | |
41 | + // originalData 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
42 | + oriNames.push(option.label); | |
43 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
44 | + const filteredData = getFilteredData(); | |
45 | + if (valueMatchArr.length === filteredData.length) { | |
46 | + setSearchValue(''); | |
47 | + } | |
48 | + }; | |
49 | + | |
29 | 50 | return ( |
30 | 51 | <SelectorWithFull |
31 | 52 | showSearch |
53 | + searchValue={searchValue} | |
54 | + onSearch={(value) => { | |
55 | + setSearchValue(value); | |
56 | + }} | |
57 | + onSelect={handleSelect} | |
32 | 58 | treeNodeFilterProp="label" |
33 | 59 | maxTagCount={100} |
34 | 60 | disabled={readOnly} | ... | ... |
src/pages/approval/FlowSetting/subpages/ConditionSetting/components/CustomFlowNewOrEdit.tsx
... | ... | @@ -26,6 +26,7 @@ import usePagination from '@/hooks/usePagination'; |
26 | 26 | import { getPost } from '../../../api'; |
27 | 27 | import PostsSelectorByAll from '../../../components/PostsSelectorByAll'; |
28 | 28 | import ShopSelectByBizType from '@/pages/approval/components/ShopSelectByBizType'; |
29 | +import type { LabeledValue } from 'antd/lib/select'; | |
29 | 30 | |
30 | 31 | const { Option } = Select; |
31 | 32 | const FormItem = Form.Item; |
... | ... | @@ -97,11 +98,11 @@ export default function CustomFlowNewOrEdit(props: Props) { |
97 | 98 | } |
98 | 99 | }); |
99 | 100 | const newCondVals = (data?.conditionValues ?? []).concat(essVals); |
100 | - // idOrCode to idOrCode--bizType | |
101 | + // idOrCode to idOrCode__bizType | |
101 | 102 | newCondVals.forEach((n) => { |
102 | 103 | if (n.flowTriggerDto.type === TriggerType.门店) { |
103 | 104 | const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ |
104 | - idOrCode: `${i.idOrCode}--${i.bizType}`, | |
105 | + idOrCode: `${i.idOrCode}__${i.bizType}`, | |
105 | 106 | name: i.name, |
106 | 107 | bizType: i.bizType, |
107 | 108 | })); |
... | ... | @@ -176,11 +177,11 @@ export default function CustomFlowNewOrEdit(props: Props) { |
176 | 177 | message.error('请填写全部触发条件的对应值'); |
177 | 178 | return; |
178 | 179 | } |
179 | - // idOrCode--bizType to idOrCode | |
180 | + // idOrCode__bizType to idOrCode | |
180 | 181 | conditionVals.forEach((n) => { |
181 | 182 | if (n.flowTriggerDto.type === TriggerType.门店) { |
182 | 183 | const value = JSON.parse(n.value).map((i: FlowSetting.CondValItem) => ({ |
183 | - idOrCode: i.idOrCode.split('--')[0]!, | |
184 | + idOrCode: i.idOrCode.split('__')[0]!, | |
184 | 185 | name: i.name, |
185 | 186 | bizType: i.bizType, |
186 | 187 | })); |
... | ... | @@ -214,12 +215,12 @@ export default function CustomFlowNewOrEdit(props: Props) { |
214 | 215 | const onConditionChange = (item: FlowSetting.ConditionVal, values: any, index: number) => { |
215 | 216 | const { value, flowTriggerDto } = item; |
216 | 217 | |
217 | - // idOrCode--bizType | |
218 | + // idOrCode__bizType | |
218 | 219 | let newValue; |
219 | 220 | if (flowTriggerDto.type === TriggerType.门店) { |
220 | 221 | newValue = Array.isArray(values) |
221 | 222 | ? values.map((i) => { |
222 | - const currBizType = i.value.split('--')[1]!; | |
223 | + const currBizType = i.value.split('__')[1]!; | |
223 | 224 | return { idOrCode: i.value, name: i.label, bizType: Number(currBizType) }; |
224 | 225 | }) |
225 | 226 | : values; |
... | ... | @@ -299,6 +300,19 @@ export default function CustomFlowNewOrEdit(props: Props) { |
299 | 300 | |
300 | 301 | const _maxRule = originalData && typeof originalData.max === 'number' ? originalData.max : Infinity; |
301 | 302 | const _minRule = originalData && typeof originalData.min === 'number' ? originalData.min : -Infinity; |
303 | + | |
304 | + let initType = 1; | |
305 | + if (type === TriggerType['门店']) { | |
306 | + const newOriginalData: LabeledValue[] = | |
307 | + originalData.length > 0 | |
308 | + ? originalData.map((i: any) => ({ | |
309 | + value: i.idOrCode, | |
310 | + label: i.name, | |
311 | + })) | |
312 | + : []; | |
313 | + const isTypeAll = newOriginalData.length === 1 && newOriginalData[0].value === '-1__-1'; // 是全部门店 | |
314 | + initType = isTypeAll ? -1 : 1; | |
315 | + } | |
302 | 316 | return ( |
303 | 317 | <FormItem key={id} label={`${index + 1}、${name || ''}(${TriggerAll[judgeRule]})`} style={{ marginBottom: 20 }}> |
304 | 318 | {judgeRule === 1 ? ( |
... | ... | @@ -350,7 +364,7 @@ export default function CustomFlowNewOrEdit(props: Props) { |
350 | 364 | <ShopSelectByBizType |
351 | 365 | labelInValue |
352 | 366 | multiple |
353 | - initType={1} | |
367 | + initType={initType} | |
354 | 368 | value={ |
355 | 369 | originalData.length > 0 |
356 | 370 | ? originalData.map((i: any) => ({ | ... | ... |
src/pages/approval/components/ShopSelectByBizType/index.tsx
1 | 1 | import type { Ref } from 'react'; |
2 | -import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; | |
3 | -import { Checkbox, Radio, Row, Spin, TreeSelect } from 'antd'; | |
2 | +import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react'; | |
3 | +import { Radio, Row, Spin, TreeSelect } from 'antd'; | |
4 | 4 | import useInitail from '@/hooks/useInitail'; |
5 | 5 | import type { ShopItem } from './api'; |
6 | 6 | import { getShopListByBizTypeApi, getShopListByDealerApi } from './api'; |
7 | -import { unique } from '@/utils/validate'; | |
8 | -import type { CheckboxChangeEvent } from 'antd/lib/checkbox'; | |
9 | 7 | import type { LabeledValue } from 'antd/lib/select'; |
8 | +import _ from 'lodash'; | |
10 | 9 | |
11 | 10 | const divId = `TreeSelect_ShopSelect_Div_${Date.now()}`; // 生成岗位div唯一key |
12 | 11 | |
13 | 12 | interface Props { |
14 | - value?: LabeledValue[]; // 人员id 列表 | |
13 | + value?: LabeledValue[]; | |
15 | 14 | onChange?: (value: LabeledValue[]) => void; |
16 | 15 | multiple?: boolean; |
17 | 16 | labelInValue?: boolean; |
18 | - initType?: 1 | 2; | |
17 | + initType?: number; | |
19 | 18 | disabled?: boolean; |
20 | - /** 📢 以下2个属性 仅同时使用一个 📢 */ | |
21 | - showIds?: number[]; // 仅显示项目ID列表 | |
22 | - hiddenIds?: number[]; // 不显示的列表ID | |
23 | - /** 📢 以上2个属性 仅同时使用一个 📢 */ | |
24 | - disabledIds?: number[]; // 禁止选择列表ID | |
25 | 19 | } |
26 | 20 | |
27 | 21 | interface DataItem { |
... | ... | @@ -43,53 +37,28 @@ export interface ShopSelectRef { |
43 | 37 | export default forwardRef(ShopSelectByBizType); |
44 | 38 | |
45 | 39 | function ShopSelectByBizType( |
46 | - { value = [], onChange, multiple = false, labelInValue = false, initType = 1, disabled = false, showIds, hiddenIds, disabledIds }: Props, | |
40 | + { value = [], onChange, multiple = false, labelInValue = false, initType = 1, disabled = false }: Props, | |
47 | 41 | ref: Ref<ShopSelectRef>, |
48 | 42 | ) { |
49 | - if (showIds?.length && hiddenIds?.length) { | |
50 | - console.error(`(<ShopSelectByBizType>):\`showIds\` 和 \`hiddenIds\` 不能同时传入。`); | |
51 | - } | |
52 | - | |
53 | 43 | const { data: byBizTypeList, loading: byBizTypeLoading } = useInitail(getShopListByBizTypeApi, [], { allType: true }); |
54 | 44 | const { data: byDealerList, loading: byDealerLoading } = useInitail(getShopListByDealerApi, [], {}); |
55 | - const [type, setType] = useState<1 | 2>(initType); | |
45 | + const [type, setType] = useState<number>(initType); | |
56 | 46 | const [values, setValues] = useState<LabeledValue[]>(value); |
57 | - const [checkInfo, setCheckInfo] = useState({ | |
58 | - indeterminate: false, | |
59 | - checkAll: false, | |
60 | - }); // 全选按钮的信息,indeterminate 半选中状态,checkAll 全选状态 | |
61 | - const allValues = useRef<LabeledValue[]>([]); // 为了方便全选按钮被点击时赋值,将所有人员再计算list的时候,顺便赋值给该变量 | |
47 | + | |
48 | + // 拓展搜索交互 | |
49 | + const [searchValue, setSearchValue] = useState(''); | |
62 | 50 | |
63 | 51 | useEffect(() => { |
64 | 52 | if (value.length > 0) { |
65 | 53 | setValues(value); |
66 | - setCheckInfo({ | |
67 | - indeterminate: value && value.length > 0 && value.length !== allValues.current.length, | |
68 | - checkAll: value && value.length === allValues.current.length, | |
69 | - }); | |
70 | 54 | } else { |
71 | 55 | setValues([]); |
72 | - setCheckInfo({ | |
73 | - indeterminate: false, | |
74 | - checkAll: false, | |
75 | - }); | |
76 | 56 | } |
77 | 57 | }, [value]); |
78 | 58 | |
79 | - useEffect(() => { | |
80 | - setCheckInfo({ | |
81 | - indeterminate: values && values.length > 0 && values.length !== allValues.current.length, | |
82 | - checkAll: values && values.length === allValues.current.length, | |
83 | - }); | |
84 | - }, [values, allValues.current]); | |
85 | - | |
86 | 59 | useImperativeHandle(ref, () => ({ |
87 | 60 | reset: () => { |
88 | 61 | setValues([]); |
89 | - setCheckInfo({ | |
90 | - indeterminate: false, | |
91 | - checkAll: false, | |
92 | - }); | |
93 | 62 | }, |
94 | 63 | })); |
95 | 64 | |
... | ... | @@ -99,21 +68,28 @@ function ShopSelectByBizType( |
99 | 68 | const list = useMemo<DataItem[]>(() => { |
100 | 69 | if (type === 1) { |
101 | 70 | // 按业态方式 |
102 | - allValues.current = []; // 将所有门店置为空 | |
103 | - return byBizTypeList.map((bizType, index) => { | |
104 | - const children = processingChildrenData(bizType, showIds, hiddenIds, disabledIds); | |
105 | - // 将门店下的门店赋值给allValues | |
106 | - allValues.current = allValues.current.concat( | |
107 | - (children || []) | |
108 | - .filter((child) => !child.disabled) | |
109 | - .map((shop) => ({ | |
110 | - label: `${shop.shopName}`, | |
111 | - value: shop.shopId, | |
112 | - })), | |
113 | - ); | |
114 | - if (index === byBizTypeList.length - 1) { | |
115 | - allValues.current = unique(allValues.current, 'value'); | |
116 | - } | |
71 | + return byBizTypeList.map((bizType) => { | |
72 | + const headerAllId = `${-1}__${bizType.value}`; | |
73 | + const children = processingChildrenData(bizType, headerAllId, value); | |
74 | + | |
75 | + // 前端手动在列表头部增加一个 {id: -1, name: '全部'} 的选项 | |
76 | + const headerAll = { | |
77 | + pid: bizType.value, | |
78 | + title: `全部${bizType.label}`, | |
79 | + // value: idOrCode to idOrCode__bizType | |
80 | + value: headerAllId, | |
81 | + key: headerAllId, | |
82 | + isLeaf: true, | |
83 | + level: 2, | |
84 | + shopId: -1, | |
85 | + shopName: '全部', | |
86 | + // disabled: | |
87 | + // value.filter((i) => { | |
88 | + // // @ts-ignore | |
89 | + // const pid = Number(i.value.split('__')[1]); | |
90 | + // return i.value !== headerAllId && pid === bizType.value; | |
91 | + // }).length > 0, | |
92 | + } as DataItem; | |
117 | 93 | |
118 | 94 | return { |
119 | 95 | pid: -1, |
... | ... | @@ -122,26 +98,15 @@ function ShopSelectByBizType( |
122 | 98 | key: `bizType-${bizType.value}`, |
123 | 99 | isLeaf: false, |
124 | 100 | level: 1, |
125 | - selectable: false, | |
126 | - disabled: !children?.length, | |
127 | - children, | |
101 | + checkable: false, | |
102 | + children: [headerAll].concat(children ?? []), | |
128 | 103 | } as DataItem; |
129 | 104 | }); |
130 | 105 | } else if (type === 2) { |
131 | 106 | // 按商家方式 |
132 | - allValues.current = []; // 将所有门店置为空 | |
133 | - return byDealerList.map((dealer, index) => { | |
134 | - const children = processingChildrenData(dealer, showIds, hiddenIds, disabledIds); | |
135 | - // 将商家下的门店赋值给allValues | |
136 | - allValues.current = allValues.current.concat( | |
137 | - (children || []).map((shop) => ({ | |
138 | - label: shop.shopName, | |
139 | - value: shop.shopId, | |
140 | - })), | |
141 | - ); | |
142 | - if (index === byDealerList.length - 1) { | |
143 | - allValues.current = unique(allValues.current, 'value'); | |
144 | - } | |
107 | + return byDealerList.map((dealer) => { | |
108 | + const headerAllId = `${-1}__${dealer.value}`; | |
109 | + const children = processingChildrenData(dealer, headerAllId, value); | |
145 | 110 | |
146 | 111 | return { |
147 | 112 | pid: -1, |
... | ... | @@ -151,40 +116,95 @@ function ShopSelectByBizType( |
151 | 116 | isLeaf: false, |
152 | 117 | level: 1, |
153 | 118 | selectable: false, |
154 | - disabled: !children?.length, | |
155 | 119 | children, |
156 | 120 | } as DataItem; |
157 | 121 | }); |
158 | 122 | } else return []; |
159 | - }, [type, byBizTypeList, byDealerList, showIds, hiddenIds]); | |
160 | - | |
161 | - const _onChange: (_value: LabeledValue[], labelList: React.ReactNode[], extra: any) => void = (_value, labelList, extra) => { | |
162 | - setValues(_value); | |
163 | - // if (multiple) { | |
164 | - // setCheckInfo({ | |
165 | - // indeterminate: | |
166 | - // _value && | |
167 | - // _value.length > 0 && | |
168 | - // _value.length !== allValues.current.length, | |
169 | - // checkAll: _value && _value.length === allValues.current.length, | |
170 | - // }); | |
171 | - // } | |
123 | + }, [type, byBizTypeList, byDealerList, value]); | |
124 | + | |
125 | + const _onChange = (_value: LabeledValue[], labelList: React.ReactNode[], extra: any) => { | |
126 | + // 手动处理互斥逻辑过滤数据 | |
127 | + // console.log('_value', _value); | |
128 | + // console.log('extra', extra); | |
129 | + let calcedValue = _.cloneDeep(_value); | |
130 | + if (calcedValue.length > 1 && type === 1) { | |
131 | + // 新增选项 | |
132 | + if (calcedValue.length > extra.preValue.length) { | |
133 | + const latestValue = calcedValue[calcedValue.length - 1]; | |
134 | + const bizType = latestValue.value.toString().split('__')[1]; | |
135 | + if (latestValue.value.toString().includes('-1')) { | |
136 | + // 说明新增选项为【全部】,则清空同级其他子项 | |
137 | + calcedValue = calcedValue.filter((i) => { | |
138 | + const currBizType = i.value.toString().split('__')[1]; | |
139 | + return currBizType !== bizType; | |
140 | + }); | |
141 | + calcedValue.push(latestValue); | |
142 | + } else { | |
143 | + // 说明新增选项为同级子项,则清空同级【全部】 | |
144 | + calcedValue = calcedValue.filter((i) => !(i.value === `-1__${bizType}`)); | |
145 | + } | |
146 | + } | |
147 | + } | |
148 | + setValues(calcedValue); | |
172 | 149 | // @ts-ignore |
173 | - onChange && onChange(labelInValue ? _value : _value.map((_v) => _v.value)); | |
150 | + onChange && onChange(labelInValue ? calcedValue : calcedValue.map((_v) => _v.value)); | |
151 | + }; | |
152 | + | |
153 | + const getFilteredData = () => { | |
154 | + if (searchValue.trim() === '') { | |
155 | + return list; | |
156 | + } | |
157 | + let newChilds: DataItem[] = []; | |
158 | + list.forEach((i) => { | |
159 | + const filteredChildren = (i.children ?? []).filter((i) => i.title.toString().toLowerCase().includes(searchValue.trim().toLowerCase())); | |
160 | + if (filteredChildren.length > 0) { | |
161 | + newChilds = newChilds.concat(filteredChildren); | |
162 | + } | |
163 | + }); | |
164 | + return newChilds; | |
174 | 165 | }; |
175 | 166 | |
176 | - const checkAll = (e: CheckboxChangeEvent) => { | |
177 | - const checked = e.target.checked; | |
178 | - // setCheckInfo({ indeterminate: false, checkAll: checked }); | |
179 | - setValues(checked ? allValues.current : []); | |
180 | - onChange && onChange((checked ? (labelInValue ? allValues.current : allValues.current.map((_v) => _v.value)) : []) as LabeledValue[]); | |
167 | + const handleSelect = (_value: any, node: any) => { | |
168 | + let oriNames = value.length > 0 ? value.map((i: any) => i.label) : []; | |
169 | + // value 更新为异步,需手动拼接最新选择值以判断当前筛选值是否已被勾选完 | |
170 | + if (node.pid === -1) { | |
171 | + // 点击父节点 | |
172 | + oriNames = oriNames.concat(node.children.map((i: DataItem) => i.title)); | |
173 | + } else { | |
174 | + oriNames.push(node.title); | |
175 | + } | |
176 | + const valueMatchArr = oriNames.filter((i: string) => i.toLowerCase().includes(searchValue.trim().toLowerCase())); | |
177 | + const filteredData = getFilteredData(); | |
178 | + if (valueMatchArr.length === filteredData.length) { | |
179 | + setSearchValue(''); | |
180 | + } | |
181 | 181 | }; |
182 | 182 | |
183 | 183 | return ( |
184 | 184 | <div id={divId}> |
185 | 185 | <Spin spinning={byDealerLoading || byBizTypeLoading}> |
186 | 186 | <Row justify="space-between" align="middle" style={{ marginBottom: 10 }}> |
187 | - <Radio.Group disabled={disabled} value={type} onChange={(e) => setType(e.target.value)}> | |
187 | + <Radio.Group | |
188 | + disabled={disabled} | |
189 | + value={type} | |
190 | + onChange={(e) => { | |
191 | + setType(e.target.value); | |
192 | + if (e.target.value !== -1) { | |
193 | + // 按业态或商家选择门店时,已选项中只要存在一项【全部】,切换时需清空已选项,反之已选项如果都是具体门店,则切换时不清空,两个维度都可回显查看数据 | |
194 | + if (value.filter((i) => i.value.toString().includes('-1')).length > 0) { | |
195 | + setValues([]); | |
196 | + onChange && onChange([]); | |
197 | + } | |
198 | + } else { | |
199 | + const typeAll = [labelInValue ? { value: '-1__-1', label: '全部门店' } : '-1__-1'] as LabeledValue[]; | |
200 | + setValues(typeAll); | |
201 | + onChange && onChange(typeAll); | |
202 | + } | |
203 | + }} | |
204 | + > | |
205 | + <Radio key={-1} value={-1}> | |
206 | + 全部门店 | |
207 | + </Radio> | |
188 | 208 | <Radio key={1} value={1}> |
189 | 209 | 按业态选择 |
190 | 210 | </Radio> |
... | ... | @@ -192,18 +212,17 @@ function ShopSelectByBizType( |
192 | 212 | 按商家选择 |
193 | 213 | </Radio> |
194 | 214 | </Radio.Group> |
195 | - {multiple && !disabled ? ( | |
196 | - <Checkbox indeterminate={checkInfo.indeterminate} checked={checkInfo.checkAll} onChange={checkAll}> | |
197 | - 全选 | |
198 | - </Checkbox> | |
199 | - ) : null} | |
200 | 215 | </Row> |
201 | 216 | <TreeSelect |
217 | + searchValue={searchValue} | |
218 | + onSearch={(value) => { | |
219 | + setSearchValue(value); | |
220 | + }} | |
221 | + onSelect={handleSelect} | |
202 | 222 | style={{ width: '100%' }} |
203 | - disabled={disabled} | |
223 | + disabled={disabled || type === -1} | |
204 | 224 | value={values} |
205 | 225 | treeData={list} |
206 | - // multiple={multiple} | |
207 | 226 | treeCheckable={multiple} |
208 | 227 | allowClear |
209 | 228 | labelInValue |
... | ... | @@ -219,34 +238,25 @@ function ShopSelectByBizType( |
219 | 238 | ); |
220 | 239 | } |
221 | 240 | |
222 | -function processingChildrenData(data: ShopItem, showIds?: number[], hiddenIds?: number[], disabledIds?: number[]): DataItem[] | undefined { | |
223 | - let _data: ShopItem[] | undefined, _children: DataItem[] | undefined; | |
224 | - | |
225 | - if (showIds?.length) { | |
226 | - _data = data.children ? data.children.filter((shop) => showIds.includes(shop.value || -1)) : undefined; | |
227 | - } else if (hiddenIds?.length) { | |
228 | - _data = data.children ? data.children.filter((shop) => !hiddenIds.includes(shop.value || -1)) : undefined; | |
229 | - } else { | |
230 | - _data = data.children; | |
231 | - } | |
241 | +function processingChildrenData(data: ShopItem, headerAllId: string, value: LabeledValue[]): DataItem[] | undefined { | |
242 | + const _data: ShopItem[] | undefined = data.children; | |
243 | + const pid = Number(headerAllId.split('__')[1]); | |
232 | 244 | |
233 | 245 | // eslint-disable-next-line prefer-const |
234 | - _children = _data | |
246 | + return _data | |
235 | 247 | ? _data.map((shop) => { |
236 | 248 | return { |
237 | 249 | pid: data.value, |
238 | 250 | title: shop.label, |
239 | - // value: idOrCode to idOrCode--bizType | |
240 | - value: `${shop.value}--${shop.bizType}`, | |
241 | - key: `${shop.value}--${shop.bizType}`, | |
251 | + // value: idOrCode to idOrCode__bizType | |
252 | + value: `${shop.value}__${shop.bizType}`, | |
253 | + key: `${shop.value}__${shop.bizType}`, | |
242 | 254 | isLeaf: true, |
243 | 255 | level: 2, |
244 | - disabled: disabledIds?.includes(shop.value || -1), | |
256 | + // disabled: value.findIndex((i) => i.value === headerAllId) > -1 && pid === data.value, | |
245 | 257 | shopId: shop.value, |
246 | 258 | shopName: shop.label, |
247 | 259 | } as DataItem; |
248 | 260 | }) |
249 | 261 | : undefined; |
250 | - | |
251 | - return _children; | |
252 | 262 | } | ... | ... |
src/pages/backlog/TaskConfig/components/CreateModal.tsx
... | ... | @@ -210,26 +210,26 @@ export default function CreateModal({ visible, onCancel, item, onRefreshing, sys |
210 | 210 | }} |
211 | 211 | </Form.Item> |
212 | 212 | |
213 | - <Form.Item noStyle shouldUpdate={(pre, cur) => pre.itemType !== cur.itemType || pre.customTemp !== cur.customTemp}> | |
213 | + <Form.Item noStyle shouldUpdate={(pre, cur) => pre.itemType !== cur.itemType}> | |
214 | 214 | {({ getFieldValue }) => { |
215 | 215 | const itemType = getFieldValue('itemType'); |
216 | 216 | const customTemp = getFieldValue('customTemp'); |
217 | 217 | |
218 | 218 | if (itemType === TodoTypeEnum['提示性']) { |
219 | 219 | // 业务性待办 |
220 | - if (!customTemp) { | |
221 | - // 不使用自定义模板 | |
222 | - return ( | |
223 | - <Form.Item | |
224 | - label="待办模版" | |
225 | - name="dynamicTemp" | |
226 | - rules={[{ required: true, message: '必填项' }]} | |
227 | - extra={<span>{'换行使用“\n”,动态内容用“${}”包含,如:您的验证码是“${}”(其中code是变量)'}</span>} | |
228 | - > | |
229 | - <TextArea placeholder="请输入" allowClear autoSize={{ minRows: 4 }} /> | |
230 | - </Form.Item> | |
231 | - ); | |
232 | - } | |
220 | + // if (!customTemp) { | |
221 | + // 不使用自定义模板 | |
222 | + return ( | |
223 | + <Form.Item | |
224 | + label="待办模版" | |
225 | + name="dynamicTemp" | |
226 | + rules={[{ required: true, message: '必填项' }]} | |
227 | + extra={<span>{'换行使用“\n”,动态内容用“${}”包含,如:您的验证码是“${}”(其中code是变量)'}</span>} | |
228 | + > | |
229 | + <TextArea placeholder="请输入" allowClear autoSize={{ minRows: 4 }} /> | |
230 | + </Form.Item> | |
231 | + ); | |
232 | + // } | |
233 | 233 | } |
234 | 234 | return null; |
235 | 235 | }} | ... | ... |
src/pages/capital/ReceiveRules/subPages/ShopsDimension/index.tsx
... | ... | @@ -14,7 +14,7 @@ import AuthCheckResult from '@/pages/capital/ReceiveRules/component/AuthCheckRes |
14 | 14 | export default function SpecConfig() { |
15 | 15 | const { list, loading, setLoading, setParams, paginationConfig } = usePagination(api.getShopPostAuthApi, {}); |
16 | 16 | const [confirLoaing, setConfirLoading] = useState<boolean>(false); |
17 | - const [modalPa, setModalPa] = useState({ visible: false, rowValue: undefined }); | |
17 | + const [modalPa, setModalPa] = useState({ visible: false, rowValue: undefined, isEdit: false }); | |
18 | 18 | |
19 | 19 | const edit = (record: any) => { |
20 | 20 | const editItem = { |
... | ... | @@ -23,7 +23,7 @@ export default function SpecConfig() { |
23 | 23 | postList: { value: record.postId, label: record.postName }, |
24 | 24 | standardId: { id: record.standardId, name: record.name } |
25 | 25 | }; |
26 | - setModalPa({ visible: true, rowValue: editItem }); | |
26 | + setModalPa({ visible: true, isEdit: true, rowValue: editItem }); | |
27 | 27 | }; |
28 | 28 | |
29 | 29 | const handDelete = (v: OdSetting.GoodsAuthList) => { |
... | ... | @@ -66,13 +66,65 @@ export default function SpecConfig() { |
66 | 66 | api.addSingleAuth(params).then(res => { |
67 | 67 | message.success('保存成功'); |
68 | 68 | setLoading(true); |
69 | - setModalPa({ visible: false, rowValue: undefined }); | |
69 | + setModalPa({ visible: false, isEdit: false, rowValue: undefined }); | |
70 | 70 | }).catch(e => { |
71 | 71 | message.error(e.message); |
72 | 72 | }).finally(() => { |
73 | 73 | // setConfirmloading(false); |
74 | 74 | }); |
75 | 75 | } |
76 | + | |
77 | + /**新增多选门店岗位 */ | |
78 | + function saveAddAuth(i: any) { | |
79 | + const params = { | |
80 | + standardIds: i.standardId.id ? [i.standardId.id] : [], | |
81 | + shopAuthPostList: [ | |
82 | + { | |
83 | + shopIds: i.shopIds.map((shop: { value: any }) => shop.value), | |
84 | + postList: i.postList.map((post: { value: any; label: any }) => ({ postId: post.value, postName: post.label })), | |
85 | + periodDto: { maxNum: i.maxNum, periodType: i.periodType, period: i.period }, | |
86 | + }, | |
87 | + ], | |
88 | + }; | |
89 | + setConfirLoading(true); | |
90 | + api.saveGoodsDimensionCheck({ ...params, pageSize: 1000 }) | |
91 | + .then((res) => { | |
92 | + if (res.data && res.data?.total) { | |
93 | + Modal.confirm({ | |
94 | + title: '已有授权信息,继续提交将覆盖以下授权', | |
95 | + icon: <ExclamationCircleOutlined />, | |
96 | + width: 700, | |
97 | + content: <AuthCheckResult data={res.data} />, | |
98 | + okText: '确认', | |
99 | + cancelText: '取消', | |
100 | + onOk: () => onSubmitItems(params), | |
101 | + }); | |
102 | + } else { | |
103 | + onSubmitItems(params); | |
104 | + } | |
105 | + }) | |
106 | + .catch((e) => { | |
107 | + message.error(e.message); | |
108 | + }) | |
109 | + .finally(() => { | |
110 | + setConfirLoading(false); | |
111 | + }); | |
112 | + } | |
113 | + | |
114 | + function onSubmitItems(params: any) { | |
115 | + api.saveGoodsDimension(params) | |
116 | + .then((res) => { | |
117 | + message.success('保存成功'); | |
118 | + // history.back(); | |
119 | + setLoading(true); | |
120 | + }) | |
121 | + .catch((e) => { | |
122 | + message.error(e.message); | |
123 | + }) | |
124 | + .finally(() => { | |
125 | + setConfirLoading(false); | |
126 | + }); | |
127 | + } | |
76 | 128 | return ( |
77 | 129 | <PageHeaderWrapper |
78 | 130 | title="门店维度授权" |
... | ... | @@ -84,7 +136,7 @@ export default function SpecConfig() { |
84 | 136 | <Button |
85 | 137 | type="primary" |
86 | 138 | icon={<PlusOutlined />} |
87 | - onClick={() => setModalPa({ visible: true, rowValue: undefined })} | |
139 | + onClick={() => setModalPa({ visible: true, isEdit: false, rowValue: undefined })} | |
88 | 140 | > |
89 | 141 | 新增 |
90 | 142 | </Button> |
... | ... | @@ -142,13 +194,14 @@ export default function SpecConfig() { |
142 | 194 | /> |
143 | 195 | </Table> |
144 | 196 | <AddModal |
145 | - multiple={false} | |
146 | - visible={modalPa.visible} | |
147 | - onSave={save} | |
197 | + // multiple={false} | |
148 | 198 | selectGoods |
199 | + multiple={!modalPa.isEdit} | |
200 | + visible={modalPa.visible} | |
201 | + onSave={modalPa.isEdit ? save : saveAddAuth} | |
149 | 202 | disabled={!!modalPa.rowValue} |
150 | 203 | current={modalPa.rowValue} |
151 | - onCancel={() => { setModalPa({ visible: false, rowValue: undefined }); }} | |
204 | + onCancel={() => { setModalPa({ visible: false, isEdit: false, rowValue: undefined }); }} | |
152 | 205 | /> |
153 | 206 | </Card> |
154 | 207 | </PageHeaderWrapper> | ... | ... |
src/pages/cas/ClaimConfirmation/components/SpecialFeeConfirm.tsx
... | ... | @@ -4,6 +4,7 @@ import type { ColumnsType } from 'antd/es/table'; |
4 | 4 | import moment from 'moment'; |
5 | 5 | |
6 | 6 | import { formatPartCnt } from '@/pages/cas/utils'; |
7 | +import rmb from '@/utils/rmb'; | |
7 | 8 | |
8 | 9 | import { checkSpecialFee, getSpecialFeeDetail, SpecialFee, SpecialFeeApproveEnum, SpecialFeeParams, SpecialItem } from '../api'; |
9 | 10 | import ImageModal from "@/pages/cas/ClaimConfirmation/components/ImageModal"; |
... | ... | @@ -86,14 +87,14 @@ export default function SpecialFeeDetail({ current, visible, setVisible, setLoad |
86 | 87 | dataIndex: 'itemPartFee', |
87 | 88 | title: '材料费', |
88 | 89 | onCell: (record: any) => renderCell(record), |
89 | - render: (val) => `${Number(val).toFixed(2)}`, | |
90 | + render: (val) => rmb.p(val), | |
90 | 91 | align: 'right', |
91 | 92 | }, |
92 | 93 | { |
93 | 94 | dataIndex: 'manHoursFee', |
94 | 95 | title: '工时费', |
95 | 96 | onCell: (record: any) => renderCell(record), |
96 | - render: (val) => `${Number(val).toFixed(2)}`, | |
97 | + render: (val) => rmb.p(val), | |
97 | 98 | align: 'right', |
98 | 99 | }, |
99 | 100 | { |
... | ... | @@ -112,13 +113,13 @@ export default function SpecialFeeDetail({ current, visible, setVisible, setLoad |
112 | 113 | { |
113 | 114 | dataIndex: 'unitPrice', |
114 | 115 | title: '原价', |
115 | - render: (val) => `${Number(val).toFixed(2)}`, | |
116 | + render: (val) => rmb.p(val), | |
116 | 117 | align: 'right', |
117 | 118 | }, |
118 | 119 | { |
119 | 120 | dataIndex: 'partFee', |
120 | 121 | title: '单价', |
121 | - render: (val) => `${Number(val).toFixed(2)}`, | |
122 | + render: (val) => rmb.p(val), | |
122 | 123 | align: 'right', |
123 | 124 | }, |
124 | 125 | ]; | ... | ... |
src/pages/cas/ClaimReviewPool/EditComfirm/index.tsx
... | ... | @@ -89,8 +89,8 @@ function Index(props: Props) { |
89 | 89 | render={(name) => (name !== undefined ? name : '--')} |
90 | 90 | width={200} |
91 | 91 | /> |
92 | - <Column title="救援费(元)" dataIndex="claimSubmitAmount" align="center" render={(name) => (name !== undefined ? name : '--')} width={200} /> | |
93 | - {/* <Column title="提报金额(元)" dataIndex="claimSubmitAmount" align="center" render={(name) => (name !== undefined ? name : '--')} /> */} | |
92 | + {/*todo 救援模块未上线,默认展示--,上线后展示对应字段 */} | |
93 | + <Column title="救援费(元)" dataIndex="claimSubmitAmount" align="center" render={() => '--'} width={200} /> | |
94 | 94 | </Table> |
95 | 95 | </Card> |
96 | 96 | </PageHeaderWrapper> | ... | ... |
src/pages/cas/MaintenanceCard/MPList/components/Operation.tsx
... | ... | @@ -18,12 +18,12 @@ export default function Oparetion(props: Props) { |
18 | 18 | |
19 | 19 | /** 查看详情 编辑 */ |
20 | 20 | function _viewDetail() { |
21 | - history.push(`/cas/MaintenancePackageCard/list/upsert/${record.brandId}/${record.maintainId}?brandName=${record && record.brandName || ''}`); | |
21 | + history.push(`/cas/promotionConfig/MaintenancePackageCard/list/upsert/${record.brandId}/${record.maintainId}?brandName=${record && record.brandName || ''}`); | |
22 | 22 | } |
23 | 23 | |
24 | 24 | function _viewDetailOil() { |
25 | 25 | history.push( |
26 | - `/cas/MaintenancePackageCard/list/oil/${record.brandId}/${ | |
26 | + `/cas/promotionConfig/MaintenancePackageCard/list/oil/${record.brandId}/${ | |
27 | 27 | record.maintainId |
28 | 28 | }?brandName=${(record && record.brandName) || ""}` |
29 | 29 | ); |
... | ... | @@ -132,4 +132,4 @@ export default function Oparetion(props: Props) { |
132 | 132 | )} |
133 | 133 | </> |
134 | 134 | ); |
135 | -} | |
136 | 135 | \ No newline at end of file |
136 | +} | ... | ... |
src/pages/cas/MaintenanceCard/MPList/index.tsx
... | ... | @@ -17,7 +17,7 @@ const Setting = (props: ConnectProps) => { |
17 | 17 | const { list, loading, innerParams, hasStorage, setParams, paginationConfig, setLoading } = usePagination<IF.ListVO>( |
18 | 18 | getListApi, |
19 | 19 | {}, |
20 | - { pageName: '/cas/MaintenancePackageCard/list', notList: true, delay }, | |
20 | + { pageName: '/cas/promotionConfig/MaintenancePackageCard/list', notList: true, delay }, | |
21 | 21 | ); |
22 | 22 | |
23 | 23 | useEffect(() => { |
... | ... | @@ -47,7 +47,7 @@ const Setting = (props: ConnectProps) => { |
47 | 47 | return; |
48 | 48 | } |
49 | 49 | const brand = brands.find((r) => r.brandId == brandId); |
50 | - history.push(`/cas/MaintenancePackageCard/list/upsert/${brandId}?brandName=${(brand && brand.brandName) || ''}`); | |
50 | + history.push(`/cas/promotionConfig/MaintenancePackageCard/list/upsert/${brandId}?brandName=${(brand && brand.brandName) || ''}`); | |
51 | 51 | } |
52 | 52 | |
53 | 53 | return ( | ... | ... |
src/pages/cas/MaintenanceCard/Upsert/index.tsx
... | ... | @@ -31,26 +31,6 @@ const Create = (props: Prop) => { |
31 | 31 | const [oil, setOil] = useState<number>(); |
32 | 32 | const [exData, setExData] = useState<any[]>([]); |
33 | 33 | |
34 | - // const { setFormStorage, removeFormStorage, hasFormStorage } = useFormStorage(`form/cas/MaintenancePackageCard/list/upsert/${brandId}/${maintainId}/${isCopy}`, form); | |
35 | - // const { removeStorage } = useStorage(`/cas/MaintenancePackageCard/list/upsert/${brandId}/${maintainId}/${isCopy}`, { | |
36 | - // detail: { | |
37 | - // data: detail, | |
38 | - // setData: setDetail | |
39 | - // }, | |
40 | - // current: { | |
41 | - // data: current, | |
42 | - // setData: setCurrent | |
43 | - // } | |
44 | - // }) | |
45 | - | |
46 | - // useEffect(() => { | |
47 | - // if (!hasFormStorage) { | |
48 | - // if (maintainId) { | |
49 | - // loadData(); | |
50 | - // } | |
51 | - // } | |
52 | - // }, [hasFormStorage]); | |
53 | - | |
54 | 34 | useEffect(() => { |
55 | 35 | if (maintainId) { |
56 | 36 | loadData(); |
... | ... | @@ -100,7 +80,7 @@ const Create = (props: Prop) => { |
100 | 80 | setOil(_oil); |
101 | 81 | }) |
102 | 82 | .catch((e) => console.log(e.message)) |
103 | - } | |
83 | + } | |
104 | 84 | _data.series = {value: res.data!.seriesId, label: res.data!.seriesName} |
105 | 85 | // _data.oilDosage = oil |
106 | 86 | if (isCopy) { |
... | ... | @@ -220,4 +200,4 @@ const Create = (props: Prop) => { |
220 | 200 | ); |
221 | 201 | } |
222 | 202 | |
223 | -export default Create; | |
224 | 203 | \ No newline at end of file |
204 | +export default Create; | ... | ... |
src/pages/cas/MarketAction/index.tsx
... | ... | @@ -46,7 +46,7 @@ export default () => { |
46 | 46 | <Card> |
47 | 47 | <Row justify="space-between" style={{ marginBottom: 16 }}> |
48 | 48 | <Filter setParams={setParams} innerParams={innerParams} /> |
49 | - <Button type="primary" onClick={() => history.push(`/cas/marketAction/edit`)}> | |
49 | + <Button type="primary" onClick={() => history.push(`/cas//marketAction/edit`)}> | |
50 | 50 | 新增 |
51 | 51 | </Button> |
52 | 52 | </Row> |
... | ... | @@ -146,7 +146,7 @@ export default () => { |
146 | 146 | {record.status !== 3 && ( |
147 | 147 | <Typography.Link |
148 | 148 | onClick={() => { |
149 | - history.push(`/cas/marketAction/edit/${record.id}`); | |
149 | + history.push(`/cas/promotionConfig/marketAction/edit/${record.id}`); | |
150 | 150 | }} |
151 | 151 | > |
152 | 152 | 编辑 | ... | ... |
src/pages/cas/WarrantyCardSetting/components/Operation.tsx
... | ... | @@ -18,7 +18,7 @@ export default function Oparetion(props: Props) { |
18 | 18 | |
19 | 19 | /** 查看详情 编辑 */ |
20 | 20 | function _viewDetail() { |
21 | - history.push(`/cas/WarrantyCard/Detail/${record.brandId}/${record.warrantyId}?brandName=${record && record.brandName || ''}`); | |
21 | + history.push(`/cas/promotionConfig/WarrantyCard/Detail/${record.brandId}/${record.warrantyId}?brandName=${record && record.brandName || ''}`); | |
22 | 22 | } |
23 | 23 | |
24 | 24 | |
... | ... | @@ -104,4 +104,4 @@ export default function Oparetion(props: Props) { |
104 | 104 | )} |
105 | 105 | </React.Fragment> |
106 | 106 | ); |
107 | -} | |
108 | 107 | \ No newline at end of file |
108 | +} | ... | ... |
src/pages/cas/WarrantyCardSetting/index.tsx
... | ... | @@ -17,7 +17,7 @@ const Setting = (props: common.ConnectProps) => { |
17 | 17 | const { list, loading, innerParams, hasStorage, setParams, paginationConfig, setLoading } = usePagination<IF.ListVO>( |
18 | 18 | getListApi, |
19 | 19 | {}, |
20 | - { pageName: '/cas/WarrantyCard/Setting', notList: true, delay }, | |
20 | + { pageName: '/cas/promotionConfig/WarrantyCard/Setting', notList: true, delay }, | |
21 | 21 | ); |
22 | 22 | |
23 | 23 | useEffect(() => { |
... | ... | @@ -47,7 +47,7 @@ const Setting = (props: common.ConnectProps) => { |
47 | 47 | return; |
48 | 48 | } |
49 | 49 | const brand = brands.find((r) => r.brandId == brandId); |
50 | - history.push(`/cas/WarrantyCard/Detail/${brandId}?brandName=${(brand && brand.brandName) || ''}`); | |
50 | + history.push(`/cas/promotionConfig/WarrantyCard/Detail/${brandId}?brandName=${(brand && brand.brandName) || ''}`); | |
51 | 51 | } |
52 | 52 | |
53 | 53 | return ( | ... | ... |
src/pages/cas/baseConfig/ShopRelateBizConfig/api.ts
0 → 100644
1 | +import { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { CAS_HOST } from '@/utils/host'; | |
4 | +import { BizType } from './entity'; | |
5 | + | |
6 | +type P<T> = http.PromiseResp<T>; | |
7 | +type Page<T> = http.PromisePageResp<T>; | |
8 | + | |
9 | +interface ListParams { | |
10 | + groupId?: number; | |
11 | + shopId?: number; | |
12 | + userId?: number; | |
13 | + userName?: string; | |
14 | + pageSize?: number; | |
15 | + current?: number; | |
16 | + keywords?: string; // 业务门店 | |
17 | + authBusiness?: BizType; // 授权售后业务类型 | |
18 | +} | |
19 | + | |
20 | +export interface ListResult { | |
21 | + id: number; // 配置 id | |
22 | + authBusiness: BizType; // 门店授权业务类型 | |
23 | + authBusinessName: string; // 业务类型名称 | |
24 | + associationShopId: number; // 业务门店id | |
25 | + associationShopName: string; // 业务门店 | |
26 | + shopList: { id: number; shopName: string }[]; // 门店列表 | |
27 | +} | |
28 | + | |
29 | +export interface Shop { | |
30 | + id: number; | |
31 | + shopName: string; | |
32 | + [key: string]: any; | |
33 | +} | |
34 | + | |
35 | +export interface SaveParams { | |
36 | + id?: number; | |
37 | + authBusiness: BizType; | |
38 | + associationShopId: number; | |
39 | + associationShopName: string; | |
40 | + shopIds: number[]; // 关联门店 | |
41 | +} | |
42 | + | |
43 | +// 列表 | |
44 | +export function listApi(params: ListParams): Page<ListResult> { | |
45 | + return request.get(`${CAS_HOST}/erp/shop/association/setting/page`, { params }); | |
46 | +} | |
47 | + | |
48 | +// 详情 | |
49 | +export function detailApi(associationShopId: number): P<ListResult> { | |
50 | + return request.get(`${CAS_HOST}/erp/shop/association/setting/detail`, { params: { associationShopId } }); | |
51 | +} | |
52 | + | |
53 | +// 保存 | |
54 | +export function saveApi(params: SaveParams) { | |
55 | + return request.post(`${CAS_HOST}/erp/shop/association/setting/save`, params); | |
56 | +} | |
57 | + | |
58 | +// 删除 | |
59 | +export function deleteApi(id: number) { | |
60 | + return request.post(`${CAS_HOST}/erp/shop/association/setting/delete`, { id }); | |
61 | +} | |
62 | + | |
63 | +// 业务对应门店列表 | |
64 | +export function getShopListApi(authBusiness: BizType): P<Shop[]> { | |
65 | + return request.get(`${CAS_HOST}/erp/shop/association/find/shops`, { params: { authBusiness } }); | |
66 | +} | ... | ... |
src/pages/cas/baseConfig/ShopRelateBizConfig/components/EditModal.tsx
0 → 100644
1 | +import React, { useEffect, useState } from 'react'; | |
2 | +import { Form, message, Modal, Radio, Select } from 'antd'; | |
3 | + | |
4 | +import SelectorWithFull from '@/components/SelectorWithFull'; | |
5 | + | |
6 | +import useInitail from '@/hooks/useInitail'; | |
7 | +import { fetchShopListByRangeTypeApi } from '@/common/api'; | |
8 | +import { BizTypeData } from "@/pages/cas/baseConfig/ShopRelateBizConfig/entity"; | |
9 | +import { getShopListApi, saveApi, type ListResult, type SaveParams } from '../api'; | |
10 | + | |
11 | +const FormItem = Form.Item; | |
12 | +const Option = Select.Option; | |
13 | + | |
14 | +interface Props { | |
15 | + open: boolean; | |
16 | + onCancel: () => any; | |
17 | + detail: ListResult; // 详情数据 | |
18 | +} | |
19 | + | |
20 | +export default function EditModal({ open, onCancel, detail }: Props) { | |
21 | + const [form] = Form.useForm(); | |
22 | + const [delay, setDelay] = useState(true); | |
23 | + const [allDelay, setAllDelay] = useState(true); | |
24 | + // 所有门店 | |
25 | + const { data: allShops, setParams: setAllParams } = useInitail(fetchShopListByRangeTypeApi, [], {}, allDelay); | |
26 | + // 包含业务的门店列表 | |
27 | + const { data: shops, setParams } = useInitail(getShopListApi, [], 10, delay); | |
28 | + | |
29 | + useEffect(() => { | |
30 | + if (open) { | |
31 | + setAllDelay(false); | |
32 | + setAllParams({}, true); | |
33 | + | |
34 | + if (detail && detail.shopList) { | |
35 | + form.setFieldsValue({ | |
36 | + id: detail.id, | |
37 | + authBusiness: detail.authBusiness, | |
38 | + associationShop: { | |
39 | + value: detail.associationShopId, | |
40 | + label: detail.associationShopName, | |
41 | + }, | |
42 | + shopIds: detail.shopList.map((shop) => shop.id), | |
43 | + }); | |
44 | + setDelay(false); | |
45 | + setParams(detail.authBusiness, true); | |
46 | + } else { | |
47 | + form.resetFields(); | |
48 | + } | |
49 | + } | |
50 | + }, [open]); | |
51 | + | |
52 | + // 获取对应业务门店列表 | |
53 | + const handleBizChange = (e) => { | |
54 | + setDelay(false); | |
55 | + setParams(e.target.value, true); | |
56 | + }; | |
57 | + | |
58 | + function handleSave(formValue: any) { | |
59 | + const params: SaveParams = { | |
60 | + id: formValue.id, | |
61 | + authBusiness: formValue.authBusiness, | |
62 | + associationShopId: formValue.associationShop.value, | |
63 | + associationShopName: formValue.associationShop.label, | |
64 | + shopIds: formValue.shopIds, | |
65 | + }; | |
66 | + | |
67 | + saveApi(params) | |
68 | + .then(() => { | |
69 | + message.success('操作成功'); | |
70 | + onCancel(); | |
71 | + }) | |
72 | + .catch((e) => message.error(e.message)); | |
73 | + } | |
74 | + | |
75 | + return ( | |
76 | + <Modal | |
77 | + open={open} | |
78 | + maskClosable={false} | |
79 | + title={`${!detail.id ? '新增' : '编辑'}业务映射门店`} | |
80 | + width={700} | |
81 | + onCancel={() => onCancel()} | |
82 | + onOk={() => form.submit()} | |
83 | + > | |
84 | + <Form form={form} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} initialValues={{ type: 1 }} onFinish={handleSave}> | |
85 | + <FormItem name="id" hidden /> | |
86 | + <FormItem name="authBusiness" label="业务" rules={[{ required: true, message: '请选择业务' }]}> | |
87 | + <Radio.Group onChange={handleBizChange}> | |
88 | + {BizTypeData.map((item) => <Radio value={item.value}>{item.label}</Radio>)} | |
89 | + </Radio.Group> | |
90 | + </FormItem> | |
91 | + <FormItem name="associationShop" label="业务门店" rules={[{ required: true, message: '请选择业务门店' }]}> | |
92 | + <Select placeholder="选择业务门店" labelInValue showSearch optionFilterProp="children"> | |
93 | + {shops.map((shop) => ( | |
94 | + <Option value={shop.id}>{shop.shopName}</Option> | |
95 | + ))} | |
96 | + </Select> | |
97 | + </FormItem> | |
98 | + <FormItem name="shopIds" label="映射门店" rules={[{ required: true, message: '映射门店' }]}> | |
99 | + <SelectorWithFull | |
100 | + placeholder="选择映射门店" | |
101 | + data={allShops} | |
102 | + allowClear | |
103 | + multiple | |
104 | + showSearch | |
105 | + treeNodeFilterProp="label" | |
106 | + autoClearSearchValue={false} | |
107 | + fieldKeyNames={{ keyName: 'id', valueName: 'id', labelName: 'name' }} | |
108 | + /> | |
109 | + </FormItem> | |
110 | + </Form> | |
111 | + </Modal> | |
112 | + ); | |
113 | +} | ... | ... |
src/pages/cas/baseConfig/ShopRelateBizConfig/entity.ts
0 → 100644
1 | +export enum BizType { | |
2 | + /** 维保 */ | |
3 | + MAINTAIN = 10, | |
4 | + /** 钣喷 */ | |
5 | + METAL = 20, | |
6 | + /** 装潢 */ | |
7 | + DECORATION = 30, | |
8 | +} | |
9 | + | |
10 | +export const BizTypeData = [ | |
11 | + { | |
12 | + label: '维保', | |
13 | + value: BizType.MAINTAIN, | |
14 | + }, | |
15 | + { | |
16 | + label: '钣喷', | |
17 | + value: BizType.METAL, | |
18 | + }, | |
19 | + { | |
20 | + label: '装潢', | |
21 | + value: BizType.DECORATION, | |
22 | + }, | |
23 | +]; | ... | ... |
src/pages/cas/baseConfig/ShopRelateBizConfig/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
3 | +import { Button, Card, Col, Divider, Input, message, Popconfirm, Radio, Row, Table } from 'antd'; | |
4 | +import { debounce } from 'lodash'; | |
5 | +import { ColumnsType } from 'antd/lib/table'; | |
6 | + | |
7 | +import usePagination from '@/hooks/usePagination'; | |
8 | + | |
9 | +import TextWithMore from '@/components/TextWithMore'; | |
10 | + | |
11 | +import { BizTypeData } from '@/pages/cas/baseConfig/ShopRelateBizConfig/entity'; | |
12 | +import { deleteApi, listApi, type ListResult } from './api'; | |
13 | + | |
14 | +import EditModal from './components/EditModal'; | |
15 | + | |
16 | +const Search = Input.Search; | |
17 | + | |
18 | +export default function WorkStationIndex() { | |
19 | + const [open, setOpen] = useState(false); | |
20 | + const [item, setItem] = useState<any>({}); | |
21 | + | |
22 | + const { list, loading, setLoading, setParams, paginationConfig } = usePagination(listApi, [], {}); | |
23 | + | |
24 | + const columns: ColumnsType<ListResult> = [ | |
25 | + { | |
26 | + title: '业务', | |
27 | + dataIndex: 'authBusinessName', | |
28 | + }, | |
29 | + { | |
30 | + title: '业务门店', | |
31 | + dataIndex: 'associationShopName', | |
32 | + }, | |
33 | + { | |
34 | + title: '映射门店', | |
35 | + dataIndex: 'shopList', | |
36 | + render: (shops: any, record) => <TextWithMore title={`${record.authBusinessName}业务映射门店`} list={shops} dataIndex="shopName" />, | |
37 | + }, | |
38 | + { | |
39 | + title: '操作', | |
40 | + dataIndex: 'associationShopId', | |
41 | + render: (id, record) => ( | |
42 | + <> | |
43 | + <a | |
44 | + onClick={(e) => { | |
45 | + e.preventDefault(); | |
46 | + setItem(record); | |
47 | + setOpen(true); | |
48 | + }} | |
49 | + > | |
50 | + 编辑 | |
51 | + </a> | |
52 | + <span> | |
53 | + <Divider type="vertical" /> | |
54 | + <Popconfirm title="是否删除?" onConfirm={() => handleDelete(id)} okText="确定" cancelText="取消"> | |
55 | + <a onClick={(e) => e.preventDefault()} style={{ color: 'red' }}> | |
56 | + 删除 | |
57 | + </a> | |
58 | + </Popconfirm> | |
59 | + </span> | |
60 | + </> | |
61 | + ), | |
62 | + }, | |
63 | + ]; | |
64 | + | |
65 | + const handleSearch = debounce((keywords: string) => setParams({ keywords }, true), 500); | |
66 | + | |
67 | + const handleTypeChange = (e: any) => { | |
68 | + setParams({ authBusiness: e.target.value }, true); | |
69 | + }; | |
70 | + | |
71 | + function handleDelete(id: number) { | |
72 | + deleteApi(id) | |
73 | + .then(() => { | |
74 | + message.success('删除成功'); | |
75 | + setLoading(true); | |
76 | + }) | |
77 | + .catch((e) => message.error(e.message)); | |
78 | + } | |
79 | + | |
80 | + return ( | |
81 | + <PageHeaderWrapper title="业务映射门店"> | |
82 | + <Card> | |
83 | + <Row justify="space-between" style={{ marginBottom: 16 }}> | |
84 | + <Col> | |
85 | + <Radio.Group defaultValue={undefined} onChange={handleTypeChange}> | |
86 | + <Radio.Button value={undefined}>全部</Radio.Button> | |
87 | + {BizTypeData.map((item) => ( | |
88 | + <Radio.Button key={item.value} value={item.value}> | |
89 | + {item.label} | |
90 | + </Radio.Button> | |
91 | + ))} | |
92 | + </Radio.Group> | |
93 | + <Search style={{ width: 240, marginLeft: 20 }} placeholder="搜索业务门店" allowClear onChange={(e) => handleSearch(e.target.value)} /> | |
94 | + </Col> | |
95 | + <Col> | |
96 | + <Button type="primary" onClick={() => setOpen(true)}> | |
97 | + 新增 | |
98 | + </Button> | |
99 | + </Col> | |
100 | + </Row> | |
101 | + | |
102 | + <Table dataSource={list} columns={columns} pagination={paginationConfig} rowKey="id" loading={loading} /> | |
103 | + </Card> | |
104 | + | |
105 | + <EditModal | |
106 | + open={open} | |
107 | + detail={item} | |
108 | + onCancel={() => { | |
109 | + setOpen(false); | |
110 | + setItem({}); | |
111 | + setLoading(true); | |
112 | + }} | |
113 | + /> | |
114 | + </PageHeaderWrapper> | |
115 | + ); | |
116 | +} | ... | ... |
src/pages/dalaran/MediaSettings/components/ThemeSettings/Modal.tsx
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | * @Author: wangqiang@feewee.cn |
3 | 3 | * @Date: 2023-05-06 10:39:03 |
4 | 4 | * @LastEditors: wangqiang@feewee.cn |
5 | - * @LastEditTime: 2024-01-05 15:07:27 | |
5 | + * @LastEditTime: 2024-04-03 09:33:29 | |
6 | 6 | */ |
7 | 7 | /** |
8 | 8 | * Disclaimer: |
... | ... | @@ -378,8 +378,8 @@ function TopicItem({ oldValue, value, onChange }: TopicItemProps) { |
378 | 378 | onChange={(e) => setInputVal(e.target.value)} |
379 | 379 | onPressEnter={save} |
380 | 380 | style={{ flex: 1 }} |
381 | - maxLength={13} | |
382 | - showCount | |
381 | + // maxLength={13} | |
382 | + // showCount | |
383 | 383 | /> |
384 | 384 | <Button type="link" size="small" onClick={save}> |
385 | 385 | {key ? '修改' : '添加'} | ... | ... |
src/pages/decoration/deco/DecorationPromotion/DecorateFullFree/index.tsx
... | ... | @@ -192,7 +192,7 @@ function DecorateFullFree() { |
192 | 192 | <Divider type="vertical" /> |
193 | 193 | <Popconfirm |
194 | 194 | title="是否提前结束?" |
195 | - onConfirm={() => earlyEndHandle(record.id || 0, () => setParams({ ...innerParams, current: 1 }, true))} | |
195 | + onConfirm={() => earlyEndHandle(record.id || 0, () => setParams({ ...innerParams }, true))} | |
196 | 196 | okText="确定" |
197 | 197 | cancelText="取消" |
198 | 198 | > |
... | ... | @@ -220,7 +220,7 @@ function DecorateFullFree() { |
220 | 220 | <AdjustDateModal |
221 | 221 | visible={adjustDateVisible} |
222 | 222 | onCancel={() => setAdjustDateVisible(false)} |
223 | - fetchList={() => setParams({ ...innerParams, current: 1 }, true)} | |
223 | + fetchList={() => setParams({ ...innerParams }, true)} | |
224 | 224 | id={item.id} |
225 | 225 | startTime={item.startTime} |
226 | 226 | endTime={item.endTime} | ... | ... |
src/pages/decoration/deco/DecorationPromotion/DecorationPackage/index.tsx
... | ... | @@ -145,7 +145,7 @@ function DecorationPackage() { |
145 | 145 | <Divider type="vertical" /> |
146 | 146 | <Popconfirm |
147 | 147 | title="是否提前结束?" |
148 | - onConfirm={() => earlyEndHandle(record.id || 0, () => setParams({...innerParams, current: 1}, true))} | |
148 | + onConfirm={() => earlyEndHandle(record.id || 0, () => setParams({...innerParams}, true))} | |
149 | 149 | okText="确定" |
150 | 150 | cancelText="取消" |
151 | 151 | > |
... | ... | @@ -173,7 +173,7 @@ function DecorationPackage() { |
173 | 173 | <AdjustDateModal |
174 | 174 | visible={adjustDateVisible} |
175 | 175 | onCancel={() => setAdjustDateVisible(false)} |
176 | - fetchList={() => setParams({...innerParams, current: 1}, true)} | |
176 | + fetchList={() => setParams({...innerParams}, true)} | |
177 | 177 | id={item.id} |
178 | 178 | startTime={item.startTime} |
179 | 179 | endTime={item.endTime} | ... | ... |
src/pages/decoration/deco/DecorationPromotion/SPPManage/subPage/indexPage.tsx
1 | 1 | import React, { useState } from 'react'; |
2 | -import { Button, Popconfirm, Divider, Table, message, DatePicker, Input } from 'antd'; | |
2 | +import { Button, Popconfirm, Divider, Table, message, DatePicker, Input, Select } from 'antd'; | |
3 | 3 | import { useStore } from '../index'; |
4 | 4 | import * as API from '../api'; |
5 | 5 | import usePagination from '@/hooks/usePagination'; |
... | ... | @@ -11,6 +11,7 @@ import AdjustDateModal from '@/pages/decoration/deco/componets/AdjustDateModal'; |
11 | 11 | const { Column } = Table; |
12 | 12 | const { RangePicker } = DatePicker; |
13 | 13 | const { Search } = Input; |
14 | +const { Option } = Select; | |
14 | 15 | |
15 | 16 | export function earlyEndHandle(id: number, callBack?: () => any) { |
16 | 17 | API.earlyEnd(id).then(() => { |
... | ... | @@ -90,9 +91,15 @@ export default function IndexPage() { |
90 | 91 | ], |
91 | 92 | }} |
92 | 93 | format="YYYY-MM-DD" |
93 | - //disabledDate={(current) => disalbeTime(current)} | |
94 | 94 | onChange={(time) => onTime(time)} |
95 | 95 | /> |
96 | + <Select style={{ width: 200, marginLeft: 10 }} placeholder="请选择状态" onChange={v => setParams({ flowStatus: v}, true)} allowClear> | |
97 | + <Option value="1">待审批</Option> | |
98 | + <Option value="2">已通过</Option> | |
99 | + <Option value="3">已拒绝</Option> | |
100 | + <Option value="98">已过期</Option> | |
101 | + <Option value="99">已取消</Option> | |
102 | + </Select> | |
96 | 103 | </div> |
97 | 104 | <Button type="primary" onClick={itemClick}> |
98 | 105 | 新增 |
... | ... | @@ -158,7 +165,7 @@ export default function IndexPage() { |
158 | 165 | <Divider type="vertical" /> |
159 | 166 | <Popconfirm |
160 | 167 | title="是否提前结束?" |
161 | - onConfirm={() => earlyEndHandle(record.id || 0, () => setParams({...innerParams, current: 1}, true))} | |
168 | + onConfirm={() => earlyEndHandle(record.id || 0, () => setParams({...innerParams}, true))} | |
162 | 169 | okText="确定" |
163 | 170 | cancelText="取消" |
164 | 171 | > |
... | ... | @@ -185,7 +192,7 @@ export default function IndexPage() { |
185 | 192 | <AdjustDateModal |
186 | 193 | visible={adjustDateVisible} |
187 | 194 | onCancel={() => setAdjustDateVisible(false)} |
188 | - fetchList={() => setParams({...innerParams, current: 1}, true)} | |
195 | + fetchList={() => setParams({}, true)} | |
189 | 196 | id={item.id} |
190 | 197 | startTime={item.startTime} |
191 | 198 | endTime={item.endTime} | ... | ... |
src/pages/ehr/CommonSettings/HrSetting/index.tsx
... | ... | @@ -58,11 +58,11 @@ const HrSettingKV: { [key in HrSettingKey]: KValue } = { |
58 | 58 | } |
59 | 59 | }, |
60 | 60 | }, |
61 | - personalityTestSystemOff: { | |
62 | - title: '性格测试', | |
63 | - type: 'custom', | |
64 | - customRender: PersonalityTest, | |
65 | - }, | |
61 | + // personalityTestSystemOff: { | |
62 | + // title: '性格测试', | |
63 | + // type: 'custom', | |
64 | + // customRender: PersonalityTest, | |
65 | + // }, | |
66 | 66 | leaveControlRate: { |
67 | 67 | title: '离职目标管控率', |
68 | 68 | type: 'custom', | ... | ... |
src/pages/ehr/PersonManage/components/PersonFilter.tsx
... | ... | @@ -2,6 +2,7 @@ import React from 'react'; |
2 | 2 | import { Input, Radio } from 'antd'; |
3 | 3 | import { useStore } from '../index'; |
4 | 4 | import FeeweeFilterOption from '@/pages/notice/components/FeeweeFilterOption'; |
5 | +import ShopSelectNew from '@/components/ShopSelectNew'; | |
5 | 6 | |
6 | 7 | const RadioButton = Radio.Button; |
7 | 8 | const RadioGroup = Radio.Group; |
... | ... | @@ -10,7 +11,7 @@ export default function PersonFilter() { |
10 | 11 | const { pagination } = useStore(); |
11 | 12 | |
12 | 13 | return ( |
13 | - <div style={{ display: 'flex', flex: 1, justifyContent: 'start', alignItems: 'end', gap: 10 }}> | |
14 | + <div style={{ display: 'flex', flex: 1, justifyContent: 'start', alignItems: 'end', flexWrap: 'wrap', gap: 10 }}> | |
14 | 15 | <RadioGroup |
15 | 16 | defaultValue={2} |
16 | 17 | buttonStyle="solid" |
... | ... | @@ -34,6 +35,56 @@ export default function PersonFilter() { |
34 | 35 | style={{ minWidth: 300 }} |
35 | 36 | /> |
36 | 37 | </FeeweeFilterOption> |
38 | + <FeeweeFilterOption title="在职门店"> | |
39 | + <ShopSelectNew | |
40 | + style={{ minWidth: 260 }} | |
41 | + value={ | |
42 | + pagination.innerParams.dutyShopName && pagination.innerParams.dutyShopId | |
43 | + ? [ | |
44 | + { | |
45 | + label: pagination.innerParams.dutyShopName, | |
46 | + value: pagination.innerParams.dutyShopId, | |
47 | + }, | |
48 | + ] | |
49 | + : [] | |
50 | + } | |
51 | + onChange={(shops: any) => | |
52 | + pagination.setParams( | |
53 | + { | |
54 | + dutyShopId: shops.length ? shops[0].value : undefined, | |
55 | + dutyShopName: shops.length ? shops[0].label : undefined, | |
56 | + current: 1, | |
57 | + }, | |
58 | + true, | |
59 | + ) | |
60 | + } | |
61 | + /> | |
62 | + </FeeweeFilterOption> | |
63 | + <FeeweeFilterOption title="社保门店"> | |
64 | + <ShopSelectNew | |
65 | + style={{ minWidth: 260 }} | |
66 | + value={ | |
67 | + pagination.innerParams.fundShopName && pagination.innerParams.fundShopId | |
68 | + ? [ | |
69 | + { | |
70 | + label: pagination.innerParams.fundShopName, | |
71 | + value: pagination.innerParams.fundShopId, | |
72 | + }, | |
73 | + ] | |
74 | + : [] | |
75 | + } | |
76 | + onChange={(shops: any) => | |
77 | + pagination.setParams( | |
78 | + { | |
79 | + fundShopId: shops.length ? shops[0].value : undefined, | |
80 | + fundShopName: shops.length ? shops[0].label : undefined, | |
81 | + current: 1, | |
82 | + }, | |
83 | + true, | |
84 | + ) | |
85 | + } | |
86 | + /> | |
87 | + </FeeweeFilterOption> | |
37 | 88 | </div> |
38 | 89 | ); |
39 | 90 | } | ... | ... |
src/pages/ehr/PersonManage/interface.d.ts
... | ... | @@ -2,12 +2,16 @@ |
2 | 2 | * @Author: wangqiang@feewee.cn |
3 | 3 | * @Date: 2022-04-13 09:39:04 |
4 | 4 | * @LastEditors: wangqiang@feewee.cn |
5 | - * @LastEditTime: 2023-04-13 15:00:55 | |
5 | + * @LastEditTime: 2024-04-02 14:20:34 | |
6 | 6 | */ |
7 | 7 | declare namespace Person { |
8 | 8 | interface QueryParams { |
9 | 9 | keyWords?: string; // 搜索关键字(岗位名称、电话号码、姓名) |
10 | 10 | staffStatus?: 1 | 2 | 8 | 9; // 员工状态 1试用期 2正式 8待离职 9离职 为空则是全部(全部不包含离职员工) |
11 | + dutyShopId?: number; // 在职门店 | |
12 | + dutyShopName?: string; | |
13 | + fundShopId?: number; // 社保门店 | |
14 | + fundShopName?: string; | |
11 | 15 | } |
12 | 16 | |
13 | 17 | interface List { | ... | ... |
src/pages/ehr/PhoneChargeAndSubsidy/subpages/SubsidyConfirm/components/ConfirmModal.tsx
1 | 1 | import React, { useEffect, useRef, useState } from "react"; |
2 | 2 | import EditTable from "@/pages/ehr/components/EditTable"; |
3 | 3 | import { useStore } from "../index"; |
4 | +import type { | |
5 | + InputRef} from "antd"; | |
4 | 6 | import { |
5 | 7 | Button, |
6 | 8 | Divider, |
7 | 9 | Input, |
8 | - InputRef, | |
9 | 10 | message, |
10 | 11 | Modal, |
11 | 12 | Popover, |
... | ... | @@ -16,8 +17,8 @@ import { SearchOutlined } from "@ant-design/icons"; |
16 | 17 | import { formatObjText, priceToThousands } from "@/utils/utils"; |
17 | 18 | import moment from "moment"; |
18 | 19 | import DetailItem from "@/pages/ehr/Authentication/Settings/components/DetailItem"; |
19 | -import { ColumnType } from "antd/lib/table"; | |
20 | -import { FilterConfirmProps } from "antd/lib/table/interface"; | |
20 | +import type { ColumnType } from "antd/lib/table"; | |
21 | +import type { FilterConfirmProps } from "antd/lib/table/interface"; | |
21 | 22 | import { checkNull } from "@/utils/validate"; |
22 | 23 | |
23 | 24 | export default function SubsidyConfirmModal() { |
... | ... | @@ -199,7 +200,7 @@ export default function SubsidyConfirmModal() { |
199 | 200 | zIndex={1002} |
200 | 201 | destroyOnClose |
201 | 202 | > |
202 | - <Row style={{ alignItems: "center", justifyContent: "space-around" }}> | |
203 | + <Row style={{ alignItems: 'center', justifyContent: 'space-around' }}> | |
203 | 204 | <DetailItem |
204 | 205 | style={{ marginBottom: 0 }} |
205 | 206 | title="补贴标准" |
... | ... | @@ -207,24 +208,25 @@ export default function SubsidyConfirmModal() { |
207 | 208 | desp={ |
208 | 209 | <> |
209 | 210 | <span> |
210 | - {`${priceToThousands(confirmModalInfo.item?.amount ?? "")} ${!confirmModalInfo.item?.specialSubsidy | |
211 | - ? confirmModalInfo.item?.amountType === 1 | |
212 | - ? "元/天" | |
213 | - : confirmModalInfo.item?.amountType === 3 | |
214 | - ? "元/月" | |
215 | - : "" | |
216 | - : "元/月" | |
217 | - }`} | |
211 | + {`${priceToThousands(confirmModalInfo.item?.amount ?? '')} ${ | |
212 | + !confirmModalInfo.item?.specialSubsidy | |
213 | + ? confirmModalInfo.item?.amountType === 1 | |
214 | + ? '元/天' | |
215 | + : confirmModalInfo.item?.amountType === 3 | |
216 | + ? '元/月' | |
217 | + : '' | |
218 | + : '元/月' | |
219 | + }`} | |
218 | 220 | </span> |
219 | 221 | {confirmModalInfo.item?.specialSubsidy ? ( |
220 | 222 | <span |
221 | 223 | style={{ |
222 | 224 | fontSize: 12, |
223 | - color: "#FF9625", | |
224 | - padding: "1px 5px", | |
225 | + color: '#FF9625', | |
226 | + padding: '1px 5px', | |
225 | 227 | marginLeft: 5, |
226 | 228 | borderRadius: 2, |
227 | - border: "1px solid #FF9625", | |
229 | + border: '1px solid #FF9625', | |
228 | 230 | }} |
229 | 231 | > |
230 | 232 | 特殊 |
... | ... | @@ -239,9 +241,9 @@ export default function SubsidyConfirmModal() { |
239 | 241 | title="适用门店" |
240 | 242 | desp={ |
241 | 243 | confirmModalInfo.item?.specialSubsidy ? ( |
242 | - "-" | |
244 | + '-' | |
243 | 245 | ) : confirmModalInfo.item?.shopScope === 1 ? ( |
244 | - "全部门店" | |
246 | + '全部门店' | |
245 | 247 | ) : ( |
246 | 248 | <Popover |
247 | 249 | trigger="click" |
... | ... | @@ -249,12 +251,12 @@ export default function SubsidyConfirmModal() { |
249 | 251 | content={ |
250 | 252 | <div |
251 | 253 | style={{ |
252 | - display: "flex", | |
253 | - flexWrap: "wrap", | |
254 | - justifyContent: "flex-start", | |
255 | - alignItems: "center", | |
254 | + display: 'flex', | |
255 | + flexWrap: 'wrap', | |
256 | + justifyContent: 'flex-start', | |
257 | + alignItems: 'center', | |
256 | 258 | maxWidth: 400, |
257 | - gap: "0 20px", | |
259 | + gap: '0 20px', | |
258 | 260 | }} |
259 | 261 | > |
260 | 262 | {confirmModalInfo.item?.shopList?.map((shop) => ( |
... | ... | @@ -264,12 +266,7 @@ export default function SubsidyConfirmModal() { |
264 | 266 | } |
265 | 267 | > |
266 | 268 | <span> |
267 | - {formatObjText( | |
268 | - confirmModalInfo.item?.shopList ?? [], | |
269 | - "shopName", | |
270 | - 2, | |
271 | - "个门店" | |
272 | - )} | |
269 | + {formatObjText(confirmModalInfo.item?.shopList ?? [], 'shopName', 2, '个门店')} | |
273 | 270 | <a>查看</a> |
274 | 271 | </span> |
275 | 272 | </Popover> |
... | ... | @@ -282,9 +279,9 @@ export default function SubsidyConfirmModal() { |
282 | 279 | title="适用岗位" |
283 | 280 | desp={ |
284 | 281 | confirmModalInfo.item?.specialSubsidy ? ( |
285 | - "-" | |
282 | + '-' | |
286 | 283 | ) : confirmModalInfo.item?.postScope === 1 ? ( |
287 | - "全部岗位" | |
284 | + '全部岗位' | |
288 | 285 | ) : ( |
289 | 286 | <Popover |
290 | 287 | trigger="click" |
... | ... | @@ -292,12 +289,12 @@ export default function SubsidyConfirmModal() { |
292 | 289 | content={ |
293 | 290 | <div |
294 | 291 | style={{ |
295 | - display: "flex", | |
296 | - flexWrap: "wrap", | |
297 | - justifyContent: "flex-start", | |
298 | - alignItems: "center", | |
292 | + display: 'flex', | |
293 | + flexWrap: 'wrap', | |
294 | + justifyContent: 'flex-start', | |
295 | + alignItems: 'center', | |
299 | 296 | maxWidth: 400, |
300 | - gap: "0 20px", | |
297 | + gap: '0 20px', | |
301 | 298 | }} |
302 | 299 | > |
303 | 300 | {confirmModalInfo.item?.postList?.map((post) => ( |
... | ... | @@ -307,12 +304,7 @@ export default function SubsidyConfirmModal() { |
307 | 304 | } |
308 | 305 | > |
309 | 306 | <span> |
310 | - {formatObjText( | |
311 | - confirmModalInfo.item?.postList ?? [], | |
312 | - "postName", | |
313 | - 2, | |
314 | - "个岗位" | |
315 | - )} | |
307 | + {formatObjText(confirmModalInfo.item?.postList ?? [], 'postName', 2, '个岗位')} | |
316 | 308 | <a>查看</a> |
317 | 309 | </span> |
318 | 310 | </Popover> |
... | ... | @@ -325,25 +317,20 @@ export default function SubsidyConfirmModal() { |
325 | 317 | title="适用范围" |
326 | 318 | desp={ |
327 | 319 | confirmModalInfo.item?.specialSubsidy ? ( |
328 | - "-" | |
320 | + '-' | |
329 | 321 | ) : confirmModalInfo.item?.scopeStaff ? ( |
330 | 322 | <span> |
331 | - {confirmModalInfo.item?.scopeStaff | |
332 | - ? ScopeType[confirmModalInfo.item?.scopeStaff] | |
333 | - : ""} | |
323 | + {confirmModalInfo.item?.scopeStaff ? ScopeType[confirmModalInfo.item?.scopeStaff] : ''} | |
334 | 324 | {confirmModalInfo.item?.scopeStaff !== 3 ? ( |
335 | 325 | <> |
336 | 326 | 时间 |
337 | - {confirmModalInfo.item?.scopeStaffTimeMin ?? ""}- | |
338 | - {confirmModalInfo.item?.scopeStaffTimeMax ?? ""} | |
339 | - {confirmModalInfo.item?.scopeStaffTimeUnit | |
340 | - ? ScopeUnit[confirmModalInfo.item?.scopeStaffTimeUnit] | |
341 | - : ""} | |
327 | + {confirmModalInfo.item?.scopeStaffTimeMin ?? ''}-{confirmModalInfo.item?.scopeStaffTimeMax ?? ''} | |
328 | + {confirmModalInfo.item?.scopeStaffTimeUnit ? ScopeUnit[confirmModalInfo.item?.scopeStaffTimeUnit] : ''} | |
342 | 329 | </> |
343 | 330 | ) : null} |
344 | 331 | </span> |
345 | 332 | ) : ( |
346 | - "-" | |
333 | + '-' | |
347 | 334 | ) |
348 | 335 | } |
349 | 336 | /> |
... | ... | @@ -352,9 +339,7 @@ export default function SubsidyConfirmModal() { |
352 | 339 | <Row> |
353 | 340 | <DetailItem |
354 | 341 | title="计算方式" |
355 | - desp={`日均补贴金额 * (${standardConfirmModalInfo.attendanceConfigList | |
356 | - ?.map((item) => item.desc + "天数") | |
357 | - .join("+")})`} | |
342 | + desp={`日均补贴金额 * (${standardConfirmModalInfo.attendanceConfigList?.map((item) => item.desc + '天数').join('+')})`} | |
358 | 343 | /> |
359 | 344 | </Row> |
360 | 345 | <EditTable |
... | ... | @@ -364,7 +349,7 @@ export default function SubsidyConfirmModal() { |
364 | 349 | showTotal: (total, range) => `共 ${total} 条数据,当前展示第 ${range[0]}-${range[1]} 条数据`, |
365 | 350 | }} |
366 | 351 | bordered={false} |
367 | - scroll={{ scrollToFirstRowOnChange: true, x: 1500, y: "65vh" }} | |
352 | + scroll={{ scrollToFirstRowOnChange: true, x: 1500, y: '65vh' }} | |
368 | 353 | rowKey="staffId" |
369 | 354 | uniqueKey="staffId" |
370 | 355 | onRow={(record) => ({ |
... | ... | @@ -374,150 +359,128 @@ export default function SubsidyConfirmModal() { |
374 | 359 | }, |
375 | 360 | })} |
376 | 361 | rowSelection={{ |
377 | - type: "checkbox", | |
378 | - selectedRowKeys: items | |
379 | - ?.filter((item) => item.selected ?? true) | |
380 | - ?.map((item) => item.staffId || ""), | |
362 | + type: 'checkbox', | |
363 | + selectedRowKeys: items?.filter((item) => item.selected ?? true)?.map((item) => item.staffId || ''), | |
381 | 364 | onSelect, |
382 | 365 | onSelectAll, |
383 | 366 | }} |
384 | 367 | columns={[ |
385 | 368 | { |
386 | - title: "员工姓名", | |
387 | - dataIndex: "staffName", | |
369 | + title: '员工姓名', | |
370 | + dataIndex: 'staffName', | |
388 | 371 | width: 120, |
389 | - fixed: "left", | |
390 | - ...getColumnSearchProps("staffName", "员工姓名"), | |
372 | + fixed: 'left', | |
373 | + ...getColumnSearchProps('staffName', '员工姓名'), | |
391 | 374 | }, |
392 | 375 | { |
393 | - title: "人员岗位", | |
394 | - dataIndex: "postName", | |
376 | + title: '人员岗位', | |
377 | + dataIndex: 'postName', | |
395 | 378 | width: 150, |
396 | - ...getColumnSearchProps("postName", "人员岗位"), | |
379 | + ...getColumnSearchProps('postName', '人员岗位'), | |
397 | 380 | }, |
398 | 381 | { |
399 | - title: "在职门店", | |
400 | - dataIndex: "shopName", | |
382 | + title: '在职门店', | |
383 | + dataIndex: 'shopName', | |
401 | 384 | width: 150, |
402 | - ...getColumnSearchProps("shopName", "在职门店"), | |
385 | + ...getColumnSearchProps('shopName', '在职门店'), | |
403 | 386 | }, |
404 | 387 | { |
405 | - title: "入职时间", | |
406 | - dataIndex: "entryDate", | |
388 | + title: '入职时间', | |
389 | + dataIndex: 'entryDate', | |
407 | 390 | width: 110, |
408 | - sorter: ( | |
409 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
410 | - b: EHrSubsidyConfirm.TypeStaffVO | |
411 | - ) => (a.entryDate ?? -1) - (b.entryDate ?? -1), | |
412 | - render: (entryDate: number) => (entryDate ? moment(entryDate).format("YYYY-MM-DD") : "-"), | |
391 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.entryDate ?? -1) - (b.entryDate ?? -1), | |
392 | + render: (entryDate: number) => (entryDate ? moment(entryDate).format('YYYY-MM-DD') : '-'), | |
413 | 393 | }, |
414 | 394 | { |
415 | - title: "转正时间", | |
416 | - dataIndex: "regularDate", | |
395 | + title: '转正时间', | |
396 | + dataIndex: 'regularDate', | |
417 | 397 | width: 110, |
418 | - sorter: ( | |
419 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
420 | - b: EHrSubsidyConfirm.TypeStaffVO | |
421 | - ) => (a.regularDate ?? -1) - (b.regularDate ?? -1), | |
422 | - render: (regularDate: number) => (regularDate ? moment(regularDate).format("YYYY-MM-DD") : "-"), | |
398 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.regularDate ?? -1) - (b.regularDate ?? -1), | |
399 | + render: (regularDate: number) => (regularDate ? moment(regularDate).format('YYYY-MM-DD') : '-'), | |
423 | 400 | }, |
424 | 401 | { |
425 | - title: "离职时间", | |
426 | - dataIndex: "leaveDate", | |
402 | + title: '离职时间', | |
403 | + dataIndex: 'leaveDate', | |
427 | 404 | width: 110, |
428 | - sorter: ( | |
429 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
430 | - b: EHrSubsidyConfirm.TypeStaffVO | |
431 | - ) => (a.leaveDate ?? -1) - (b.leaveDate ?? -1), | |
432 | - render: (leaveDate: number) => (leaveDate ? moment(leaveDate).format("YYYY-MM-DD") : "-"), | |
405 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.leaveDate ?? -1) - (b.leaveDate ?? -1), | |
406 | + render: (leaveDate: number) => (leaveDate ? moment(leaveDate).format('YYYY-MM-DD') : '-'), | |
433 | 407 | }, |
434 | 408 | { |
435 | - title: "上班天数", | |
436 | - hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes("上班") | |
437 | - ), | |
438 | - dataIndex: "workDays", | |
409 | + title: '上班天数', | |
410 | + hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes('上班')), | |
411 | + dataIndex: 'workDays', | |
439 | 412 | width: 90, |
440 | - sorter: ( | |
441 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
442 | - b: EHrSubsidyConfirm.TypeStaffVO | |
443 | - ) => (a.workDays ?? -1) - (b.workDays ?? -1), | |
413 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.workDays ?? -1) - (b.workDays ?? -1), | |
444 | 414 | render: (workDays: number) => `${workDays ?? 0} 天`, |
445 | 415 | }, |
446 | 416 | { |
447 | - title: "请假天数", | |
448 | - hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes("请假") | |
449 | - ), | |
450 | - dataIndex: "askForLeaveDays", | |
417 | + title: '请假天数', | |
418 | + hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes('请假')), | |
419 | + dataIndex: 'askForLeaveDays', | |
451 | 420 | width: 90, |
452 | - sorter: ( | |
453 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
454 | - b: EHrSubsidyConfirm.TypeStaffVO | |
455 | - ) => (a.askForLeaveDays ?? -1) - (b.askForLeaveDays ?? -1), | |
421 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.askForLeaveDays ?? -1) - (b.askForLeaveDays ?? -1), | |
456 | 422 | render: (askForLeaveDays: number) => `${askForLeaveDays ?? 0} 天`, |
457 | 423 | }, |
458 | 424 | { |
459 | - title: "出差天数", | |
460 | - hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes("出差") | |
461 | - ), | |
462 | - dataIndex: "evectionDays", | |
425 | + title: '出差天数', | |
426 | + hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes('出差')), | |
427 | + dataIndex: 'evectionDays', | |
463 | 428 | width: 90, |
464 | - sorter: ( | |
465 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
466 | - b: EHrSubsidyConfirm.TypeStaffVO | |
467 | - ) => (a.evectionDays ?? -1) - (b.evectionDays ?? -1), | |
429 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.evectionDays ?? -1) - (b.evectionDays ?? -1), | |
468 | 430 | render: (evectionDays: number) => `${evectionDays ?? 0} 天`, |
469 | 431 | }, |
470 | 432 | { |
471 | - title: "休息天数", | |
472 | - hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes("休息") | |
473 | - ), | |
474 | - dataIndex: "restDays", | |
433 | + title: '休息天数', | |
434 | + hide: !standardConfirmModalInfo.attendanceConfigList?.find((item) => item.desc?.includes('休息')), | |
435 | + dataIndex: 'restDays', | |
475 | 436 | width: 90, |
476 | - sorter: ( | |
477 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
478 | - b: EHrSubsidyConfirm.TypeStaffVO | |
479 | - ) => (a.restDays ?? -1) - (b.restDays ?? -1), | |
437 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.restDays ?? -1) - (b.restDays ?? -1), | |
480 | 438 | render: (restDays: number) => `${restDays ?? 0} 天`, |
481 | 439 | }, |
482 | 440 | { |
483 | - title: "补贴标准", | |
441 | + title: '晚班天数', | |
442 | + dataIndex: 'nightDays', | |
443 | + width: 90, | |
444 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.nightDays ?? -1) - (b.nightDays ?? -1), | |
445 | + render: (nightDays: number) => `${nightDays ?? 0} 天`, | |
446 | + }, | |
447 | + { | |
448 | + title: '补贴标准', | |
484 | 449 | width: 150, |
485 | - dataIndex: "standardAmount", | |
486 | - sorter: ( | |
487 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
488 | - b: EHrSubsidyConfirm.TypeStaffVO | |
489 | - ) => (a.standardAmount ?? -1) - (b.standardAmount ?? -1), | |
450 | + dataIndex: 'standardAmount', | |
451 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.standardAmount ?? -1) - (b.standardAmount ?? -1), | |
490 | 452 | render: (standardAmount: number) => `${priceToThousands(standardAmount)} 元`, |
491 | 453 | }, |
492 | 454 | { |
493 | - title: "系统计算金额", | |
455 | + title: '系统计算金额', | |
494 | 456 | width: 150, |
495 | - dataIndex: "systemCalcAmount", | |
496 | - sorter: ( | |
497 | - a: EHrSubsidyConfirm.TypeStaffVO, | |
498 | - b: EHrSubsidyConfirm.TypeStaffVO | |
499 | - ) => (a.standardAmount ?? -1) - (b.standardAmount ?? -1), | |
457 | + dataIndex: 'systemCalcAmount', | |
458 | + sorter: (a: EHrSubsidyConfirm.TypeStaffVO, b: EHrSubsidyConfirm.TypeStaffVO) => (a.standardAmount ?? -1) - (b.standardAmount ?? -1), | |
500 | 459 | render: (systemCalcAmount: number) => `${priceToThousands(systemCalcAmount)} 元`, |
501 | 460 | }, |
502 | 461 | { |
503 | - title: "实际补贴金额", | |
504 | - dataIndex: "realAmount", | |
462 | + title: '实际补贴金额', | |
463 | + dataIndex: 'realAmount', | |
505 | 464 | width: 150, |
506 | 465 | editable: true, |
507 | - inputType: "number", | |
466 | + inputType: 'number', | |
508 | 467 | max: 999.99, |
509 | - fixed: "right", | |
510 | - render: (realAmount: number, record: EHrSubsidyConfirm.TypeStaffVO) => <span style={record.systemCalcAmount !== record.realAmount ? { color: '#F4333C' } : undefined}>{`${priceToThousands(realAmount)} 元`}</span>, | |
468 | + fixed: 'right', | |
469 | + render: (realAmount: number, record: EHrSubsidyConfirm.TypeStaffVO) => ( | |
470 | + <span style={record.systemCalcAmount !== record.realAmount ? { color: '#F4333C' } : undefined}>{`${priceToThousands( | |
471 | + realAmount, | |
472 | + )} 元`}</span> | |
473 | + ), | |
511 | 474 | }, |
512 | 475 | { |
513 | - title: "备注", | |
476 | + title: '备注', | |
514 | 477 | editable: true, |
515 | 478 | required: false, |
516 | - inputType: "text", | |
479 | + inputType: 'text', | |
517 | 480 | width: 200, |
518 | - dataIndex: "remark", | |
519 | - fixed: "right", | |
520 | - render: (remark: string) => remark ?? "-", | |
481 | + dataIndex: 'remark', | |
482 | + fixed: 'right', | |
483 | + render: (remark: string) => remark ?? '-', | |
521 | 484 | }, |
522 | 485 | ]} |
523 | 486 | /> | ... | ... |
src/pages/ehr/PhoneChargeAndSubsidy/subpages/SubsidyConfirm/interface.d.ts
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | * @Author: wangqiang@feewee.cn |
3 | 3 | * @Date: 2023-03-13 09:12:25 |
4 | 4 | * @LastEditors: wangqiang@feewee.cn |
5 | - * @LastEditTime: 2023-06-02 09:19:30 | |
5 | + * @LastEditTime: 2024-03-28 15:27:21 | |
6 | 6 | */ |
7 | 7 | declare namespace EHrSubsidyConfirm { |
8 | 8 | interface QueryParams { |
... | ... | @@ -127,6 +127,7 @@ declare namespace EHrSubsidyConfirm { |
127 | 127 | askForLeaveDays?: number; // 请假天数 |
128 | 128 | evectionDays?: number; // 出差天数 |
129 | 129 | restDays?: number; // 休息天数 |
130 | + nightDays?: number; // 晚班天数 | |
130 | 131 | standardAmount?: number; // 补贴标准金额 |
131 | 132 | realAmount?: number; // 实际补贴金额 |
132 | 133 | systemCalcAmount?: number; // 系统计算金额 | ... | ... |
src/pages/ehr/PhoneChargeAndSubsidy/subpages/SubsidySettings/components/List.tsx
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | * @Author: wangqiang@feewee.cn |
3 | 3 | * @Date: 2023-02-15 17:42:54 |
4 | 4 | * @LastEditors: wangqiang@feewee.cn |
5 | - * @LastEditTime: 2023-05-11 11:40:29 | |
5 | + * @LastEditTime: 2024-03-28 15:14:20 | |
6 | 6 | */ |
7 | 7 | import { |
8 | 8 | formatObjText, |
... | ... | @@ -38,7 +38,7 @@ export default function SubsidySettingsList() { |
38 | 38 | align="left" |
39 | 39 | width={120} |
40 | 40 | render={(amount: number, record: EHrSubsidySetting.List) => `${priceToThousands(amount)} ${ |
41 | - pagination.innerParams.type === 2 | |
41 | + pagination.innerParams.type !== 1 | |
42 | 42 | ? record.amountType === 1 |
43 | 43 | ? "元/天" |
44 | 44 | : record.amountType === 3 | ... | ... |
src/pages/ehr/PhoneChargeAndSubsidy/subpages/SubsidySettings/components/Modal.tsx
1 | 1 | import { checkNull, validatorNumberCanWithDecimal } from '@/utils/validate'; |
2 | 2 | import { Form, Input, message, Modal, Select } from 'antd'; |
3 | -import { LabeledValue } from 'antd/lib/select'; | |
3 | +import type { LabeledValue } from 'antd/lib/select'; | |
4 | 4 | import React, { useEffect, useRef, useState } from 'react'; |
5 | 5 | import { saveSubsidySettingApi } from '../api'; |
6 | 6 | import { useStore } from '../index'; |
7 | -import Post, { PostRef } from './Post'; | |
8 | -import Scope, { Value as ScopeValue } from './Scope'; | |
9 | -import Shop, { Value as ShopValue } from './Shop'; | |
7 | +import type { PostRef } from './Post'; | |
8 | +import Post from './Post'; | |
9 | +import type { Value as ScopeValue } from './Scope'; | |
10 | +import Scope from './Scope'; | |
11 | +import type { Value as ShopValue } from './Shop'; | |
12 | +import Shop from './Shop'; | |
10 | 13 | |
11 | 14 | export default function SubsidySettingsModal() { |
12 | 15 | const { current, setCurrent, visible, setVisible, pagination, subsidyTypeList, nationInitial } = useStore(); |
... | ... | @@ -138,9 +141,9 @@ export default function SubsidySettingsModal() { |
138 | 141 | <Input |
139 | 142 | placeholder="请输入补贴金额" |
140 | 143 | allowClear |
141 | - suffix={pagination.innerParams.type === 2 ? undefined : '元'} | |
144 | + suffix={pagination.innerParams.type !== 1 ? undefined : '元'} | |
142 | 145 | addonAfter={ |
143 | - pagination.innerParams.type === 2 ? ( | |
146 | + pagination.innerParams.type !== 1 ? ( | |
144 | 147 | <Form.Item noStyle name="amountType"> |
145 | 148 | <Select> |
146 | 149 | <Select.Option value={1}>元/天</Select.Option> | ... | ... |
src/pages/ehr/PostSetting/components/IndexDetail.tsx
... | ... | @@ -2,18 +2,18 @@ |
2 | 2 | * @Author: wangqiang@feewee.cn |
3 | 3 | * @Date: 2022-04-13 09:39:04 |
4 | 4 | * @LastEditors: wangqiang@feewee.cn |
5 | - * @LastEditTime: 2024-03-08 11:26:17 | |
5 | + * @LastEditTime: 2024-04-02 14:46:43 | |
6 | 6 | */ |
7 | 7 | import React from 'react'; |
8 | 8 | import { useStore } from '../index'; |
9 | -import { Table, Popover, Row, Button } from 'antd'; | |
9 | +import { Table, Popover, Row, Button, Badge } from 'antd'; | |
10 | 10 | import { LeftCircleOutlined } from '@ant-design/icons'; |
11 | 11 | import { detailShopApi } from '../api'; |
12 | 12 | import useInitail from '@/hooks/useInitail'; |
13 | 13 | import { PersonStatus, PersonStatusColor } from '@/pages/ehr/PersonManage/entity'; |
14 | 14 | |
15 | 15 | export default function IndexDetail() { |
16 | - const { currentShopItem, setCurrentShopItem, breadcrumbs, setBreadcrumbs, setCurrentBreadcrumb } = useStore(); | |
16 | + const { currentShopItem, setCurrentShopItem, breadcrumbs, setBreadcrumbs, setCurrentBreadcrumb, ChangeType, ChangeTypeColor } = useStore(); | |
17 | 17 | const { data, loading } = useInitail(detailShopApi, [], (currentShopItem && currentShopItem.id) || 0); |
18 | 18 | |
19 | 19 | const getBack = () => { |
... | ... | @@ -30,6 +30,7 @@ export default function IndexDetail() { |
30 | 30 | <span style={{ display: 'inline-block', marginBottom: 20, fontSize: 16 }}> |
31 | 31 | 合计:{new Set(data.map((d) => d.staffId)).size || 0} 人 |
32 | 32 | </span> |
33 | + {/* @ts-ignore */} | |
33 | 34 | <Button icon={<LeftCircleOutlined />} type="link" onClick={getBack}> |
34 | 35 | 返回 |
35 | 36 | </Button> |
... | ... | @@ -45,9 +46,13 @@ export default function IndexDetail() { |
45 | 46 | title="人员状态" |
46 | 47 | dataIndex="staffStatus" |
47 | 48 | align="center" |
48 | - render={(staffStatus: number) => | |
49 | - staffStatus ? <span style={{ color: PersonStatusColor[staffStatus] || '#000' }}>{PersonStatus[staffStatus]}</span> : '-' | |
50 | - } | |
49 | + render={(staffStatus: number) => (staffStatus ? <Badge color={PersonStatusColor[staffStatus]} text={PersonStatus[staffStatus]} /> : '-')} | |
50 | + /> | |
51 | + <Table.Column | |
52 | + title="人员变动状态" | |
53 | + dataIndex="changeType" | |
54 | + align="center" | |
55 | + render={(changeType: number) => (changeType ? <Badge color={ChangeTypeColor[changeType]} text={ChangeType[changeType]} /> : '-')} | |
51 | 56 | /> |
52 | 57 | <Table.Column |
53 | 58 | title="门店" | ... | ... |
src/pages/ehr/PostSetting/components/IndexPostDetail.tsx
... | ... | @@ -2,18 +2,19 @@ |
2 | 2 | * @Author: wangqiang@feewee.cn |
3 | 3 | * @Date: 2022-04-13 09:39:04 |
4 | 4 | * @LastEditors: wangqiang@feewee.cn |
5 | - * @LastEditTime: 2024-01-05 09:30:40 | |
5 | + * @LastEditTime: 2024-04-02 14:43:45 | |
6 | 6 | */ |
7 | 7 | import React from 'react'; |
8 | 8 | import { useStore } from '../index'; |
9 | -import { Table, Popover, Row, Button } from 'antd'; | |
9 | +import { Table, Popover, Row, Button, Badge } from 'antd'; | |
10 | 10 | import { LeftCircleOutlined } from '@ant-design/icons'; |
11 | 11 | import { postDetailApi } from '../api'; |
12 | 12 | import usePagination from '@/hooks/usePagination'; |
13 | 13 | import { PersonStatus, PersonStatusColor } from '@/pages/ehr/PersonManage/entity'; |
14 | 14 | |
15 | 15 | export default function IndexDetail() { |
16 | - const { currentPostItem, setCurrentPostItem, breadcrumbs, setBreadcrumbs, setCurrentBreadcrumb, isShopGoToDetail } = useStore(); | |
16 | + const { currentPostItem, setCurrentPostItem, breadcrumbs, setBreadcrumbs, setCurrentBreadcrumb, isShopGoToDetail, ChangeType, ChangeTypeColor } = | |
17 | + useStore(); | |
17 | 18 | const { list, paginationConfig, loading } = usePagination(postDetailApi, { |
18 | 19 | postId: (currentPostItem && currentPostItem.id) || 0, |
19 | 20 | }); |
... | ... | @@ -30,6 +31,7 @@ export default function IndexDetail() { |
30 | 31 | <> |
31 | 32 | <Row justify="space-between" style={{ marginBottom: 20 }}> |
32 | 33 | <span style={{ display: 'inline-block', marginBottom: 20, fontSize: 16 }}>合计:{paginationConfig.total || 0} 人</span> |
34 | + {/* @ts-ignore */} | |
33 | 35 | <Button icon={<LeftCircleOutlined />} type="link" onClick={getBack}> |
34 | 36 | 返回 |
35 | 37 | </Button> |
... | ... | @@ -45,9 +47,13 @@ export default function IndexDetail() { |
45 | 47 | title="人员状态" |
46 | 48 | dataIndex="staffStatus" |
47 | 49 | align="center" |
48 | - render={(staffStatus: number) => | |
49 | - staffStatus ? <span style={{ color: PersonStatusColor[staffStatus] || '#000' }}>{PersonStatus[staffStatus]}</span> : '-' | |
50 | - } | |
50 | + render={(staffStatus: number) => (staffStatus ? <Badge color={PersonStatusColor[staffStatus]} text={PersonStatus[staffStatus]} /> : '-')} | |
51 | + /> | |
52 | + <Table.Column | |
53 | + title="人员变动状态" | |
54 | + dataIndex="changeType" | |
55 | + align="center" | |
56 | + render={(changeType: number) => (changeType ? <Badge color={ChangeTypeColor[changeType]} text={ChangeType[changeType]} /> : '-')} | |
51 | 57 | /> |
52 | 58 | <Table.Column |
53 | 59 | title="门店" | ... | ... |
src/pages/ehr/PostSetting/components/IndexShop/ShopList.tsx
1 | 1 | import React from 'react'; |
2 | -import { Row, Popconfirm, message, Divider, Radio, Tag, Table } from 'antd'; | |
2 | +import { Row, Popconfirm, message, Divider, Radio, Tag, Table, Popover } from 'antd'; | |
3 | +import { InfoCircleOutlined } from '@ant-design/icons'; | |
3 | 4 | import { useStore } from '../../index'; |
4 | 5 | import Modal from './ShopModal'; |
5 | 6 | import { cancelApprovalApi, deleteShopPostApi, postLimitApi } from '../../api'; |
... | ... | @@ -120,7 +121,19 @@ export default function ShopList() { |
120 | 121 | title="当前在岗数" |
121 | 122 | dataIndex="postNum" |
122 | 123 | align="left" |
123 | - render={(num: number, item: PostSetting.ShopList) => <a onClick={() => detailClick(item)}>{priceToThousands(num, 0)} 人</a>} | |
124 | + render={(num: number, item: PostSetting.ShopList) => | |
125 | + item.remark ? ( | |
126 | + <Popover content={item.remark} title="提示" placement="topLeft"> | |
127 | + <Row align="middle" style={{ gap: 10 }}> | |
128 | + <a onClick={() => detailClick(item)}>{priceToThousands(num, 0)} 人</a> | |
129 | + {/* @ts-ignore */} | |
130 | + <InfoCircleOutlined style={{ color: 'var(--antd-wave-shadow-color)' }} /> | |
131 | + </Row> | |
132 | + </Popover> | |
133 | + ) : ( | |
134 | + <a onClick={() => detailClick(item)}>{priceToThousands(num, 0)} 人</a> | |
135 | + ) | |
136 | + } | |
124 | 137 | /> |
125 | 138 | ) : ( |
126 | 139 | <Table.Column title="原定岗数" dataIndex="oldLimitNum" align="left" render={(num: number) => `${priceToThousands(num, 0)} 人`} /> | ... | ... |
src/pages/ehr/PostSetting/interface.d.ts
... | ... | @@ -51,6 +51,7 @@ declare namespace PostSetting { |
51 | 51 | auditNo?: string; |
52 | 52 | oldLimitNum?: number; // 原岗位标准限制人数 |
53 | 53 | status?: number; // 状态 1草稿 2待审批 3审批拒绝 4审批通过 5撤销审批 |
54 | + remark?: string; // 提示,有则需要提示 | |
54 | 55 | } |
55 | 56 | |
56 | 57 | interface PostLimit { |
... | ... | @@ -77,6 +78,7 @@ declare namespace PostSetting { |
77 | 78 | salaryShopId?: number; // 薪资发放门店id |
78 | 79 | salaryShopName?: string; // 薪资发放门店名称 |
79 | 80 | staffStatus?: number; |
81 | + changeType?: number; // 2 调岗位 | |
80 | 82 | } |
81 | 83 | |
82 | 84 | type PostLevel = '业务岗位' | '初级管理岗' | '中级管理岗' | '高级管理岗'; | ... | ... |
src/pages/ehr/PostSetting/store.ts
... | ... | @@ -69,6 +69,18 @@ export default function useStore() { |
69 | 69 | '#FF921C', |
70 | 70 | } |
71 | 71 | |
72 | + enum ChangeType { | |
73 | + 调角色 = 1, | |
74 | + 调岗位 = 2, | |
75 | + 离职 = 3 | |
76 | + } | |
77 | + | |
78 | + enum ChangeTypeColor { | |
79 | + '#FF921C' = 1, | |
80 | + '#4189FD' = 2, | |
81 | + '#F4333C' = 3, | |
82 | + } | |
83 | + | |
72 | 84 | useEffect(() => { |
73 | 85 | // // 仅查询流程角色 roleType = 2 |
74 | 86 | getAllRoleCodeApi({ roleType: 2 }).then((res) => { |
... | ... | @@ -120,5 +132,7 @@ export default function useStore() { |
120 | 132 | roleList, |
121 | 133 | Status, |
122 | 134 | StatusColor, |
135 | + ChangeType, | |
136 | + ChangeTypeColor | |
123 | 137 | }; |
124 | 138 | } | ... | ... |
src/pages/ehr/ProgramOfStudy/QuestionBank/api.ts
1 | -import request from "@/utils/request"; | |
2 | -import { ABILITY_HOST } from "@/utils/host"; | |
3 | -import { http } from "@/typing/http"; | |
1 | +import request from '@/utils/request'; | |
2 | +import { ABILITY_HOST } from '@/utils/host'; | |
3 | +import type { http } from '@/typing/http'; | |
4 | 4 | |
5 | 5 | /** 获取题库列表 */ |
6 | -export function getQuestionBankListApi( | |
7 | - params: QuestionBank.QueryParams | |
8 | -): http.PromisePageResp<QuestionBank.List> { | |
6 | +export function getQuestionBankListApi(params: QuestionBank.QueryParams): http.PromisePageResp<QuestionBank.List> { | |
9 | 7 | return request.get(`${ABILITY_HOST}/erp/question/factory/list`, { params }); |
10 | 8 | } |
11 | 9 | |
... | ... | @@ -22,9 +20,7 @@ export function deleteQuestionBankApi(id: number) { |
22 | 20 | } |
23 | 21 | |
24 | 22 | /** 获取题目列表 */ |
25 | -export function getQuestionListApi(params: { | |
26 | - factoryId: number; | |
27 | -}): http.PromisePageResp<QuestionBank.Question> { | |
23 | +export function getQuestionListApi(params: { factoryId: number }): http.PromisePageResp<QuestionBank.Question> { | |
28 | 24 | return request.get(`${ABILITY_HOST}/erp/question/info/list`, { params }); |
29 | 25 | } |
30 | 26 | |
... | ... | @@ -45,11 +41,7 @@ export function deleteQuestionApi(id: number) { |
45 | 41 | * @param {QuestionBank.ImportQuestionParams} params |
46 | 42 | */ |
47 | 43 | export function importQuestionApi(params: QuestionBank.ImportQuestionParams) { |
48 | - return request.post<string>( | |
49 | - `${ABILITY_HOST}/erp/question/import/excel`, | |
50 | - params, | |
51 | - { contentType: "form-data" } | |
52 | - ); | |
44 | + return request.post<string>(`${ABILITY_HOST}/erp/question/import/excel`, params, { contentType: 'form-data' }); | |
53 | 45 | } |
54 | 46 | |
55 | 47 | /** |
... | ... | @@ -57,9 +49,7 @@ export function importQuestionApi(params: QuestionBank.ImportQuestionParams) { |
57 | 49 | * @param {QuestionBank.QueryParams} params |
58 | 50 | * @return {http.PromisePageResp<QuestionBank.List>} |
59 | 51 | */ |
60 | -export function getDraftListApi( | |
61 | - params: QuestionBank.QueryParams | |
62 | -): http.PromisePageResp<QuestionBank.List> { | |
52 | +export function getDraftListApi(params: QuestionBank.QueryParams): http.PromisePageResp<QuestionBank.List> { | |
63 | 53 | return request.get(`${ABILITY_HOST}/erp/draft/page`, { params }); |
64 | 54 | } |
65 | 55 | |
... | ... | @@ -68,9 +58,7 @@ export function getDraftListApi( |
68 | 58 | * @param {QuestionBank.List} params |
69 | 59 | * @return {http.PromiseResp<string>} |
70 | 60 | */ |
71 | -export function saveDraftApi( | |
72 | - params: QuestionBank.List | |
73 | -): http.PromiseResp<string> { | |
61 | +export function saveDraftApi(params: QuestionBank.List): http.PromiseResp<string> { | |
74 | 62 | return request.post(`${ABILITY_HOST}/erp/draft/save`, params); |
75 | 63 | } |
76 | 64 | |
... | ... | @@ -79,9 +67,7 @@ export function saveDraftApi( |
79 | 67 | * @param {number} factoryId |
80 | 68 | * @return {http.PromiseResp<QuestionBank.List>} |
81 | 69 | */ |
82 | -export function getDraftByFactoryIdApi( | |
83 | - factoryId: number | |
84 | -): http.PromiseResp<QuestionBank.List> { | |
70 | +export function getDraftByFactoryIdApi(factoryId: number): http.PromiseResp<QuestionBank.List> { | |
85 | 71 | return request.get(`${ABILITY_HOST}/erp/draft/by/factory`, { |
86 | 72 | params: { factoryId }, |
87 | 73 | }); |
... | ... | @@ -103,9 +89,7 @@ export function deleteDraftApi(draftId: number): http.PromiseResp<string> { |
103 | 89 | * @param {QuestionBank.DraftQuestionParams} params |
104 | 90 | * @return {http.PromiseRespA<QuestionBank.Question>} |
105 | 91 | */ |
106 | -export function getQuestionListByDraftApi( | |
107 | - params: QuestionBank.DraftQuestionParams | |
108 | -): http.PromiseRespA<QuestionBank.Question> { | |
92 | +export function getQuestionListByDraftApi(params: QuestionBank.DraftQuestionParams): http.PromiseRespA<QuestionBank.Question> { | |
109 | 93 | return request.get(`${ABILITY_HOST}/erp/draft/question/list`, { |
110 | 94 | params, |
111 | 95 | }); |
... | ... | @@ -116,9 +100,7 @@ export function getQuestionListByDraftApi( |
116 | 100 | * @param {QuestionBank.Question} params |
117 | 101 | * @return {http.PromiseResp<number>} |
118 | 102 | */ |
119 | -export function saveDraftQuestionApi( | |
120 | - params: QuestionBank.Question | |
121 | -): http.PromiseResp<number> { | |
103 | +export function saveDraftQuestionApi(params: QuestionBank.Question): http.PromiseResp<number> { | |
122 | 104 | return request.post(`${ABILITY_HOST}/erp/draft/question/save`, params); |
123 | 105 | } |
124 | 106 | |
... | ... | @@ -127,9 +109,7 @@ export function saveDraftQuestionApi( |
127 | 109 | * @param {QuestionBank.DeleteDraftQuestionParams} params |
128 | 110 | * @return {http.PromiseResp<string>} |
129 | 111 | */ |
130 | -export function deleteDraftQuestionApi( | |
131 | - params: QuestionBank.DeleteDraftQuestionParams | |
132 | -): http.PromiseResp<string> { | |
112 | +export function deleteDraftQuestionApi(params: QuestionBank.DeleteDraftQuestionParams): http.PromiseResp<string> { | |
133 | 113 | return request.post(`${ABILITY_HOST}/erp/draft/question/remove`, params); |
134 | 114 | } |
135 | 115 | |
... | ... | @@ -138,13 +118,8 @@ export function deleteDraftQuestionApi( |
138 | 118 | * @param {QuestionBank.BatchDeleteDraftQuestionParams} params |
139 | 119 | * @return {http.PromiseResp<string>} |
140 | 120 | */ |
141 | -export function batchDeleteDraftQuestionApi( | |
142 | - params: QuestionBank.BatchDeleteDraftQuestionParams | |
143 | -): http.PromiseResp<string> { | |
144 | - return request.post( | |
145 | - `${ABILITY_HOST}/erp/draft/question/batch/remove`, | |
146 | - params | |
147 | - ); | |
121 | +export function batchDeleteDraftQuestionApi(params: QuestionBank.BatchDeleteDraftQuestionParams): http.PromiseResp<string> { | |
122 | + return request.post(`${ABILITY_HOST}/erp/draft/question/batch/remove`, params); | |
148 | 123 | } |
149 | 124 | |
150 | 125 | /** |
... | ... | @@ -152,9 +127,7 @@ export function batchDeleteDraftQuestionApi( |
152 | 127 | * @param {number} draftId |
153 | 128 | * @return {http.PromiseResp<string>} |
154 | 129 | */ |
155 | -export function deleteAllDraftQuestionApi( | |
156 | - draftId: number | |
157 | -): http.PromiseResp<string> { | |
130 | +export function deleteAllDraftQuestionApi(draftId: number): http.PromiseResp<string> { | |
158 | 131 | return request.get(`${ABILITY_HOST}/erp/draft/question/all/remove`, { |
159 | 132 | params: { draftId }, |
160 | 133 | }); |
... | ... | @@ -166,11 +139,7 @@ export function deleteAllDraftQuestionApi( |
166 | 139 | * @return {http.PromiseResp<string>} |
167 | 140 | */ |
168 | 141 | export function approvalDraftApi(draftId: number): http.PromiseResp<string> { |
169 | - return request.post( | |
170 | - `${ABILITY_HOST}/erp/draft/submit`, | |
171 | - { draftId }, | |
172 | - { contentType: "form-data" } | |
173 | - ); | |
142 | + return request.post(`${ABILITY_HOST}/erp/draft/submit`, { draftId }, { contentType: 'form-data' }); | |
174 | 143 | } |
175 | 144 | |
176 | 145 | /** |
... | ... | @@ -178,9 +147,7 @@ export function approvalDraftApi(draftId: number): http.PromiseResp<string> { |
178 | 147 | * @param {number} factoryId |
179 | 148 | * @return {*} |
180 | 149 | */ |
181 | -export function exportQuestionBankApi( | |
182 | - factoryId: number | |
183 | -): http.PromiseResp<BlobPart> { | |
150 | +export function exportQuestionBankApi(factoryId: number): http.PromiseResp<BlobPart> { | |
184 | 151 | return request.get(`${ABILITY_HOST}/erp/question/export/question`, { |
185 | 152 | params: { factoryId }, |
186 | 153 | }); |
... | ... | @@ -202,10 +169,17 @@ export function exportDraftApi(draftId: number): http.PromiseResp<BlobPart> { |
202 | 169 | * @param {QuestionBank.ImportQuestionParams} params |
203 | 170 | * @return {http.PromiseResp<string>} |
204 | 171 | */ |
205 | -export function importDraftQuestionApi( | |
206 | - params: QuestionBank.ImportQuestionParams | |
207 | -): http.PromiseResp<string> { | |
172 | +export function importDraftQuestionApi(params: QuestionBank.ImportQuestionParams): http.PromiseResp<string> { | |
208 | 173 | return request.post(`${ABILITY_HOST}/erp/draft/import/excel`, params, { |
209 | - contentType: "form-data", | |
174 | + contentType: 'form-data', | |
210 | 175 | }); |
211 | 176 | } |
177 | + | |
178 | +/** | |
179 | + * @description: 撤销草稿审批 | |
180 | + * @param {string} auditNo | |
181 | + * @return {http.PromiseResp<string>} | |
182 | + */ | |
183 | +export function cancelDraftApprovalApi(auditNo: string): http.PromiseResp<string> { | |
184 | + return request.get(`${ABILITY_HOST}/erp/draft/cancel/audit`, { params: { auditNo } }); | |
185 | +} | ... | ... |
src/pages/ehr/ProgramOfStudy/QuestionBank/components/QuestionBankList/components/DraftList/index.tsx
1 | 1 | /* |
2 | 2 | * @Date: 2021-07-26 17:19:45 |
3 | 3 | * @LastEditors: wangqiang@feewee.cn |
4 | - * @LastEditTime: 2023-09-02 15:51:55 | |
4 | + * @LastEditTime: 2024-03-29 16:46:18 | |
5 | 5 | */ |
6 | 6 | import React, { useEffect } from 'react'; |
7 | 7 | import { useStore } from '../../../../index'; |
8 | -import { deleteDraftApi, approvalDraftApi } from '../../../../api'; | |
8 | +import { deleteDraftApi, approvalDraftApi, cancelDraftApprovalApi } from '../../../../api'; | |
9 | 9 | import { Badge, Button, Divider, Input, message, Modal, Popconfirm, Row, Table } from 'antd'; |
10 | 10 | import { PlusOutlined } from '@ant-design/icons'; |
11 | 11 | import QuestionBankModal from '../../QuestionBankModal'; |
... | ... | @@ -92,6 +92,19 @@ export default function DraftList() { |
92 | 92 | message.error(error.message); |
93 | 93 | }); |
94 | 94 | }; |
95 | + const cancelApprovalDraft = (auditNo: string) => { | |
96 | + const hide = message.loading('撤销中,请稍后...', 0); | |
97 | + cancelDraftApprovalApi(auditNo) | |
98 | + .then((res) => { | |
99 | + hide(); | |
100 | + message.success(res.result); | |
101 | + setLoading(true); | |
102 | + }) | |
103 | + .catch((error) => { | |
104 | + hide(); | |
105 | + message.error(error.message); | |
106 | + }); | |
107 | + }; | |
95 | 108 | |
96 | 109 | return ( |
97 | 110 | <> |
... | ... | @@ -210,7 +223,14 @@ export default function DraftList() { |
210 | 223 | <Divider type="vertical" /> |
211 | 224 | </> |
212 | 225 | ) : null} |
213 | - {record.status === StatusText.审批中 ? null : ( | |
226 | + {record.status === StatusText.审批中 ? ( | |
227 | + <> | |
228 | + <Popconfirm title={`确定撤销【${record.name}】审批?`} onConfirm={() => cancelApprovalDraft(record.auditNo ?? '')}> | |
229 | + <a style={{ color: 'red' }}>撤销审批</a> | |
230 | + </Popconfirm> | |
231 | + <Divider type="vertical" /> | |
232 | + </> | |
233 | + ) : ( | |
214 | 234 | <> |
215 | 235 | <a |
216 | 236 | onClick={() => { | ... | ... |
src/pages/finance/BasicConfig/FinanceType/components/CreateModal.tsx
... | ... | @@ -164,6 +164,12 @@ export default function CreateModal() { |
164 | 164 | <Radio value={false}>否</Radio> |
165 | 165 | </Radio.Group> |
166 | 166 | </FormItem> |
167 | + <FormItem label="是否支持主动报销" name='canMainReimburse' initialValue={false} rules={[{ required: true, message: '请选择' }]}> | |
168 | + <Radio.Group> | |
169 | + <Radio value>是</Radio> | |
170 | + <Radio value={false}>否</Radio> | |
171 | + </Radio.Group> | |
172 | + </FormItem> | |
167 | 173 | </Form> |
168 | 174 | </Modal> |
169 | 175 | ); | ... | ... |
src/pages/finance/BasicConfig/FinanceType/index.tsx
... | ... | @@ -59,6 +59,7 @@ function FinanceType() { |
59 | 59 | <Column width={140} title="是否支持划扣" dataIndex="abatement" render={(value: boolean) => (value ? '是' : '否')} /> |
60 | 60 | <Column width={160} title="划扣是否生成费用" dataIndex="abatementCanCost" render={(value: boolean) => (value ? '是' : '否')} /> |
61 | 61 | <Column title="是否支持代垫" dataIndex="disbursements" render={(value: boolean) => (value ? '是' : '否')} /> |
62 | + <Column title="是否支持主动报销" dataIndex="canMainReimburse" render={(value: boolean) => (value ? '是' : '否')} /> | |
62 | 63 | <Column |
63 | 64 | title="操作" |
64 | 65 | align="center" | ... | ... |
src/pages/finance/FinanceInvestor/api.ts
... | ... | @@ -8,7 +8,8 @@ type PrRes<T> = http.PromiseResp<T>; |
8 | 8 | * 获取数据列表 |
9 | 9 | */ |
10 | 10 | export function getFinanceSubjectApi(): PrRes<FinanceSubject.SubjectList[]> { |
11 | - return request.get(`${FINANCE2_HOST}/investment/subject/list`); | |
11 | + // return request.get(`${FINANCE2_HOST}/investment/subject/list`); | |
12 | + return request.get(`${FINANCE2_HOST}/config/investment/subject/list`); | |
12 | 13 | } |
13 | 14 | |
14 | 15 | /** | ... | ... |
src/pages/finance/PaymentAllocation/components/ApitalModal.tsx
1 | -import React, { useState, useEffect } from "react"; | |
1 | +import React, { useState, useEffect, useMemo } from "react"; | |
2 | 2 | import { Modal, Form, Input, Select, message, Radio } from "antd"; |
3 | 3 | import { useStore } from "../index"; |
4 | 4 | import { getRpTypeConfigSaveApi, commonRpTypesApi, RpTypesItem } from "../api"; |
5 | 5 | import useInitial from "@/hooks/useInitail"; |
6 | -import { CapitalAccountTypeEnum, ConfigType, ConfigTypeEnum, FinanceBankAccountTypeEnum, ProcessMode, ProcessModeEnum } from "@/pages/finance/entitys"; | |
6 | +import { ConfigType, ConfigTypeEnum, ProcessMode, ProcessMode2, ProcessModeEnum } from "@/pages/finance/entitys"; | |
7 | 7 | import { getCompanyBusinessTypesApi } from "@/pages/finance/TradeCompany/api"; |
8 | 8 | import { getAllRoleCodeApi } from "@/common/api"; |
9 | 9 | import { Label } from "bizcharts"; |
... | ... | @@ -21,6 +21,7 @@ export default function CreateModal() { |
21 | 21 | const { visible, setVisible, current, setCurrent, setLoading, } = |
22 | 22 | useStore(); |
23 | 23 | const [delay, setDelay] = useState(true); |
24 | + const [configValue, setConfigValue] = useState(); | |
24 | 25 | |
25 | 26 | // 查询收支类型(款项) |
26 | 27 | const { data, setParams: setRpTypesParams, params: rpTypesParams } = useInitial<RpTypesItem[], any>(commonRpTypesApi, [], {}, delay); |
... | ... | @@ -79,12 +80,16 @@ export default function CreateModal() { |
79 | 80 | }) |
80 | 81 | .catch((e) => { |
81 | 82 | message.error(e.message); |
82 | - }).finally(()=>setSaveLoading(false)); | |
83 | + }).finally(() => setSaveLoading(false)); | |
83 | 84 | } |
84 | 85 | |
85 | 86 | function onCancel() { |
86 | 87 | setVisible(false); |
87 | 88 | } |
89 | + const processMode = useMemo(() => { | |
90 | + if (!visible) setConfigValue(undefined); | |
91 | + return (current.configType == 5 || configValue==5) ? ProcessMode2 : ProcessMode; | |
92 | + }, [configValue, visible, current]) | |
88 | 93 | |
89 | 94 | return ( |
90 | 95 | <Modal |
... | ... | @@ -106,6 +111,7 @@ export default function CreateModal() { |
106 | 111 | if (type) { |
107 | 112 | setRpTypesParams({ ...rpTypesParams, ConfigType: type }, true); |
108 | 113 | setDelay(false); |
114 | + setConfigValue(type) | |
109 | 115 | //切换款项配置类型,清空已选款项 |
110 | 116 | form.setFieldValue("typeValue", undefined); |
111 | 117 | } |
... | ... | @@ -127,15 +133,18 @@ export default function CreateModal() { |
127 | 133 | ))} |
128 | 134 | </Select> |
129 | 135 | </FormItem> |
130 | - <FormItem name="processMode" label="款项处理" rules={[{ required: true, message: "请选择款项处理方式" }]}> | |
131 | - <Select placeholder="请选择款项处理方式" showSearch optionFilterProp="children"> | |
132 | - {ProcessMode.map((item) => ( | |
133 | - <Option key={item.value} value={item.value}> | |
134 | - {item.label} | |
135 | - </Option> | |
136 | - ))} | |
137 | - </Select> | |
138 | - </FormItem> | |
136 | + { | |
137 | + (configValue || current.id) && | |
138 | + <FormItem name="processMode" label="款项处理" rules={[{ required: true, message: "请选择款项处理方式" }]}> | |
139 | + <Select placeholder="请选择款项处理方式" showSearch optionFilterProp="children"> | |
140 | + {processMode.map((item) => ( | |
141 | + <Option key={item.value} value={item.value}> | |
142 | + {item.label} | |
143 | + </Option> | |
144 | + ))} | |
145 | + </Select> | |
146 | + </FormItem> | |
147 | + } | |
139 | 148 | <FormItem noStyle shouldUpdate={(prevValues, curValues) => (prevValues.processMode !== curValues.processMode) || (prevValues.configType !== curValues.configType)}> |
140 | 149 | {({ getFieldValue }) => { |
141 | 150 | const _processMode = (getFieldValue("processMode") || {}); | ... | ... |
src/pages/finance/SpecialAccount/FinancingCompany/components/CreateModal.tsx
... | ... | @@ -83,14 +83,14 @@ export default function CreateModal() { |
83 | 83 | } |
84 | 84 | |
85 | 85 | function submit(fieldValue: any) { |
86 | - if ( | |
87 | - fieldValue.depositAccount && | |
88 | - fieldValue?.account && | |
89 | - fieldValue.depositAccount.value === fieldValue?.account.value | |
90 | - ) { | |
91 | - message.error("还款保证金账户、一般账户请勿配置为同一账户", 1.5); | |
92 | - return; | |
93 | - } | |
86 | + // if ( | |
87 | + // fieldValue.depositAccount && | |
88 | + // fieldValue?.account && | |
89 | + // fieldValue.depositAccount.value === fieldValue?.account.value | |
90 | + // ) { | |
91 | + // message.error("还款保证金账户、一般账户请勿配置为同一账户", 1.5); | |
92 | + // return; | |
93 | + // } | |
94 | 94 | const param = { |
95 | 95 | dealerId, |
96 | 96 | ...fieldValue, | ... | ... |
src/pages/finance/entitys.ts
... | ... | @@ -225,6 +225,7 @@ export enum ConfigTypeEnum { |
225 | 225 | // '付款申请', |
226 | 226 | '缴费申请' = 3, |
227 | 227 | '付款申请' = 4, |
228 | + '主动报销' = 5, | |
228 | 229 | } |
229 | 230 | |
230 | 231 | export const ConfigType = [ |
... | ... | @@ -244,6 +245,10 @@ export const ConfigType = [ |
244 | 245 | label: '付款申请', |
245 | 246 | value: ConfigTypeEnum['付款申请'], |
246 | 247 | }, |
248 | + { | |
249 | + label: '主动报销', | |
250 | + value: ConfigTypeEnum['主动报销'], | |
251 | + }, | |
247 | 252 | ]; |
248 | 253 | /** |
249 | 254 | * 款项处理方式 |
... | ... | @@ -277,6 +282,16 @@ export const ProcessMode = [ |
277 | 282 | value: ProcessModeEnum['生成预付款'], |
278 | 283 | }, |
279 | 284 | ]; |
285 | +export const ProcessMode2 = [ | |
286 | + { | |
287 | + label: '默认', | |
288 | + value: ProcessModeEnum['默认'], | |
289 | + }, | |
290 | + { | |
291 | + label: '生成费用', | |
292 | + value: ProcessModeEnum['生成费用'], | |
293 | + }, | |
294 | +]; | |
280 | 295 | |
281 | 296 | /** 财务角色码 */ |
282 | 297 | export enum FinanceRoleCode { | ... | ... |
src/pages/stock/DirectVehicles/api.ts
... | ... | @@ -36,7 +36,8 @@ export function saveRebateApi(params: DirectVehicles.ListItem): PromiseResp<null |
36 | 36 | * 获取投资主体数据列表 |
37 | 37 | */ |
38 | 38 | export function getFinanceSubjectApi(): PromiseResp<FinanceSubject.SubjectList[]> { |
39 | - return request.get(`${FINANCE2_HOST}/investment/subject/list`); | |
39 | + // return request.get(`${FINANCE2_HOST}/investment/subject/list`); | |
40 | + return request.get(`${FINANCE2_HOST}/config/investment/subject/list`); | |
40 | 41 | } |
41 | 42 | /** |
42 | 43 | * 直营车现金折让提交确认 | ... | ... |
src/pages/trial/SystemSettings/OilSettings/index.tsx
1 | 1 | import React, { useEffect, useState } from "react"; |
2 | +import type { | |
3 | + DatePickerProps | |
4 | +} from "antd"; | |
2 | 5 | import { |
3 | - DatePickerProps, | |
4 | 6 | InputNumber, |
5 | 7 | Row, |
6 | 8 | Card, |
... | ... | @@ -13,9 +15,11 @@ import { |
13 | 15 | Switch, |
14 | 16 | } from "antd"; |
15 | 17 | import { PageHeaderWrapper } from "@ant-design/pro-layout"; |
18 | +import type { | |
19 | + ListVO | |
20 | +} from "./api"; | |
16 | 21 | import { |
17 | 22 | getOilListApi, |
18 | - ListVO, | |
19 | 23 | saveOilListApi, |
20 | 24 | getIsEditStatusApi, |
21 | 25 | saveIsEditStatusApi, |
... | ... | @@ -56,7 +60,7 @@ export default function OilSettings() { |
56 | 60 | |
57 | 61 | const onChange: DatePickerProps["onChange"] = (date, dateString) => { |
58 | 62 | setSaveDate(dateString); |
59 | - let newDataString = dateString.split("-"); | |
63 | + const newDataString = dateString.split("-"); | |
60 | 64 | setParams( |
61 | 65 | { |
62 | 66 | year: Number(newDataString[0]), |
... | ... | @@ -65,7 +69,7 @@ export default function OilSettings() { |
65 | 69 | true |
66 | 70 | ); |
67 | 71 | }; |
68 | - | |
72 | + | |
69 | 73 | function handleSubmit() { |
70 | 74 | setConfirmLoading(true); |
71 | 75 | saveOilListApi(data.vos!) |
... | ... | @@ -91,7 +95,7 @@ export default function OilSettings() { |
91 | 95 | }; |
92 | 96 | const changeOilPrice = (id: number, value: number) => { |
93 | 97 | if (value === undefined) return; |
94 | - let newList = data?.vos.map((item) => { | |
98 | + const newList = data?.vos.map((item) => { | |
95 | 99 | if (item.id === id) { |
96 | 100 | return { ...item, price: value }; |
97 | 101 | } |
... | ... | @@ -111,7 +115,7 @@ export default function OilSettings() { |
111 | 115 | return ( |
112 | 116 | <PageHeaderWrapper title="油价设置"> |
113 | 117 | <Spin spinning={loading}> |
114 | - <Card loading={loading} style={{height: 420}}> | |
118 | + <Card loading={loading} style={{ height: 420 }}> | |
115 | 119 | <div |
116 | 120 | style={{ |
117 | 121 | display: "flex", |
... | ... | @@ -126,19 +130,19 @@ export default function OilSettings() { |
126 | 130 | picker="month" |
127 | 131 | disabledDate={disabledDate} |
128 | 132 | /> |
129 | - <div style={{display: "flex", alignItems: "center"}}> | |
133 | + {/* <div style={{display: "flex", alignItems: "center"}}> | |
130 | 134 | <span>整点自动获取油价:</span> |
131 | 135 | <Switch |
132 | 136 | checked={isEdit === IsEdit["自动获取油价"]} |
133 | 137 | onChange={changeStatus} |
134 | 138 | /> |
135 | - </div> | |
139 | + </div> */} | |
136 | 140 | </div> |
137 | 141 | <List |
138 | 142 | dataSource={data?.vos} |
139 | 143 | style={{ display: "flex", alignItems: "center", marginTop: 20 }} |
140 | 144 | renderItem={(item: ListVO) => ( |
141 | - <List.Item style={{display: "flex", alignItems: "center", justifyContent: "space-between", height: 57, width: 400}}> | |
145 | + <List.Item style={{ display: "flex", alignItems: "center", justifyContent: "space-between", height: 57, width: 400 }}> | |
142 | 146 | <span style={{ width: 100 }}> |
143 | 147 | {item.typeDesc} |
144 | 148 | </span> |
... | ... | @@ -159,8 +163,8 @@ export default function OilSettings() { |
159 | 163 | value={item.price} |
160 | 164 | disabled={!edit} |
161 | 165 | onChange={(value) => { |
162 | - changeOilPrice(item.id, value); | |
163 | - }} | |
166 | + changeOilPrice(item.id, value); | |
167 | + }} | |
164 | 168 | /> |
165 | 169 | <span style={{ margin: "0 10px" }}>元/升</span> |
166 | 170 | </Row> | ... | ... |