diff --git a/_config/sql/iam_perm_menu.sql b/_config/sql/iam_perm_menu.sql index ed1462e00..0f7db0bed 100644 --- a/_config/sql/iam_perm_menu.sql +++ b/_config/sql/iam_perm_menu.sql @@ -12,7 +12,7 @@ Target Server Version : 160009 (160009) File Encoding : 65001 - Date: 27/06/2026 18:30:43 + Date: 01/07/2026 15:07:57 */ @@ -90,27 +90,27 @@ COMMENT ON TABLE "public"."iam_perm_menu" IS '菜单权限配置'; -- ---------------------------- INSERT INTO "public"."iam_perm_menu" VALUES (202, 2, NULL, 'admin', 'FileUploadDemo', '文件上传演示', 'File Upload Demo', 'menu.demos.fileUpload', 'lucide:upload', 'f', 'f', '/demos/file-upload/FileUploadDemo', '/demos/file-upload', NULL, 2, 'f', 't', 'f', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-09 16:00:00+00', '2026-04-09 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (307, 3, 'system:monitor', 'admin', 'SystemMonitor', '系统监控', 'System Monitor', 'menu.system.monitor', 'lucide:monitor', 'f', 'f', NULL, '/system/monitor', NULL, 50, 'f', 't', 'f', 1, 1, 1, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-10 16:00:00+00', '2026-04-12 12:53:45.790453+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (101, 1, 'dashboard:analytics', 'admin', 'Analytics', '分析页', 'Analytics', 'menu.dashboard.analytics', 'lucide:area-chart', 'f', 'f', '/dashboard/analytics/index', '/analytics', NULL, 2, 'f', 'f', 't', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-03-20 03:11:13.134079+00'); INSERT INTO "public"."iam_perm_menu" VALUES (305, 3, 'iam:perm', 'admin', 'SystemPerm', '权限管理', 'Permission Management', 'menu.system.perm', 'lucide:shield', 'f', 'f', NULL, '/system/perm', NULL, 2, 'f', 't', 'f', 1, 1, 1, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-08 16:00:00+00', '2026-04-09 15:10:44.651238+00'); INSERT INTO "public"."iam_perm_menu" VALUES (302, 3, NULL, 'admin', 'SystemLog', '日志管理', 'Log Management', 'menu.system.log', 'lucide:file-text', 'f', 'f', NULL, '/system/log', NULL, 99, 'f', 't', 'f', 0, 1, 1, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-04-05 08:56:11.97756+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (1, NULL, NULL, 'admin', 'Dashboard', '仪表板', 'Dashboard', 'menu.dashboard', 'lucide:layout-dashboard', 'f', 'f', NULL, '/dashboard', '/workspace', -1, 'f', 'f', 'f', 0, NULL, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-03-20 03:11:13.134079+00'); INSERT INTO "public"."iam_perm_menu" VALUES (304, 3, 'system:config', 'admin', 'SystemConfig', '系统配置', 'System Config', 'menu.system.config', 'lucide:settings-2', 'f', 'f', NULL, '/system/config', NULL, 10, 'f', 't', 'f', 0, 1, 1, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-04 16:00:00+00', '2026-04-09 15:11:00.840153+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30701, 307, 'iam:online:user', 'admin', 'OnlineUser', '在线用户', 'Online User', 'menu.system.monitor.online', 'lucide:users', 'f', 'f', '/system/monitor/online/OnlineUserList', '/system/monitor/online', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-11 16:00:00+00', '2026-04-11 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (401, 4, 'payment:platform', 'admin', 'PaymentPlatform', '支付主数据', 'Payment Master Data', 'menu.payment.platform', 'lucide:building', 'f', 'f', NULL, '/payment/platform', NULL, 1, 'f', 't', 'f', 0, 1, 3, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-05 16:00:00+00', '2026-05-28 06:25:42.880461+00'); INSERT INTO "public"."iam_perm_menu" VALUES (203, 2, 'demos:region', 'admin', 'RegionCascaderDemo', '行政区划选择器', 'Region Cascader', 'menu.demos.region', 'lucide:map-pin', 'f', 'f', '/demos/region/RegionCascaderDemo', '/demos/region', NULL, 3, 'f', 't', 'f', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-24 16:00:00+00', '2026-04-24 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (6, NULL, 'trade', 'admin', 'TransactionManagement', '交易管理', 'Transaction Management', 'menu.trade', 'lucide:arrow-left-right', 'f', 'f', NULL, '/trade', '/trade/index', 3.5, 'f', 't', 'f', 1, 1, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-24 16:00:00+00', '2026-05-24 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (3, NULL, NULL, 'admin', 'System', '系统管理', 'System', 'menu.system', 'lucide:sliders-horizontal', 'f', 'f', NULL, '/system', NULL, 0, 'f', 't', 'f', 0, 1, 2, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-06-25 02:00:30.22348+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (102, 1, 'dashboard:workspace', 'admin', 'Workspace', '工作台', 'Workspace', 'menu.dashboard.workspace', 'lucide:panels-top-left', 'f', 'f', '/dashboard/workspace/index', '/workspace', NULL, 1, 'f', 'f', 'f', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-06-25 02:00:30.233427+00'); INSERT INTO "public"."iam_perm_menu" VALUES (301, 3, NULL, 'admin', 'SystemBasic', '基础数据', 'Basic Data', 'menu.system.basic', 'lucide:boxes', 'f', 'f', NULL, '/system/basic', NULL, 1, 'f', 't', 'f', 0, NULL, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-06-25 02:00:30.236321+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30101, 301, 'system:dict', 'admin', 'SystemDict', '字典管理', 'Dictionary', 'menu.system.basic.dict', 'lucide:book-open', 'f', 'f', '/system/basic/dict/DictList', '/system/basic/dict', NULL, 1, 'f', 't', 'f', 0, 1, 2, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-06-25 02:00:30.243488+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (30401, 304, 'system:security_config', 'admin', 'SecurityConfig', '安全配置', 'Security Config', 'menu.system.config.security', 'lucide:shield-check', 'f', 'f', '/system/config/security/SecurityConfig', '/system/config/security', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-05 02:00:00+00', '2026-06-27 13:01:24.303469+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (30402, 304, 'system:platform_config', 'admin', 'PlatformConfig', '平台配置', 'Platform Config', 'menu.system.config.platform', 'lucide:settings', 'f', 'f', '/system/config/platform/PlatformConfig', '/system/config/platform', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-07 16:00:00+00', '2026-06-27 13:01:24.311831+00'); INSERT INTO "public"."iam_perm_menu" VALUES (2, NULL, NULL, 'admin', 'Demos', '演示', 'Demos', 'menu.demos', 'lucide:blocks', 'f', 'f', NULL, '/demos', NULL, 1000, 'f', 't', 'f', 0, NULL, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-06-25 02:00:30.27727+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (1, NULL, NULL, 'admin', 'Dashboard', '仪表板', 'Dashboard', 'menu.dashboard', 'lucide:layout-dashboard', 'f', 'f', NULL, '/dashboard', '/workspace', -1, 'f', 'f', 'f', 0, NULL, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-06-27 13:46:52.151771+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30202, 302, 'system:log:operate', 'admin', 'SystemOperateLog', '操作日志', 'Operate Log', 'menu.system.log.operate', 'lucide:activity', 'f', 'f', '/system/log/operate/OperateLogList', '/system/log/operate', NULL, 2, 'f', 't', 'f', 0, 1, 1, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-03-30 15:24:57.076166+00'); INSERT INTO "public"."iam_perm_menu" VALUES (40401, 404, 'merchant:info', 'admin', 'MerchantInfo', '商户信息', 'Merchant Info', 'menu.merchant.info', 'lucide:shopping-bag', 'f', 'f', '/payment/merchant/info/MerchantList', '/payment/merchant/info', NULL, 1, 'f', 't', 'f', 1, 1, 1, 'f', 'menu', NULL, NULL, NULL, NULL, '', '', '2026-04-13 16:00:00+00', '2026-06-25 02:00:30.290399+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30601, 307, 'system:file:platform', 'admin', 'StorageFile', '存储文件', 'Storage File', 'menu.system.monitor.file', 'lucide:files', 'f', 'f', '/system/monitor/file/PlatformFileList', '/system/monitor/file', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-09 16:00:00+00', '2026-06-25 02:43:43.71511+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4, NULL, 'payment', 'admin', 'PaymentSystem', '平台管理', 'Platform Management', 'menu.platform', 'lucide:credit-card', 'f', 'f', NULL, '/payment', NULL, 3, 'f', 't', 'f', 0, 1, 1, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-05 16:00:00+00', '2026-06-13 00:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30201, 302, 'system:log:login', 'admin', 'SystemLoginLog', '登录日志', 'Login Log', 'menu.system.log.login', 'lucide:log-in', 'f', 'f', '/system/log/login/LoginLogList', '/system/log/login', NULL, 1, 'f', 't', 'f', 0, 1, 1, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-03-20 03:11:13.134079+00', '2026-03-30 15:25:09.855555+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (30401, 304, 'system:securityConfig', 'admin', 'SecurityConfig', '安全配置', 'Security Config', 'menu.system.config.security', 'lucide:shield-check', 'f', 'f', '/system/config/security/SecurityConfig', '/system/config/security', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-05 02:00:00+00', '2026-04-05 02:00:00+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (30402, 304, 'system:platformConfig', 'admin', 'PlatformConfig', '平台配置', 'Platform Config', 'menu.system.config.platform', 'lucide:settings', 'f', 'f', '/system/config/platform/PlatformConfig', '/system/config/platform', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-07 16:00:00+00', '2026-04-07 16:00:00+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (102, 1, 'dashboard:workspace', 'admin', 'Workspace', '工作台', 'Workspace', 'menu.dashboard.workspace', 'lucide:panels-top-left', 'f', 'f', '/dashboard/workspace/index', '/workspace', NULL, 1, 'f', 'f', 't', 0, 1, 1, 'f', 'menu', NULL, NULL, NULL, NULL, '', '', '2026-03-20 03:11:13.134079+00', '2026-06-28 02:50:37.055128+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (101, 1, 'dashboard:analytics', 'admin', 'Analytics', '分析页', 'Analytics', 'menu.dashboard.analytics', 'lucide:area-chart', 'f', 'f', '/dashboard/analytics/index', '/analytics', NULL, 2, 'f', 'f', 'f', 0, 1, 1, 'f', 'menu', NULL, NULL, NULL, NULL, '', '', '2026-03-20 03:11:13.134079+00', '2026-06-28 02:50:43.072618+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30103, 305, 'iam:role', 'admin', 'SystemRole', '角色管理', 'Role Management', 'menu.system.perm.role', 'lucide:shield-user', 'f', 'f', '/iam/perm/role/RoleList', '/iam/perm/role', NULL, 3, 'f', 't', 'f', 0, 1, 2, 'f', 'menu', NULL, NULL, NULL, NULL, '', '', '2026-03-20 03:11:13.134079+00', '2026-06-25 02:00:30.246504+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30501, 305, 'iam:user:manager', 'admin', 'UserList', '用户管理', 'User Management', 'menu.system.perm.user', 'lucide:users-round', 'f', 'f', 'views/iam/user/UserList', '/iam/user', NULL, 10, 'f', 't', 'f', 1, 1, 4, 'f', 'menu', NULL, NULL, NULL, NULL, '', '', '2026-03-31 00:23:04.37507+00', '2026-06-25 02:00:30.279649+00'); INSERT INTO "public"."iam_perm_menu" VALUES (30102, 301, 'iam:perm:menu', 'admin', 'SystemMenu', '菜单管理', 'Menu Management', 'menu.system.perm.menu', 'lucide:panel-top', 'f', 'f', '/iam/perm/menu/MenuList', '/system/basic/menu', NULL, 0, 'f', 't', 'f', 0, 1, 3, 'f', 'menu', NULL, NULL, NULL, NULL, '', '', '2026-03-20 03:11:13.134079+00', '2026-06-27 10:29:51.371435+00'); @@ -119,8 +119,8 @@ INSERT INTO "public"."iam_perm_menu" VALUES (40104, 401, 'payment:platform:capab INSERT INTO "public"."iam_perm_menu" VALUES (4040111, 40401, 'merchant:app:route', 'admin', 'PayRouteConfig', '通道路由', 'Channel Routing', 'menu.payment.merchant.app.payRoute', NULL, 't', 'f', '/payment/merchant/route/PayRouteConfig', '/payment/merchant/route', NULL, 2, 'f', 't', 'f', 1, 1, 1, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-24 22:23:46.483985+00', '2026-05-26 20:03:06.445803+00'); INSERT INTO "public"."iam_perm_menu" VALUES (40102, 401, 'payment:platform:provider', 'admin', 'PayProviderList', '支付方式', 'Payment Method', 'menu.payment.platform.provider', 'lucide:list-tree', 'f', 'f', '/payment/masterdata/provider/PayMethodList', '/payment/platform/pay-method', NULL, 1, 'f', 't', 'f', 1, 1, 5, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-27 20:18:01.383008+00', '2026-05-30 08:21:19.464024+00'); INSERT INTO "public"."iam_perm_menu" VALUES (404, NULL, 'merchant', 'admin', 'PaymentMerchant', '商户管理', 'Merchant Management', 'menu.merchant', 'lucide:store', 'f', 'f', NULL, '/payment/merchant', NULL, 4, 't', 't', 'f', 0, NULL, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-05 16:00:00+00', '2026-06-13 00:00:00+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (40103, 401, 'payment:platform:pay_channel', 'admin', 'PayChannelList', '支付通道', 'Payment Channel', 'menu.payment.platform.channel', 'lucide:radio-tower', 'f', 'f', '/payment/masterdata/channel/PayChannelList', '/payment/platform/pay-channel', NULL, 0, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-28 16:00:00+00', '2026-06-27 13:01:24.315365+00'); INSERT INTO "public"."iam_perm_menu" VALUES (40101, 401, 'payment:platform:product', 'admin', 'ProductList', '支付产品', 'Payment Product', 'menu.payment.platform.product', 'lucide:package', 'f', 'f', '/payment/masterdata/product/PayProductList', '/payment/platform/product', NULL, 2, 'f', 't', 'f', 1, 1, 3, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-23 16:00:00+00', '2026-05-28 06:25:42.892396+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (40103, 401, 'payment:platform:payChannel', 'admin', 'PayChannelList', '支付通道', 'Payment Channel', 'menu.payment.platform.channel', 'lucide:radio-tower', 'f', 'f', '/payment/masterdata/channel/PayChannelList', '/payment/platform/pay-channel', NULL, 0, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-28 16:00:00+00', '2026-05-28 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040101, 40401, 'merchant:workbench', 'admin', 'MerchantManage', '商户管理', 'Merchant Management', 'menu.payment.merchant.manage', '', 't', 'f', '/payment/merchant/manage/workbench/MerchantManage', '/payment/merchant/manage', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-04-13 16:00:00+00', '2026-05-02 06:57:49.052168+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040102, 40401, 'merchant:credential', 'admin', 'MerchantCredentialConfig', '对接配置', 'Credential Config', 'menu.payment.merchant.manage.credentialConfig', NULL, 't', 'f', '/payment/merchant/manage/credential/MerchantCredentialConfig', '/payment/merchant/manage/credential', NULL, 3, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-01 16:00:00+00', '2026-05-01 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040108, 40401, 'merchant:user', 'admin', 'MerchantUser', '商户用户', 'Merchant User', 'menu.payment.merchant.user', '', 't', 'f', '/payment/merchant/user/MerchantUserList', '/payment/merchant/user', NULL, 8, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-04 16:00:00+00', '2026-05-04 16:00:00+00'); @@ -130,28 +130,30 @@ INSERT INTO "public"."iam_perm_menu" VALUES (4040109, 40401, 'channel:merchant:c INSERT INTO "public"."iam_perm_menu" VALUES (4040114, 40401, 'channel:alipay:app', 'admin', 'AlipayMchAppManage', '支付宝通道商户应用', 'Alipay Channel Merchant App', 'menu.payment.merchant.channelMerchant.alipayApp', NULL, 't', 'f', '/payment/channel/alipay/manage/mch/app/AlipayMchAppManage', '/payment/merchant/channel-merchant/alipay-app-manage', NULL, 12, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-11 22:28:11.274785+00', '2026-06-11 22:28:11.274785+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040113, 40401, 'channel:wechat:app', 'admin', 'WechatMchAppManage', '微信通道商户应用', 'WeChat Channel Merchant App', 'menu.payment.merchant.channelMerchant.wechatApp', NULL, 't', 'f', '/payment/channel/wechat/manage/mch/app/WechatMchAppManage', '/payment/merchant/channel-merchant/wechat-app-manage', NULL, 11, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-07 23:57:13.620205+00', '2026-06-07 23:57:13.620205+00'); INSERT INTO "public"."iam_perm_menu" VALUES (405, 4, 'payment:config', 'admin', 'PaymentConfig', '支付配置', 'Payment Config', 'menu.payment.config', 'lucide:settings-2', 'f', 'f', NULL, '/payment/config', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-14 00:00:00+00', '2026-06-14 00:00:00+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (40105, 405, 'payment:config:productConfig', 'admin', 'ProductConfig', '支付产品管理', 'Payment Product Management', 'menu.payment.config.productConfig', 'lucide:layout-grid', 'f', 'f', '/payment/config/product/ProductConfig', '/payment/config/product', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-13 00:00:00+00', '2026-06-13 09:14:10.179605+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (90201, 9, 'device:vendor_config', 'admin', 'VendorManage', '设备厂商管理', 'Device Vendor Management', 'menu.device.vendor', 'lucide:building-2', 'f', 'f', '/payment/device/vendor/VendorManage', '/device/vendor', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.646017+00', '2026-06-27 13:01:24.320315+00'); INSERT INTO "public"."iam_perm_menu" VALUES (40502, 40105, 'payment:alipay:isv', 'admin', 'AlipayIsvAppManage', '支付宝服务商应用', 'Alipay ISV Application', 'menu.payment.alipay.isvApp', NULL, 't', 'f', '/payment/channel/alipay/manage/app/AlipayIsvAppManage', '/payment/config/product/app-manage', NULL, 3, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-14 00:00:00+00', '2026-06-14 00:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (90202, 9, 'device:speaker', 'admin', 'DeviceSpeakerList', '云音箱管理', 'Speaker Management', 'menu.device.speaker', 'lucide:speaker', 'f', 'f', '/payment/device/speaker/DeviceSpeakerList', '/device/speaker', NULL, 3, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.647632+00', '2026-06-25 12:51:25.245363+00'); INSERT INTO "public"."iam_perm_menu" VALUES (8, NULL, 'develop', 'admin', 'Develop', '开发调试', 'Develop', 'menu.develop', 'lucide:wrench', 'f', 'f', NULL, '/develop', NULL, 5, 'f', 't', 'f', 1, 1, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-23 16:00:00+00', '2026-06-23 16:00:00+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (309, 3, 'system:notify', 'admin', 'SystemNotify', '公告通知', 'Notification', 'menu.system.notify', 'lucide:bell', 'f', 'f', '/system/notify/notice/NoticeList', '/system/notify', NULL, 20, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, '2026-06-24 16:00:00+00', '2026-06-24 16:00:00+00', NULL); +INSERT INTO "public"."iam_perm_menu" VALUES (308, 3, 'system:notify', 'admin', 'SystemNotice', '通知中心', 'Notification Center', 'menu.system.notify', 'lucide:bell', 'f', 'f', NULL, '/system/notify', '/system/notify/notice', 20, 'f', 't', 'f', 1, 1, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-07-01 16:00:00+00', '2026-07-01 16:00:00+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (309, 308, 'system:notify:notice', 'admin', 'SystemNotify', '公告通知', 'Notification', 'menu.system.notify.notice', 'lucide:megaphone', 'f', 'f', '/system/notify/notice/NoticeList', '/system/notify/notice', NULL, 20, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-07-01 16:00:00+00', '2026-07-01 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (901, 9, 'device:qrcode', 'admin', 'DeviceQrCode', '码牌管理', 'QR Code Management', 'menu.device.qrcode', 'lucide:qr-code', 't', 'f', '/_core/fallback/coming-soon', '/device/qrcode', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.634639+00', '2026-06-25 12:51:25.24304+00'); INSERT INTO "public"."iam_perm_menu" VALUES (204, 2, 'demos:artemis', 'admin', 'ArtemisDemo', '消息队列演示', 'Message Queue Demo', 'menu.demos.artemis', 'lucide:send', 'f', 'f', '/demos/artemis/ArtemisDemo', '/demos/artemis', NULL, 4, 'f', 't', 'f', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-18 00:00:00+00', '2026-06-18 00:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (900001, 304, 'iam:social:config', 'admin', 'SocialConfig', '三方平台登录', 'Third-party Platform Login', 'menu.system.config.social', 'lucide:share-2', 'f', 'f', 'views/iam/social/social-config', '/system/config/social', NULL, 5, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); INSERT INTO "public"."iam_perm_menu" VALUES (30403, 304, 'system:protocol', 'admin', 'UserProtocol', '用户协议', 'User Protocol', 'menu.system.config.protocol', 'lucide:file-text', 'f', 'f', '/system/protocol/UserProtocolList', '/system/config/protocol', NULL, 10, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-24 10:32:13.183371+00', '2026-06-24 10:32:13.183371+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040106, 40401, 'channel:merchant', 'admin', 'ChannelMerchant', '通道商户', 'Channel Merchant', 'menu.payment.merchant.channelMerchant', NULL, 't', 'f', '/payment/merchant/channel-merchant/ChannelMerchantList', '/payment/merchant/channel-merchant', NULL, 6, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-03 16:00:00+00', '2026-05-03 16:00:00+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (4040116, 401, 'payment:platform:provider:manage', 'admin', 'PayProviderManage', '支付渠道', 'Payment Provider', 'menu.payment.platform.provider.manage', 'lucide:wallet', 'f', 'f', '/payment/masterdata/provider/PayProviderList', '/payment/platform/pay-provider', NULL, 0.5, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-17 10:00:31.640482+00', '2026-06-25 01:21:34.621269+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (40501, 40105, 'payment:config:productDetail', 'admin', 'ProductDetailDispatch', '支付产品详情', 'Payment Product Detail', 'menu.payment.config.productDetail', NULL, 't', 'f', '/payment/config/product/detail/ProductDetailDispatch', '/payment/product-detail', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-14 00:00:00+00', '2026-06-14 00:00:00+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (40501, 40105, 'payment:config:product_detail', 'admin', 'ProductDetailDispatch', '支付产品详情', 'Payment Product Detail', 'menu.payment.config.productDetail', NULL, 't', 'f', '/payment/config/product/detail/ProductDetailDispatch', '/payment/product-detail', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-14 00:00:00+00', '2026-06-27 13:01:24.321883+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (4040103, 40401, 'merchant:mchInfo', 'admin', 'MchInfoManage', '商户信息', 'Merchant Basic Info', 'menu.payment.merchant.manage.mchInfo', NULL, 't', 'f', '/payment/merchant/manage/info/MchInfoManage', '/payment/merchant/manage/info', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); INSERT INTO "public"."iam_perm_menu" VALUES (801, 8, 'develop:trade', 'admin', 'DevelopTrade', '支付调试', 'Payment Develop', 'menu.develop.trade', 'lucide:credit-card', 'f', 'f', '/payment/develop/trade/DevelopTrade', '/develop/trade', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-23 16:00:00+00', '2026-06-23 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (802, 8, 'develop:sign', 'admin', 'DevelopSign', '签名调试', 'Sign Develop', 'menu.develop.sign', 'lucide:file-signature', 'f', 'f', '/payment/develop/sign/DevelopSign', '/develop/sign', NULL, 2, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-23 16:00:00+00', '2026-06-23 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040117, 40401, 'merchant:store', 'admin', 'MchStoreInfoList', '门店管理', 'Store Management', 'menu.payment.merchant.store', NULL, 't', 'f', '/payment/merchant/store/MchStoreInfoList', '/payment/merchant/store', NULL, 15, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-24 16:00:00+00', '2026-06-24 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (40503, 40105, 'payment:wechat:isv', 'admin', 'WechatIsvAppManage', '微信服务商应用', 'WeChat ISV Application', 'menu.payment.wechat.isvApp', NULL, 't', 'f', '/payment/channel/wechat/manage/app/WechatIsvAppManage', '/payment/config/product/wechat-app-manage', NULL, 4, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-14 00:00:00+00', '2026-06-14 00:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (4040115, 40401, 'channel:douyin:app', 'admin', 'DouyinMchAppManage', '抖音通道商户应用', 'Douyin Channel Merchant App', 'menu.payment.merchant.channelMerchant.douyinApp', NULL, 't', 'f', '/payment/channel/douyin/manage/app/DouyinMchAppManage', '/payment/merchant/channel-merchant/douyin-app-manage', NULL, 13, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-15 16:00:00+00', '2026-06-15 16:00:00+00'); INSERT INTO "public"."iam_perm_menu" VALUES (904, 9, 'device:assistant', 'admin', 'DeviceAssistant', '辅助支付终端', 'Payment Assistant Terminal', 'menu.device.assistant', 'lucide:monitor-smartphone', 'f', 'f', '/_core/fallback/coming-soon', '/device/assistant', NULL, 5, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 12:51:25.252086+00', '2026-06-25 12:51:25.252086+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (90201, 9, 'device:vendorConfig', 'admin', 'VendorManage', '设备厂商管理', 'Device Vendor Management', 'menu.device.vendor', 'lucide:building-2', 'f', 'f', '/payment/device/vendor/VendorManage', '/device/vendor', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.646017+00', '2026-06-25 12:51:25.240464+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (30404, 304, 'system:oss_config', 'admin', 'OssConfig', 'OSS配置', 'OSS Config', 'menu.system.config.oss', 'lucide:hard-drive', 't', 'f', '/system/config/oss/OssConfig', '/system/config/oss', NULL, 3, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-27 13:01:24.313531+00'); INSERT INTO "public"."iam_perm_menu" VALUES (9, NULL, 'device', 'admin', 'DeviceManagement', '设备管理', 'Device Management', 'menu.device', 'lucide:monitor-speaker', 'f', 'f', NULL, '/device', NULL, 4.2, 'f', 't', 'f', 1, 1, 1, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.631155+00', '2026-06-25 12:51:25.231569+00'); INSERT INTO "public"."iam_perm_menu" VALUES (90302, 9, 'device:printer', 'admin', 'DevicePrinterList', '云打印', 'Cloud Printer', 'menu.device.printer', 'lucide:printer', 'f', 'f', '/payment/device/printer/DevicePrinterList', '/device/printer', NULL, 3, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.651889+00', '2026-06-26 02:06:38.060486+00'); -INSERT INTO "public"."iam_perm_menu" VALUES (30404, 304, 'system:ossConfig', 'admin', 'OssConfig', 'OSS配置', 'OSS Config', 'menu.system.config.oss', 'lucide:hard-drive', 't', 'f', '/system/config/oss/OssConfig', '/system/config/oss', NULL, 3, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +INSERT INTO "public"."iam_perm_menu" VALUES (40105, 405, 'payment:config:product_config', 'admin', 'ProductConfig', '支付产品管理', 'Payment Product Management', 'menu.payment.config.productConfig', 'lucide:layout-grid', 'f', 'f', '/payment/config/product/ProductConfig', '/payment/config/product', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-13 00:00:00+00', '2026-06-27 13:01:24.317032+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (4040116, 401, 'payment:platform:provider_manage', 'admin', 'PayProviderManage', '支付渠道', 'Payment Provider', 'menu.payment.platform.provider.manage', 'lucide:wallet', 'f', 'f', '/payment/masterdata/provider/PayProviderList', '/payment/platform/pay-provider', NULL, 0.5, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-17 10:00:31.640482+00', '2026-06-27 13:01:24.318649+00'); -- ---------------------------- -- Primary Key structure for table iam_perm_menu diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/AlipayChannelClient.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/AlipayChannelClient.java index b1ba42a23..3274a2e6c 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/AlipayChannelClient.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/AlipayChannelClient.java @@ -1,7 +1,7 @@ package cn.daxpay.open.channel.alipay.client; -import cn.daxpay.open.channel.alipay.dto.AlipayPayReq; -import cn.daxpay.open.channel.alipay.dto.AlipayPayResp; +import cn.daxpay.open.channel.alipay.client.req.AlipayPayReq; +import cn.daxpay.open.channel.alipay.client.resp.AlipayPayResp; import cn.daxpay.open.payment.common.result.DaxResult; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/credential/AlipaySdkCredential.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/credential/AlipaySdkCredential.java new file mode 100644 index 000000000..a414867a6 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/credential/AlipaySdkCredential.java @@ -0,0 +1,33 @@ +package cn.daxpay.open.channel.alipay.client.credential; + +import lombok.Data; + +/// # 支付宝 SDK 凭证 +/// +/// 与子应用 dax-pay-channel-one 的 `AlipaySdkCredential` 镜像, 跨 HTTP 传输时字段对齐。 +/// 主应用从进件实体提取 appId / 私钥 / 证书后组装, 下发给子应用构建 AlipayClient。 +@Data +public class AlipaySdkCredential { + /// 支付宝应用ID + private String aliAppId; + /// 应用私钥 + private String privateKey; + /// 支付宝公钥(公钥模式使用) + private String alipayPublicKey; + /// 应用公钥证书内容(证书模式使用) + private String appCert; + /// 支付宝公钥证书内容(证书模式使用) + private String alipayCert; + /// 支付宝根证书内容(证书模式使用) + private String alipayRootCert; + /// 网关地址(为空时按沙箱标志自动选择) + private String serverUrl; + /// 签名类型(默认 RSA2) + private String signType; + /// 鉴权方式(publickey 公钥模式 / cert 证书模式) + private String authType; + /// 是否沙箱环境 + private Boolean sandbox; + /// 应用授权令牌(服务商代商户调用时使用) + private String appAuthToken; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/enums/AlipayPayBodyType.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/enums/AlipayPayBodyType.java new file mode 100644 index 000000000..4c9b8f3f3 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/enums/AlipayPayBodyType.java @@ -0,0 +1,15 @@ +package cn.daxpay.open.channel.alipay.client.enums; + +/// # 支付内容类型 +/// +/// 与子应用 dax-pay-channel-one 的 `AlipayPayBodyType` 镜像, 跨 HTTP 传输时按枚举名(name)序列化对齐。 +public enum AlipayPayBodyType { + /// 跳转链接(wap / pc 场景, 前端可直接 location.href) + LINK, + /// 二维码内容(qr 扫码场景) + QR_CODE, + /// APP 订单串(app 场景) + ORDER_STR, + /// 标识符(jsapi 场景, 支付宝交易号 tradeNo) + IDENTIFIER; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/enums/AlipayPayMethod.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/enums/AlipayPayMethod.java new file mode 100644 index 000000000..e43bc430b --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/enums/AlipayPayMethod.java @@ -0,0 +1,19 @@ +package cn.daxpay.open.channel.alipay.client.enums; + +/// # 支付宝支付方式 +/// +/// 与子应用 dax-pay-channel-one 的 `AlipayPayMethod` 镜像, 跨 HTTP 传输时按枚举名(name)序列化对齐。 +public enum AlipayPayMethod { + /// 手机网站支付(QUICK_WAP_WAY) + WAP, + /// APP 支付(QUICK_MSECURITY_PAY) + APP, + /// 电脑网站支付(FAST_INSTANT_TRADE_PAY) + PC, + /// 扫码预下单(precreate) + QR, + /// 付款码支付(当面付 bar_code 场景, 同步扣款) + BARCODE, + /// 小程序/JSAPI 支付(JSAPI_PAY, alipay.trade.create) + JSAPI; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/req/AlipayPayReq.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/req/AlipayPayReq.java new file mode 100644 index 000000000..d946613f9 --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/req/AlipayPayReq.java @@ -0,0 +1,34 @@ +package cn.daxpay.open.channel.alipay.client.req; + +import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; +import cn.daxpay.open.channel.alipay.client.enums.AlipayPayMethod; +import lombok.Data; + +import java.time.OffsetDateTime; + +/// # 支付宝通道支付请求 +/// +/// 与子应用 dax-pay-channel-one 的 `AlipayPayReq` 镜像, 经声明式 HTTP 客户端 [cn.daxpay.open.channel.alipay.client.AlipayChannelClient] 序列化传输, 字段对齐。 +@Data +public class AlipayPayReq { + /// 商户订单号(主应用支付交易号, 作为支付宝 out_trade_no) + private String outTradeNo; + /// 订单金额(单位: 分) + private Long amount; + /// 订单标题 + private String subject; + /// 订单描述(对应支付宝 body) + private String body; + /// 支付方式 + private AlipayPayMethod method; + /// 订单过期时间 + private OffsetDateTime expireTime; + /// 异步通知地址 + private String notifyUrl; + /// 付款码(BARCODE 付款码支付必填) + private String authCode; + /// 买家标识(JSAPI 小程序支付必填; 2088 开头为支付宝用户ID, 否则视为小程序 openid) + private String openId; + /// 通道调用凭证 + private AlipaySdkCredential credential; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/resp/AlipayPayResp.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/resp/AlipayPayResp.java new file mode 100644 index 000000000..b2cd2cf4e --- /dev/null +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/client/resp/AlipayPayResp.java @@ -0,0 +1,29 @@ +package cn.daxpay.open.channel.alipay.client.resp; + +import cn.daxpay.open.channel.alipay.client.enums.AlipayPayBodyType; +import lombok.Data; + +import java.time.OffsetDateTime; + +/// # 支付宝通道支付响应 +/// +/// 与子应用 dax-pay-channel-one 的 `AlipayPayResp` 镜像, 字段对齐。 +@Data +public class AlipayPayResp { + /// 商户订单号(透传 Req.outTradeNo) + private String outTradeNo; + /// 支付宝交易号(trade_no) + private String tradeNo; + /// 支付内容 + private String payBody; + /// 支付内容类型 + private AlipayPayBodyType payBodyType; + /// 是否已终态完成(BARCODE 付款码可能同步成功) + private Boolean complete; + /// 完成时间 + private OffsetDateTime finishTime; + /// 实付金额(单位: 分, BARCODE 同步成功时返回) + private Long realAmount; + /// 买家标识(BARCODE 同步成功时返回买家 openid) + private String buyerId; +} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/dto/AlipayPayReq.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/dto/AlipayPayReq.java deleted file mode 100644 index a9e46bab6..000000000 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/dto/AlipayPayReq.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.daxpay.open.channel.alipay.dto; - -import lombok.Data; - -import java.util.Map; - -/// # 支付宝通道支付请求 -/// -/// 与子应用 ChannelPayReq 字段一致, 通过 Jackson 序列化传输 -@Data -public class AlipayPayReq { - private String channel; - private String bizOrderNo; - private Long amount; - private String subject; - private String description; - private String method; - private String expireTime; - private String otherMethod; - private Map config; -} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/dto/AlipayPayResp.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/dto/AlipayPayResp.java deleted file mode 100644 index 1db0fa187..000000000 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/dto/AlipayPayResp.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.daxpay.open.channel.alipay.dto; - -import lombok.Data; - -/// # 支付宝通道支付响应 -/// -/// 与子应用 ChannelPayResp 字段一致 -@Data -public class AlipayPayResp { - private String bizOrderNo; - private String outOrderNo; - private String transOrderNo; - private String payBody; - private String payBodyType; - private Boolean complete; - private String finishTime; -} diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/direct/AlipayDirectConfigAssembler.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/direct/AlipayDirectConfigAssembler.java index 0933916b9..8fe1106e2 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/direct/AlipayDirectConfigAssembler.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/direct/AlipayDirectConfigAssembler.java @@ -1,25 +1,27 @@ package cn.daxpay.open.channel.alipay.service.direct; import cn.daxpay.open.channel.alipay.dao.direct.AlipayDirectAppManager; +import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.entity.direct.AlipayDirectApp; import cn.daxpay.open.channel.alipay.entity.direct.AlipayDirectAppKeyConfig; +import cn.daxpay.open.payment.masterdata.constants.product.dao.PayProductConfigManager; +import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum; +import cn.daxpay.open.platform.core.enums.pay.config.PayEnvEnum; import cn.daxpay.open.platform.core.exception.DataNotExistException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; -/// # 支付宝直连通道配置组装器 +/// # 支付宝直连通道凭证组装器 /// /// 从进件商户对象([AlipayDirectApp] + [AlipayDirectAppKeyConfig])读取密钥/证书, -/// 并补充主应用回调地址(notifyUrl)与沙箱标志(sandbox), 组装为下发给子应用的 config Map。 +/// 组装为下发给子应用的通道调用凭证 [AlipaySdkCredential]。 /// /// 应用解析优先级:能力关联(显式配置 > appType自动推导) > 通道商户首个应用 > 商户号首个应用(兜底)。 /// -/// 供支付策略([cn.daxpay.open.channel.alipay.strategy.direct.AlipayDirectPayStrategy])组装通道调用配置。 +/// 供支付策略([cn.daxpay.open.channel.alipay.strategy.direct.AlipayDirectPayStrategy])组装通道调用凭证。 @Slf4j @Service @RequiredArgsConstructor @@ -28,27 +30,33 @@ public class AlipayDirectConfigAssembler { private final AlipayDirectAppManager alipayDirectAppManager; private final AlipayDirectAppKeyConfigService alipayDirectAppKeyConfigService; private final AlipayDirectAppCapabilityService alipayDirectAppCapabilityService; + private final PayProductConfigManager payProductConfigManager; - /// 组装直连商户的通道调用配置(下发给子应用) + /// 组装直连商户的通道调用凭证(下发给子应用) /// /// @param mchNo 商户号(最终兜底定位应用) /// @param channelMchNo 通道商户号(路由回填) /// @param capability 支付能力编码(路由回填,用于选择匹配的应用) - /// @return 通道配置 Map, 字段对齐子应用 `AlipayConfigDto` - public Map buildConfig(String mchNo, String channelMchNo, String capability) { + /// @return 支付宝 SDK 凭证, 字段对齐子应用 AlipaySdkCredential + public AlipaySdkCredential buildConfig(String mchNo, String channelMchNo, String capability) { AlipayDirectApp app = resolveApp(mchNo, channelMchNo, capability); AlipayDirectAppKeyConfig keyConfig = alipayDirectAppKeyConfigService.findByAlipayDirectAppId(app.getId()); - Map config = new HashMap<>(); - config.put("aliAppId", app.getAliAppId()); - config.put("privateKey", keyConfig.getPrivateKey()); - config.put("alipayPublicKey", keyConfig.getAlipayPublicKey()); - config.put("authType", keyConfig.getAuthType()); - config.put("appCert", keyConfig.getAppCert()); - config.put("alipayCert", keyConfig.getAlipayCert()); - config.put("alipayRootCert", keyConfig.getAlipayRootCert()); - // TODO notifyUrl/sandbox 后续按业务要求手动组装(来源已迁移至进件配置, 待确认组装方式) - return config; + AlipaySdkCredential credential = new AlipaySdkCredential(); + credential.setAliAppId(app.getAliAppId()); + credential.setPrivateKey(keyConfig.getPrivateKey()); + credential.setAlipayPublicKey(keyConfig.getAlipayPublicKey()); + credential.setAuthType(keyConfig.getAuthType()); + credential.setAppCert(keyConfig.getAppCert()); + credential.setAlipayCert(keyConfig.getAlipayCert()); + credential.setAlipayRootCert(keyConfig.getAlipayRootCert()); + // 读取支付产品当前生效环境, 判断是否沙箱 + boolean sandbox = payProductConfigManager.findByProduct(ProductEnum.ALIPAY.getCode()) + .map(c -> PayEnvEnum.SANDBOX.getCode().equals(c.getActiveEnv())) + .orElse(false); + credential.setSandbox(sandbox); + // TODO notifyUrl 后续按业务要求手动组装(来源已迁移至进件配置, 待确认组装方式) + return credential; } /// 解析支付使用的应用,优先级:能力关联 > 通道商户首个 > 商户号首个兜底 diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/pay/AlipayPayService.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/pay/AlipayPayService.java index 7a8adc994..e3b35bcac 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/pay/AlipayPayService.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/pay/AlipayPayService.java @@ -1,22 +1,22 @@ package cn.daxpay.open.channel.alipay.service.pay; import cn.daxpay.open.channel.alipay.client.AlipayChannelClient; -import cn.daxpay.open.channel.alipay.dto.AlipayPayReq; -import cn.daxpay.open.channel.alipay.dto.AlipayPayResp; +import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; +import cn.daxpay.open.channel.alipay.client.enums.AlipayPayBodyType; +import cn.daxpay.open.channel.alipay.client.enums.AlipayPayMethod; +import cn.daxpay.open.channel.alipay.client.req.AlipayPayReq; +import cn.daxpay.open.channel.alipay.client.resp.AlipayPayResp; import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; import cn.daxpay.open.payment.pay.order.entity.PayTrade; import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; import cn.daxpay.open.platform.core.enums.pay.channel.PayMethodEnum; import cn.daxpay.open.platform.core.enums.unipay.PayBodyTypeEnum; +import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Map; - /// # 支付宝支付执行业务服务 /// /// 通过 [AlipayChannelClient] 调用子应用 dax-pay-channel-one 完成支付宝支付下单。 @@ -30,22 +30,24 @@ public class AlipayPayService { /// 执行支付宝支付 /// - /// @param order 支付订单 - /// @param payParam 支付参数 - /// @param config 通道调用配置(密钥/证书/回调地址等) + /// @param order 支付订单 + /// @param payParam 支付参数 + /// @param credential 通道调用凭证(密钥/证书) /// @return 支付结果 - public PayTradeResultBo pay(PayTrade order, NormalPayParam payParam, Map config) { + public PayTradeResultBo pay(PayTrade order, NormalPayParam payParam, AlipaySdkCredential credential) { // 构建请求 AlipayPayReq req = new AlipayPayReq(); - req.setChannel("alipay"); // 使用支付交易号作为商户订单号透传给支付宝, 回调时凭此反查 PayTrade - req.setBizOrderNo(order.getTradeNo()); + req.setOutTradeNo(order.getTradeNo()); req.setAmount(payParam.getAmount()); req.setSubject(payParam.getTitle()); - req.setDescription(payParam.getDescription()); - // 将平台支付方式(PayMethodEnum code)映射为支付宝通道识别码 + req.setBody(payParam.getDescription()); + // 将平台支付方式(PayMethodEnum code)映射为支付宝通道支付方式 req.setMethod(mapMethod(payParam.getMethod())); - req.setConfig(config); + // 付款码(BARCODE) / 买家标识(JSAPI) 通道专属参数透传 + req.setAuthCode(payParam.getAuthCode()); + req.setOpenId(payParam.getOpenId()); + req.setCredential(credential); // 调用子应用 DaxResult result = alipayChannelClient.pay(req); @@ -56,14 +58,16 @@ public class AlipayPayService { return toPayResult(result.getData()); } - /// 平台支付方式([PayMethodEnum] code) -> 支付宝通道识别码 - private static String mapMethod(String methodCode) { + /// 平台支付方式([PayMethodEnum] code) -> 支付宝通道支付方式 + private static AlipayPayMethod mapMethod(String methodCode) { PayMethodEnum m = PayMethodEnum.findByCode(methodCode); return switch (m) { - case ALIPAY_PC -> "alipay_page"; - case ALIPAY_H5 -> "alipay_wap"; - case ALIPAY_APP -> "alipay_app"; - case ALIPAY_QR, ALIPAY_ORDER_QR -> "alipay_qr"; + case ALIPAY_PC -> AlipayPayMethod.PC; + case ALIPAY_H5 -> AlipayPayMethod.WAP; + case ALIPAY_APP -> AlipayPayMethod.APP; + case ALIPAY_QR, ALIPAY_ORDER_QR -> AlipayPayMethod.QR; + case ALIPAY_BARCODE -> AlipayPayMethod.BARCODE; + case ALIPAY_JSAPI, ALIPAY_MINI -> AlipayPayMethod.JSAPI; default -> throw new UnsupportedOperationException( "暂不支持的支付宝支付方式: " + methodCode); }; @@ -72,26 +76,31 @@ public class AlipayPayService { /// 解析子应用响应为支付结果 BO private PayTradeResultBo toPayResult(AlipayPayResp resp) { PayTradeResultBo bo = new PayTradeResultBo() - .setOutOrderNo(resp.getOutOrderNo()) + .setOutOrderNo(resp.getTradeNo()) .setComplete(Boolean.TRUE.equals(resp.getComplete())) - .setPayBody(resp.getPayBody()) - .setTransOrderNo(resp.getTransOrderNo()); + .setPayBody(resp.getPayBody()); - // 支付参数体类型 - String payBodyType = resp.getPayBodyType(); - if (payBodyType != null) { - for (PayBodyTypeEnum type : PayBodyTypeEnum.values()) { - if (type.getCode().equals(payBodyType)) { - bo.setPayBodyType(type); - break; - } + // 支付内容类型映射(子应用 AlipayPayBodyType -> 平台 PayBodyTypeEnum) + AlipayPayBodyType bodyType = resp.getPayBodyType(); + if (bodyType != null) { + switch (bodyType) { + case LINK -> bo.setPayBodyType(PayBodyTypeEnum.LINK); + case QR_CODE -> bo.setPayBodyType(PayBodyTypeEnum.QR_CODE); + case ORDER_STR, IDENTIFIER -> bo.setPayBodyType(PayBodyTypeEnum.IDENTIFIER); } } // 完成时间 - String finishTime = resp.getFinishTime(); - if (finishTime != null && !finishTime.isBlank()) { - bo.setFinishTime(OffsetDateTime.parse(finishTime, DateTimeFormatter.ISO_DATE_TIME)); + if (resp.getFinishTime() != null) { + bo.setFinishTime(resp.getFinishTime()); + } + // 实付金额(BARCODE 付款码同步成功时返回) + if (resp.getRealAmount() != null) { + bo.setRealAmount(resp.getRealAmount()); + } + // 买家标识(BARCODE 付款码同步成功时返回) + if (StrUtil.isNotBlank(resp.getBuyerId())) { + bo.setBuyerId(resp.getBuyerId()); } return bo; diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/result/develop/DevelopPayResult.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/result/develop/DevelopPayResult.java index 81bb85d97..9f73b8b1f 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/result/develop/DevelopPayResult.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/result/develop/DevelopPayResult.java @@ -11,15 +11,11 @@ import lombok.experimental.Accessors; @Schema(title = "支付调试结果") public class DevelopPayResult { - /// 发送的请求体 JSON - @Schema(description = "请求体JSON") - private String requestBody; - - /// 签名信息(传入私钥时返回) - @Schema(description = "签名信息") - private DevelopSignResult signInfo; - /// 支付结果 @Schema(description = "支付结果") private NormalPayResult payResult; + + /// 响应签名(平台私钥签名, 可用于验证响应完整性) + @Schema(description = "响应签名") + private String sign; } diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/service/develop/DevelopTradeService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/service/develop/DevelopTradeService.java index 526d7e720..3651ca5d1 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/service/develop/DevelopTradeService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/service/develop/DevelopTradeService.java @@ -3,6 +3,7 @@ package cn.daxpay.open.payment.admin.service.develop; import cn.daxpay.open.payment.admin.param.develop.DevelopParam; import cn.daxpay.open.payment.admin.result.develop.DevelopPayResult; import cn.daxpay.open.payment.admin.result.develop.DevelopSignResult; +import cn.daxpay.open.payment.common.context.PaymentAssistService; import cn.daxpay.open.payment.common.context.PaymentContextManager; import cn.daxpay.open.payment.common.util.ObjectSignStrUtil; import cn.daxpay.open.payment.common.util.PaySignUtil; @@ -12,7 +13,9 @@ import cn.daxpay.open.payment.merchant.service.route.support.PayRouteStrategyCap import cn.daxpay.open.payment.pay.service.NormalPayService; import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPayResult; -import cn.daxpay.open.platform.common.json.util.JsonUtil; +import cn.daxpay.open.platform.common.config.properties.PlatformConfigProperties; +import cn.daxpay.open.platform.core.code.CommonErrorCode; +import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.daxpay.open.platform.core.rest.dto.LabelValue; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; @@ -32,6 +35,8 @@ public class DevelopTradeService { private final NormalPayService normalPayService; private final PaymentContextManager paymentContextManager; + private final PaymentAssistService paymentAssistService; + private final PlatformConfigProperties platformConfigProperties; private final PayProviderMethodService payProviderMethodService; private final PayRouteStrategyCapabilitySupport payRouteStrategyCapabilitySupport; @@ -45,24 +50,35 @@ public class DevelopTradeService { } /// 支付调试(真实发起) + /// + /// 安全流程与正式支付一致: + /// 1. 使用传入的商户私钥对参数签名, 再用系统配置的商户公钥验签, 校验私钥是否正确 + /// 2. 发起真实支付 + /// 3. 使用平台私钥对支付结果签名, 便于客户端验证响应完整性 public DevelopPayResult pay(DevelopParam param) { NormalPayParam payParam = param.getParam(); - // 记录发送的请求体 - String requestBody = JsonUtil.toJsonStr(payParam); - // 签名信息(传入私钥时生成, 便于核对) - DevelopSignResult signInfo = null; - if (StrUtil.isNotBlank(param.getPrivateKey())) { - signInfo = this.sign(param); + // 私钥必填 + if (StrUtil.isBlank(param.getPrivateKey())) { + throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "pay.error.assist.privateKeyEmpty"); } // 在支付作用域内执行, 初始化商户上下文, 使 mchNo/appId 等字段自动填充 - NormalPayResult payResult = paymentContextManager.executeWithScope( + return paymentContextManager.executeWithScope( payParam.getMchNo(), payParam.getAppId(), - () -> normalPayService.pay(payParam) + () -> { + // 私钥验证: 用传入私钥签名, 再用系统配置的商户公钥验签 + String sign = PaySignUtil.sign(payParam, param.getPrivateKey()); + payParam.setSign(sign); + paymentAssistService.signVerify(payParam); + // 发起真实支付 + NormalPayResult payResult = normalPayService.pay(payParam); + // 使用平台私钥对支付结果签名 + String platformPrivateKey = platformConfigProperties.getKeyConfig().getPrivateKey(); + String resultSign = PaySignUtil.sign(payResult, platformPrivateKey); + return new DevelopPayResult() + .setPayResult(payResult) + .setSign(resultSign); + } ); - return new DevelopPayResult() - .setRequestBody(requestBody) - .setSignInfo(signInfo) - .setPayResult(payResult); } /// 已启用渠道支付方式目录(供调试页支付方式下拉) diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/enum/pay_body_type.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/enum/pay_body_type.json index b3bf8de64..9406d71d5 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/enum/pay_body_type.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/enum/pay_body_type.json @@ -3,5 +3,6 @@ "jsapi": "JSAPI Object", "from": "Form Data", "identifier": "Identifier", + "qr_code": "QR Code", "json": "JSON Object" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/pay/error.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/pay/error.json index 013a262e9..165147747 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/pay/error.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/pay/error.json @@ -69,6 +69,7 @@ }, "assist": { "mchPublicKeyEmpty": "Merchant public key is empty", + "privateKeyEmpty": "Merchant private key is empty", "signEmpty": "Signature is empty", "mchNoAppNoMatch": "Merchant number and application number do not match", "mchNotOwnApp": "Merchant does not own this application", diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/enum/pay_body_type.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/enum/pay_body_type.json index 67e15c3f9..9c6cbdb0e 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/enum/pay_body_type.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/enum/pay_body_type.json @@ -3,5 +3,6 @@ "jsapi": "JSAPI对象", "from": "表单数据", "identifier": "标识码", + "qr_code": "二维码", "json": "JSON对象" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/pay/error.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/pay/error.json index cd2dccefc..791f6d8b1 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/pay/error.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/pay/error.json @@ -68,6 +68,7 @@ }, "assist": { "mchPublicKeyEmpty": "商户公钥为空", + "privateKeyEmpty": "商户私钥为空", "signEmpty": "签名为空", "mchNoAppNoMatch": "商户号和应用号不匹配", "mchNotOwnApp": "该商户不拥有该应用", diff --git a/daxpay-platform/daxpay-platform-core/src/main/java/cn/daxpay/open/platform/core/enums/unipay/PayBodyTypeEnum.java b/daxpay-platform/daxpay-platform-core/src/main/java/cn/daxpay/open/platform/core/enums/unipay/PayBodyTypeEnum.java index 2db4e7d9a..2466c7f91 100644 --- a/daxpay-platform/daxpay-platform-core/src/main/java/cn/daxpay/open/platform/core/enums/unipay/PayBodyTypeEnum.java +++ b/daxpay-platform/daxpay-platform-core/src/main/java/cn/daxpay/open/platform/core/enums/unipay/PayBodyTypeEnum.java @@ -18,6 +18,8 @@ public enum PayBodyTypeEnum implements I18nSupport { FROM("from"), /// 标识码 IDENTIFIER("identifier"), + /// 二维码内容(前端渲染成二维码图片) + QR_CODE("qr_code"), /// JSON对象 JSON("json"); diff --git a/daxpay-platform/daxpay-platform-service/service-notify/src/main/java/cn/daxpay/open/platform/notify/controller/notice/NotifyNoticeController.java b/daxpay-platform/daxpay-platform-service/service-notify/src/main/java/cn/daxpay/open/platform/notify/controller/notice/NotifyNoticeController.java index ce630dd7a..5fc1ef3a5 100644 --- a/daxpay-platform/daxpay-platform-service/service-notify/src/main/java/cn/daxpay/open/platform/notify/controller/notice/NotifyNoticeController.java +++ b/daxpay-platform/daxpay-platform-service/service-notify/src/main/java/cn/daxpay/open/platform/notify/controller/notice/NotifyNoticeController.java @@ -23,7 +23,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /// 公告管理(管理端) -@PermCode(menuCode = "system:notify") +@PermCode(menuCode = "system:notify:notice") @Validated @Tag(name = "公告管理") @RestController