!542 同步支付中心、商城最新实现

Merge pull request !542 from 芋道源码/feature/mall_product
plp
芋道源码 3 years ago committed by Gitee
commit 999dfd7c4a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F

@ -160,12 +160,11 @@
| | 功能 | 描述 |
|-----|------|---------------------------|
| 🚀 | 商户信息 | 管理商户信息,支持 Saas 场景下的多商户功能 |
| 🚀 | 应用信息 | 配置商户的应用信息,对接支付宝、微信等多个支付渠道 |
| 🚀 | 支付订单 | 查看用户发起的支付宝、微信等的【支付】订单 |
| 🚀 | 退款订单 | 查看用户发起的支付宝、微信等的【退款】订单 |
ps核心功能已经实现正在对接微信小程序中...
| 🚀 | 回调通知 | 查看支付回调业务的【支付】【退款】的通知结果 |
| 🚀 | 接入示例 | 提供接入支付系统的【支付】【退款】的功能实战 |
### 基础设施

@ -1797,27 +1797,112 @@ INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT"
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2046,'','promotion:reward-activity:close',3,5,2041,'','','',null,0,1,1,1,'1','2022-11-05 10:42:53','1','2022-11-05 10:42:53',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2047,'','',2,7,2030,'discount-activity','time','mall/promotion/discountActivity/index','PromotionDiscountActivity',0,1,1,1,'','2022-11-05 17:12:15','1','2023-04-08 11:45:44',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2048,'','promotion:discount-activity:query',3,1,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:15','','2022-11-05 17:12:15',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2049,'','promotion:discount-activity:create',3,2,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:15','','2022-11-05 17:12:15',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2050,'','promotion:discount-activity:update',3,3,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:16','','2022-11-05 17:12:16',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2051,'','promotion:discount-activity:delete',3,4,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:16','','2022-11-05 17:12:16',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2052,'','promotion:discount-activity:close',3,5,2047,'','','',null,0,1,1,1,'','2022-11-05 17:12:16','','2022-11-05 17:12:16',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2059,'','',2,0,2030,'seckill-activity','time-range','mall/promotion/seckill/seckillActivity/index','PromotionSeckillActivity',0,1,1,1,'','2022-11-06 22:24:49','1','2023-04-08 11:46:02',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2060,'','promotion:seckill-activity:query',3,1,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2061,'','promotion:seckill-activity:create',3,2,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2062,'','promotion:seckill-activity:update',3,3,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2063,'','promotion:seckill-activity:delete',3,4,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2064,'','promotion:seckill-activity:export',3,5,2059,'','','',null,0,1,1,1,'','2022-11-06 22:24:49','','2022-11-06 22:24:49',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2066,'','',2,0,2030,'seckill-time','','mall/promotion/seckill/seckillTime/index','PromotionSeckillTime',0,0,1,1,'','2022-11-15 19:46:50','1','2023-04-08 11:46:17',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2067,'','promotion:seckill-time:query',3,1,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2068,'','promotion:seckill-time:create',3,2,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2069,'','promotion:seckill-time:update',3,3,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2070,'','promotion:seckill-time:delete',3,4,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2071,'','promotion:seckill-time:export',3,5,2066,'','','',null,0,1,1,1,'','2022-11-15 19:46:51','','2022-11-15 19:46:51',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2072,'','',1,65,0,'/trade','order',null,null,0,1,1,1,'1','2022-11-19 18:57:19','1','2022-12-10 16:32:57',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2073,'退','',2,1,2072,'trade/after-sale','education','mall/trade/afterSale/index','TradeAfterSale',0,1,1,1,'','2022-11-19 20:15:32','1','2023-04-08 11:43:19',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2074,'','trade:after-sale:query',3,1,2073,'','','',null,0,1,1,1,'','2022-11-19 20:15:33','1','2022-12-10 21:04:29',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2075,'','promotion:sekill-activity:close',3,6,2059,'','','',null,0,1,1,1,'1','2022-11-28 20:20:15','1','2022-11-28 20:20:15',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2076,'','',2,0,2072,'trade/order','list','mall/trade/order/index','TradeOrder',0,1,1,1,'1','2022-12-10 21:05:44','1','2023-04-08 11:42:23',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2049, '', 'promotion:discount-activity:create', 3, 2, 2047, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-05 17:12:15', '', '2022-11-05 17:12:15', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2050, '', 'promotion:discount-activity:update', 3, 3, 2047, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-05 17:12:16', '', '2022-11-05 17:12:16', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2051, '', 'promotion:discount-activity:delete', 3, 4, 2047, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-05 17:12:16', '', '2022-11-05 17:12:16', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2052, '', 'promotion:discount-activity:close', 3, 5, 2047, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-05 17:12:16', '', '2022-11-05 17:12:16', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2059, '', '', 2, 0, 2030, 'seckill-activity', 'time-range',
'mall/promotion/seckill/seckillActivity/index', 'PromotionSeckillActivity', 0, 1, 1, 1, '',
'2022-11-06 22:24:49', '1', '2023-04-08 11:46:02', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2060, '', 'promotion:seckill-activity:query', 3, 1, 2059, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2061, '', 'promotion:seckill-activity:create', 3, 2, 2059, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2062, '', 'promotion:seckill-activity:update', 3, 3, 2059, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2063, '', 'promotion:seckill-activity:delete', 3, 4, 2059, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2064, '', 'promotion:seckill-activity:export', 3, 5, 2059, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-06 22:24:49', '', '2022-11-06 22:24:49', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2066, '', '', 2, 0, 2030, 'seckill-time', '', 'mall/promotion/seckill/SeckillConfig/index',
'PromotionSeckillConfig', 0, 0, 1, 1, '', '2022-11-15 19:46:50', '1', '2023-04-08 11:46:17', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2067, '', 'promotion:seckill-time:query', 3, 1, 2066, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2068, '', 'promotion:seckill-time:create', 3, 2, 2066, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2069, '', 'promotion:seckill-time:update', 3, 3, 2066, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2070, '', 'promotion:seckill-time:delete', 3, 4, 2066, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2071, '', 'promotion:seckill-time:export', 3, 5, 2066, '', '', '', null, 0, 1, 1, 1, '',
'2022-11-15 19:46:51', '', '2022-11-15 19:46:51', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2072, '', '', 1, 65, 0, '/trade', 'order', null, null, 0, 1, 1, 1, '1', '2022-11-19 18:57:19', '1',
'2022-12-10 16:32:57', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2073, '退', '', 2, 1, 2072, 'trade/after-sale', 'education', 'mall/trade/afterSale/index',
'TradeAfterSale', 0, 1, 1, 1, '', '2022-11-19 20:15:32', '1', '2023-04-08 11:43:19', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2074, '', 'trade:after-sale:query', 3, 1, 2073, '', '', '', null, 0, 1, 1, 1, '', '2022-11-19 20:15:33',
'1', '2022-12-10 21:04:29', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2075, '', 'promotion:sekill-activity:close', 3, 6, 2059, '', '', '', null, 0, 1, 1, 1, '1',
'2022-11-28 20:20:15', '1', '2022-11-28 20:20:15', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID", "NAME", "PERMISSION", "TYPE", "SORT", "PARENT_ID", "PATH", "ICON",
"COMPONENT", "COMPONENT_NAME", "STATUS", "VISIBLE", "KEEP_ALIVE",
"ALWAYS_SHOW", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED")
VALUES (2076, '', '', 2, 0, 2072, 'trade/order', 'list', 'mall/trade/order/index', 'TradeOrder', 0, 1, 1, 1,
'1', '2022-12-10 21:05:44', '1', '2023-04-08 11:42:23', 0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2077,'','',2,0,2072,'express-company','','mall/trade/expressCompany/index',null,0,1,1,1,'','2022-12-20 23:27:55','1','2022-12-20 23:36:20',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2078,'','trade:express-company:query',3,1,2077,'','','',null,0,1,1,1,'','2022-12-20 23:27:55','','2022-12-20 23:27:55',0);
INSERT INTO "RUOYI_VUE_PRO"."SYSTEM_MENU"("ID","NAME","PERMISSION","TYPE","SORT","PARENT_ID","PATH","ICON","COMPONENT","COMPONENT_NAME","STATUS","VISIBLE","KEEP_ALIVE","ALWAYS_SHOW","CREATOR","CREATE_TIME","UPDATER","UPDATE_TIME","DELETED") VALUES(2079,'','trade:express-company:create',3,2,2077,'','','',null,0,1,1,1,'','2022-12-20 23:27:55','','2022-12-20 23:27:55',0);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -11,7 +11,7 @@
Target Server Version : 80026
File Encoding : 65001
Date: 13/04/2023 23:37:01
Date: 24/07/2023 08:51:31
*/
SET NAMES utf8mb4;
@ -73,6 +73,9 @@ CREATE TABLE `QRTZ_CRON_TRIGGERS` (
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', '* * * * * ?', 'Asia/Shanghai');
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'payOrderExpireJob', 'DEFAULT', '0 0/1 * * * ?', 'Asia/Shanghai');
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'payOrderSyncJob', 'DEFAULT', '0 0/1 * * * ?', 'Asia/Shanghai');
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'payRefundSyncJob', 'DEFAULT', '0 0/1 * * * ?', 'Asia/Shanghai');
COMMIT;
-- ----------------------------
@ -133,6 +136,9 @@ CREATE TABLE `QRTZ_JOB_DETAILS` (
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000057400104A4F425F48414E444C45525F4E414D4574000C7061794E6F746966794A6F627800);
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'payOrderExpireJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000127400104A4F425F48414E444C45525F4E414D457400117061794F726465724578706972654A6F627800);
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'payOrderSyncJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000117400104A4F425F48414E444C45525F4E414D4574000F7061794F7264657253796E634A6F627800);
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'payRefundSyncJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000137400104A4F425F48414E444C45525F4E414D45740010706179526566756E6453796E634A6F627800);
COMMIT;
-- ----------------------------
@ -185,7 +191,7 @@ CREATE TABLE `QRTZ_SCHEDULER_STATE` (
-- Records of QRTZ_SCHEDULER_STATE
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_SCHEDULER_STATE` (`SCHED_NAME`, `INSTANCE_NAME`, `LAST_CHECKIN_TIME`, `CHECKIN_INTERVAL`) VALUES ('schedulerName', 'Yunai1677076619095', 1677076631456, 15000);
INSERT INTO `QRTZ_SCHEDULER_STATE` (`SCHED_NAME`, `INSTANCE_NAME`, `LAST_CHECKIN_TIME`, `CHECKIN_INTERVAL`) VALUES ('schedulerName', 'Yunai1690117495401', 1690119854263, 15000);
COMMIT;
-- ----------------------------
@ -279,202 +285,10 @@ CREATE TABLE `QRTZ_TRIGGERS` (
-- Records of QRTZ_TRIGGERS
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', 'payNotifyJob', 'DEFAULT', NULL, 1677076638000, 1677076637000, 5, 'WAITING', 'CRON', 1635294882000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
COMMIT;
-- ----------------------------
-- Table structure for bpm_form
-- ----------------------------
DROP TABLE IF EXISTS `bpm_form`;
CREATE TABLE `bpm_form` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`conf` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`fields` varchar(5000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of bpm_form
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for bpm_oa_leave
-- ----------------------------
DROP TABLE IF EXISTS `bpm_oa_leave`;
CREATE TABLE `bpm_oa_leave` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`user_id` bigint NOT NULL COMMENT '',
`type` tinyint NOT NULL COMMENT '',
`reason` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`start_time` datetime NOT NULL COMMENT '',
`end_time` datetime NOT NULL COMMENT '',
`day` tinyint NOT NULL COMMENT '',
`result` tinyint NOT NULL COMMENT '',
`process_instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 35 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OA ';
-- ----------------------------
-- Records of bpm_oa_leave
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for bpm_process_definition_ext
-- ----------------------------
DROP TABLE IF EXISTS `bpm_process_definition_ext`;
CREATE TABLE `bpm_process_definition_ext` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`process_definition_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`model_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`form_type` tinyint NOT NULL COMMENT '',
`form_id` bigint NULL DEFAULT NULL COMMENT '',
`form_conf` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`form_fields` varchar(5000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`form_custom_create_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`form_custom_view_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 141 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm \n';
-- ----------------------------
-- Records of bpm_process_definition_ext
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for bpm_process_instance_ext
-- ----------------------------
DROP TABLE IF EXISTS `bpm_process_instance_ext`;
CREATE TABLE `bpm_process_instance_ext` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`start_user_id` bigint NOT NULL COMMENT '',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`process_instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`process_definition_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`result` tinyint NOT NULL COMMENT '',
`end_time` datetime NULL DEFAULT NULL COMMENT '',
`form_variables` varchar(5000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 296 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of bpm_process_instance_ext
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for bpm_task_assign_rule
-- ----------------------------
DROP TABLE IF EXISTS `bpm_task_assign_rule`;
CREATE TABLE `bpm_task_assign_rule` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`model_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`process_definition_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`task_definition_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT ' key',
`type` tinyint NOT NULL COMMENT '',
`options` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'JSON ',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 275 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm ';
-- ----------------------------
-- Records of bpm_task_assign_rule
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for bpm_task_ext
-- ----------------------------
DROP TABLE IF EXISTS `bpm_task_ext`;
CREATE TABLE `bpm_task_ext` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`assignee_user_id` bigint NULL DEFAULT NULL COMMENT '',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`task_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`result` tinyint NOT NULL COMMENT '',
`reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`end_time` datetime NULL DEFAULT NULL COMMENT '',
`process_instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`process_definition_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 351 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of bpm_task_ext
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for bpm_user_group
-- ----------------------------
DROP TABLE IF EXISTS `bpm_user_group`;
CREATE TABLE `bpm_user_group` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '',
`member_user_ids` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '',
`status` tinyint NOT NULL COMMENT '0 1',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 113 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of bpm_user_group
-- ----------------------------
BEGIN;
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', 'payNotifyJob', 'DEFAULT', NULL, 1688907102000, 1688907101000, 5, 'PAUSED', 'CRON', 1635294882000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'payOrderExpireJob', 'DEFAULT', 'payOrderExpireJob', 'DEFAULT', NULL, 1690011600000, -1, 5, 'PAUSED', 'CRON', 1690011553000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'payOrderSyncJob', 'DEFAULT', 'payOrderSyncJob', 'DEFAULT', NULL, 1690011600000, 1690011540000, 5, 'PAUSED', 'CRON', 1690007785000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'payRefundSyncJob', 'DEFAULT', 'payRefundSyncJob', 'DEFAULT', NULL, 1690117560000, 1690117500000, 5, 'PAUSED', 'CRON', 1690117424000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
COMMIT;
-- ----------------------------
@ -546,7 +360,7 @@ CREATE TABLE `infra_api_error_log` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1110 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 1391 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_api_error_log
@ -584,7 +398,7 @@ CREATE TABLE `infra_codegen_column` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1688 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 1715 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_codegen_column
@ -617,7 +431,7 @@ CREATE TABLE `infra_codegen_table` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 131 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 132 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_codegen_table
@ -644,7 +458,7 @@ CREATE TABLE `infra_config` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_config
@ -655,6 +469,7 @@ INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `val
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8, 'url', 2, 'SkyWalking ', 'url.skywalking', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:57:03', b'0');
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (9, 'url', 2, 'Spring Boot Admin ', 'url.spring-boot-admin', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:52:07', b'0');
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (10, 'url', 2, 'Swagger ', 'url.swagger', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:59:00', b'0');
INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (11, 'ui', 2, ' key', 'tencent.lbs.key', 'TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E', b'1', ' key', '1', '2023-06-03 19:16:27', '1', '2023-06-03 19:16:27', b'0');
COMMIT;
-- ----------------------------
@ -699,7 +514,7 @@ CREATE TABLE `infra_file` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 912 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 953 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_file
@ -753,7 +568,7 @@ CREATE TABLE `infra_file_content` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_file_content
@ -781,14 +596,17 @@ CREATE TABLE `infra_job` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_job
-- ----------------------------
BEGIN;
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5, ' Job', 1, 'payNotifyJob', NULL, '* * * * * ?', 0, 0, 0, '1', '2021-10-27 08:34:42', '1', '2022-11-24 23:01:35', b'0');
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5, ' Job', 2, 'payNotifyJob', NULL, '* * * * * ?', 0, 0, 0, '1', '2021-10-27 08:34:42', '1', '2023-07-09 20:51:41', b'0');
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 'Job ', 1, 'demoJob', NULL, '* * * L * ?', 1, 1, 0, '1', '2022-09-24 22:31:41', '1', '2022-09-24 22:31:42', b'0');
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, ' Job', 2, 'payOrderSyncJob', NULL, '0 0/1 * * * ?', 0, 0, 0, '1', '2023-07-22 14:36:26', '1', '2023-07-22 15:39:08', b'0');
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (18, ' Job', 2, 'payOrderExpireJob', NULL, '0 0/1 * * * ?', 0, 0, 0, '1', '2023-07-22 15:36:23', '1', '2023-07-22 15:39:54', b'0');
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (19, '退 Job', 2, 'payRefundSyncJob', NULL, '0 0/1 * * * ?', 0, 0, 0, '1', '2023-07-23 21:03:44', '1', '2023-07-23 21:09:00', b'0');
COMMIT;
-- ----------------------------
@ -812,7 +630,7 @@ CREATE TABLE `infra_job_log` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 168767 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 161 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of infra_job_log
@ -867,7 +685,7 @@ CREATE TABLE `member_user` (
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_mobile`(`mobile` ASC) USING BTREE COMMENT ''
) ENGINE = InnoDB AUTO_INCREMENT = 247 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 248 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '';
-- ----------------------------
-- Records of member_user
@ -875,294 +693,6 @@ CREATE TABLE `member_user` (
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_app
-- ----------------------------
DROP TABLE IF EXISTS `pay_app`;
CREATE TABLE `pay_app` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`pay_notify_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`refund_notify_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退',
`merchant_id` bigint NOT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of pay_app
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_channel
-- ----------------------------
DROP TABLE IF EXISTS `pay_channel`;
CREATE TABLE `pay_channel` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`fee_rate` double NOT NULL DEFAULT 0 COMMENT '',
`merchant_id` bigint NOT NULL COMMENT '',
`app_id` bigint NOT NULL COMMENT '',
`config` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '\n';
-- ----------------------------
-- Records of pay_channel
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_demo_order
-- ----------------------------
DROP TABLE IF EXISTS `pay_demo_order`;
CREATE TABLE `pay_demo_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`user_id` bigint UNSIGNED NOT NULL COMMENT '',
`spu_id` bigint NOT NULL COMMENT '',
`spu_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '',
`price` int NOT NULL COMMENT '',
`payed` bit(1) NOT NULL DEFAULT b'0' COMMENT '[0: 1:]',
`pay_order_id` bigint NULL DEFAULT NULL COMMENT '',
`pay_channel_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '',
`pay_time` datetime NULL DEFAULT NULL COMMENT '',
`pay_refund_id` bigint NULL DEFAULT NULL COMMENT '退',
`refund_price` int NOT NULL DEFAULT 0 COMMENT '退',
`refund_time` datetime NULL DEFAULT NULL COMMENT '退',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 72 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '\n';
-- ----------------------------
-- Records of pay_demo_order
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_merchant
-- ----------------------------
DROP TABLE IF EXISTS `pay_merchant`;
CREATE TABLE `pay_merchant` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`short_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of pay_merchant
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_notify_log
-- ----------------------------
DROP TABLE IF EXISTS `pay_notify_log`;
CREATE TABLE `pay_notify_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`task_id` bigint NOT NULL COMMENT '',
`notify_times` tinyint NOT NULL COMMENT '',
`response` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 371964 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = ' App ';
-- ----------------------------
-- Records of pay_notify_log
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_notify_task
-- ----------------------------
DROP TABLE IF EXISTS `pay_notify_task`;
CREATE TABLE `pay_notify_task` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`merchant_id` bigint NOT NULL COMMENT '',
`app_id` bigint NOT NULL COMMENT '',
`type` tinyint NOT NULL COMMENT '',
`data_id` bigint NOT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`merchant_order_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`next_notify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`last_execute_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`notify_times` tinyint NOT NULL COMMENT '',
`max_notify_times` tinyint NOT NULL COMMENT '',
`notify_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 151 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '退\n';
-- ----------------------------
-- Records of pay_notify_task
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_order
-- ----------------------------
DROP TABLE IF EXISTS `pay_order`;
CREATE TABLE `pay_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`merchant_id` bigint NOT NULL COMMENT '',
`app_id` bigint NOT NULL COMMENT '',
`channel_id` bigint NULL DEFAULT NULL COMMENT '',
`channel_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`merchant_order_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`subject` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`body` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`notify_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`notify_status` tinyint NOT NULL COMMENT '',
`amount` bigint NOT NULL COMMENT '',
`channel_fee_rate` double NULL DEFAULT 0 COMMENT '',
`channel_fee_amount` bigint NULL DEFAULT 0 COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT ' IP',
`expire_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`success_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`notify_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`success_extension_id` bigint NULL DEFAULT NULL COMMENT '',
`refund_status` tinyint NOT NULL COMMENT '退',
`refund_times` tinyint NOT NULL COMMENT '退',
`refund_amount` bigint NOT NULL COMMENT '退',
`channel_user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`channel_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 171 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '\n';
-- ----------------------------
-- Records of pay_order
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_order_extension
-- ----------------------------
DROP TABLE IF EXISTS `pay_order_extension`;
CREATE TABLE `pay_order_extension` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`order_id` bigint NOT NULL COMMENT '',
`channel_id` bigint NOT NULL COMMENT '',
`channel_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT ' IP',
`status` tinyint NOT NULL COMMENT '',
`channel_extras` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`channel_notify_data` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 383 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '\n';
-- ----------------------------
-- Records of pay_order_extension
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for pay_refund
-- ----------------------------
DROP TABLE IF EXISTS `pay_refund`;
CREATE TABLE `pay_refund` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '退',
`merchant_id` bigint NOT NULL COMMENT '',
`app_id` bigint NOT NULL COMMENT '',
`channel_id` bigint NOT NULL COMMENT '',
`channel_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`order_id` bigint NOT NULL COMMENT ' pay_order id',
`trade_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT ' pay_extension no ',
`merchant_order_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`merchant_refund_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退',
`notify_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '',
`notify_status` tinyint NOT NULL COMMENT '退',
`status` tinyint NOT NULL COMMENT '退',
`type` tinyint NOT NULL COMMENT '退(退退)',
`pay_amount` bigint NOT NULL COMMENT ',',
`refund_amount` bigint NOT NULL COMMENT '退,',
`reason` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退',
`user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT ' IP',
`channel_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'pay_order channel_order_no ',
`channel_refund_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '退',
`channel_error_code` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`channel_error_msg` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`channel_extras` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '',
`expire_time` datetime NULL DEFAULT NULL COMMENT '退',
`success_time` datetime NULL DEFAULT NULL COMMENT '退',
`notify_time` datetime NULL DEFAULT NULL COMMENT '退',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '退';
-- ----------------------------
-- Records of pay_refund
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for system_dept
-- ----------------------------
@ -1223,7 +753,7 @@ CREATE TABLE `system_dict_data` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1234 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 1348 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of system_dict_data
@ -1299,33 +829,22 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (86, 0, '', '1', 'bpm_oa_leave_type', 0, 'primary', '', NULL, '1', '2021-09-21 22:35:28', '1', '2022-02-16 10:00:41', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (87, 1, '', '2', 'bpm_oa_leave_type', 0, 'info', '', NULL, '1', '2021-09-21 22:36:11', '1', '2022-02-16 10:00:49', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (88, 2, '', '3', 'bpm_oa_leave_type', 0, 'warning', '', NULL, '1', '2021-09-21 22:36:38', '1', '2022-02-16 10:00:53', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (98, 1, 'v2', 'v2', 'pay_channel_wechat_version', 0, '', '', 'v2', '1', '2021-11-08 17:00:58', '1', '2021-11-08 17:00:58', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (99, 2, 'v3', 'v3', 'pay_channel_wechat_version', 0, '', '', 'v3', '1', '2021-11-08 17:01:07', '1', '2021-11-08 17:01:07', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (108, 1, 'RSA2', 'RSA2', 'pay_channel_alipay_sign_type', 0, '', '', 'RSA2', '1', '2021-11-18 15:39:29', '1', '2021-11-18 15:39:29', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (109, 1, '', '1', 'pay_channel_alipay_mode', 0, '', '', 'privateKey + alipayPublicKey', '1', '2021-11-18 15:45:23', '1', '2021-11-18 15:45:23', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (110, 2, '', '2', 'pay_channel_alipay_mode', 0, '', '', 'appCertContent + alipayPublicCertContent + rootCertContent', '1', '2021-11-18 15:45:40', '1', '2021-11-18 15:45:40', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, 1, '线', 'https://openapi.alipay.com/gateway.do', 'pay_channel_alipay_server_type', 0, '', '', '网关地址 - 线上', '1', '2021-11-18 16:59:32', '1', '2021-11-21 17:37:29', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (112, 2, '', 'https://openapi.alipaydev.com/gateway.do', 'pay_channel_alipay_server_type', 0, '', '', '网关地址 - 沙箱', '1', '2021-11-18 16:59:48', '1', '2021-11-21 17:37:39', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (113, 1, ' JSAPI ', 'wx_pub', 'pay_channel_code_type', 0, '', '', ' JSAPI ', '1', '2021-12-03 10:40:24', '1', '2021-12-04 16:41:00', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (114, 2, '', 'wx_lite', 'pay_channel_code_type', 0, '', '', '', '1', '2021-12-03 10:41:06', '1', '2021-12-03 10:41:06', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (115, 3, ' App ', 'wx_app', 'pay_channel_code_type', 0, '', '', ' App ', '1', '2021-12-03 10:41:20', '1', '2021-12-03 10:41:20', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (116, 4, ' PC ', 'alipay_pc', 'pay_channel_code_type', 0, '', '', ' PC ', '1', '2021-12-03 10:42:09', '1', '2021-12-03 10:42:09', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (117, 5, ' Wap ', 'alipay_wap', 'pay_channel_code_type', 0, '', '', ' Wap ', '1', '2021-12-03 10:42:26', '1', '2021-12-03 10:42:26', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (118, 6, 'App ', 'alipay_app', 'pay_channel_code_type', 0, '', '', 'App ', '1', '2021-12-03 10:42:55', '1', '2021-12-03 10:42:55', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (119, 7, '', 'alipay_qr', 'pay_channel_code_type', 0, '', '', '', '1', '2021-12-03 10:43:10', '1', '2021-12-03 10:43:10', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (120, 1, '', '10', 'pay_order_notify_status', 0, 'success', '', '', '1', '2021-12-03 11:02:41', '1', '2022-02-16 13:59:13', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, 2, '', '20', 'pay_order_notify_status', 0, 'danger', '', '', '1', '2021-12-03 11:02:59', '1', '2022-02-16 13:59:17', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, 3, '', '0', 'pay_order_notify_status', 0, 'info', '', '', '1', '2021-12-03 11:03:10', '1', '2022-02-16 13:59:23', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (123, 1, '', '10', 'pay_order_status', 0, 'success', '', '', '1', '2021-12-03 11:18:29', '1', '2022-02-16 15:24:25', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (124, 2, '', '20', 'pay_order_status', 0, 'danger', '', '', '1', '2021-12-03 11:18:42', '1', '2022-02-16 15:24:31', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (125, 3, '', '0', 'pay_order_status', 0, 'info', '', '', '1', '2021-12-03 11:18:18', '1', '2022-02-16 15:24:35', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (126, 1, '退', '0', 'pay_order_refund_status', 0, '', '', '退', '1', '2021-12-03 11:30:35', '1', '2021-12-03 11:34:05', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (127, 2, '退', '10', 'pay_order_refund_status', 0, '', '', '退', '1', '2021-12-03 11:30:44', '1', '2021-12-03 11:34:10', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (128, 3, '退', '20', 'pay_order_refund_status', 0, '', '', '退', '1', '2021-12-03 11:30:52', '1', '2021-12-03 11:34:14', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1117, 1, '退', '0', 'pay_refund_order_status', 0, 'primary', '', '退', '1', '2021-12-10 16:44:44', '1', '2022-02-16 14:05:24', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1118, 2, '退', '1', 'pay_refund_order_status', 0, 'success', '', '退', '1', '2021-12-10 16:44:59', '1', '2022-02-16 14:05:28', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1119, 3, '退', '2', 'pay_refund_order_status', 0, 'danger', '', '退', '1', '2021-12-10 16:45:10', '1', '2022-02-16 14:05:34', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1124, 8, '退', '99', 'pay_refund_order_status', 0, 'info', '', '退', '1', '2021-12-10 16:46:26', '1', '2022-02-16 14:05:40', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (113, 1, '', 'wx_pub', 'pay_channel_code', 0, 'success', '', '', '1', '2021-12-03 10:40:24', '1', '2023-07-19 20:08:47', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (114, 2, '', 'wx_lite', 'pay_channel_code', 0, 'success', '', '', '1', '2021-12-03 10:41:06', '1', '2023-07-19 20:08:50', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (115, 3, ' App ', 'wx_app', 'pay_channel_code', 0, 'success', '', ' App ', '1', '2021-12-03 10:41:20', '1', '2023-07-19 20:08:56', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (116, 10, ' PC ', 'alipay_pc', 'pay_channel_code', 0, 'primary', '', ' PC ', '1', '2021-12-03 10:42:09', '1', '2023-07-19 20:09:12', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (117, 11, ' Wap ', 'alipay_wap', 'pay_channel_code', 0, 'primary', '', ' Wap ', '1', '2021-12-03 10:42:26', '1', '2023-07-19 20:09:16', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (118, 12, ' App ', 'alipay_app', 'pay_channel_code', 0, 'primary', '', ' App ', '1', '2021-12-03 10:42:55', '1', '2023-07-19 20:09:20', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (119, 14, '', 'alipay_qr', 'pay_channel_code', 0, 'primary', '', '', '1', '2021-12-03 10:43:10', '1', '2023-07-19 20:09:28', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (120, 10, '', '10', 'pay_notify_status', 0, 'success', '', '', '1', '2021-12-03 11:02:41', '1', '2023-07-19 10:08:19', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, 20, '', '20', 'pay_notify_status', 0, 'danger', '', '', '1', '2021-12-03 11:02:59', '1', '2023-07-19 10:08:21', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, 0, '', '0', 'pay_notify_status', 0, 'info', '', '', '1', '2021-12-03 11:03:10', '1', '2023-07-19 10:08:24', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (123, 10, '', '10', 'pay_order_status', 0, 'success', '', '', '1', '2021-12-03 11:18:29', '1', '2023-07-19 18:04:28', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (124, 30, '', '30', 'pay_order_status', 0, 'info', '', '', '1', '2021-12-03 11:18:42', '1', '2023-07-19 18:05:07', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (125, 0, '', '0', 'pay_order_status', 0, 'info', '', '', '1', '2021-12-03 11:18:18', '1', '2023-07-19 18:04:15', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1118, 0, '退', '0', 'pay_refund_status', 0, 'info', '', '退', '1', '2021-12-10 16:44:59', '1', '2023-07-19 10:14:39', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1119, 20, '退', '20', 'pay_refund_status', 0, 'danger', '', '退', '1', '2021-12-10 16:45:10', '1', '2023-07-19 10:15:10', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1124, 10, '退', '10', 'pay_refund_status', 0, 'success', '', '退', '1', '2021-12-10 16:46:26', '1', '2023-07-19 10:15:00', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1125, 0, '', '1', 'bpm_model_category', 0, 'primary', '', ' - ', '1', '2022-01-02 08:41:11', '1', '2022-02-16 20:01:42', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1126, 0, 'OA', '2', 'bpm_model_category', 0, 'success', '', ' - OA', '1', '2022-01-02 08:41:22', '1', '2022-02-16 20:01:50', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1127, 0, '', '1', 'bpm_process_instance_status', 0, 'primary', '', ' - ', '1', '2022-01-07 23:47:22', '1', '2022-02-16 20:07:49', b'0');
@ -1348,9 +867,6 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1144, 21, '', '21', 'bpm_task_assign_script', 0, '', '', ' - ', '103', '2022-01-15 21:24:46', '103', '2022-01-15 21:24:57', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1145, 1, '', '1', 'infra_codegen_scene', 0, '', '', ' - ', '1', '2022-02-02 13:15:06', '1', '2022-03-10 16:32:59', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1146, 2, ' APP', '2', 'infra_codegen_scene', 0, '', '', ' - APP', '1', '2022-02-02 13:15:19', '1', '2022-03-10 16:33:03', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1147, 0, '退', '0', 'pay_refund_order_type', 0, 'info', '', '退 - 退', '1', '2022-02-16 14:09:01', '1', '2022-02-16 14:09:01', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1148, 10, '退', '10', 'pay_refund_order_type', 0, 'success', '', '退 - 退', '1', '2022-02-16 14:09:25', '1', '2022-02-16 14:11:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1149, 20, '退', '20', 'pay_refund_order_type', 0, 'warning', '', '退 - 退', '1', '2022-02-16 14:11:33', '1', '2022-02-16 14:11:33', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1150, 1, '', '1', 'infra_file_storage', 0, 'default', '', NULL, '1', '2022-03-15 00:25:28', '1', '2022-03-15 00:25:28', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1151, 10, '', '10', 'infra_file_storage', 0, 'default', '', NULL, '1', '2022-03-15 00:25:41', '1', '2022-03-15 00:25:56', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1152, 11, 'FTP ', '11', 'infra_file_storage', 0, 'default', '', NULL, '1', '2022-03-15 00:26:06', '1', '2022-03-15 00:26:10', b'0');
@ -1429,12 +945,37 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1226, 30, '', '30', 'system_mail_send_status', 0, 'info', '', ' - ', '1', '2023-01-26 09:55:06', '1', '2023-01-26 16:36:36', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1227, 1, '', '1', 'system_notify_template_type', 0, 'primary', '', ' - ', '1', '2023-01-28 10:35:59', '1', '2023-01-28 10:35:59', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1228, 2, '', '2', 'system_notify_template_type', 0, 'success', '', ' - ', '1', '2023-01-28 10:36:20', '1', '2023-01-28 10:36:25', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1229, 0, '', 'mock', 'pay_channel_code_type', 0, 'default', '', NULL, '1', '2023-02-12 21:50:22', '1', '2023-02-12 21:50:22', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1230, 8, '', 'alipay_bar', 'pay_channel_code_type', 0, 'default', '', NULL, '1', '2023-02-18 23:32:24', '1', '2023-02-18 23:32:32', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1229, 0, '', 'mock', 'pay_channel_code', 0, 'default', '', '', '1', '2023-02-12 21:50:22', '1', '2023-07-10 10:11:02', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1230, 13, '', 'alipay_bar', 'pay_channel_code', 0, 'primary', '', '', '1', '2023-02-18 23:32:24', '1', '2023-07-19 20:09:23', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1231, 10, 'Vue2 Element UI ', '10', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:03:55', '1', '2023-04-13 00:03:55', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1232, 20, 'Vue3 Element Plus ', '20', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:08', '1', '2023-04-13 00:04:08', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1233, 21, 'Vue3 Element Plus Schema ', '21', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:26', '1', '2023-04-13 00:04:26', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1234, 30, 'Vue3 vben ', '30', 'infra_codegen_front_type', 0, '', '', '', '1', '2023-04-13 00:04:26', '1', '2023-04-13 00:04:26', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1235, 1, '个', '1', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1236, 1, '件', '2', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1237, 1, '盒', '3', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1238, 1, '袋', '4', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1239, 1, '箱', '5', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1240, 1, '套', '6', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1241, 1, '包', '7', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1242, 1, '双', '8', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1243, 1, '卷', '9', 'product_unit', 0, '', '', '', '1', '2023-05-23 14:38:38', '1', '2023-05-23 14:38:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1244, 0, '', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1245, 1, '', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1246, 2, '', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1335, 1, '', '1', 'member_point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:27', '1', '2023-06-28 13:48:28', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1336, 2, '', '2', 'member_point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:48', '1', '2023-06-28 13:48:31', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1337, 1, '', '1', 'member_point_status', 0, '', '', '', '1', '2023-06-10 12:16:42', '1', '2023-06-28 13:48:34', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1338, 2, '', '2', 'member_point_status', 0, '', '', '', '1', '2023-06-10 12:16:58', '1', '2023-06-28 13:48:36', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1339, 3, '', '3', 'member_point_status', 0, '', '', '', '1', '2023-06-10 12:17:07', '1', '2023-06-28 13:48:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1340, 4, '(退)', '4', 'member_point_status', 0, '', '', '', '1', '2023-06-10 12:17:21', '1', '2023-06-28 13:48:42', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1341, 20, '退', '20', 'pay_order_status', 0, 'danger', '', '退', '1', '2023-07-19 18:05:37', '1', '2023-07-19 18:05:37', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1342, 21, '', '21', 'pay_notify_status', 0, 'warning', '', '', '1', '2023-07-19 18:10:47', '1', '2023-07-19 18:11:38', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1343, 22, '', '22', 'pay_notify_status', 0, 'warning', '', NULL, '1', '2023-07-19 18:11:05', '1', '2023-07-19 18:11:27', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1344, 4, '', 'wx_native', 'pay_channel_code', 0, 'success', '', '', '1', '2023-07-19 20:07:47', '1', '2023-07-19 20:09:03', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1345, 5, '', 'wx_bar', 'pay_channel_code', 0, 'success', '', '\n', '1', '2023-07-19 20:08:06', '1', '2023-07-19 20:09:08', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1346, 1, '', '1', 'pay_notify_type', 0, 'primary', '', '', '1', '2023-07-20 12:23:17', '1', '2023-07-20 12:23:17', b'0');
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1347, 2, '退', '2', 'pay_notify_type', 0, 'danger', '', NULL, '1', '2023-07-20 12:23:26', '1', '2023-07-20 12:23:26', b'0');
COMMIT;
-- ----------------------------
@ -1455,7 +996,7 @@ CREATE TABLE `system_dict_type` (
`deleted_time` datetime NULL DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 169 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 174 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of system_dict_type
@ -1481,16 +1022,10 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (115, '', 'system_error_code_type', 0, NULL, '1', '2021-04-21 00:06:30', '1', '2022-02-01 16:36:49', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (116, '', 'system_login_type', 0, '', '1', '2021-10-06 00:50:46', '1', '2022-02-01 16:35:56', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (117, 'OA ', 'bpm_oa_leave_type', 0, NULL, '1', '2021-09-21 22:34:33', '1', '2022-01-22 10:41:37', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (122, '', 'pay_channel_wechat_version', 0, '', '1', '2021-11-08 17:00:26', '1', '2021-11-08 17:00:26', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (127, '', 'pay_channel_alipay_sign_type', 0, '', '1', '2021-11-18 15:39:09', '1', '2021-11-18 15:39:09', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (128, '', 'pay_channel_alipay_mode', 0, '', '1', '2021-11-18 15:44:28', '1', '2021-11-18 15:44:28', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (129, '', 'pay_channel_alipay_server_type', 0, '', '1', '2021-11-18 16:58:55', '1', '2021-11-18 17:01:34', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (130, '', 'pay_channel_code_type', 0, '', '1', '2021-12-03 10:35:08', '1', '2021-12-03 10:35:08', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (131, '', 'pay_order_notify_status', 0, '', '1', '2021-12-03 10:53:29', '1', '2021-12-03 10:53:29', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (130, '', 'pay_channel_code', 0, '', '1', '2021-12-03 10:35:08', '1', '2023-07-10 10:11:39', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (131, '', 'pay_notify_status', 0, '退', '1', '2021-12-03 10:53:29', '1', '2023-07-19 18:09:43', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (132, '', 'pay_order_status', 0, '', '1', '2021-12-03 11:17:50', '1', '2021-12-03 11:17:50', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (133, '退', 'pay_order_refund_status', 0, '退', '1', '2021-12-03 11:27:31', '1', '2021-12-03 11:27:31', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (134, '退', 'pay_refund_order_status', 0, '退', '1', '2021-12-10 16:42:50', '1', '2021-12-10 16:42:50', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (135, '退', 'pay_refund_order_type', 0, '退', '1', '2021-12-10 17:14:53', '1', '2021-12-10 17:14:53', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (134, '退', 'pay_refund_status', 0, '退', '1', '2021-12-10 16:42:50', '1', '2023-07-19 10:13:17', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (138, '', 'bpm_model_category', 0, '', '1', '2022-01-02 08:40:45', '1', '2022-01-02 08:40:45', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (139, '', 'bpm_process_instance_status', 0, '', '1', '2022-01-07 23:46:42', '1', '2022-01-07 23:46:42', b'0', NULL);
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (140, '', 'bpm_process_instance_result', 0, '', '1', '2022-01-07 23:48:10', '1', '2022-01-07 23:48:10', b'0', NULL);
@ -1521,6 +1056,11 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (166, '', 'system_mail_send_status', 0, '', '1', '2023-01-26 09:53:13', '1', '2023-01-26 09:53:13', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (167, '', 'system_notify_template_type', 0, '', '1', '2023-01-28 10:35:10', '1', '2023-01-28 10:35:10', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (168, '', 'infra_codegen_front_type', 0, '', '1', '2023-04-12 23:57:52', '1', '2023-04-12 23:57:52', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (169, '', 'product_unit', 0, '', '1', '2023-05-24 21:23:59', '1', '2023-05-24 21:23:59', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (170, '', 'trade_delivery_express_charge_mode', 0, '', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (171, '', 'member_point_biz_type', 0, '', '1', '2023-06-10 12:15:00', '1', '2023-06-28 13:48:20', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (172, '', 'member_point_status', 0, '', '1', '2023-06-10 12:16:27', '1', '2023-06-28 13:48:17', b'0', '1970-01-01 00:00:00');
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (173, '', 'pay_notify_type', 0, NULL, '1', '2023-07-20 12:23:03', '1', '2023-07-20 12:23:03', b'0', '1970-01-01 00:00:00');
COMMIT;
-- ----------------------------
@ -1540,7 +1080,7 @@ CREATE TABLE `system_error_code` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5832 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 5833 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of system_error_code
@ -1569,7 +1109,7 @@ CREATE TABLE `system_login_log` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2163 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '访';
) ENGINE = InnoDB AUTO_INCREMENT = 2243 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '访';
-- ----------------------------
-- Records of system_login_log
@ -1699,7 +1239,7 @@ CREATE TABLE `system_menu` (
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2162 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 2303 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of system_menu
@ -1833,12 +1373,11 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1118, '', '', 2, 0, 5, 'leave', 'user', 'bpm/oa/leave/index', 'BpmOALeave', 0, b'1', b'1', b'1', '', '2021-09-20 08:51:03', '1', '2023-04-08 11:30:40', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1119, '', 'bpm:oa-leave:query', 3, 1, 1118, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-09-20 08:51:03', '1', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1120, '', 'bpm:oa-leave:create', 3, 2, 1118, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-09-20 08:51:03', '1', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1126, '', '', 2, 1, 1117, 'app', 'table', 'pay/app/index', 'PayMerchant', 0, b'1', b'1', b'1', '', '2021-11-10 01:13:30', '1', '2023-04-08 10:43:14', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1126, '', '', 2, 1, 1117, 'app', 'table', 'pay/app/index', 'PayApp', 0, b'1', b'1', b'1', '', '2021-11-10 01:13:30', '1', '2023-07-20 12:13:32', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1127, '', 'pay:app:query', 3, 1, 1126, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:31', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1128, '', 'pay:app:create', 3, 2, 1126, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:31', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1129, '', 'pay:app:update', 3, 3, 1126, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:31', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1130, '', 'pay:app:delete', 3, 4, 1126, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:31', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1131, '', 'pay:app:export', 3, 5, 1126, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:31', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1132, '', 'pay:channel:parsing', 3, 6, 1129, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2021-11-08 15:15:47', '1', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1133, '', 'pay:merchant:query', 3, 1, 1132, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:41', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1134, '', 'pay:merchant:create', 3, 2, 1132, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-11-10 01:13:41', '', '2022-04-20 17:03:10', b'0');
@ -1864,12 +1403,6 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1176, '', 'pay:order:update', 3, 3, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1177, '', 'pay:order:delete', 3, 4, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1178, '', 'pay:order:export', 3, 5, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1179, '', '', 2, 0, 1117, 'merchant', 'merchant', 'pay/merchant/index', 'PayApp', 0, b'1', b'1', b'1', '', '2021-12-25 09:01:44', '1', '2023-04-08 10:42:32', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1180, '', 'pay:merchant:query', 3, 1, 1179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 09:01:44', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1181, '', 'pay:merchant:create', 3, 2, 1179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 09:01:44', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1182, '', 'pay:merchant:update', 3, 3, 1179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 09:01:44', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1183, '', '', 3, 4, 1179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 09:01:44', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1184, '', 'pay:merchant:export', 3, 5, 1179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 09:01:44', '', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1185, '', '', 1, 50, 0, '/bpm', 'tool', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:26:36', '103', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1186, '', '', 1, 10, 1185, 'manager', 'nested', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:28:30', '1', '2022-04-20 17:03:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1187, '', '', 2, 0, 1186, 'form', 'form', 'bpm/form/index', 'BpmForm', 0, b'1', b'1', b'1', '', '2021-12-30 12:38:22', '1', '2023-04-08 10:50:37', b'0');
@ -1984,29 +1517,22 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2050, '', 'promotion:discount-activity:update', 3, 3, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2051, '', 'promotion:discount-activity:delete', 3, 4, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2052, '', 'promotion:discount-activity:close', 3, 5, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2059, '', '', 2, 0, 2030, 'seckill-activity', 'time-range', 'mall/promotion/seckill/seckillActivity/index', 'PromotionSeckillActivity', 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '1', '2023-04-08 11:46:02', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2059, '', '', 2, 2, 2209, 'activity', 'ep:basketball', 'mall/promotion/seckill/activity/index', 'PromotionSeckillActivity', 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '1', '2023-06-24 18:57:25', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2060, '', 'promotion:seckill-activity:query', 3, 1, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2061, '', 'promotion:seckill-activity:create', 3, 2, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2062, '', 'promotion:seckill-activity:update', 3, 3, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2063, '', 'promotion:seckill-activity:delete', 3, 4, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2064, '', 'promotion:seckill-activity:export', 3, 5, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-06 22:24:49', '', '2022-11-06 22:24:49', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2066, '', '', 2, 0, 2030, 'seckill-time', '', 'mall/promotion/seckill/seckillTime/index', 'PromotionSeckillTime', 0, b'0', b'1', b'1', '', '2022-11-15 19:46:50', '1', '2023-04-08 11:46:17', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2067, '', 'promotion:seckill-time:query', 3, 1, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2068, '', 'promotion:seckill-time:create', 3, 2, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2069, '', 'promotion:seckill-time:update', 3, 3, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2070, '', 'promotion:seckill-time:delete', 3, 4, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2071, '', 'promotion:seckill-time:export', 3, 5, 2066, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '', '2022-11-15 19:46:51', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2066, '', '', 2, 1, 2209, 'config', 'ep:baseball', 'mall/promotion/seckill/config/index', 'PromotionSeckillConfig', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:50', '1', '2023-06-24 18:57:14', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2067, '', 'promotion:seckill-config:query', 3, 1, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:25', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2068, '', 'promotion:seckill-config:create', 3, 2, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:48:39', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2069, '', 'promotion:seckill-config:update', 3, 3, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2070, '', 'promotion:seckill-config:delete', 3, 4, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:32', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2072, '', '', 1, 65, 0, '/trade', 'order', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-11-19 18:57:19', '1', '2022-12-10 16:32:57', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2073, '退', '', 2, 1, 2072, 'trade/after-sale', 'education', 'mall/trade/afterSale/index', 'TradeAfterSale', 0, b'1', b'1', b'1', '', '2022-11-19 20:15:32', '1', '2023-04-08 11:43:19', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2074, '', 'trade:after-sale:query', 3, 1, 2073, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-19 20:15:33', '1', '2022-12-10 21:04:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2075, '', 'promotion:sekill-activity:close', 3, 6, 2059, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2022-11-28 20:20:15', '1', '2022-11-28 20:20:15', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2076, '', '', 2, 0, 2072, 'trade/order', 'list', 'mall/trade/order/index', 'TradeOrder', 0, b'1', b'1', b'1', '1', '2022-12-10 21:05:44', '1', '2023-04-08 11:42:23', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2077, '', '', 2, 0, 2072, 'express-company', '', 'mall/trade/expressCompany/index', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '1', '2022-12-20 23:36:20', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2078, '', 'trade:express-company:query', 3, 1, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2079, '', 'trade:express-company:create', 3, 2, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2080, '', 'trade:express-company:update', 3, 3, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2081, '', 'trade:express-company:delete', 3, 4, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2082, '', 'trade:express-company:export', 3, 5, 2077, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-12-20 23:27:55', '', '2022-12-20 23:27:55', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2083, '', '', 2, 14, 1, 'area', 'row', 'system/area/index', 'SystemArea', 0, b'1', b'1', b'1', '1', '2022-12-23 17:35:05', '1', '2023-04-08 09:01:37', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2084, '', '', 1, 100, 0, '/mp', 'wechat', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-01 20:11:04', '1', '2023-01-15 11:28:57', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2085, '', '', 2, 1, 2084, 'account', 'phone', 'mp/account/index', 'MpAccount', 0, b'1', b'1', b'1', '1', '2023-01-01 20:13:31', '1', '2023-02-09 23:56:39', b'0');
@ -2086,6 +1612,47 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2159, 'Boot ', '', 1, 1, 0, 'https://doc.iocoder.cn/', 'education', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:46:28', '1', '2023-02-10 22:46:28', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2160, 'Cloud ', '', 1, 2, 0, 'https://cloud.iocoder.cn', 'documentation', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:47:07', '1', '2023-02-10 22:47:07', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2161, '', '', 2, 99, 1117, 'demo-order', 'drag', 'pay/demo/index', NULL, 0, b'1', b'1', b'1', '', '2023-02-11 14:21:42', '1', '2023-02-11 22:26:35', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2162, '', 'product:spu:export', 3, 5, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2164, '', '', 1, 2, 2072, 'delivery', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-05-24 23:24:13', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2165, '', '', 1, 0, 2164, 'express', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-05-18 09:22:06', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2166, '', '', 1, 1, 2164, 'pick-up-store', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2167, '', '', 2, 0, 2165, 'express', '', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-05-18 22:11:14', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2168, '', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2169, '', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2170, '', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2171, '', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, '', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, '', 'trade:delivery:express-template:query', 2, 1, 2165, 'express-template', '', 'mall/trade/delivery/expressTemplate/index', 'ExpressTemplate', 0, b'1', b'1', b'1', '1', '2023-05-20 06:48:10', '1', '2023-05-20 06:48:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2174, '', 'trade:delivery:express-template:query', 3, 1, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2175, '', 'trade:delivery:express-template:create', 3, 2, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2176, '', 'trade:delivery:express-template:update', 3, 3, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2177, '', 'trade:delivery:express-template:delete', 3, 4, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2178, '', 'trade:delivery:express-template:export', 3, 5, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2179, '', '', 2, 1, 2166, 'pick-up-store', '', 'mall/trade/delivery/pickUpStore/index', 'PickUpStore', 0, b'1', b'1', b'1', '1', '2023-05-25 10:50:00', '1', '2023-05-25 10:50:00', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2180, '', 'trade:delivery:pick-up-store:query', 3, 1, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2181, '', 'trade:delivery:pick-up-store:create', 3, 2, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2182, '', 'trade:delivery:pick-up-store:update', 3, 3, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2183, '', 'trade:delivery:pick-up-store:delete', 3, 4, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2184, '', 'trade:delivery:pick-up-store:export', 3, 5, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2209, '', '', 2, 3, 2030, 'seckill', 'ep:place', '', '', 0, b'1', b'1', b'1', '1', '2023-06-24 17:39:13', '1', '2023-06-24 18:55:15', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2262, '', '', 1, 55, 0, '/member', 'date-range', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-06-10 00:42:03', '1', '2023-06-28 22:52:34', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2275, '', '', 2, 0, 2299, 'config', '', 'member/point/config/index', 'PointConfig', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-06-27 22:50:59', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2276, '', 'point:config:query', 3, 1, 2275, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '', '2023-06-10 02:07:44', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2277, '', 'point:config:save', 3, 2, 2275, '', '', '', '', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-06-27 20:32:31', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2281, '', '', 2, 2, 2300, 'sign-in-config', '', 'member/signin/config/index', 'SignInConfig', 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '1', '2023-07-02 15:04:15', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2282, '', 'point:sign-in-config:query', 3, 1, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2283, '', 'point:sign-in-config:create', 3, 2, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2284, '', 'point:sign-in-config:update', 3, 3, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2285, '', 'point:sign-in-config:delete', 3, 4, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2287, '', '', 2, 1, 2299, 'record', '', 'member/point/record/index', 'PointRecord', 0, b'1', b'1', b'1', '', '2023-06-10 04:18:50', '1', '2023-06-27 22:51:07', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2288, '', 'point:record:query', 3, 1, 2287, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:18:50', '', '2023-06-10 04:18:50', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2293, '', '', 2, 3, 2300, 'sign-in-record', '', 'member/signin/record/index', 'SignInRecord', 0, b'1', b'1', b'1', '', '2023-06-10 04:48:22', '1', '2023-07-02 15:04:10', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2294, '', 'point:sign-in-record:query', 3, 1, 2293, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:48:22', '', '2023-06-10 04:48:22', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2297, '', 'point:sign-in-record:delete', 3, 4, 2293, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 04:48:22', '', '2023-06-10 04:48:22', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2299, '', '', 1, 1, 2262, 'point', '', '', '', 0, b'1', b'1', b'1', '1', '2023-06-27 22:48:51', '1', '2023-06-27 22:48:51', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2300, '', '', 1, 2, 2262, 'signin', '', '', '', 0, b'1', b'1', b'1', '1', '2023-06-27 22:49:53', '1', '2023-06-27 22:49:53', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2301, '', '', 2, 4, 1117, 'notify', 'example', 'pay/notify/index', 'PayNotify', 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '1', '2023-07-20 13:45:08', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2302, '', 'pay:notify:query', 3, 1, 2301, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '', '2023-07-20 04:41:32', b'0');
COMMIT;
-- ----------------------------
@ -2202,7 +1769,7 @@ CREATE TABLE `system_oauth2_access_token` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1785 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访';
) ENGINE = InnoDB AUTO_INCREMENT = 2231 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访';
-- ----------------------------
-- Records of system_oauth2_access_token
@ -2324,7 +1891,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 738 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 ';
) ENGINE = InnoDB AUTO_INCREMENT = 804 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 ';
-- ----------------------------
-- Records of system_oauth2_refresh_token
@ -2364,7 +1931,7 @@ CREATE TABLE `system_operate_log` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6440 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
) ENGINE = InnoDB AUTO_INCREMENT = 7134 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '';
-- ----------------------------
-- Records of system_operate_log
@ -2946,7 +2513,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2062, 2, 1128, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2063, 2, 1129, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2064, 2, 1130, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2065, 2, 1131, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2066, 2, 1132, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2067, 2, 1133, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2068, 2, 1134, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
@ -2974,12 +2540,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2090, 2, 1176, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2091, 2, 1177, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2092, 2, 1178, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2093, 2, 1179, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2094, 2, 1180, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2095, 2, 1181, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2096, 2, 1182, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2097, 2, 1183, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2098, 2, 1184, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2099, 2, 1226, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2100, 2, 1227, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2101, 2, 1228, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
@ -3524,7 +3084,7 @@ CREATE TABLE `system_tenant` (
BEGIN;
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '', NULL, '', '17321315478', 0, 'https://www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2022-02-23 12:15:11', b'0');
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '', 110, '2', '15601691300', 0, 'http://www.iocoder.cn', 111, '2024-03-11 00:00:00', 20, '1', '2022-02-22 00:56:14', '1', '2022-05-17 10:03:59', b'0');
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '', 113, '', '15601691300', 0, 'https://www.iocoder.cn', 111, '2022-04-30 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0');
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '', 113, '', '15601691300', 0, 'https://www.iocoder.cn', 111, '2022-04-30 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2023-04-15 09:17:54', b'0');
COMMIT;
-- ----------------------------
@ -3662,7 +3222,7 @@ CREATE TABLE `system_users` (
-- Records of system_users
-- ----------------------------
BEGIN;
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '', '', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/e1fdd7271685ec143a0900681606406621717a666ad0b2798b096df41422b32f.png', 0, '0:0:0:0:0:0:0:1', '2023-04-13 23:09:16', 'admin', '2021-01-05 17:03:47', NULL, '2023-04-13 23:09:16', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '', '', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/e1fdd7271685ec143a0900681606406621717a666ad0b2798b096df41422b32f.png', 0, '127.0.0.1', '2023-07-24 08:41:23', 'admin', '2021-01-05 17:03:47', NULL, '2023-07-24 08:41:23', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '', '', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1);
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '127.0.0.1', '2022-05-28 15:43:17', '', '2021-01-21 02:13:53', NULL, '2022-07-09 09:00:33', b'0', 1);

@ -96,6 +96,11 @@
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>

@ -33,7 +33,11 @@ public class ServiceErrorCodeRange {
// 模块 system 错误码区间 [1-002-000-000 ~ 1-003-000-000)
// 模块 report 错误码区间 [1-003-000-000 ~ 1-004-000-000)
// 模块 member 错误码区间 [1-004-000-000 ~ 1-005-000-000)
// 模块 mp 错误码区间 [1-006-000-000 ~ 1-007-000-000)
// 模块 pay 错误码区间 [1-007-000-000 ~ 1-008-000-000)
// 模块 product 错误码区间 [1-008-000-000 ~ 1-009-000-000)
// 模块 bpm 错误码区间 [1-009-000-000 ~ 1-010-000-000)
// 模块 trade 错误码区间 [1-011-000-000 ~ 1-012-000-000)
// 模块 promotion 错误码区间 [1-013-000-000 ~ 1-014-000-000)
}

@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.exception.util;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
@ -80,6 +81,10 @@ public class ServiceExceptionUtil {
return new ServiceException(code, message);
}
public static ServiceException invalidParamException(String messagePattern, Object... params) {
return exception0(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), messagePattern, params);
}
// ========== 格式化方法 ==========
/**

@ -55,7 +55,6 @@ public class DateUtils {
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
@Deprecated
public static Date addTime(Duration duration) {
return new Date(System.currentTimeMillis() + duration.toMillis());
}

@ -4,6 +4,7 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@ -13,6 +14,7 @@ import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
@ -29,6 +31,7 @@ public class JsonUtils {
static {
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化
}
@ -70,6 +73,18 @@ public class JsonUtils {
}
}
public static <T> T parseObject(String text, Type type) {
if (StrUtil.isEmpty(text)) {
return null;
}
try {
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructType(type));
} catch (IOException e) {
log.error("json parse err,json:{}", text, e);
throw new RuntimeException(e);
}
}
/**
*
* 使 {@link #parseObject(String, Class)} @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)

@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.spring;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
@ -24,7 +25,13 @@ import java.util.Map;
*/
public class SpringExpressionUtils {
/**
* spel
*/
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
/**
*
*/
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
private SpringExpressionUtils() {
@ -33,7 +40,7 @@ public class SpringExpressionUtils {
/**
* EL
*
* @param joinPoint
* @param joinPoint
* @param expressionString EL
* @return
*/
@ -45,7 +52,7 @@ public class SpringExpressionUtils {
/**
* EL
*
* @param joinPoint
* @param joinPoint
* @param expressionStrings EL
* @return key value
*/
@ -79,4 +86,48 @@ public class SpringExpressionUtils {
});
return result;
}
/**
* JoinPoint EL jspl
*
* @param joinPoint
* @param info
* @param expressionStrings EL
* @return Map<String, Object>
* @author
* @since 2023/6/18 11:20
*/
// TODO @chenchen: 这个方法,和 parseExpressions 比较接近,是不是可以合并下;
public static Map<String, Object> parseExpression(JoinPoint joinPoint, Object info, List<String> expressionStrings) {
// 如果为空,则不进行解析
if (CollUtil.isEmpty(expressionStrings)) {
return MapUtil.newHashMap();
}
// 第一步,构建解析的上下文 EvaluationContext
// 通过 joinPoint 获取被注解方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 使用 spring 的 ParameterNameDiscoverer 获取方法形参名数组
String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
// Spring 的表达式上下文对象
EvaluationContext context = new StandardEvaluationContext();
if (ArrayUtil.isNotEmpty(parameterNames)) {
//获取方法参数值
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
// 替换 SP EL 里的变量值为实际值, 比如 #user --> user对象
context.setVariable(parameterNames[i], args[i]);
}
context.setVariable("info", info);
}
// 第二步,逐个参数解析
Map<String, Object> result = MapUtil.newHashMap(expressionStrings.size(), true);
expressionStrings.forEach(key -> {
Object value = EXPRESSION_PARSER.parseExpression(key).getValue(context);
result.put(key, value);
});
return result;
}
}

@ -1,6 +1,5 @@
package cn.iocoder.yudao.framework.common.util.string;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
@ -17,14 +16,7 @@ import java.util.stream.Collectors;
public class StrUtils {
public static String maxLength(CharSequence str, int maxLength) {
Assert.isTrue(maxLength > 0);
if (null == str) {
return null;
}
if (str.length() <= maxLength) {
return str.toString();
}
return StrUtil.sub(str, 0, maxLength - 3) + "..."; // -3 的原因,是该方法会补充 ... 恰好
return StrUtil.maxLength(str, maxLength - 3); // -3 的原因,是该方法会补充 ... 恰好
}
/**
@ -48,12 +40,14 @@ public class StrUtils {
return false;
}
public static List<Long> splitToLong(String value, CharSequence separator) {
public static List<Long> splitToLong(String value, CharSequence separator) {
long[] longs = StrUtil.splitToLong(value, separator);
return Arrays.stream(longs).boxed().collect(Collectors.toList());
}
public static void main(String[] args) {
System.out.println(maxLength("aaaaa", 4));
public static List<Integer> splitToInteger(String value, CharSequence separator) {
int[] integers = StrUtil.splitToInt(value, separator);
return Arrays.stream(integers).boxed().collect(Collectors.toList());
}
}

@ -1,10 +1,12 @@
package cn.iocoder.yudao.framework.common.util.validation;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import org.springframework.util.StringUtils;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
import java.util.regex.Pattern;
@ -37,6 +39,12 @@ public class ValidationUtils {
&& PATTERN_XML_NCNAME.matcher(str).matches();
}
public static void validate(Object object, Class<?>... groups) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Assert.notNull(validator);
validate(validator, object, groups);
}
public static void validate(Validator validator, Object object, Class<?>... groups) {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (CollUtil.isNotEmpty(constraintViolations)) {

@ -48,6 +48,10 @@ public class BannerApplicationRunner implements ApplicationRunner {
if (isNotPresent("cn.iocoder.yudao.module.trade.framework.web.config.TradeWebConfiguration")) {
System.out.println("[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
}
// 支付
if (isNotPresent("cn.iocoder.yudao.module.pay.framework.pay.config.PayConfiguration")) {
System.out.println("[支付系统 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]");
}
});
}

@ -57,6 +57,11 @@ public class DictFrameworkUtils {
log.info("[init][初始化 DictFrameworkUtils 成功]");
}
@SneakyThrows
public static String getDictDataLabel(String dictType, Integer value) {
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, String.valueOf(value))).getLabel();
}
@SneakyThrows
public static String getDictDataLabel(String dictType, String value) {
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();

@ -37,7 +37,7 @@
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>

@ -1,35 +0,0 @@
package cn.iocoder.yudao.framework.pay.config;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
@ConfigurationProperties(prefix = "yudao.pay")
@Validated
@Data
public class PayProperties {
/**
*
*
* PayNotifyController notifyCallback URL
*
* payNotifyUrl PayAppDO.payNotifyUrl
*/
@NotEmpty(message = "回调地址不能为空")
@URL(message = "回调地址的格式必须是 URL")
private String callbackUrl;
/**
*
*
* PayNotifyController returnCallback URL
*/
@URL(message = "回跳地址的格式必须是 URL")
@NotEmpty(message = "回跳地址不能为空")
private String returnUrl;
}

@ -12,7 +12,6 @@ import org.springframework.context.annotation.Bean;
* @author
*/
@AutoConfiguration
@EnableConfigurationProperties(PayProperties.class)
public class YudaoPayAutoConfiguration {
@Bean

@ -1,12 +1,11 @@
package cn.iocoder.yudao.framework.pay.core.client;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import java.util.Map;
/**
* SDK退
@ -22,31 +21,59 @@ public interface PayClient {
*/
Long getId();
// ============ 支付相关 ==========
/**
*
*
* @param reqDTO
* @return
* @return
*/
PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
/**
* order
*
* @param params HTTP content type application/x-www-form-urlencoded
* @param body HTTP request body
* @return
*/
PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body);
/**
*
*
* @param outTradeNo
* @return
*/
PayOrderUnifiedRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
PayOrderRespDTO getOrder(String outTradeNo);
// ============ 退款相关 ==========
/**
* 退
*
* @param reqDTO 退
* @return
* @return 退
*/
PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
/**
* refund
*
* @param params HTTP content type application/x-www-form-urlencoded
* @param body HTTP request body
* @return
*/
PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body);
/**
*
* 退
*
* @param rawNotify
* @return
* 1. {@link PayRefundNotifyRespDTO} 退
* 2. {@link PayOrderNotifyRespDTO}
* @param outTradeNo
* @param outRefundNo 退
* @return 退
*/
default Object parseNotify(PayNotifyReqDTO rawNotify) {
throw new UnsupportedOperationException("未实现 parseNotify 方法!");
}
PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo);
}

@ -1,5 +1,6 @@
package cn.iocoder.yudao.framework.pay.core.client;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import javax.validation.ConstraintViolation;
@ -19,24 +20,11 @@ import java.util.Set;
// 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
public interface PayClientConfig {
/**
*
*
* @param validator
* @return
*/
Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator);
// TODO @aquan貌似抽象一个 validation group 就好了!
/**
*
*
* @param validator
*/
default void validate(Validator validator) {
Set<ConstraintViolation<PayClientConfig>> violations = verifyParam(validator);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
void validate(Validator validator);
}

@ -1,29 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.notify;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import java.util.Map;
/**
* 退
*/
@Data
@ToString
@Builder
public class PayNotifyReqDTO {
/**
* HTTP request body
*/
private String body;
/**
* HTTP content type application/x-www-form-urlencoded
*/
private Map<String,String> params;
}

@ -1,48 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.notify;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* Response DTO
*
* @author
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PayOrderNotifyRespDTO {
/**
*
*/
private String orderExtensionNo;
/**
*
*/
private String channelOrderNo;
/**
*
*/
private String channelUserId;
/**
*
*/
private LocalDateTime successTime;
/**
* TODO @jason ,
*
* alipay
* TRADE_CLOSED,退
* TRADE_SUCCESS,
* TRADE_FINISHED 退
*/
private String tradeStatus;
}

@ -1,58 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.notify;
import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import java.time.LocalDateTime;
/**
* 退Notify DTO
*
* @author jason
*/
@Data
@ToString
@Builder
public class PayRefundNotifyRespDTO {
/**
*
*/
private String channelOrderNo;
/**
*
* 使
* 1. https://api.mch.weixin.qq.com/pay/unifiedorder 时,使用该字段作为 out_trade_no
* 2. https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no
* pay_extension no
* P202110132239124200055
*/
private String tradeNo;
/**
* https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no
* https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_request_no
* 退
* 退退
* 退退
* 退退退
* 退
*
* RR202109181134287570000
*/
private String reqNo;
/**
* 退
*/
private PayNotifyRefundStatusEnum status;
/**
* 退
*/
private LocalDateTime refundSuccessTime;
}

@ -0,0 +1,141 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.order;
import cn.iocoder.yudao.framework.pay.core.client.exception.PayException;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Response DTO
*
* @author
*/
@Data
public class PayOrderRespDTO {
/**
*
*
* {@link PayOrderStatusRespEnum}
*/
private Integer status;
/**
*
*
* PayOrderExtensionDO no
*/
private String outTradeNo;
/**
*
*/
private String channelOrderNo;
/**
*
*/
private String channelUserId;
/**
*
*/
private LocalDateTime successTime;
/**
* /
*/
private Object rawData;
// ========== 主动发起支付时,会返回的字段 ==========
/**
*
*
* {@link PayOrderDisplayModeEnum}
*/
private String displayMode;
/**
*
*/
private String displayContent;
/**
*
*
*
* {@link PayException}
*/
private String channelErrorCode;
/**
*
*/
private String channelErrorMsg;
public PayOrderRespDTO() {
}
/**
* WAITING
*/
public static PayOrderRespDTO waitingOf(String displayMode, String displayContent,
String outTradeNo, Object rawData) {
PayOrderRespDTO respDTO = new PayOrderRespDTO();
respDTO.status = PayOrderStatusRespEnum.WAITING.getStatus();
respDTO.displayMode = displayMode;
respDTO.displayContent = displayContent;
// 相对通用的字段
respDTO.outTradeNo = outTradeNo;
respDTO.rawData = rawData;
return respDTO;
}
/**
* SUCCESS
*/
public static PayOrderRespDTO successOf(String channelOrderNo, String channelUserId, LocalDateTime successTime,
String outTradeNo, Object rawData) {
PayOrderRespDTO respDTO = new PayOrderRespDTO();
respDTO.status = PayOrderStatusRespEnum.SUCCESS.getStatus();
respDTO.channelOrderNo = channelOrderNo;
respDTO.channelUserId = channelUserId;
respDTO.successTime = successTime;
// 相对通用的字段
respDTO.outTradeNo = outTradeNo;
respDTO.rawData = rawData;
return respDTO;
}
/**
*
*/
public static PayOrderRespDTO of(Integer status, String channelOrderNo, String channelUserId, LocalDateTime successTime,
String outTradeNo, Object rawData) {
PayOrderRespDTO respDTO = new PayOrderRespDTO();
respDTO.status = status;
respDTO.channelOrderNo = channelOrderNo;
respDTO.channelUserId = channelUserId;
respDTO.successTime = successTime;
// 相对通用的字段
respDTO.outTradeNo = outTradeNo;
respDTO.rawData = rawData;
return respDTO;
}
/**
* CLOSED
*/
public static PayOrderRespDTO closedOf(String channelErrorCode, String channelErrorMsg,
String outTradeNo, Object rawData) {
PayOrderRespDTO respDTO = new PayOrderRespDTO();
respDTO.status = PayOrderStatusRespEnum.CLOSED.getStatus();
respDTO.channelErrorCode = channelErrorCode;
respDTO.channelErrorMsg = channelErrorMsg;
// 相对通用的字段
respDTO.outTradeNo = outTradeNo;
respDTO.rawData = rawData;
return respDTO;
}
}

@ -1,6 +1,6 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.order;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.URL;
@ -8,7 +8,6 @@ import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.awt.*;
import java.time.LocalDateTime;
import java.util.Map;
@ -29,10 +28,12 @@ public class PayOrderUnifiedReqDTO {
// ========== 商户相关字段 ==========
/**
*
*
*
* PayOrderExtensionDO no
*/
@NotEmpty(message = "商户订单编号不能为空")
private String merchantOrderId;
@NotEmpty(message = "外部订单编号不能为空")
private String outTradeNo;
/**
*
*/
@ -42,7 +43,6 @@ public class PayOrderUnifiedReqDTO {
/**
*
*/
@NotEmpty(message = "商品描述信息不能为空")
@Length(max = 128, message = "商品描述信息长度不能超过128")
private String body;
/**
@ -64,7 +64,7 @@ public class PayOrderUnifiedReqDTO {
*/
@NotNull(message = "支付金额不能为空")
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
private Integer amount;
private Integer price;
/**
*
@ -85,7 +85,7 @@ public class PayOrderUnifiedReqDTO {
*
* 使
*
* {@link PayDisplayModeEnum}
* {@link PayOrderDisplayModeEnum}
*/
private String displayMode;

@ -1,23 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.order;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* Response DTO
*
* @author
*/
@Data
public class PayOrderUnifiedRespDTO {
/**
*
*/
private String displayMode;
/**
*
*/
private String displayContent;
}

@ -0,0 +1,115 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.refund;
import cn.iocoder.yudao.framework.pay.core.client.exception.PayException;
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 退 Response DTO
*
* @author jason
*/
@Data
public class PayRefundRespDTO {
/**
* 退
*
* {@link PayRefundStatusRespEnum}
*/
private Integer status;
/**
* 退
*
* PayRefundDO no
*/
private String outRefundNo;
/**
* 退
*
* PayRefundDO.channelRefundNo
*/
private String channelRefundNo;
/**
* 退
*/
private LocalDateTime successTime;
/**
*
*/
private Object rawData;
/**
*
*
*
* {@link PayException}
*/
private String channelErrorCode;
/**
*
*/
private String channelErrorMsg;
private PayRefundRespDTO() {
}
/**
* WAITING退
*/
public static PayRefundRespDTO waitingOf(String channelRefundNo,
String outRefundNo, Object rawData) {
PayRefundRespDTO respDTO = new PayRefundRespDTO();
respDTO.status = PayRefundStatusRespEnum.WAITING.getStatus();
respDTO.channelRefundNo = channelRefundNo;
// 相对通用的字段
respDTO.outRefundNo = outRefundNo;
respDTO.rawData = rawData;
return respDTO;
}
/**
* SUCCESS退
*/
public static PayRefundRespDTO successOf(String channelRefundNo, LocalDateTime successTime,
String outRefundNo, Object rawData) {
PayRefundRespDTO respDTO = new PayRefundRespDTO();
respDTO.status = PayRefundStatusRespEnum.SUCCESS.getStatus();
respDTO.channelRefundNo = channelRefundNo;
respDTO.successTime = successTime;
// 相对通用的字段
respDTO.outRefundNo = outRefundNo;
respDTO.rawData = rawData;
return respDTO;
}
/**
* FAILURE退
*/
public static PayRefundRespDTO failureOf(String outRefundNo, Object rawData) {
return failureOf(null, null,
outRefundNo, rawData);
}
/**
* FAILURE退
*/
public static PayRefundRespDTO failureOf(String channelErrorCode, String channelErrorMsg,
String outRefundNo, Object rawData) {
PayRefundRespDTO respDTO = new PayRefundRespDTO();
respDTO.status = PayRefundStatusRespEnum.FAILURE.getStatus();
respDTO.channelErrorCode = channelErrorCode;
respDTO.channelErrorMsg = channelErrorMsg;
// 相对通用的字段
respDTO.outRefundNo = outRefundNo;
respDTO.rawData = rawData;
return respDTO;
}
}

@ -24,33 +24,20 @@ import javax.validation.constraints.NotNull;
public class PayRefundUnifiedReqDTO {
/**
* IP
*
*
* PayOrderExtensionDO no
*/
private String userIp;
@NotEmpty(message = "外部订单编号不能为空")
private String outTradeNo;
// TODO @jason这个是否为非必传字段呀只需要传递 payTradeNo 字段即可。尽可能精简
/**
* https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 transaction_id
* https://opendocs.alipay.com/apis alipay.trade.refund 中的 trade_no
*
* 退
*
* PayRefundDO no
*/
private String channelOrderNo;
/**
* https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_trade_no
* https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no
* {PayOrderExtensionDO no}
*/
private String payTradeNo;
/**
* https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no
* https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no
* 退 退退
* 使 退{PayRefundDO merchantRefundNo}
*/
@NotEmpty(message = "退款请求单号")
private String merchantRefundId;
@NotEmpty(message = "退款请求单号不能为空")
private String outRefundNo;
/**
* 退
@ -58,16 +45,25 @@ public class PayRefundUnifiedReqDTO {
@NotEmpty(message = "退款原因不能为空")
private String reason;
/**
*
*
* 退
*/
@NotNull(message = "支付金额不能为空")
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
private Integer payPrice;
/**
* 退
*/
@NotNull(message = "退款金额不能为空")
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
private Integer amount;
private Integer refundPrice;
/**
* 退 notify 退
* 退 notify
*/
@NotEmpty(message = "支付结果的回调地址不能为空")
@URL(message = "支付结果的 notify 回调地址必须是 URL 格式")
private String notifyUrl;

@ -1,25 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.dto.refund;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRefundRespEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 退 Response DTO
*
* @author jason
*/
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class PayRefundUnifiedRespDTO {
/**
* 退
*/
private String channelRefundId;
}

@ -0,0 +1,17 @@
package cn.iocoder.yudao.framework.pay.core.client.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* Exception
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PayException extends RuntimeException {
public PayException(Throwable cause) {
super(cause);
}
}

@ -1,23 +1,19 @@
package cn.iocoder.yudao.framework.pay.core.client.impl;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import com.alipay.api.AlipayResponse;import lombok.extern.slf4j.Slf4j;
import cn.iocoder.yudao.framework.pay.core.client.exception.PayException;
import lombok.extern.slf4j.Slf4j;
import javax.validation.Validation;
import java.time.LocalDateTime;
import java.util.Map;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MS_FORMATTER;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
import static cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants.PAY_EXCEPTION;
/**
*
@ -34,6 +30,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
/**
*
*/
@SuppressWarnings("FieldCanBeLocal")
private final String channelCode;
/**
*
@ -51,7 +48,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
*/
public final void init() {
doInit();
log.info("[init][配置({}) 初始化完成]", config);
log.info("[init][客户端({}) 初始化完成]", getId());
}
/**
@ -64,7 +61,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
if (config.equals(this.config)) {
return;
}
log.info("[refresh][配置({})发生变化,重新初始化]", config);
log.info("[refresh][客户端({})发生变化,重新初始化]", getId());
this.config = config;
// 初始化
this.init();
@ -75,67 +72,122 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
return channelId;
}
// ============ 支付相关 ==========
@Override
public final PayOrderUnifiedRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
Validation.buildDefaultValidatorFactory().getValidator().validate(reqDTO);
// 执行短信发送
PayOrderUnifiedRespDTO result;
public final PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
ValidationUtils.validate(reqDTO);
// 执行统一下单
PayOrderRespDTO resp;
try {
result = doUnifiedOrder(reqDTO);
resp = doUnifiedOrder(reqDTO);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
// 打印异常日志
log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), ex);
throw buildException(ex);
// 系统异常,则包装成 PayException 异常抛出
log.error("[unifiedOrder][客户端({}) request({}) 发起支付异常]",
getId(), toJsonString(reqDTO), ex);
throw buildPayException(ex);
}
return result;
return resp;
}
protected abstract PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO)
protected abstract PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO)
throws Throwable;
@Override
public PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
PayRefundUnifiedRespDTO resp;
public final PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body) {
try {
resp = doUnifiedRefund(reqDTO);
} catch (Throwable ex) {
// 记录异常日志
log.error("[unifiedRefund][request({}) 发起退款失败]", toJsonString(reqDTO), ex);
throw buildException(ex);
return doParseOrderNotify(params, body);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
log.error("[parseOrderNotify][客户端({}) params({}) body({}) 解析失败]",
getId(), params, body, ex);
throw buildPayException(ex);
}
return resp;
}
protected abstract PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
// ========== 各种工具方法 ==========
protected abstract PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body)
throws Throwable;
private RuntimeException buildException(Throwable ex) {
if (ex instanceof RuntimeException) {
return (RuntimeException) ex;
@Override
public final PayOrderRespDTO getOrder(String outTradeNo) {
try {
return doGetOrder(outTradeNo);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
log.error("[getOrder][客户端({}) outTradeNo({}) 查询支付单异常]",
getId(), outTradeNo, ex);
throw buildPayException(ex);
}
throw new RuntimeException(ex);
}
protected void validateSuccess(AlipayResponse response) {
if (response.isSuccess()) {
return;
protected abstract PayOrderRespDTO doGetOrder(String outTradeNo)
throws Throwable;
// ============ 退款相关 ==========
@Override
public final PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
ValidationUtils.validate(reqDTO);
// 执行统一退款
PayRefundRespDTO resp;
try {
resp = doUnifiedRefund(reqDTO);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
// 系统异常,则包装成 PayException 异常抛出
log.error("[unifiedRefund][客户端({}) request({}) 发起退款异常]",
getId(), toJsonString(reqDTO), ex);
throw buildPayException(ex);
}
throw exception0(PAY_EXCEPTION.getCode(), response.getSubMsg());
return resp;
}
protected String formatAmount(Integer amount) {
return String.valueOf(amount / 100.0);
protected abstract PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
@Override
public final PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body) {
try {
return doParseRefundNotify(params, body);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
log.error("[parseRefundNotify][客户端({}) params({}) body({}) 解析失败]",
getId(), params, body, ex);
throw buildPayException(ex);
}
}
protected String formatTime(LocalDateTime time) {
// "yyyy-MM-dd HH:mm:ss"
return LocalDateTimeUtil.format(time, NORM_DATETIME_FORMATTER);
protected abstract PayRefundRespDTO doParseRefundNotify(Map<String, String> params, String body)
throws Throwable;
@Override
public final PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo) {
try {
return doGetRefund(outTradeNo, outRefundNo);
} catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可
throw ex;
} catch (Throwable ex) {
log.error("[getRefund][客户端({}) outTradeNo({}) outRefundNo({}) 查询退款单异常]",
getId(), outTradeNo, outRefundNo, ex);
throw buildPayException(ex);
}
}
protected LocalDateTime parseTime(String str) {
// "yyyy-MM-dd HH:mm:ss"
return LocalDateTimeUtil.parse(str, NORM_DATETIME_FORMATTER);
protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo)
throws Throwable;
// ========== 各种工具方法 ==========
private PayException buildPayException(Throwable ex) {
if (ex instanceof PayException) {
return (PayException) ex;
}
throw new PayException(ex);
}
}

@ -5,11 +5,8 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXLitePayClient;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXNativePayClient;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPubPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ConcurrentHashMap;
@ -58,12 +55,14 @@ public class PayClientFactoryImpl implements PayClientFactory {
PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode);
Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelEnum));
// 创建客户端
// TODO @芋艿 WX_LITE WX_APP 如果不添加在 项目启动的时候去初始化会报错无法启动。所以我手动加了两个,具体需要你来配
switch (channelEnum) {
case WX_PUB: return (AbstractPayClient<Config>) new WXPubPayClient(channelId, (WXPayClientConfig) config);
case WX_LITE: return (AbstractPayClient<Config>) new WXLitePayClient(channelId, (WXPayClientConfig) config); //微信小程序请求支付
case WX_APP: return (AbstractPayClient<Config>) new WXPubPayClient(channelId, (WXPayClientConfig) config);
case WX_NATIVE: return (AbstractPayClient<Config>) new WXNativePayClient(channelId, (WXPayClientConfig) config);
// 微信支付
case WX_PUB: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config);
case WX_LITE: return (AbstractPayClient<Config>) new WxLitePayClient(channelId, (WxPayClientConfig) config);
case WX_APP: return (AbstractPayClient<Config>) new WxAppPayClient(channelId, (WxPayClientConfig) config);
case WX_BAR: return (AbstractPayClient<Config>) new WxBarPayClient(channelId, (WxPayClientConfig) config);
case WX_NATIVE: return (AbstractPayClient<Config>) new WxNativePayClient(channelId, (WxPayClientConfig) config);
// 支付宝支付
case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayAppPayClient(channelId, (AlipayPayClientConfig) config);

@ -1,115 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
/**
* 退
*
* @author jason
*/
@Slf4j
public abstract class AbstractAlipayClient extends AbstractPayClient<AlipayPayClientConfig> {
protected DefaultAlipayClient client;
public AbstractAlipayClient(Long channelId, String channelCode, AlipayPayClientConfig config) {
super(channelId, channelCode, config);
}
@Override
@SneakyThrows
protected void doInit() {
AlipayConfig alipayConfig = new AlipayConfig();
BeanUtil.copyProperties(config, alipayConfig, false);
this.client = new DefaultAlipayClient(alipayConfig);
}
/**
* 退 alipay.trade.refund
* @param reqDTO 退 request DTO
* @return 退 Response
*/
@Override
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
AlipayTradeRefundModel model=new AlipayTradeRefundModel();
model.setTradeNo(reqDTO.getChannelOrderNo());
model.setOutTradeNo(reqDTO.getPayTradeNo());
model.setOutRequestNo(reqDTO.getMerchantRefundId());
model.setRefundAmount(formatAmount(reqDTO.getAmount()).toString());
model.setRefundReason(reqDTO.getReason());
AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
refundRequest.setBizModel(model);
refundRequest.setNotifyUrl(reqDTO.getNotifyUrl());
refundRequest.setReturnUrl(reqDTO.getNotifyUrl());
try {
AlipayTradeRefundResponse response = client.execute(refundRequest);
log.info("[doUnifiedRefund][response({}) 发起退款 渠道返回", toJsonString(response));
if (response.isSuccess()) {
//退款导致触发的异步通知是发送到支付接口中设置的notify_url
//支付宝不返回退款单号,设置为空
PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO();
respDTO.setChannelRefundId("");
// return PayCommonResult.build(response.getCode(), response.getMsg(), respDTO, codeMapping); TODO
return null;
}
// 失败。需要抛出异常
// return PayCommonResult.build(response.getCode(), response.getMsg(), null, codeMapping); TODO
return null;
} catch (AlipayApiException e) {
// TODO 记录异常日志
log.error("[doUnifiedRefund][request({}) 发起退款失败,网络读超时,退款状态未知]", toJsonString(reqDTO), e);
// return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); TODO
return null;
}
}
@Override
@SneakyThrows
public Object parseNotify(PayNotifyReqDTO rawNotify) {
// 1. 校验回调数据
String body = rawNotify.getBody();
Map<String, String> params = rawNotify.getParams();
Map<String, String> bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
AlipaySignature.rsaCheckV1(bodyObj, config.getAlipayPublicKey(),
StandardCharsets.UTF_8.name(), "RSA2");
// 2.1 退款的情况
if (bodyObj.containsKey("refund_fee")) {
return PayRefundNotifyRespDTO.builder().channelOrderNo(bodyObj.get("trade_no"))
.tradeNo(bodyObj.get("out_trade_no")).reqNo(bodyObj.get("out_biz_no"))
.status(PayNotifyRefundStatusEnum.SUCCESS)
.refundSuccessTime(parseTime(params.get("gmt_refund")))
.build();
}
// 2.2 支付的情况
return PayOrderNotifyRespDTO.builder().orderExtensionNo(bodyObj.get("out_trade_no"))
.channelOrderNo(bodyObj.get("trade_no")).channelUserId(bodyObj.get("seller_id"))
.tradeStatus(bodyObj.get("trade_status")).successTime(parseTime(params.get("notify_time")))
.build();
}
}

@ -0,0 +1,213 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.AlipayResponse;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
/**
* 退
*
* @author jason
*/
@Slf4j
public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPayClientConfig> {
protected DefaultAlipayClient client;
public AbstractAlipayPayClient(Long channelId, String channelCode, AlipayPayClientConfig config) {
super(channelId, channelCode, config);
}
@Override
@SneakyThrows
protected void doInit() {
AlipayConfig alipayConfig = new AlipayConfig();
BeanUtil.copyProperties(config, alipayConfig, false);
this.client = new DefaultAlipayClient(alipayConfig);
}
// ============ 支付相关 ==========
/**
* {@link PayOrderRespDTO}
*
* @return {@link PayOrderRespDTO}
*/
protected PayOrderRespDTO buildClosedPayOrderRespDTO(PayOrderUnifiedReqDTO reqDTO, AlipayResponse response) {
Assert.isFalse(response.isSuccess());
return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
reqDTO.getOutTradeNo(), response);
}
@Override
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws Throwable {
// 1. 校验回调数据
Map<String, String> bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
AlipaySignature.rsaCheckV1(bodyObj, config.getAlipayPublicKey(),
StandardCharsets.UTF_8.name(), config.getSignType());
// 2. 解析订单的状态
// 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂
Integer status = parseStatus(bodyObj.get("trade_status"));
// 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功
if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) {
status = PayOrderStatusRespEnum.REFUND.getStatus();
}
Assert.notNull(status, (Supplier<Throwable>) () -> {
throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", body));
});
return PayOrderRespDTO.of(status, bodyObj.get("trade_no"), bodyObj.get("seller_id"), parseTime(params.get("gmt_payment")),
bodyObj.get("out_trade_no"), body);
}
@Override
protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable {
// 1.1 构建 AlipayTradeRefundModel 请求
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo(outTradeNo);
// 1.2 构建 AlipayTradeQueryRequest 请求
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizModel(model);
// 2.1 执行请求
AlipayTradeQueryResponse response = client.execute(request);
if (!response.isSuccess()) { // 不成功,例如说订单不存在
return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
outTradeNo, response);
}
// 2.2 解析订单的状态
Integer status = parseStatus(response.getTradeStatus());
Assert.notNull(status, (Supplier<Throwable>) () -> {
throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody()));
});
return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()),
outTradeNo, response);
}
private static Integer parseStatus(String tradeStatus) {
return Objects.equals("WAIT_BUYER_PAY", tradeStatus) ? PayOrderStatusRespEnum.WAITING.getStatus()
: ObjectUtils.equalsAny(tradeStatus, "TRADE_FINISHED", "TRADE_SUCCESS") ? PayOrderStatusRespEnum.SUCCESS.getStatus()
: Objects.equals("TRADE_CLOSED", tradeStatus) ? PayOrderStatusRespEnum.CLOSED.getStatus() : null;
}
// ============ 退款相关 ==========
/**
* 退 alipay.trade.refund
*
* @param reqDTO 退 request DTO
* @return 退 Response
*/
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws AlipayApiException {
// 1.1 构建 AlipayTradeRefundModel 请求
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setOutRequestNo(reqDTO.getOutRefundNo());
model.setRefundAmount(formatAmount(reqDTO.getRefundPrice()));
model.setRefundReason(reqDTO.getReason());
// 1.2 构建 AlipayTradePayRequest 请求
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.setBizModel(model);
// 2.1 执行请求
AlipayTradeRefundResponse response = client.execute(request);
if (!response.isSuccess()) {
return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
}
// 2.2 创建返回结果
// 支付宝只要退款调用返回 success就认为退款成功不需要回调。具体可见 parseNotify 方法的说明。
// 另外,支付宝没有退款单号,所以不用设置
return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()),
reqDTO.getOutRefundNo(), response);
}
@Override
public PayRefundRespDTO doParseRefundNotify(Map<String, String> params, String body) {
// 补充说明:支付宝退款时,没有回调,这点和微信支付是不同的。并且,退款分成部分退款、和全部退款。
// ① 部分退款:是会有回调,但是它回调的是订单状态的同步回调,不是退款订单的回调
// ② 全部退款Wap 支付有订单状态的同步回调,但是 PC/扫码又没有
// 所以,这里在解析时,即使是退款导致的订单状态同步,我们也忽略不做为“退款同步”,而是订单的回调。
// 实际上,支付宝退款只要发起成功,就可以认为退款成功,不需要等待回调。
throw new UnsupportedOperationException("支付宝无退款回调");
}
@Override
protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws AlipayApiException {
// 1.1 构建 AlipayTradeFastpayRefundQueryModel 请求
AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
model.setOutTradeNo(outTradeNo);
model.setOutRequestNo(outRefundNo);
model.setQueryOptions(Collections.singletonList("gmt_refund_pay"));
// 1.2 构建 AlipayTradeFastpayRefundQueryRequest 请求
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
request.setBizModel(model);
// 2.1 执行请求
AlipayTradeFastpayRefundQueryResponse response = client.execute(request);
if (!response.isSuccess()) {
// 明确不存在的情况,应该就是失败,可进行关闭
if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
return PayRefundRespDTO.failureOf(outRefundNo, response);
}
// 可能存在“ACQ.SYSTEM_ERROR”系统错误等情况所以返回 WAIT 继续等待
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
}
// 2.2 创建返回结果
if (Objects.equals(response.getRefundStatus(), "REFUND_SUCCESS")) {
return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()),
outRefundNo, response);
}
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
}
// ========== 各种工具方法 ==========
protected String formatAmount(Integer amount) {
return String.valueOf(amount / 100.0);
}
protected String formatTime(LocalDateTime time) {
return LocalDateTimeUtil.format(time, NORM_DATETIME_FORMATTER);
}
protected LocalDateTime parseTime(String str) {
return LocalDateTimeUtil.parse(str, NORM_DATETIME_FORMATTER);
}
}

@ -1,9 +1,9 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
@ -20,25 +20,26 @@ import lombok.extern.slf4j.Slf4j;
* @author
*/
@Slf4j
public class AlipayAppPayClient extends AbstractAlipayClient {
public class AlipayAppPayClient extends AbstractAlipayPayClient {
public AlipayAppPayClient(Long channelId, AlipayPayClientConfig config) {
super(channelId, PayChannelEnum.ALIPAY_APP.getCode(), config);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
// 1.1 构建 AlipayTradeAppPayModel 请求
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// ① 通用的参数
model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody());
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
model.setProductCode(" QUICK_MSECURITY_PAY"); // 销售产品码:无线快捷支付产品
model.setBody(reqDTO.getBody() + "test");
model.setTotalAmount(formatAmount(reqDTO.getPrice()));
model.setTimeExpire(formatTime(reqDTO.getExpireTime()));
model.setProductCode("QUICK_MSECURITY_PAY"); // 销售产品码:无线快捷支付产品
// ② 个性化的参数【无】
// ③ 支付宝扫码支付只有一种展示
String displayMode = PayDisplayModeEnum.APP.getMode();
String displayMode = PayOrderDisplayModeEnum.APP.getMode();
// 1.2 构建 AlipayTradePrecreateRequest 请求
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
@ -47,11 +48,13 @@ public class AlipayAppPayClient extends AbstractAlipayClient {
request.setReturnUrl(reqDTO.getReturnUrl());
// 2.1 执行请求
AlipayTradeAppPayResponse response = client.execute(request);
AlipayTradeAppPayResponse response = client.sdkExecute(request);
// 2.2 处理结果
validateSuccess(response);
return new PayOrderUnifiedRespDTO()
.setDisplayMode(displayMode).setDisplayContent("");
if (!response.isSuccess()) {
return buildClosedPayOrderRespDTO(reqDTO, response);
}
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
reqDTO.getOutTradeNo(), response);
}
}

@ -1,11 +1,12 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.request.AlipayTradePayRequest;
@ -13,7 +14,6 @@ import com.alipay.api.response.AlipayTradePayResponse;
import lombok.extern.slf4j.Slf4j;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
/**
@ -24,14 +24,14 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
* @author
*/
@Slf4j
public class AlipayBarPayClient extends AbstractAlipayClient {
public class AlipayBarPayClient extends AbstractAlipayPayClient {
public AlipayBarPayClient(Long channelId, AlipayPayClientConfig config) {
super(channelId, PayChannelEnum.ALIPAY_BAR.getCode(), config);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "auth_code");
if (StrUtil.isEmpty(authCode)) {
throw exception0(BAD_REQUEST.getCode(), "条形码不能为空");
@ -40,15 +40,15 @@ public class AlipayBarPayClient extends AbstractAlipayClient {
// 1.1 构建 AlipayTradePayModel 请求
AlipayTradePayModel model = new AlipayTradePayModel();
// ① 通用的参数
model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody());
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
model.setTotalAmount(formatAmount(reqDTO.getPrice()));
model.setScene("bar_code"); // 当面付条码支付场景
// ② 个性化的参数
model.setAuthCode(authCode);
// ③ 支付宝条码支付只有一种展示
String displayMode = PayDisplayModeEnum.BAR_CODE.getMode();
String displayMode = PayOrderDisplayModeEnum.BAR_CODE.getMode();
// 1.2 构建 AlipayTradePayRequest 请求
AlipayTradePayRequest request = new AlipayTradePayRequest();
@ -59,8 +59,16 @@ public class AlipayBarPayClient extends AbstractAlipayClient {
// 2.1 执行请求
AlipayTradePayResponse response = client.execute(request);
// 2.2 处理结果
validateSuccess(response);
return new PayOrderUnifiedRespDTO()
.setDisplayMode(displayMode).setDisplayContent("");
if (!response.isSuccess()) {
return buildClosedPayOrderRespDTO(reqDTO, response);
}
if ("10000".equals(response.getCode())) { // 免密支付
return PayOrderRespDTO.successOf(response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getGmtPayment()),
response.getOutTradeNo(), response);
}
// 大额支付,需要用户输入密码,所以返回 waiting。此时前端一般会进行轮询
return PayOrderRespDTO.waitingOf(displayMode, "",
reqDTO.getOutTradeNo(), response);
}
}

@ -1,5 +1,6 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import lombok.Data;
@ -9,8 +10,6 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Set;
// TODO 芋艿:参数校验
/**
* PayClientConfig
* {@link com.alipay.api.AlipayConfig}
@ -20,15 +19,6 @@ import java.util.Set;
@Data
public class AlipayPayClientConfig implements PayClientConfig {
/**
* - 线
*/
public static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do";
/**
* -
*/
public static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
/**
* -
*/
@ -45,8 +35,9 @@ public class AlipayPayClientConfig implements PayClientConfig {
/**
*
* 1. {@link #SERVER_URL_PROD}
* 2. {@link #SERVER_URL_SANDBOX}
*
* 1. <a href="https://openapi.alipay.com/gateway.do"></a>
* 2. <a href="https://openapi-sandbox.dl.alipaydev.com/gateway.do"></a>
*/
@NotBlank(message = "网关地址不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
private String serverUrl;
@ -110,8 +101,9 @@ public class AlipayPayClientConfig implements PayClientConfig {
}
@Override
public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
return validator.validate(this,
public void validate(Validator validator) {
ValidationUtils.validate(validator, this,
MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
}
}

@ -1,12 +1,11 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Method;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
@ -23,29 +22,29 @@ import java.util.Objects;
* @author XGD
*/
@Slf4j
public class AlipayPcPayClient extends AbstractAlipayClient {
public class AlipayPcPayClient extends AbstractAlipayPayClient {
public AlipayPcPayClient(Long channelId, AlipayPayClientConfig config) {
super(channelId, PayChannelEnum.ALIPAY_PC.getCode(), config);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
// 1.1 构建 AlipayTradePagePayModel 请求
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
// ① 通用的参数
model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody());
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
model.setTotalAmount(formatAmount(reqDTO.getPrice()));
model.setTimeExpire(formatTime(reqDTO.getExpireTime()));
model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前 PC 支付场景下仅支持 FAST_INSTANT_TRADE_PAY
// ② 个性化的参数
// 参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分
model.setQrPayMode(MapUtil.getStr(reqDTO.getChannelExtras(), "qr_pay_mode"));
model.setQrcodeWidth(MapUtil.getLong(reqDTO.getChannelExtras(), "qr_code_width"));
// ③ 支付宝 PC 支付有多种展示模式,因此这里需要计算
String displayMode = getDisplayMode(reqDTO.getDisplayMode(), model.getQrPayMode());
// 如果想弄更多个性化的参数,可参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分进行拓展
model.setQrPayMode("2"); // 跳转模式 - 订单码效果参见https://help.pingxx.com/article/1137360/
// ③ 支付宝 PC 支付有两种展示模式FORM、URL
String displayMode = ObjectUtil.defaultIfNull(reqDTO.getDisplayMode(),
PayOrderDisplayModeEnum.URL.getMode());
// 1.2 构建 AlipayTradePagePayRequest 请求
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
@ -55,37 +54,17 @@ public class AlipayPcPayClient extends AbstractAlipayClient {
// 2.1 执行请求
AlipayTradePagePayResponse response;
if (Objects.equals(displayMode, PayDisplayModeEnum.FORM.getMode())) {
if (Objects.equals(displayMode, PayOrderDisplayModeEnum.FORM.getMode())) {
response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求
} else {
response = client.pageExecute(request, Method.GET.name());
}
// 2.2 处理结果
validateSuccess(response);
return new PayOrderUnifiedRespDTO().setDisplayMode(displayMode)
.setDisplayContent(response.getBody());
}
/**
* UI
*
* @param displayMode UI
* @param qrPayMode
* @return UI
*/
private String getDisplayMode(String displayMode, String qrPayMode) {
// 1.1 支付宝二维码的前置模式
if (StrUtil.equalsAny(qrPayMode, "0", "1", "3", "4")) {
return PayDisplayModeEnum.IFRAME.getMode();
}
// 1.2 支付宝二维码的跳转模式
if (StrUtil.equals(qrPayMode, "2")) {
return PayDisplayModeEnum.URL.getMode();
if (!response.isSuccess()) {
return buildClosedPayOrderRespDTO(reqDTO, response);
}
// 2. 前端传递了 UI 展示模式
return displayMode != null ? displayMode :
PayDisplayModeEnum.URL.getMode(); // 模式使用 URL 跳转
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
reqDTO.getOutTradeNo(), response);
}
}

@ -1,9 +1,9 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
@ -18,25 +18,25 @@ import lombok.extern.slf4j.Slf4j;
* @author
*/
@Slf4j
public class AlipayQrPayClient extends AbstractAlipayClient {
public class AlipayQrPayClient extends AbstractAlipayPayClient {
public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) {
super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
// 1.1 构建 AlipayTradePrecreateModel 请求
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
// ① 通用的参数
model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody());
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
model.setTotalAmount(formatAmount(reqDTO.getPrice()));
model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 FACE_TO_FACE_PAYMENT
// ② 个性化的参数【无】
// ③ 支付宝扫码支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
String displayMode = PayDisplayModeEnum.QR_CODE.getMode();
String displayMode = PayOrderDisplayModeEnum.QR_CODE.getMode();
// 1.2 构建 AlipayTradePrecreateRequest 请求
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
@ -47,8 +47,11 @@ public class AlipayQrPayClient extends AbstractAlipayClient {
// 2.1 执行请求
AlipayTradePrecreateResponse response = client.execute(request);
// 2.2 处理结果
validateSuccess(response);
return new PayOrderUnifiedRespDTO()
.setDisplayMode(displayMode).setDisplayContent(response.getQrCode());
if (!response.isSuccess()) {
return buildClosedPayOrderRespDTO(reqDTO, response);
}
return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
reqDTO.getOutTradeNo(), response);
}
}

@ -1,11 +1,10 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Method;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
@ -20,26 +19,25 @@ import lombok.extern.slf4j.Slf4j;
* @author
*/
@Slf4j
public class AlipayWapPayClient extends AbstractAlipayClient {
public class AlipayWapPayClient extends AbstractAlipayPayClient {
public AlipayWapPayClient(Long channelId, AlipayPayClientConfig config) {
super(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
// 1.1 构建 AlipayTradeWapPayModel 请求
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
// ① 通用的参数
model.setOutTradeNo(reqDTO.getMerchantOrderId());
model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setSubject(reqDTO.getSubject());
model.setBody(reqDTO.getBody());
model.setTotalAmount(formatAmount(reqDTO.getAmount()));
model.setTotalAmount(formatAmount(reqDTO.getPrice()));
model.setProductCode("QUICK_WAP_PAY"); // 销售产品码. 目前 Wap 支付场景下仅支持 QUICK_WAP_PAY
// ② 个性化的参数【无】
// ③ 支付宝 Wap 支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开
String displayMode = ObjectUtil.defaultIfNull(reqDTO.getDisplayMode(),
PayDisplayModeEnum.URL.getMode());
// ③ 支付宝 Wap 支付只有一种展示URL
String displayMode = PayOrderDisplayModeEnum.URL.getMode();
// 1.2 构建 AlipayTradeWapPayRequest 请求
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
@ -50,11 +48,12 @@ public class AlipayWapPayClient extends AbstractAlipayClient {
// 2.1 执行请求
AlipayTradeWapPayResponse response = client.pageExecute(request, Method.GET.name());
// 2.2 处理结果
validateSuccess(response);
return new PayOrderUnifiedRespDTO()
.setDisplayMode(displayMode).setDisplayContent(response.getBody());
if (!response.isSuccess()) {
return buildClosedPayOrderRespDTO(reqDTO, response);
}
return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
reqDTO.getOutTradeNo(), response);
}
}

@ -0,0 +1,470 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.*;
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
import java.util.Objects;
import static cn.hutool.core.date.DatePattern.*;
import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V2;
/**
* 退
*
* @author
*/
@Slf4j
public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientConfig> {
protected WxPayService client;
public AbstractWxPayClient(Long channelId, String channelCode, WxPayClientConfig config) {
super(channelId, channelCode, config);
}
/**
* client
*
* @param tradeType
*/
protected void doInit(String tradeType) {
// 创建 config 配置
WxPayConfig payConfig = new WxPayConfig();
BeanUtil.copyProperties(config, payConfig, "keyContent");
payConfig.setTradeType(tradeType);
// weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决
if (Base64.isBase64(config.getKeyContent())) {
payConfig.setKeyPath(FileUtils.createTempFile(Base64.decode(config.getKeyContent())).getPath());
}
if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
}
if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
}
// 创建 client 客户端
client = new WxPayServiceImpl();
client.setConfig(payConfig);
}
// ============ 支付相关 ==========
@Override
protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Exception {
try {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doUnifiedOrderV2(reqDTO);
case WxPayClientConfig.API_VERSION_V3:
return doUnifiedOrderV3(reqDTO);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
} catch (WxPayException e) {
String errorCode = getErrorCode(e);
String errorMessage = getErrorMessage(e);
return PayOrderRespDTO.closedOf(errorCode, errorMessage,
reqDTO.getOutTradeNo(), e.getXmlString());
}
}
/**
* V2
*
* @param reqDTO
* @return
*/
protected abstract PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO)
throws Exception;
/**
* V3
*
* @param reqDTO
* @return
*/
protected abstract PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO)
throws WxPayException;
/**
* V2
*
* @param reqDTO
* @return
*/
protected WxPayUnifiedOrderRequest buildPayUnifiedOrderRequestV2(PayOrderUnifiedReqDTO reqDTO) {
return WxPayUnifiedOrderRequest.newBuilder()
.outTradeNo(reqDTO.getOutTradeNo())
.body(reqDTO.getSubject())
.detail(reqDTO.getBody())
.totalFee(reqDTO.getPrice()) // 单位分
.timeExpire(formatDateV2(reqDTO.getExpireTime()))
.spbillCreateIp(reqDTO.getUserIp())
.notifyUrl(reqDTO.getNotifyUrl())
.build();
}
/**
* V3
*
* @param reqDTO
* @return
*/
protected WxPayUnifiedOrderV3Request buildPayUnifiedOrderRequestV3(PayOrderUnifiedReqDTO reqDTO) {
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
request.setOutTradeNo(reqDTO.getOutTradeNo());
request.setDescription(reqDTO.getSubject());
request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分
request.setTimeExpire(formatDateV3(reqDTO.getExpireTime()));
request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
request.setNotifyUrl(reqDTO.getNotifyUrl());
return request;
}
@Override
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) throws WxPayException {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doParseOrderNotifyV2(body);
case WxPayClientConfig.API_VERSION_V3:
return doParseOrderNotifyV3(body);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
}
private PayOrderRespDTO doParseOrderNotifyV2(String body) throws WxPayException {
// 1. 解析回调
WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body);
// 2. 构建结果
// V2 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ?
PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus();
return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
response.getOutTradeNo(), body);
}
private PayOrderRespDTO doParseOrderNotifyV3(String body) throws WxPayException {
// 1. 解析回调
WxPayOrderNotifyV3Result response = client.parseOrderNotifyV3Result(body, null);
WxPayOrderNotifyV3Result.DecryptNotifyResult result = response.getResult();
// 2. 构建结果
Integer status = parseStatus(result.getTradeState());
String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null;
return PayOrderRespDTO.of(status, result.getTransactionId(), openid, parseDateV3(result.getSuccessTime()),
result.getOutTradeNo(), body);
}
@Override
protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable {
try {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doGetOrderV2(outTradeNo);
case WxPayClientConfig.API_VERSION_V3:
return doGetOrderV3(outTradeNo);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
} catch (WxPayException e) {
if (ObjectUtils.equalsAny(e.getErrCode(), "ORDERNOTEXIST", "ORDER_NOT_EXIST")) {
String errorCode = getErrorCode(e);
String errorMessage = getErrorMessage(e);
return PayOrderRespDTO.closedOf(errorCode, errorMessage,
outTradeNo, e.getXmlString());
}
throw e;
}
}
private PayOrderRespDTO doGetOrderV2(String outTradeNo) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayOrderQueryRequest request = WxPayOrderQueryRequest.newBuilder()
.outTradeNo(outTradeNo).build();
// 执行请求
WxPayOrderQueryResult response = client.queryOrder(request);
// 转换结果
Integer status = parseStatus(response.getTradeState());
return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
outTradeNo, response);
}
private PayOrderRespDTO doGetOrderV3(String outTradeNo) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request()
.setOutTradeNo(outTradeNo);
// 执行请求
WxPayOrderQueryV3Result response = client.queryOrderV3(request);
// 转换结果
Integer status = parseStatus(response.getTradeState());
String openid = response.getPayer() != null ? response.getPayer().getOpenid() : null;
return PayOrderRespDTO.of(status, response.getTransactionId(), openid, parseDateV3(response.getSuccessTime()),
outTradeNo, response);
}
private static Integer parseStatus(String tradeState) {
switch (tradeState) {
case "NOTPAY":
case "USERPAYING": // 支付中,等待用户输入密码(条码支付独有)
return PayOrderStatusRespEnum.WAITING.getStatus();
case "SUCCESS":
return PayOrderStatusRespEnum.SUCCESS.getStatus();
case "REFUND":
return PayOrderStatusRespEnum.REFUND.getStatus();
case "CLOSED":
case "REVOKED": // 已撤销(刷卡支付独有)
case "PAYERROR": // 支付失败(其它原因,如银行返回失败)
return PayOrderStatusRespEnum.CLOSED.getStatus();
default:
throw new IllegalArgumentException(StrUtil.format("未知的支付状态({})", tradeState));
}
}
// ============ 退款相关 ==========
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
try {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doUnifiedRefundV2(reqDTO);
case WxPayClientConfig.API_VERSION_V3:
return doUnifiedRefundV3(reqDTO);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
} catch (WxPayException e) {
String errorCode = getErrorCode(e);
String errorMessage = getErrorMessage(e);
return PayRefundRespDTO.failureOf(errorCode, errorMessage,
reqDTO.getOutTradeNo(), e.getXmlString());
}
}
private PayRefundRespDTO doUnifiedRefundV2(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
// 1. 构建 WxPayRefundRequest 请求
WxPayRefundRequest request = new WxPayRefundRequest()
.setOutTradeNo(reqDTO.getOutTradeNo())
.setOutRefundNo(reqDTO.getOutRefundNo())
.setRefundFee(reqDTO.getRefundPrice())
.setRefundDesc(reqDTO.getReason())
.setTotalFee(reqDTO.getPayPrice())
.setNotifyUrl(reqDTO.getNotifyUrl());
// 2.1 执行请求
WxPayRefundResult response = client.refundV2(request);
// 2.2 创建返回结果
if (Objects.equals("SUCCESS", response.getResultCode())) { // V2 情况下,不直接返回退款成功,而是等待异步通知
return PayRefundRespDTO.waitingOf(response.getRefundId(),
reqDTO.getOutRefundNo(), response);
}
return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
}
private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
// 1. 构建 WxPayRefundRequest 请求
WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo(reqDTO.getOutTradeNo())
.setOutRefundNo(reqDTO.getOutRefundNo())
.setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice())
.setTotal(reqDTO.getPayPrice()).setCurrency("CNY"))
.setReason(reqDTO.getReason())
.setNotifyUrl(reqDTO.getNotifyUrl());
// 2.1 执行请求
WxPayRefundV3Result response = client.refundV3(request);
// 2.2 创建返回结果
if (Objects.equals("SUCCESS", response.getStatus())) {
return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()),
reqDTO.getOutRefundNo(), response);
}
if (Objects.equals("PROCESSING", response.getStatus())) {
return PayRefundRespDTO.waitingOf(response.getRefundId(),
reqDTO.getOutRefundNo(), response);
}
return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
}
@Override
public PayRefundRespDTO doParseRefundNotify(Map<String, String> params, String body) throws WxPayException {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doParseRefundNotifyV2(body);
case WxPayClientConfig.API_VERSION_V3:
return parseRefundNotifyV3(body);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
}
private PayRefundRespDTO doParseRefundNotifyV2(String body) throws WxPayException {
// 1. 解析回调
WxPayRefundNotifyResult response = client.parseRefundNotifyResult(body);
WxPayRefundNotifyResult.ReqInfo result = response.getReqInfo();
// 2. 构建结果
if (Objects.equals("SUCCESS", result.getRefundStatus())) {
return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV2B(result.getSuccessTime()),
result.getOutRefundNo(), response);
}
return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response);
}
private PayRefundRespDTO parseRefundNotifyV3(String body) throws WxPayException {
// 1. 解析回调
WxPayRefundNotifyV3Result response = client.parseRefundNotifyV3Result(body, null);
WxPayRefundNotifyV3Result.DecryptNotifyResult result = response.getResult();
// 2. 构建结果
if (Objects.equals("SUCCESS", result.getRefundStatus())) {
return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV3(result.getSuccessTime()),
result.getOutRefundNo(), response);
}
return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response);
}
@Override
protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws WxPayException {
try {
switch (config.getApiVersion()) {
case API_VERSION_V2:
return doGetRefundV2(outTradeNo, outRefundNo);
case WxPayClientConfig.API_VERSION_V3:
return doGetRefundV3(outTradeNo, outRefundNo);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
} catch (WxPayException e) {
if (ObjectUtils.equalsAny(e.getErrCode(), "REFUNDNOTEXIST", "RESOURCE_NOT_EXISTS")) {
String errorCode = getErrorCode(e);
String errorMessage = getErrorMessage(e);
return PayRefundRespDTO.failureOf(errorCode, errorMessage,
outRefundNo, e.getXmlString());
}
throw e;
}
}
private PayRefundRespDTO doGetRefundV2(String outTradeNo, String outRefundNo) throws WxPayException {
// 1. 构建 WxPayRefundRequest 请求
WxPayRefundQueryRequest request = WxPayRefundQueryRequest.newBuilder()
.outTradeNo(outTradeNo)
.outRefundNo(outRefundNo)
.build();
// 2.1 执行请求
WxPayRefundQueryResult response = client.refundQuery(request);
// 2.2 创建返回结果
if (!Objects.equals("SUCCESS", response.getResultCode())) {
return PayRefundRespDTO.waitingOf(null,
outRefundNo, response);
}
WxPayRefundQueryResult.RefundRecord refund = CollUtil.findOne(response.getRefundRecords(),
record -> record.getOutRefundNo().equals(outRefundNo));
if (refund == null) {
return PayRefundRespDTO.failureOf(outRefundNo, response);
}
switch (refund.getRefundStatus()) {
case "SUCCESS":
return PayRefundRespDTO.successOf(refund.getRefundId(), parseDateV2B(refund.getRefundSuccessTime()),
outRefundNo, response);
case "PROCESSING":
return PayRefundRespDTO.waitingOf(refund.getRefundId(),
outRefundNo, response);
case "CHANGE": // 退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转账的方式进行退款
case "FAIL":
return PayRefundRespDTO.failureOf(outRefundNo, response);
default:
throw new IllegalArgumentException(String.format("未知的退款状态(%s)", refund.getRefundStatus()));
}
}
private PayRefundRespDTO doGetRefundV3(String outTradeNo, String outRefundNo) throws WxPayException {
// 1. 构建 WxPayRefundRequest 请求
WxPayRefundQueryV3Request request = new WxPayRefundQueryV3Request();
request.setOutRefundNo(outRefundNo);
// 2.1 执行请求
WxPayRefundQueryV3Result response = client.refundQueryV3(request);
// 2.2 创建返回结果
switch (response.getStatus()) {
case "SUCCESS":
return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()),
outRefundNo, response);
case "PROCESSING":
return PayRefundRespDTO.waitingOf(response.getRefundId(),
outRefundNo, response);
case "ABNORMAL": // 退款异常
case "CLOSED":
return PayRefundRespDTO.failureOf(outRefundNo, response);
default:
throw new IllegalArgumentException(String.format("未知的退款状态(%s)", response.getStatus()));
}
}
// ========== 各种工具方法 ==========
static String formatDateV2(LocalDateTime time) {
return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN);
}
static LocalDateTime parseDateV2(String time) {
return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN);
}
static LocalDateTime parseDateV2B(String time) {
return LocalDateTimeUtil.parse(time, NORM_DATETIME_PATTERN);
}
static String formatDateV3(LocalDateTime time) {
return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN);
}
static LocalDateTime parseDateV3(String time) {
return LocalDateTimeUtil.parse(time, UTC_WITH_XXX_OFFSET_PATTERN);
}
static String getErrorCode(WxPayException e) {
if (StrUtil.isNotEmpty(e.getErrCode())) {
return e.getErrCode();
}
if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) {
return "CUSTOM_ERROR";
}
return e.getReturnCode();
}
static String getErrorMessage(WxPayException e) {
if (StrUtil.isNotEmpty(e.getErrCode())) {
return e.getErrCodeDes();
}
if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) {
return e.getCustomErrorMsg();
}
return e.getReturnMsg();
}
}

@ -0,0 +1,63 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import lombok.extern.slf4j.Slf4j;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
/**
* App PayClient
*
* <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_5_3.shtml">App </a>
*
* // TODO 芋艿:未详细测试,因为手头没 App
*
* @author
*/
@Slf4j
public class WxAppPayClient extends AbstractWxPayClient {
public WxAppPayClient(Long channelId, WxPayClientConfig config) {
super(channelId, PayChannelEnum.WX_APP.getCode(), config);
}
@Override
protected void doInit() {
super.doInit(WxPayConstants.TradeType.APP);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO);
// 执行请求
WxPayMpOrderResult response = client.createOrder(request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
reqDTO.getOutTradeNo(), response);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderV3Request 对象
WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO);
// 执行请求
WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.APP, request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
reqDTO.getOutTradeNo(), response);
}
}

@ -0,0 +1,107 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import lombok.extern.slf4j.Slf4j;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
/**
* PayClient
*
* <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1"></a>
*
* @author
*/
@Slf4j
public class WxBarPayClient extends AbstractWxPayClient {
/**
*
*/
private static final Duration AUTH_CODE_EXPIRE = Duration.ofMinutes(3);
public WxBarPayClient(Long channelId, WxPayClientConfig config) {
super(channelId, PayChannelEnum.WX_BAR.getCode(), config);
}
@Override
protected void doInit() {
super.doInit(WxPayConstants.TradeType.MICROPAY);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 由于付款码需要不断轮询,所以需要在较短的时间完成支付
LocalDateTime expireTime = LocalDateTimeUtils.addTime(AUTH_CODE_EXPIRE);
if (expireTime.isAfter(reqDTO.getExpireTime())) {
expireTime = reqDTO.getExpireTime();
}
// 构建 WxPayMicropayRequest 对象
WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
.outTradeNo(reqDTO.getOutTradeNo())
.body(reqDTO.getSubject())
.detail(reqDTO.getBody())
.totalFee(reqDTO.getPrice()) // 单位分
.timeExpire(formatDateV2(expireTime))
.spbillCreateIp(reqDTO.getUserIp())
.authCode(getAuthCode(reqDTO))
.build();
// 执行请求,重试直到失败(过期),或者成功
WxPayException lastWxPayException = null;
for (int i = 1; i < Byte.MAX_VALUE; i++) {
try {
WxPayMicropayResult response = client.micropay(request);
// 支付成功例如说1用户输入了密码2用户免密支付
return PayOrderRespDTO.successOf(response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
response.getOutTradeNo(), response)
.setDisplayMode(PayOrderDisplayModeEnum.BAR_CODE.getMode());
} catch (WxPayException ex) {
lastWxPayException = ex;
// 如果不满足这 3 种任一的,则直接抛出 WxPayException 异常,不仅需处理
// 1. SYSTEMERROR接口返回错误请立即调用被扫订单结果查询API查询当前订单状态并根据订单的状态决定下一步的操作。
// 2. USERPAYING用户支付中需要输入密码等待 5 秒,然后调用被扫订单结果查询 API查询当前订单的不同状态决定下一步的操作。
// 3. BANKERROR银行系统异常请立即调用被扫订单结果查询 API查询当前订单的不同状态决定下一步的操作。
if (!StrUtil.equalsAny(ex.getErrCode(), "SYSTEMERROR", "USERPAYING", "BANKERROR")) {
throw ex;
}
// 等待 5 秒,继续下一轮重新发起支付
log.info("[doUnifiedOrderV2][发起微信 Bar 支付第({})失败,等待下一轮重试,请求({}),响应({})]", i,
toJsonString(request), ex.getMessage());
ThreadUtil.sleep(5, TimeUnit.SECONDS);
}
}
throw lastWxPayException;
}
@Override
protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
return doUnifiedOrderV2(reqDTO);
}
// ========== 各种工具方法 ==========
static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) {
String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "authCode");
if (StrUtil.isEmpty(authCode)) {
throw invalidParamException("支付请求的 authCode 不能为空!");
}
return authCode;
}
}

@ -0,0 +1,22 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import lombok.extern.slf4j.Slf4j;
/**
* PayClient
*
*
*
* <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml">JSAPI </>
*
* @author zwy
*/
@Slf4j
public class WxLitePayClient extends WxPubPayClient {
public WxLitePayClient(Long channelId, WxPayClientConfig config) {
super(channelId, PayChannelEnum.WX_LITE.getCode(), config);
}
}

@ -0,0 +1,58 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import lombok.extern.slf4j.Slf4j;
/**
* Native PayClient
*
* <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml">Native </a>
*
* @author zwy
*/
@Slf4j
public class WxNativePayClient extends AbstractWxPayClient {
public WxNativePayClient(Long channelId, WxPayClientConfig config) {
super(channelId, PayChannelEnum.WX_NATIVE.getCode(), config);
}
@Override
protected void doInit() {
super.doInit(WxPayConstants.TradeType.NATIVE);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO);
// 执行请求
WxPayNativeOrderResult response = client.createOrder(request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response.getCodeUrl(),
reqDTO.getOutTradeNo(), response);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderV3Request 对象
WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO);
// 执行请求
String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response,
reqDTO.getOutTradeNo(), response);
}
}

@ -1,15 +1,14 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.hutool.core.io.IoUtil;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import lombok.Data;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.constraints.NotBlank;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Set;
/**
* PayClientConfig
@ -18,33 +17,37 @@ import java.util.Set;
* @author
*/
@Data
public class WXPayClientConfig implements PayClientConfig {
public class WxPayClientConfig implements PayClientConfig {
/**
* API - V2
* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1
*
* <a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1">V2 </a>
*/
public static final String API_VERSION_V2 = "v2";
/**
* API - V3
* https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml
*
* <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml">V3 </a>
*/
public static final String API_VERSION_V3 = "v3";
/**
* appid
*
*
*/
@NotBlank(message = "APPID 不能为空", groups = {V2.class, V3.class})
private String appId;
/**
*
*/
@NotBlank(message = "商户号 不能为空", groups = {V2.class, V3.class})
@NotBlank(message = "商户号不能为空", groups = {V2.class, V3.class})
private String mchId;
/**
* API
*/
@NotBlank(message = "API 版本 不能为空", groups = {V2.class, V3.class})
@NotBlank(message = "API 版本不能为空", groups = {V2.class, V3.class})
private String apiVersion;
// ========== V2 版本的参数 ==========
@ -52,36 +55,31 @@ public class WXPayClientConfig implements PayClientConfig {
/**
*
*/
@NotBlank(message = "商户密钥 不能为空", groups = V2.class)
@NotBlank(message = "商户密钥不能为空", groups = V2.class)
private String mchKey;
/**
* apiclient_cert.p12 classpath: .
*
* apiclient_cert.p12 base64
*
* {@link #main(String[])}
* base64 p12 base64
*/
/// private String keyContent;
@NotBlank(message = "apiclient_cert.p12 不能为空", groups = V2.class)
private String keyContent;
// ========== V3 版本的参数 ==========
/**
* apiclient_key.pem classpath: .
*
* {@link #main(String[])}
* apiclient_key.pem
*/
@NotBlank(message = "apiclient_key 不能为空", groups = V3.class)
private String privateKeyContent;
/**
* apiclient_cert.pem classpath: .
*
* <p>
* {@link #main(String[])}
* apiclient_cert.pem
*/
@NotBlank(message = "apiclient_cert 不能为空", groups = V3.class)
private String privateCertContent;
/**
* apiV3
*/
@NotBlank(message = "apiV3 密钥值 不能为空", groups = V3.class)
@NotBlank(message = "apiV3 密钥值不能为空", groups = V3.class)
private String apiV3Key;
/**
@ -97,8 +95,9 @@ public class WXPayClientConfig implements PayClientConfig {
}
@Override
public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
return validator.validate(this, this.getApiVersion().equals(API_VERSION_V2) ? V2.class : V3.class);
public void validate(Validator validator) {
ValidationUtils.validate(validator, this,
API_VERSION_V2.equals(this.getApiVersion()) ? V2.class : V3.class);
}
public static void main(String[] args) throws FileNotFoundException {

@ -0,0 +1,80 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import lombok.extern.slf4j.Slf4j;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
/**
* PayClient
*
* <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml">JSAPI </>
*
* @author
*/
@Slf4j
public class WxPubPayClient extends AbstractWxPayClient {
public WxPubPayClient(Long channelId, WxPayClientConfig config) {
super(channelId, PayChannelEnum.WX_PUB.getCode(), config);
}
protected WxPubPayClient(Long channelId, String channelCode, WxPayClientConfig config) {
super(channelId, channelCode, config);
}
@Override
protected void doInit() {
super.doInit(WxPayConstants.TradeType.JSAPI);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO)
.setOpenid(getOpenid(reqDTO));
// 执行请求
WxPayMpOrderResult response = client.createOrder(request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
reqDTO.getOutTradeNo(), response);
}
@Override
protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO)
.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));
// 执行请求
WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
reqDTO.getOutTradeNo(), response);
}
// ========== 各种工具方法 ==========
static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
if (StrUtil.isEmpty(openid)) {
throw invalidParamException("支付请求的 openid 不能为空!");
}
return openid;
}
}

@ -1,198 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.time.ZoneId;
import java.util.Date;
import java.util.Objects;
/**
*
*
* @author zwy
*/
@Slf4j
public class WXLitePayClient extends AbstractPayClient<WXPayClientConfig> {
private WxPayService client;
public WXLitePayClient(Long channelId, WXPayClientConfig config) {
super(channelId, PayChannelEnum.WX_LITE.getCode(), config);
}
@Override
protected void doInit() {
WxPayConfig payConfig = new WxPayConfig();
BeanUtil.copyProperties(config, payConfig, "privateKeyContent","privateCertContent");
payConfig.setTradeType(WxPayConstants.TradeType.JSAPI); // 设置使用 JS API 支付方式
// if (StrUtil.isNotEmpty(config.getKeyContent())) {
// payConfig.setKeyContent(config.getKeyContent().getBytes(StandardCharsets.UTF_8));
// }
if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
}
if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
}
// 真实客户端
this.client = new WxPayServiceImpl();
client.setConfig(payConfig);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
throw new UnsupportedOperationException();
// WxPayMpOrderResult response;
// try {
// switch (config.getApiVersion()) {
// case WXPayClientConfig.API_VERSION_V2:
// response = this.unifiedOrderV2(reqDTO);
// break;
// case WXPayClientConfig.API_VERSION_V3:
// WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
// // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
// response = new WxPayMpOrderResult();
// BeanUtil.copyProperties(responseV3, response, true);
// break;
// default:
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
// }
// } catch (WxPayException e) {
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
// }
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
}
private WxPayMpOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
.outTradeNo(reqDTO.getMerchantOrderId())
.body(reqDTO.getBody())
.totalFee(reqDTO.getAmount().intValue()) // 单位分
.timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")) // v2的时间格式
.spbillCreateIp(reqDTO.getUserIp())
.openid(getOpenid(reqDTO))
.notifyUrl(reqDTO.getNotifyUrl())
.build();
// 执行请求
return client.createOrder(request);
}
private WxPayUnifiedOrderV3Result.JsapiResult unifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
request.setOutTradeNo(reqDTO.getMerchantOrderId());
request.setDescription(reqDTO.getBody());
request.setAmount(new WxPayUnifiedOrderV3Request
.Amount()
.setTotal(reqDTO
.getAmount()
.intValue())); // 单位分
request.setTimeExpire(DateUtil.format(Date.from(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()).toInstant()), "yyyy-MM-dd'T'HH:mm:ssXXX")); // v3的时间格式
request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));
request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
request.setNotifyUrl(reqDTO.getNotifyUrl());
// 执行请求
return client.createOrderV3(TradeTypeEnum.JSAPI, request);
}
private static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
if (StrUtil.isEmpty(openid)) {
throw new IllegalArgumentException("支付请求的 openid 不能为空!");
}
return openid;
}
/**
*
* v2 v3
*
* @param data
* @return
* @throws WxPayException
*/
// @Override
public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyReqDTO data) throws WxPayException {
log.info("[parseOrderNotify][微信支付回调data数据:{}]", data.getBody());
// 微信支付 v2 回调结果处理
switch (config.getApiVersion()) {
case WXPayClientConfig.API_VERSION_V2:
return parseOrderNotifyV2(data);
case WXPayClientConfig.API_VERSION_V3:
return parseOrderNotifyV3(data);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
}
private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyReqDTO data) throws WxPayException {
WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
// 转换结果
Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
"支付结果非 SUCCESS");
return PayOrderNotifyRespDTO
.builder()
.orderExtensionNo(result.getOutTradeNo())
.channelOrderNo(result.getTransactionId())
.channelUserId(result.getPayer().getOpenid())
.successTime(LocalDateTimeUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
.build();
}
private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyReqDTO data) throws WxPayException {
WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
// 转换结果
return PayOrderNotifyRespDTO
.builder()
.orderExtensionNo(notifyResult.getOutTradeNo())
.channelOrderNo(notifyResult.getTransactionId())
.channelUserId(notifyResult.getOpenid())
.successTime(LocalDateTimeUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
.build();
}
@Override
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
//TODO 需要实现
throw new UnsupportedOperationException();
}
}

@ -1,181 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.time.ZoneId;
import java.util.Date;
import java.util.Objects;
/**
* App
*
* @author zwy
*/
@Slf4j
public class WXNativePayClient extends AbstractPayClient<WXPayClientConfig> {
private WxPayService client;
public WXNativePayClient(Long channelId, WXPayClientConfig config) {
super(channelId, PayChannelEnum.WX_NATIVE.getCode(), config);
}
@Override
protected void doInit() {
WxPayConfig payConfig = new WxPayConfig();
BeanUtil.copyProperties(config, payConfig, "keyContent");
payConfig.setTradeType(WxPayConstants.TradeType.NATIVE); // 设置使用 native 支付方式
// if (StrUtil.isNotEmpty(config.getKeyContent())) {
// payConfig.setKeyContent(config.getKeyContent().getBytes(StandardCharsets.UTF_8));
// }
if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
}
if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
}
// 真实客户端
this.client = new WxPayServiceImpl();
client.setConfig(payConfig);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
throw new UnsupportedOperationException();
// // 这里原生的返回的是支付的 url 所以直接使用string接收
// // "invokeResponse": "weixin://wxpay/bizpayurl?pr=EGYAem7zz"
// String responseV3;
// try {
// switch (config.getApiVersion()) {
// case WXPayClientConfig.API_VERSION_V2:
// responseV3 = unifiedOrderV2(reqDTO).getCodeUrl();
// break;
// case WXPayClientConfig.API_VERSION_V3:
// responseV3 = this.unifiedOrderV3(reqDTO);
// break;
// default:
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
// }
// } catch (WxPayException e) {
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()), null, codeMapping);
// }
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, responseV3, codeMapping);
}
private WxPayNativeOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
//前端
String tradeType = reqDTO.getChannelExtras().get("trade_type");
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest
.newBuilder()
.outTradeNo(reqDTO.getMerchantOrderId())
.body(reqDTO.getBody())
.totalFee(reqDTO.getAmount().intValue()) // 单位分
.timeExpire(DateUtil.format(Date.from(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()).toInstant()), "yyyy-MM-dd'T'HH:mm:ssXXX"))
.spbillCreateIp(reqDTO.getUserIp())
.notifyUrl(reqDTO.getNotifyUrl())
.productId(tradeType)
.build();
// 执行请求
return client.createOrder(request);
}
private String unifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
request.setOutTradeNo(reqDTO.getMerchantOrderId());
request.setDescription(reqDTO.getBody());
request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount().intValue())); // 单位分
request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
request.setNotifyUrl(reqDTO.getNotifyUrl());
// 执行请求
return client.createOrderV3(TradeTypeEnum.NATIVE, request);
}
/**
*
* v2 v3
*
* @param data
* @return
* @throws WxPayException
*/
// @Override
public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyReqDTO data) throws WxPayException {
log.info("微信支付回调data数据:{}", data.getBody());
// 微信支付 v2 回调结果处理
switch (config.getApiVersion()) {
case WXPayClientConfig.API_VERSION_V2:
return parseOrderNotifyV2(data);
case WXPayClientConfig.API_VERSION_V3:
return parseOrderNotifyV3(data);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
}
private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyReqDTO data) throws WxPayException {
WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
// 转换结果
Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
"支付结果非 SUCCESS");
return PayOrderNotifyRespDTO
.builder()
.orderExtensionNo(result.getOutTradeNo())
.channelOrderNo(result.getTradeState())
.successTime(LocalDateTimeUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
.build();
}
private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyReqDTO data) throws WxPayException {
WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
// 转换结果
return PayOrderNotifyRespDTO
.builder()
.orderExtensionNo(notifyResult.getOutTradeNo())
.channelOrderNo(notifyResult.getTransactionId())
.channelUserId(notifyResult.getOpenid())
.successTime(LocalDateTimeUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
.build();
}
@Override
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
// TODO 需要实现
throw new UnsupportedOperationException();
}
}

@ -1,196 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Objects;
/**
* PayClient
*
* @author
*/
@Slf4j
public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
private WxPayService client;
public WXPubPayClient(Long channelId, WXPayClientConfig config) {
super(channelId, PayChannelEnum.WX_PUB.getCode(), config);
}
@Override
protected void doInit() {
WxPayConfig payConfig = new WxPayConfig();
BeanUtil.copyProperties(config, payConfig, "keyContent");
payConfig.setTradeType(WxPayConstants.TradeType.JSAPI); // 设置使用 JS API 支付方式
// if (StrUtil.isNotEmpty(config.getKeyContent())) {
// payConfig.setKeyContent(config.getKeyContent().getBytes(StandardCharsets.UTF_8));
// }
if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
}
if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
}
// 真实客户端
this.client = new WxPayServiceImpl();
client.setConfig(payConfig);
}
@Override
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
throw new UnsupportedOperationException();
//
// WxPayMpOrderResult response;
// try {
// switch (config.getApiVersion()) {
// case WXPayClientConfig.API_VERSION_V2:
// response = this.unifiedOrderV2(reqDTO);
// break;
// case WXPayClientConfig.API_VERSION_V3:
// WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
// // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
// response = new WxPayMpOrderResult();
// BeanUtil.copyProperties(responseV3, response, true);
// break;
// default:
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
// }
// } catch (WxPayException e) {
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping);
// }
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
}
private WxPayMpOrderResult unifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
.outTradeNo(reqDTO.getMerchantOrderId())
.body(reqDTO.getBody())
.totalFee(reqDTO.getAmount()) // 单位分
.timeExpire(formatDate(reqDTO.getExpireTime()))
.spbillCreateIp(reqDTO.getUserIp())
.openid(getOpenid(reqDTO))
.notifyUrl(reqDTO.getNotifyUrl())
.build();
// 执行请求
return client.createOrder(request);
}
private WxPayUnifiedOrderV3Result.JsapiResult unifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
// 构建 WxPayUnifiedOrderRequest 对象
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
request.setOutTradeNo(reqDTO.getMerchantOrderId());
request.setDescription(reqDTO.getBody());
request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount())); // 单位分
request.setTimeExpire(formatDate(reqDTO.getExpireTime()));
request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO)));
request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
request.setNotifyUrl(reqDTO.getNotifyUrl());
// 执行请求
return client.createOrderV3(TradeTypeEnum.JSAPI, request);
}
private static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
if (StrUtil.isEmpty(openid)) {
throw new IllegalArgumentException("支付请求的 openid 不能为空!");
}
return openid;
}
/**
*
* v2 v3
*
* @param data
* @return
* @throws WxPayException
*/
// @Override
public PayOrderNotifyRespDTO parseOrderNotify(PayNotifyReqDTO data) throws WxPayException {
log.info("[parseOrderNotify][微信支付回调data数据: {}]", data.getBody());
// 微信支付 v2 回调结果处理
switch (config.getApiVersion()) {
case WXPayClientConfig.API_VERSION_V2:
return parseOrderNotifyV2(data);
case WXPayClientConfig.API_VERSION_V3:
return parseOrderNotifyV3(data);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
}
private PayOrderNotifyRespDTO parseOrderNotifyV3(PayNotifyReqDTO data) throws WxPayException {
WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = client.parseOrderNotifyV3Result(data.getBody(), null);
WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
// 转换结果
Assert.isTrue(Objects.equals(wxPayOrderNotifyV3Result.getResult().getTradeState(), "SUCCESS"),
"支付结果非 SUCCESS");
return PayOrderNotifyRespDTO
.builder()
.orderExtensionNo(result.getOutTradeNo())
.channelOrderNo(result.getTradeState())
.successTime(LocalDateTimeUtil.parse(result.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"))
.build();
}
private PayOrderNotifyRespDTO parseOrderNotifyV2(PayNotifyReqDTO data) throws WxPayException {
WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(data.getBody());
Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
// 转换结果
return PayOrderNotifyRespDTO
.builder()
.orderExtensionNo(notifyResult.getOutTradeNo())
.channelOrderNo(notifyResult.getTransactionId())
.channelUserId(notifyResult.getOpenid())
.successTime(LocalDateTimeUtil.parse(notifyResult.getTimeEnd(), "yyyyMMddHHmmss"))
.build();
}
@Override
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
// TODO 需要实现
throw new UnsupportedOperationException();
}
private static String formatDate(LocalDateTime time) {
return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyy-MM-dd'T'HH:mm:ssXXX");
}
}

@ -1,23 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 退
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum PayChannelRefundRespEnum {
SUCCESS(1, "退款成功"),
FAILURE(2, "退款失败"),
PROCESSING(3,"退款处理中"),
CLOSED(4, "退款关闭");
private final Integer status;
private final String name;
}

@ -1,29 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
*
*
* 使 2-002-000-000
*
* @author
*/
public interface PayFrameworkErrorCodeConstants {
ErrorCode PAY_UNKNOWN = new ErrorCode(2002000000, "未知错误,需要解析");
// ========== 配置相关相关 2002000100 ==========
// todo 芋艿:如下的错误码,怎么处理掉
ErrorCode PAY_CONFIG_APP_ID_ERROR = new ErrorCode(2002000100, "支付渠道 AppId 不正确");
ErrorCode PAY_CONFIG_SIGN_ERROR = new ErrorCode(2002000100, "签名错误"); // 例如说,微信支付,配置错了 mchId 或者 mchKey
// ========== 其它相关 2002000900 开头 ==========
// todo 芋艿:如下的错误码,怎么处理掉
ErrorCode PAY_OPENID_ERROR = new ErrorCode(2002000900, "无效的 openid"); // 例如说,微信 openid 未授权过
ErrorCode PAY_PARAM_MISSING = new ErrorCode(2002000901, "请求参数缺失"); // 例如说,支付少传了金额
ErrorCode PAY_EXCEPTION = new ErrorCode(2002000999, "调用异常");
}

@ -1,22 +0,0 @@
package cn.iocoder.yudao.framework.pay.core.enums;
/**
* 退, 退
*
* @author jason
*/
public enum PayNotifyRefundStatusEnum {
/**
* 退 trade_status=TRADE_CLOSED 退 trade_status=TRADE_SUCCESS
* 退
*/
SUCCESS,
/**
* 退
* 退
*/
ABNORMAL;
}

@ -1,15 +1,14 @@
package cn.iocoder.yudao.framework.pay.core.enums;
package cn.iocoder.yudao.framework.pay.core.enums.channel;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
*
* @author
*/
@ -17,10 +16,11 @@ import lombok.Getter;
@AllArgsConstructor
public enum PayChannelEnum {
WX_PUB("wx_pub", "微信 JSAPI 支付", WXPayClientConfig.class), // 公众号网页
WX_LITE("wx_lite", "微信小程序支付", WXPayClientConfig.class),
WX_APP("wx_app", "微信 App 支付", WXPayClientConfig.class),
WX_NATIVE("wx_native", "微信 native 支付", WXPayClientConfig.class),
WX_PUB("wx_pub", "微信 JSAPI 支付", WxPayClientConfig.class), // 公众号网页
WX_LITE("wx_lite", "微信小程序支付", WxPayClientConfig.class),
WX_APP("wx_app", "微信 App 支付", WxPayClientConfig.class),
WX_NATIVE("wx_native", "微信 Native 支付", WxPayClientConfig.class),
WX_BAR("wx_bar", "微信付款码支付", WxPayClientConfig.class),
ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class),
ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class),
@ -30,8 +30,8 @@ public enum PayChannelEnum {
/**
*
* <p>
* https://www.pingxx.com/api/支付渠道属性值.html
*
* <a href="https://www.pingxx.com/api/支付渠道属性值.html"></a>
*/
private final String code;
/**

@ -1,4 +1,4 @@
package cn.iocoder.yudao.framework.pay.core.enums;
package cn.iocoder.yudao.framework.pay.core.enums.order;
import lombok.AllArgsConstructor;
import lombok.Getter;
@ -10,15 +10,15 @@ import lombok.Getter;
*/
@Getter
@AllArgsConstructor
public enum PayDisplayModeEnum {
public enum PayOrderDisplayModeEnum {
URL("url"), // Redirect 跳转链接的方式
IFRAME("iframe"), // IFrame 内嵌链接的方式
IFRAME("iframe"), // IFrame 内嵌链接的方式【目前暂时用不到】
FORM("form"), // HTML 表单提交
QR_CODE("qr_code"), // 二维码的文字内容
QR_CODE_URL("qr_code_url"), // 二维码的图片链接
BAR_CODE("bar_code"), // 条形码
APP("app"), // 应用
APP("app"), // 应用Android、iOS、微信小程序、微信公众号等需要做自定义处理的
;
/**

@ -0,0 +1,56 @@
package cn.iocoder.yudao.framework.pay.core.enums.order;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Objects;
/**
*
*
* @author
*/
@Getter
@AllArgsConstructor
public enum PayOrderStatusRespEnum {
WAITING(0, "未支付"),
SUCCESS(10, "支付成功"),
REFUND(20, "已退款"),
CLOSED(30, "支付关闭"),
;
private final Integer status;
private final String name;
/**
*
*
* @param status
* @return
*/
public static boolean isSuccess(Integer status) {
return Objects.equals(status, SUCCESS.getStatus());
}
/**
* 退
*
* @param status
* @return
*/
public static boolean isRefund(Integer status) {
return Objects.equals(status, REFUND.getStatus());
}
/**
*
*
* @param status
* @return
*/
public static boolean isClosed(Integer status) {
return Objects.equals(status, CLOSED.getStatus());
}
}

@ -0,0 +1,32 @@
package cn.iocoder.yudao.framework.pay.core.enums.refund;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Objects;
/**
* 退
*
* @author jason
*/
@Getter
@AllArgsConstructor
public enum PayRefundStatusRespEnum {
WAITING(0, "等待退款"),
SUCCESS(10, "退款成功"),
FAILURE(20, "退款失败");
private final Integer status;
private final String name;
public static boolean isSuccess(Integer status) {
return Objects.equals(status, SUCCESS.getStatus());
}
public static boolean isFailure(Integer status) {
return Objects.equals(status, FAILURE.getStatus());
}
}

@ -2,17 +2,14 @@ package cn.iocoder.yudao.framework.pay.core.client.impl;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayQrPayClient;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayWapPayClient;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPubPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPubPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -27,18 +24,20 @@ import java.io.FileNotFoundException;
@Disabled
public class PayClientFactoryImplIntegrationTest {
private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
private final PayClientFactoryImpl payClientFactory = new PayClientFactoryImpl();
/**
* {@link WXPubPayClient} V2
* {@link WxPubPayClient} V2
*/
@Test
public void testCreatePayClient_WX_PUB_V2() {
// 创建配置
WXPayClientConfig config = new WXPayClientConfig();
WxPayClientConfig config = new WxPayClientConfig();
config.setAppId("wx041349c6f39b268b");
config.setMchId("1545083881");
config.setApiVersion(WXPayClientConfig.API_VERSION_V2);
config.setApiVersion(WxPayClientConfig.API_VERSION_V2);
config.setMchKey("0alL64UDQdlCwiKZ73ib7ypaIjMns06p");
// 创建客户端
Long channelId = RandomUtil.randomLong();
@ -51,15 +50,15 @@ public class PayClientFactoryImplIntegrationTest {
}
/**
* {@link WXPubPayClient} V3
* {@link WxPubPayClient} V3
*/
@Test
public void testCreatePayClient_WX_PUB_V3() throws FileNotFoundException {
// 创建配置
WXPayClientConfig config = new WXPayClientConfig();
WxPayClientConfig config = new WxPayClientConfig();
config.setAppId("wx041349c6f39b268b");
config.setMchId("1545083881");
config.setApiVersion(WXPayClientConfig.API_VERSION_V3);
config.setApiVersion(WxPayClientConfig.API_VERSION_V3);
config.setPrivateKeyContent(IoUtil.readUtf8(new FileInputStream("/Users/yunai/Downloads/wx_pay/apiclient_key.pem")));
config.setPrivateCertContent(IoUtil.readUtf8(new FileInputStream("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem")));
config.setApiV3Key("joerVi8y5DJ3o4ttA0o1uH47Xz1u2Ase");
@ -82,7 +81,7 @@ public class PayClientFactoryImplIntegrationTest {
// 创建配置
AlipayPayClientConfig config = new AlipayPayClientConfig();
config.setAppId("2021000118634035");
config.setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX);
config.setServerUrl(SERVER_URL_SANDBOX);
config.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8=");
config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB");
@ -106,7 +105,7 @@ public class PayClientFactoryImplIntegrationTest {
// 创建配置
AlipayPayClientConfig config = new AlipayPayClientConfig();
config.setAppId("2021000118634035");
config.setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX);
config.setServerUrl(SERVER_URL_SANDBOX);
config.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8=");
config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB");
@ -122,10 +121,10 @@ public class PayClientFactoryImplIntegrationTest {
private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() {
PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO();
reqDTO.setAmount(123);
reqDTO.setPrice(123);
reqDTO.setSubject("IPhone 13");
reqDTO.setBody("biubiubiu");
reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis()));
reqDTO.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
reqDTO.setUserIp("127.0.0.1");
reqDTO.setNotifyUrl("http://127.0.0.1:8080");
return reqDTO;

@ -1,8 +1,6 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
@ -22,9 +20,11 @@ import static org.mockito.Mockito.when;
public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
private final AlipayPayClientConfig config = new AlipayPayClientConfig()
.setAppId("2021000118634035")
.setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX)
.setServerUrl(SERVER_URL_SANDBOX)
.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
// TODO @tinakey 可以随机就好,简洁一点哈。
.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJ" +
@ -72,8 +72,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
// 这里,设置可以直接随机整个对象。
Long shopOrderId = System.currentTimeMillis();
PayOrderUnifiedReqDTO reqDTO=new PayOrderUnifiedReqDTO();
reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis()));
reqDTO.setAmount(1);
reqDTO.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
reqDTO.setPrice(1);
reqDTO.setBody("内容:" + shopOrderId);
reqDTO.setSubject("标题:"+shopOrderId);
String notify="http://niubi.natapp1.cc/api/pay/order/notify";

@ -0,0 +1,123 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV2;
/**
* {@link WxBarPayClient}
*
* @author
*/
@Disabled
public class WxBarPayClientIntegrationTest {
@Test
public void testPayV2() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起支付
WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
.outTradeNo(String.valueOf(System.currentTimeMillis()))
.body("测试支付-body")
.detail("测试支付-detail")
.totalFee(1) // 单位分
.timeExpire(formatDateV2(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
.spbillCreateIp("127.0.0.1")
.authCode("134298744426278497")
.build();
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayMicropayResult response = client.micropay(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
@Test
public void testParseRefundNotifyV2() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行解析
String xml = "<xml><return_code>SUCCESS</return_code><appid><![CDATA[wx62056c0d5e8db250]]></appid><mch_id><![CDATA[1545083881]]></mch_id><nonce_str><![CDATA[ed8f02c21d15635cede114a42d0525a0]]></nonce_str><req_info><![CDATA[bGp+wB9DAHjoOO9Nw1iSmmIFdN2zZDhsoRWZBYdf/8bcpjowr4T8i2qjLsbMtvKQeVC5kBZOL/Agal3be6UPwnoantil+L+ojZgvLch7dXFKs/AcoxIYcVYyGka+wmnRJfUmuFRBgzt++8HOFsmJz6e2brYv1EAz+93fP2AsJtRuw1FEzodcg8eXm52hbE0KhLNqC2OyNVkn8AbOOrwIxSYobg2jVbuJ4JllYbEGIQ/6kWzNbVmMKhGJGYBy/NbUGKoQsoe4QeTQqcqQqVp08muxaOfJGThaN3B9EEMFSrog/3yT7ykVV6WQ5+Ygt89LplOf5ucWa4Ird7VJhHWtzI92ZePj4Omy1XkT1TRlwtDegA0S5MeQpM4WZ1taMrhxgmNkTUJ0JXFncx5e2KLQvbvD/HOcccx48Xv1c16JBz6G3501k8E++LWXgZ2TeNXwGsk6FyRZb0ApLyQHIx5ZtPo/UET9z3AmJCPXkrUsZ4WK46fDtbzxVPU2r8nTOcGCPbO0LUsGT6wpsuQVC4CisXDJwoZmL6kKwHfKs6mmUL2YZYzNfgoB/KgpJYSpC96kcpQyFvw+xuwqK2SXGZbAl9lADT+a83z04feQHSSIG3PCrX4QEWzpCZZ4+ySEz1Y34aoU20X9GtX+1LSwUjmQgwHrMBSvFm3/B7+IFM8OUqDB+Uvkr9Uvy7P2/KDvfy3Ih7GFcGd0C5NXpSvVTTfu1IlK/T3/t6MR/8iq78pp/2ZTYvO6eNDRJWaXYU+x6sl2dTs9n+2Z4W4AfYTvEyuxlx+aI19SqCJh7WmaFcAxidFl/9iqDjWiplb9+C6ijZv2hJtVjSCuoptIWpGDYItH7RAqlKHrx6flJD+M/5BceMHBv2w4OWCD9vPRLo8gl9o06ip0iflzO1dixhOAgLFjsQmQHNGFtR3EvCID+iS4FUlilwK+hcKNxrr0wp9Btkl9W1R9aTo289CUiIxx45skfCYzHwb+7Hqj3uTiXnep6zhCKZBAnPsDOvISXfBgXKufcFsTNtts09jX8H5/uMc9wyJ179H1cp+At1mIK2duwfo4Q9asfEoffl6Zn1olGdtEruxHGeVU0NwJ8V7RflC/Cx5RXtJ3sPJ/sHmVnBlVyR0=]]></req_info></xml>";
WxPayRefundNotifyResult response = client.parseRefundNotifyResult(xml);
System.out.println(response.getReqInfo());
}
@Test
public void testRefundV2() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起退款
WxPayRefundRequest request = new WxPayRefundRequest()
.setOutTradeNo("1689545667276")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setRefundFee(1)
.setRefundDesc("就是想退了")
.setTotalFee(1);
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayRefundResult response = client.refund(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
@Test
public void testRefundV3() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起退款
WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo("1689506325635")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
.setReason("就是想退了");
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayRefundV3Result response = client.refundV3(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
private WxPayConfig buildWxPayConfigV2() {
WxPayConfig config = new WxPayConfig();
config.setAppId("wx62056c0d5e8db250");
config.setMchId("1545083881");
config.setMchKey("dS1ngeN63JLr3NRbvPH9AJy3MyUxZdim");
// config.setSignType(WxPayConstants.SignType.MD5);
config.setKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.p12");
return config;
}
}

@ -0,0 +1,83 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV3;
/**
* {@link WxNativePayClient}
*
* @author
*/
@Disabled
public class WxNativePayClientIntegrationTest {
@Test
public void testPayV3() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV3();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起支付
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request()
.setOutTradeNo(String.valueOf(System.currentTimeMillis()))
.setDescription("测试支付-body")
.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(1)) // 单位分
.setTimeExpire(formatDateV3(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp("127.0.0.1"))
.setNotifyUrl("http://127.0.0.1:48080");
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
@Test
public void testRefundV3() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV3();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起退款
WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo("1689545729695")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
.setReason("就是想退了");
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayRefundV3Result response = client.refundV3(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
private WxPayConfig buildWxPayConfigV3() {
WxPayConfig config = new WxPayConfig();
config.setAppId("wx62056c0d5e8db250");
config.setMchId("1545083881");
config.setApiV3Key("459arNsYHl1mgkiO6H9ZH5KkhFXSxaA4");
// config.setCertSerialNo(serialNo);
config.setPrivateCertPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem");
config.setPrivateKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_key.pem");
return config;
}
}

@ -82,9 +82,9 @@ public class TenantUtils {
* header
*
* @param headers HTTP headers
* @param tenantId
*/
public static void addTenantHeader(Map<String, String> headers) {
Long tenantId = TenantContextHolder.getTenantId();
public static void addTenantHeader(Map<String, String> headers, Long tenantId) {
if (tenantId != null) {
headers.put(HEADER_TENANT_ID, tenantId.toString());
}

@ -0,0 +1,39 @@
package cn.iocoder.yudao.framework.excel.core.convert;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
*
*
*
*
* @author
*/
public class MoneyConvert implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
throw new UnsupportedOperationException("暂不支持,也不需要");
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
throw new UnsupportedOperationException("暂不支持,也不需要");
}
@Override
public WriteCellData<String> convertToExcelData(Integer value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
BigDecimal result = BigDecimal.valueOf(value)
.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
return new WriteCellData<>(result.toString());
}
}

@ -46,6 +46,18 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
}
default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
SFunction<T, ?> field3, Object value3) {
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)
.eq(field3, value3));
}
default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
SFunction<T, ?> field3, Object value3, SFunction<T, ?> field4, Object value4) {
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)
.eq(field3, value3).eq(field4, value4));
}
default Long selectCount() {
return selectCount(new QueryWrapper<T>());
}
@ -105,8 +117,26 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
update(update, new QueryWrapper<>());
}
/**
* ID
*
* @param entities
*/
default void updateBatch(Collection<T> entities) {
Db.updateBatchById(entities);
}
default void updateBatch(Collection<T> entities, int size) {
Db.updateBatchById(entities, size);
}
/**
* , 1000
*
* @param entities
*/
default void saveOrUpdateBatch(Collection<T> entities){
Db.saveOrUpdateBatch(entities);
}
}

@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.query;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

@ -0,0 +1,56 @@
package cn.iocoder.yudao.framework.mybatis.core.type;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
* List<Integer> varchar
*
* @author jason
*/
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class IntegerListTypeHandler implements TypeHandler<List<Integer>> {
private static final String COMMA = ",";
@Override
public void setParameter(PreparedStatement ps, int i, List<Integer> strings, JdbcType jdbcType) throws SQLException {
ps.setString(i, CollUtil.join(strings, COMMA));
}
@Override
public List<Integer> getResult(ResultSet rs, String columnName) throws SQLException {
String value = rs.getString(columnName);
return getResult(value);
}
@Override
public List<Integer> getResult(ResultSet rs, int columnIndex) throws SQLException {
String value = rs.getString(columnIndex);
return getResult(value);
}
@Override
public List<Integer> getResult(CallableStatement cs, int columnIndex) throws SQLException {
String value = cs.getString(columnIndex);
return getResult(value);
}
private List<Integer> getResult(String value) {
if (value == null) {
return null;
}
return StrUtils.splitToInteger(value, COMMA);
}
}

@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import org.redisson.spring.starter.RedissonAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@ -41,7 +40,6 @@ public class BaseDbAndRedisUnitTest {
// Redis 配置类
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
RedisAutoConfiguration.class, // Spring Redis 自动配置类
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
RedissonAutoConfiguration.class, // Redisson 自动高配置类
})

@ -55,6 +55,9 @@ public class RandomUtils {
}
return RandomUtil.randomInt();
});
// LocalDateTime
PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(LocalDateTime.class,
(dataProviderStrategy, attributeMetadata, map) -> randomLocalDateTime());
// Boolean
PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Boolean.class, (dataProviderStrategy, attributeMetadata, map) -> {
// 如果是 deleted 的字段,返回非删除
@ -82,7 +85,8 @@ public class RandomUtils {
}
public static LocalDateTime randomLocalDateTime() {
return LocalDateTimeUtil.of(randomDate());
// 设置 Nano 为零的原因,避免 MySQL、H2 存储不到时间戳
return LocalDateTimeUtil.of(randomDate()).withNano(0);
}
public static Short randomShort() {
@ -102,6 +106,10 @@ public class RandomUtils {
return randomString() + "@qq.com";
}
public static String randomURL() {
return "https://www.iocoder.cn/" + randomString();
}
@SafeVarargs
public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
T pojo = PODAM_FACTORY.manufacturePojo(clazz);

@ -10,11 +10,14 @@ import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@ -113,4 +116,13 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
return bean;
}
/**
* RestTemplate
*
* @param restTemplateBuilder {@link RestTemplateAutoConfiguration#restTemplateBuilder}
*/
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
}

@ -3,16 +3,16 @@ package cn.iocoder.yudao.module.bpm.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
*
* Bpm
*
* 使 1-009-000-000
* bpm 使 1-009-000-000
*/
public interface ErrorCodeConstants {
// ========== 通用流程处理 模块 1-009-000-000 ==========
// ========== 通用流程处理 模块 1009000000 ==========
ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
// ========== OA 流程模块 1-009-001-000 ==========
// ========== OA 流程模块 1009001000 ==========
ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009001001, "请假申请不存在");
ErrorCode OA_PM_POST_NOT_EXISTS = new ErrorCode(1009001002, "项目经理岗位未设置");
ErrorCode OA_DEPART_PM_POST_NOT_EXISTS = new ErrorCode(1009001009, "部门的项目经理不存在");
@ -21,7 +21,7 @@ public interface ErrorCodeConstants {
ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1009001006, "HR岗位未设置");
ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1009001007, "请假天数必须>=1");
// ========== 流程模型 1-009-002-000 ==========
// ========== 流程模型 1009002000 ==========
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
@ -30,34 +30,34 @@ public interface ErrorCodeConstants {
"原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1009003005, "流程定义部署失败,原因:信息未发生变化");
// ========== 流程定义 1-009-003-000 ==========
// ========== 流程定义 1009003000 ==========
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003003, "流程定义处于挂起状态");
ErrorCode PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS = new ErrorCode(1009003004, "流程定义的模型不存在");
// ========== 流程实例 1-009-004-000 ==========
// ========== 流程实例 1009004000 ==========
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在");
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的");
// ========== 流程任务 1-009-005-000 ==========
// ========== 流程任务 1009005000 ==========
ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009005000, "审批任务失败,原因:该任务不处于未审批");
ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1009005001, "审批任务失败,原因:该任务的审批人不是你");
// ========== 流程任务分配规则 1-009-006-000 ==========
// ========== 流程任务分配规则 1009006000 ==========
ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则");
ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1009006001, "流程任务分配规则不存在");
ErrorCode TASK_UPDATE_FAIL_NOT_MODEL = new ErrorCode(1009006002, "只有流程模型的任务分配规则,才允许被修改");
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1009006003, "操作失败,原因:找不到任务的审批人!");
ErrorCode TASK_ASSIGN_SCRIPT_NOT_EXISTS = new ErrorCode(1009006004, "操作失败,原因:任务分配脚本({}) 不存在");
// ========== 动态表单模块 1-009-010-000 ==========
// ========== 动态表单模块 1009010000 ==========
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010001, "表单项({}) 和 ({}) 使用了相同的字段名({})");
// ========== 用户组模块 1-009-011-000 ==========
// ========== 用户组模块 1009011000 ==========
ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1009011000, "用户组不存在");
ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1009011001, "名字为【{}】的用户组已被禁用");

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.product.api.comment;
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
/**
* API
*
* @author HUIHUI
*/
public interface ProductCommentApi {
/**
*
*
* @param createReqDTO
* @return id
*/
Long createComment(ProductCommentCreateReqDTO createReqDTO);
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.product.api.comment.dto;
import lombok.Data;
import java.util.List;
/**
* DTO
*
* @author HUIHUI
*/
@Data
public class ProductCommentCreateReqDTO {
/**
* SKU
*/
private Long skuId;
/**
*
*/
private Long orderId;
/**
*
*/
private Long orderItemId;
/**
* 1-5
*/
private Integer scores;
/**
* 1-5
*/
private Integer descriptionScores;
/**
* 1-5
*/
private Integer benefitScores;
/**
*
*/
private String content;
/**
* 9
*/
private List<String> picUrls;
/**
*
*/
private Boolean anonymous;
/**
*
*/
private Long userId;
}

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.product.api.sku;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import java.util.Collection;
import java.util.List;
@ -30,6 +30,15 @@ public interface ProductSkuApi {
*/
List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
// TODO puhui999入参用 Collection<Long> 更通用
/**
* SKU
*
* @param spuIds SPU
* @return SKU
*/
List<ProductSkuRespDTO> getSkuListBySpuId(List<Long> spuIds);
/**
* SKU
*

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.api.sku.dto;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import lombok.Data;
import java.util.List;
@ -22,15 +22,11 @@ public class ProductSkuRespDTO {
* SPU
*/
private Long spuId;
/**
* SPU
*/
private String spuName;
/**
* JSON
*
*/
private List<Property> properties;
private List<ProductPropertyValueDetailRespDTO> properties;
/**
*
*/
@ -51,20 +47,10 @@ public class ProductSkuRespDTO {
*
*/
private String picUrl;
/**
* SKU
* <p>
* {@link CommonStatusEnum}
*/
private Integer status;
/**
*
*/
private Integer stock;
/**
*
*/
private Integer warnStock;
/**
* kg
*/
@ -74,22 +60,4 @@ public class ProductSkuRespDTO {
*/
private Double volume;
/**
*
*/
@Data
public static class Property {
/**
*
*/
private Long propertyId;
/**
*
*/
private Long valueId;
}
}

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.product.api.spu.dto;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import lombok.Data;
@ -29,17 +28,23 @@ public class ProductSpuRespDTO {
*/
private String name;
/**
*
*
*/
private String code;
private String keyword;
/**
*
*
*/
private String sellPoint;
private String introduction;
/**
*
*/
private String description;
// TODO @芋艿:是不是要删除
/**
*
*/
private String barCode;
/**
*
*/
@ -49,13 +54,13 @@ public class ProductSpuRespDTO {
*/
private Long brandId;
/**
*
* <p>
* 1.
* 2. 使 800x800 1M
* 3. 1 10
*
*/
private List<String> picUrls;
private String picUrl;
/**
*
*/
private List<String> sliderPicUrls;
/**
*
*/
@ -76,38 +81,36 @@ public class ProductSpuRespDTO {
/**
*
* <p>
* {@link ProductSpuSpecTypeEnum}
*
* false -
* true -
*/
private Integer specType;
private Boolean specType;
/**
* 使
* <p>
* {@link ProductSkuRespDTO#getPrice()}
* 使
*/
private Integer minPrice;
/**
* 使
* <p>
* {@link ProductSkuRespDTO#getPrice()}
*/
private Integer maxPrice;
private Integer price;
/**
* 使
* <p>
* {@link ProductSkuRespDTO#getMarketPrice()}
*/
private Integer marketPrice;
/**
*
* <p>
* {@link ProductSkuRespDTO#getStock()}
* 使
*/
private Integer totalStock;
private Integer costPrice;
/**
*
*/
private Integer stock;
// ========== 物流相关字段 =========
/**
*
*
*
* TradeDeliveryExpressTemplateDO id
*/
private Boolean showStock;
private Long deliveryTemplateId;
// ========== 统计相关字段 =========

@ -0,0 +1,13 @@
package cn.iocoder.yudao.module.product.enums;
/**
* product
*
* @author HUIHUI
*/
public interface DictTypeConstants {
String PRODUCT_UNIT = "product_unit"; // 商品单位
String PRODUCT_SPU_STATUS = "product_spu_status"; // 商品 SPU 状态
}

@ -15,10 +15,11 @@ public interface ErrorCodeConstants {
ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
ErrorCode CATEGORY_HAVE_BIND_SPU = new ErrorCode(1008001005, "类别下存在商品,无法删除");
// ========== 商品品牌相关编号 1008002000 ==========
ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在");
ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌已禁用");
ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在");
// ========== 商品属性项 1008003000 ==========
@ -32,8 +33,9 @@ public interface ErrorCodeConstants {
// ========== 商品 SPU 1008005000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下");
ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第二级的商品分类及以下");
ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态");
ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1008005003, "商品 SPU 不处于回收站状态");
// ========== 商品 SKU 1008006000 ==========
ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
@ -42,4 +44,14 @@ public interface ErrorCodeConstants {
ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU必须不重复");
ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
// ========== 商品 评价 1008007000 ==========
ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");
ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");
ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在");
// ========== 商品 收藏 1008008000 ==========
ErrorCode FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏");
ErrorCode FAVORITE_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在");
}

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.product.enums;
/**
* Product
*
* @author HUIHUI
*/
public interface ProductConstants {
/**
* TODO 10使
*/
int ALERT_STOCK = 10;
}

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.product.enums.comment;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
*
*
* @author wangzhs
*/
@Getter
@AllArgsConstructor
public enum ProductCommentScoresEnum implements IntArrayValuable {
ONE(1, "1星"),
TWO(2, "2星"),
THREE(3, "3星"),
FOUR(4, "4星"),
FIVE(5, "5星");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentScoresEnum::getScores).toArray();
/**
*
*/
private final Integer scores;
/**
*
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -1,37 +0,0 @@
package cn.iocoder.yudao.module.product.enums.spu;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* SPU
*
* @author
*/
@Getter
@AllArgsConstructor
public enum ProductSpuSpecTypeEnum implements IntArrayValuable {
RECYCLE(1, "统一规格"),
DISABLE(2, "多规格");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray();
/**
*
*/
private final Integer type;
/**
*
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -17,7 +17,7 @@ public enum ProductSpuStatusEnum implements IntArrayValuable {
RECYCLE(-1, "回收站"),
DISABLE(0, "下架"),
ENABLE(1, "上架"),;
ENABLE(1, "上架");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray();

@ -23,12 +23,27 @@
<artifactId>yudao-module-product-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- TODO 芋艿:看看~~~ -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-trade-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-member-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.product.api.comment;
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API
*
* @author HUIHUI
*/
@Service
@Validated
public class ProductCommentApiImpl implements ProductCommentApi {
@Resource
private ProductCommentService productCommentService;
@Override
public Long createComment(ProductCommentCreateReqDTO createReqDTO) {
return productCommentService.createComment(createReqDTO);
}
}

@ -15,7 +15,8 @@ import java.util.Collections;
import java.util.List;
/**
* TODO LeeYan9: ;
* SKU API
*
* @author LeeYan9
* @since 2022-09-06
*/
@ -28,8 +29,8 @@ public class ProductSkuApiImpl implements ProductSkuApi {
@Override
public ProductSkuRespDTO getSku(Long id) {
// TODO TODO LeeYan9: 需要实现
return null;
ProductSkuDO sku = productSkuService.getSku(id);
return ProductSkuConvert.INSTANCE.convert02(sku);
}
@Override
@ -41,6 +42,15 @@ public class ProductSkuApiImpl implements ProductSkuApi {
return ProductSkuConvert.INSTANCE.convertList04(skus);
}
@Override
public List<ProductSkuRespDTO> getSkuListBySpuId(List<Long> spuIds) {
if (CollUtil.isEmpty(spuIds)) {
return Collections.emptyList();
}
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spuIds);
return ProductSkuConvert.INSTANCE.convertList04(skus);
}
@Override
public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) {
productSkuService.updateSkuStock(updateStockReqDTO);

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.api.spu;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
@ -14,7 +14,7 @@ import java.util.Collections;
import java.util.List;
/**
* TODO LeeYan9: ;
* SPU API
*
* @author LeeYan9
* @since 2022-09-06
@ -28,11 +28,11 @@ public class ProductSpuApiImpl implements ProductSpuApi {
@Override
public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {
// TODO TODO LeeYan9: AllEmpty?
if (CollectionUtils.isAnyEmpty(spuIds)) {
if (CollectionUtil.isEmpty(spuIds)) {
return Collections.emptyList();
}
List<ProductSpuDO> productSpuDOList = productSpuMapper.selectBatchIds(spuIds);
return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList);
}
}

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.product.controller.admin.brand;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
@ -62,6 +63,15 @@ public class ProductBrandController {
return success(ProductBrandConvert.INSTANCE.convert(brand));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取品牌精简信息列表", description = "主要用于前端的下拉选项")
public CommonResult<List<ProductBrandSimpleRespVO>> getSimpleBrandList() {
// 获取品牌列表,只要开启状态的
List<ProductBrandDO> list = brandService.getBrandListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 排序后,返回给前端
return success(ProductBrandConvert.INSTANCE.convertList1(list));
}
@GetMapping("/page")
@Operation(summary = "获得品牌分页")
@PreAuthorize("@ss.hasPermission('product:brand:query')")

@ -12,7 +12,7 @@ import javax.validation.constraints.NotNull;
@Data
public class ProductBrandBaseVO {
@Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "苹果")
@NotNull(message = "品牌名称不能为空")
private String name;

@ -7,7 +7,7 @@ import lombok.Data;
@Data
public class ProductBrandListReqVO {
@Schema(description = "品牌名称", example = "芋道")
@Schema(description = "品牌名称", example = "苹果")
private String name;
}

@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class ProductBrandPageReqVO extends PageParam {
@Schema(description = "品牌名称", example = "芋道")
@Schema(description = "品牌名称", example = "苹果")
private String name;
@Schema(description = "状态", example = "0")

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Schema(description = "管理后台 - 品牌精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductBrandSimpleRespVO {
@Schema(description = "品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "品牌名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "苹果")
private String name;
}

@ -21,16 +21,16 @@ public class ProductCategoryBaseVO {
@NotBlank(message = "分类名称不能为空")
private String name;
@Schema(description = "分类图", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "分类图不能为空")
@Schema(description = "移动端分类图", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "移动端分类图不能为空")
private String picUrl;
@Schema(description = "PC 端分类图")
private String bigPicUrl;
@Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer sort;
@Schema(description = "分类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "描述")
private String description;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "开启状态不能为空")
private Integer status;

@ -5,10 +5,15 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotBlank;
@Schema(description = "管理后台 - 商品分类创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO {
@Schema(description = "分类描述", example = "描述")
private String description;
}

@ -10,4 +10,10 @@ public class ProductCategoryListReqVO {
@Schema(description = "分类名称", example = "办公文具")
private String name;
@Schema(description = "开启状态", example = "0")
private Integer status;
@Schema(description = "父分类编号", example = "1")
private Long parentId;
}

@ -5,6 +5,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 商品分类更新 Request VO")
@ -17,4 +18,7 @@ public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO {
@NotNull(message = "分类编号不能为空")
private Long id;
@Schema(description = "分类描述", example = "描述")
private String description;
}

@ -0,0 +1,62 @@
package cn.iocoder.yudao.module.product.controller.admin.comment;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*;
import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 商品评价")
@RestController
@RequestMapping("/product/comment")
@Validated
public class ProductCommentController {
@Resource
private ProductCommentService productCommentService;
@GetMapping("/page")
@Operation(summary = "获得商品评价分页")
@PreAuthorize("@ss.hasPermission('product:comment:query')")
public CommonResult<PageResult<ProductCommentRespVO>> getCommentPage(@Valid ProductCommentPageReqVO pageVO) {
PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO);
return success(ProductCommentConvert.INSTANCE.convertPage(pageResult));
}
@PutMapping("/update-visible")
@Operation(summary = "显示 / 隐藏评论")
@PreAuthorize("@ss.hasPermission('product:comment:update')")
public CommonResult<Boolean> updateCommentVisible(@Valid @RequestBody ProductCommentUpdateVisibleReqVO updateReqVO) {
productCommentService.updateCommentVisible(updateReqVO);
return success(true);
}
@PutMapping("/reply")
@Operation(summary = "商家回复")
@PreAuthorize("@ss.hasPermission('product:comment:update')")
public CommonResult<Boolean> commentReply(@Valid @RequestBody ProductCommentReplyReqVO replyVO) {
productCommentService.replyComment(replyVO, getLoginUserId());
return success(true);
}
@PutMapping("/create")
@Operation(summary = "添加自评")
@PreAuthorize("@ss.hasPermission('product:comment:update')")
public CommonResult<Boolean> createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) {
productCommentService.createComment(createReqVO);
return success(true);
}
}

@ -0,0 +1,62 @@
package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
@Data
public class ProductCommentBaseVO {
@Schema(description = "评价人", requiredMode = Schema.RequiredMode.REQUIRED, example = "16868")
@NotNull(message = "评价人不能为空")
private Long userId;
@Schema(description = "评价订单项", requiredMode = Schema.RequiredMode.REQUIRED, example = "19292")
@NotNull(message = "评价订单项不能为空")
private Long orderItemId;
@Schema(description = "评价人名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小姑凉")
@NotNull(message = "评价人名称不能为空")
private String userNickname;
@Schema(description = "评价人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
@NotNull(message = "评价人头像不能为空")
private String userAvatar;
// TODO @puhuispuId、spuName 是不是只有 ProductCommentRespVO 有呀。
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotNull(message = "商品 SPU 名称不能为空")
private String spuName;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
@NotNull(message = "评分星级不能为空")
private Integer scores;
@Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
@NotNull(message = "描述星级不能为空")
private Integer descriptionScores;
@Schema(description = "服务星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
@NotNull(message = "服务星级分不能为空")
private Integer benefitScores;
@Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "穿起来非常丝滑凉快")
@NotNull(message = "评论内容不能为空")
private String content;
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
private List<String> picUrls;
}

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 商品评价创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCommentCreateReqVO extends ProductCommentBaseVO {
}

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 商品评价分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCommentPageReqVO extends PageParam {
@Schema(description = "评价人名称", example = "王二狗")
private String userNickname;
@Schema(description = "交易订单编号", example = "24428")
private Long orderId;
@Schema(description = "商品SPU编号", example = "29502")
private Long spuId;
@Schema(description = "商品SPU名称", example = "感冒药")
private String spuName;
@Schema(description = "评分星级 1-5 分", example = "5")
@InEnum(ProductCommentScoresEnum.class)
private Integer scores;
// TODO @puhui999replyStatus 哈
@Schema(description = "商家是否回复", example = "true")
private Boolean replied;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save