diff --git a/_config/sql/iam_perm_menu.sql b/_config/sql/iam_perm_menu.sql index 0f7db0bed..a08791dbc 100644 --- a/_config/sql/iam_perm_menu.sql +++ b/_config/sql/iam_perm_menu.sql @@ -96,7 +96,7 @@ INSERT INTO "public"."iam_perm_menu" VALUES (304, 3, 'system:config', 'admin', ' 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 (6, NULL, 'trade', 'admin', 'TransactionManagement', '交易管理', 'Transaction Management', 'menu.trade', 'lucide:arrow-left-right', 'f', 'f', NULL, '/trade', '/trade/normal-pay', 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 (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'); @@ -114,7 +114,8 @@ INSERT INTO "public"."iam_perm_menu" VALUES (101, 1, 'dashboard:analytics', 'adm 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'); -INSERT INTO "public"."iam_perm_menu" VALUES (601, 6, NULL, 'admin', 'TransactionIndex', '功能开发中', 'Coming Soon', 'menu.trade.index', 'lucide:construction', 'f', 'f', '/_core/fallback/coming-soon', '/trade/index', NULL, 1, 'f', 'f', 'f', 1, 1, 0, 'f', 'menu', 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 (601, 6, 'payment:order', 'admin', 'NormalOrderList', '支付订单', 'Payment Orders', 'menu.trade.normalPay', 'lucide:receipt', 'f', 'f', '/payment/order/NormalOrderList', '/trade/normal-pay', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-24 16:00:00+00', '2026-07-01 16:00:00+00'); +INSERT INTO "public"."iam_perm_menu" VALUES (602, 6, 'payment:trade', 'admin', 'PayTradeList', '资金交易', 'Fund Trades', 'menu.trade.payTrade', 'lucide:arrow-left-right', 'f', 'f', '/payment/order/PayTradeList', '/trade/pay-trade', NULL, 2, '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 (40104, 401, 'payment:platform:capability', 'admin', 'PayCapabilityList', '支付能力', 'Payment Capability', 'menu.payment.platform.capability', 'lucide:zap', 'f', 'f', '/payment/masterdata/capability/PayCapabilityList', '/payment/platform/pay-capability', NULL, 3, 'f', 't', 'f', 1, 1, 4, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-05-26 16:00:00+00', '2026-05-28 06:43:27.505831+00'); 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'); diff --git a/_config/sql/update-datas.sql b/_config/sql/update-datas.sql index 60b83f908..e69de29bb 100644 --- a/_config/sql/update-datas.sql +++ b/_config/sql/update-datas.sql @@ -1,100 +0,0 @@ --- 设备管理菜单: iot → device 命名修正 + 目录层级合并(去除云音箱/云打印中间目录层) --- 执行顺序: update-tables.sql -> update-datas.sql --- 基于现有 iam_perm_menu 记录 UPDATE/DELETE(菜单已存在, 非新增) - --- 1. 设备管理 根目录 (id=9) -UPDATE "iam_perm_menu" SET - menu_code = 'device', - name = 'DeviceManagement', - i18n_key = 'menu.device', - path = '/device', - last_modified_time = now() -WHERE id = 9; - --- 2. 码牌 (id=901) -UPDATE "iam_perm_menu" SET - menu_code = 'device:qrcode', - name = 'DeviceQrCode', - i18n_key = 'menu.device.qrcode', - path = '/device/qrcode', - last_modified_time = now() -WHERE id = 901; - --- 3. 删除 云音箱 目录 (id=902) --- 去除中间目录层, 子菜单 90202 提升为顶层并继承 title/key/path -DELETE FROM "iam_perm_menu" WHERE id = 902; - --- 4. 删除 云打印 目录 (id=903) --- 去除中间目录层, 子菜单 90302 提升为顶层并继承 title/key/path -DELETE FROM "iam_perm_menu" WHERE id = 903; - --- 5. 设备厂商管理 (id=90201) 提升为设备管理顶层(pid 902→9) --- 厂商配置为平台级通用表(device_vendor_config), 统一入口, 不再按设备类型分散 -UPDATE "iam_perm_menu" SET - pid = 9, - menu_code = 'payment:device:vendorConfig', - name = 'VendorManage', - title_cn = '设备厂商管理', - title_en = 'Device Vendor Management', - i18n_key = 'menu.device.vendor', - component = '/payment/device/vendor/VendorManage', - path = '/device/vendor', - sort_no = 4, - last_modified_time = now() -WHERE id = 90201; - --- 6. 云音箱 (id=90202) 提升为顶层, 合并原目录 title/key/path --- 原: pid=902, title=云音箱管理, key=menu.device.speaker.manage, path=/device/speaker/manage --- 现: pid=9, title=云音箱, key=menu.device.speaker, path=/device/speaker -UPDATE "iam_perm_menu" SET - pid = 9, - menu_code = 'payment:device:speaker', - name = 'DeviceSpeakerList', - title_cn = '云音箱', - title_en = 'Cloud Speaker', - i18n_key = 'menu.device.speaker', - component = '/payment/device/speaker/DeviceSpeakerList', - path = '/device/speaker', - sort_no = 2, - last_modified_time = now() -WHERE id = 90202; - --- 7. 云打印 (id=90302) 提升为顶层, 合并原目录 title/key/path, 并接入已实现的列表组件 --- 原: pid=903, title=云打印管理, key=menu.device.printer.manage, path=/device/printer/device --- 现: pid=9, title=云打印, key=menu.device.printer, path=/device/printer -UPDATE "iam_perm_menu" SET - pid = 9, - menu_code = 'payment:device:printer', - name = 'DevicePrinterList', - title_cn = '云打印', - title_en = 'Cloud Printer', - i18n_key = 'menu.device.printer', - component = '/payment/device/printer/DevicePrinterList', - path = '/device/printer', - sort_no = 3, - last_modified_time = now() -WHERE id = 90302; - --- 8. 删除 云打印 > 厂商管理 (id=90301) --- 厂商配置统一到顶层 90201, 各设备类型下不再单设厂商管理入口 -DELETE FROM "iam_perm_menu" WHERE id = 90301; - --- 9. Dashboard 目录 (id=1): 默认进入工作台 (/analytics → /workspace) -UPDATE "iam_perm_menu" SET - redirect = '/workspace', - last_modified_time = now() -WHERE id = 1; - --- 10. 工作台 (id=102): 补菜单编码占位 + 排序提前到分析页之前 -UPDATE "iam_perm_menu" SET - menu_code = 'dashboard:workspace', - sort_no = 1, - last_modified_time = now() -WHERE id = 102; - --- 11. 分析页 (id=101): 补菜单编码占位 + 排序后移到工作台之后 -UPDATE "iam_perm_menu" SET - menu_code = 'dashboard:analytics', - sort_no = 2, - last_modified_time = now() -WHERE id = 101; diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/controller/order/NormalPayOrderAdminController.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/controller/order/NormalPayOrderAdminController.java new file mode 100644 index 000000000..590a219e4 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/controller/order/NormalPayOrderAdminController.java @@ -0,0 +1,68 @@ +package cn.daxpay.open.payment.admin.controller.order; + +import cn.daxpay.open.platform.core.annotation.PermCode; +import cn.daxpay.open.platform.core.rest.Res; +import cn.daxpay.open.platform.core.rest.param.PageParam; +import cn.daxpay.open.platform.core.rest.result.PageResult; +import cn.daxpay.open.platform.core.rest.result.Result; +import cn.daxpay.open.payment.pay.param.order.NormalPayOrderQuery; +import cn.daxpay.open.payment.pay.result.order.NormalPayOrderResult; +import cn.daxpay.open.payment.pay.service.admin.NormalPayOrderAdminService; +import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPaySyncResult; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/// # 普通支付业务单(管理) +/// +/// 面向运营/商户后台的业务订单(容器)管理: 分页查询、详情、状态同步、关闭/撤销 +@PermCode(menuCode = "payment:order") +@Validated +@Tag(name = "普通支付业务单(管理)") +@RestController +@RequestMapping("/admin/order/normal-pay") +@RequiredArgsConstructor +public class NormalPayOrderAdminController { + + private final NormalPayOrderAdminService normalPayOrderAdminService; + + @PermCode(code = "view", nameCn = "订单查看", nameEn = "Order View") + @Operation(summary = "普通支付业务单分页") + @GetMapping("/page") + public Result> page(PageParam pageParam, NormalPayOrderQuery query) { + return Res.ok(normalPayOrderAdminService.page(pageParam, query)); + } + + @PermCode(code = "view", nameCn = "订单查看", nameEn = "Order View") + @Operation(summary = "根据ID查询普通支付业务单详情") + @GetMapping("/get-by-id") + public Result findById( + @NotNull(message = "{validation.field.id.notNull}") Long id) { + return Res.ok(normalPayOrderAdminService.findById(id)); + } + + @PermCode(code = "manage", nameCn = "订单管理", nameEn = "Order Manage") + @Operation(summary = "同步支付状态") + @PostMapping("/sync") + public Result sync( + @NotNull(message = "{validation.field.id.notNull}") Long id) { + return Res.ok(normalPayOrderAdminService.sync(id)); + } + + @PermCode(code = "manage", nameCn = "订单管理", nameEn = "Order Manage") + @Operation(summary = "关闭/撤销订单") + @PostMapping("/close") + public Result close( + @NotNull(message = "{validation.field.id.notNull}") Long id, + @RequestParam(defaultValue = "false") boolean useCancel) { + normalPayOrderAdminService.close(id, useCancel); + return Res.ok(); + } +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/controller/order/PayTradeAdminController.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/controller/order/PayTradeAdminController.java new file mode 100644 index 000000000..29ff641ca --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/admin/controller/order/PayTradeAdminController.java @@ -0,0 +1,68 @@ +package cn.daxpay.open.payment.admin.controller.order; + +import cn.daxpay.open.platform.core.annotation.PermCode; +import cn.daxpay.open.platform.core.rest.Res; +import cn.daxpay.open.platform.core.rest.param.PageParam; +import cn.daxpay.open.platform.core.rest.result.PageResult; +import cn.daxpay.open.platform.core.rest.result.Result; +import cn.daxpay.open.payment.pay.param.order.PayTradeQuery; +import cn.daxpay.open.payment.pay.result.order.PayTradeResult; +import cn.daxpay.open.payment.pay.service.admin.PayTradeAdminService; +import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPaySyncResult; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/// # 资金交易凭证(管理) +/// +/// 面向运营/商户后台的资金交易(凭证)管理: 分页查询、详情、状态同步、关闭/撤销 +@PermCode(menuCode = "payment:trade") +@Validated +@Tag(name = "资金交易凭证(管理)") +@RestController +@RequestMapping("/admin/order/pay-trade") +@RequiredArgsConstructor +public class PayTradeAdminController { + + private final PayTradeAdminService payTradeAdminService; + + @PermCode(code = "view", nameCn = "交易查看", nameEn = "Trade View") + @Operation(summary = "资金交易凭证分页") + @GetMapping("/page") + public Result> page(PageParam pageParam, PayTradeQuery query) { + return Res.ok(payTradeAdminService.page(pageParam, query)); + } + + @PermCode(code = "view", nameCn = "交易查看", nameEn = "Trade View") + @Operation(summary = "根据ID查询资金交易凭证详情") + @GetMapping("/get-by-id") + public Result findById( + @NotNull(message = "{validation.field.id.notNull}") Long id) { + return Res.ok(payTradeAdminService.findById(id)); + } + + @PermCode(code = "manage", nameCn = "交易管理", nameEn = "Trade Manage") + @Operation(summary = "同步支付状态") + @PostMapping("/sync") + public Result sync( + @NotNull(message = "{validation.field.id.notNull}") Long id) { + return Res.ok(payTradeAdminService.sync(id)); + } + + @PermCode(code = "manage", nameCn = "交易管理", nameEn = "Trade Manage") + @Operation(summary = "关闭/撤销订单") + @PostMapping("/close") + public Result close( + @NotNull(message = "{validation.field.id.notNull}") Long id, + @RequestParam(defaultValue = "false") boolean useCancel) { + payTradeAdminService.close(id, useCancel); + return Res.ok(); + } +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/convert/NormalPayOrderConvert.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/convert/NormalPayOrderConvert.java new file mode 100644 index 000000000..5bf2876a1 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/convert/NormalPayOrderConvert.java @@ -0,0 +1,19 @@ +package cn.daxpay.open.payment.pay.convert; + +import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; +import cn.daxpay.open.payment.pay.result.order.NormalPayOrderResult; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/// # 普通支付业务单转换器(管理) +/// +/// 仅做容器(NormalPayOrder)到列表 Result 的映射; +/// 详情场景的资金凭证(PayTrade)字段由 Service 层手动补充, 避免多参数源同名字段歧义 +@Mapper +public interface NormalPayOrderConvert { + + NormalPayOrderConvert CONVERT = Mappers.getMapper(NormalPayOrderConvert.class); + + /// NormalPayOrder → Result (列表用, 不含资金凭证字段) + NormalPayOrderResult toResult(NormalPayOrder entity); +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/convert/PayTradeAdminConvert.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/convert/PayTradeAdminConvert.java new file mode 100644 index 000000000..19e044e19 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/convert/PayTradeAdminConvert.java @@ -0,0 +1,19 @@ +package cn.daxpay.open.payment.pay.convert; + +import cn.daxpay.open.payment.pay.order.entity.PayTrade; +import cn.daxpay.open.payment.pay.result.order.PayTradeResult; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/// # 资金交易凭证转换器(管理) +/// +/// 仅做凭证(PayTrade)到列表 Result 的映射; +/// 详情场景的容器(NormalPayOrder)字段由 Service 层手动补充, 避免多参数源同名字段歧义 +@Mapper +public interface PayTradeAdminConvert { + + PayTradeAdminConvert CONVERT = Mappers.getMapper(PayTradeAdminConvert.class); + + /// PayTrade → Result (列表用, 不含容器字段) + PayTradeResult toResult(PayTrade entity); +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/NormalPayOrderManager.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/NormalPayOrderManager.java index 889f3229d..5fbf677a9 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/NormalPayOrderManager.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/NormalPayOrderManager.java @@ -1,7 +1,13 @@ package cn.daxpay.open.payment.pay.order.dao; import cn.daxpay.open.platform.common.mybatisplus.impl.BaseManager; +import cn.daxpay.open.platform.common.mybatisplus.query.generator.QueryGenerator; +import cn.daxpay.open.platform.common.mybatisplus.util.MpUtil; +import cn.daxpay.open.platform.core.rest.param.PageParam; import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; +import cn.daxpay.open.payment.pay.param.order.NormalPayOrderQuery; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.stereotype.Repository; import java.util.Optional; @@ -17,4 +23,13 @@ public class NormalPayOrderManager extends BaseManager page(PageParam pageParam, NormalPayOrderQuery query) { + Page mpPage = MpUtil.getMpPage(pageParam); + QueryWrapper wrapper = QueryGenerator.generator(query); + // 默认按创建时间倒序 + wrapper.orderByDesc("create_time"); + return this.page(mpPage, wrapper); + } } diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/PayTradeManager.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/PayTradeManager.java index 617aebb86..e90cada95 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/PayTradeManager.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/order/dao/PayTradeManager.java @@ -1,10 +1,16 @@ package cn.daxpay.open.payment.pay.order.dao; import cn.daxpay.open.platform.common.mybatisplus.impl.BaseManager; +import cn.daxpay.open.platform.common.mybatisplus.query.generator.QueryGenerator; +import cn.daxpay.open.platform.common.mybatisplus.util.MpUtil; import cn.daxpay.open.platform.core.annotation.IgnoreTenant; import cn.daxpay.open.platform.core.exception.DangerSqlException; import cn.daxpay.open.platform.core.code.CommonCode; +import cn.daxpay.open.platform.core.rest.param.PageParam; import cn.daxpay.open.payment.pay.order.entity.PayTrade; +import cn.daxpay.open.payment.pay.param.order.PayTradeQuery; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.stereotype.Repository; import java.util.Optional; @@ -39,6 +45,15 @@ public class PayTradeManager extends BaseManager { .oneOpt(); } + /// 分页查询(管理端), 默认按创建时间倒序 + public Page page(PageParam pageParam, PayTradeQuery query) { + Page mpPage = MpUtil.getMpPage(pageParam); + QueryWrapper wrapper = QueryGenerator.generator(query); + // 默认按创建时间倒序 + wrapper.orderByDesc("create_time"); + return this.page(mpPage, wrapper); + } + /// 根据id进行更新,失败时抛出异常 @Override public int updateById(PayTrade entity) { diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/param/order/NormalPayOrderQuery.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/param/order/NormalPayOrderQuery.java new file mode 100644 index 000000000..65f5ce812 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/param/order/NormalPayOrderQuery.java @@ -0,0 +1,79 @@ +package cn.daxpay.open.payment.pay.param.order; + +import cn.daxpay.open.platform.core.annotation.QueryParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.OffsetDateTime; + +/// # 普通支付业务单查询参数(管理) +/// +@Data +@Accessors(chain = true) +@Schema(title = "普通支付业务单查询参数") +public class NormalPayOrderQuery { + + /// 商户号 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "商户号") + private String mchNo; + + /// 应用号 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "应用号") + private String appId; + + /// 商户业务单号 + @QueryParam(type = QueryParam.CompareTypeEnum.LIKE) + @Schema(description = "商户业务单号") + private String bizOrderNo; + + /// 订单标题 + @QueryParam(type = QueryParam.CompareTypeEnum.LIKE) + @Schema(description = "订单标题") + private String title; + + /// 业务状态 + /// @see cn.daxpay.open.payment.common.enums.NormalPayOrderStatusEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "业务状态") + private String status; + + /// 支付通道 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付通道") + private String channel; + + /// 支付方式 + /// @see cn.daxpay.open.platform.core.enums.pay.channel.PayMethodEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付方式") + private String method; + + /// 支付产品 + /// @see cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付产品") + private String product; + + /// 创建时间-开始 + @QueryParam(type = QueryParam.CompareTypeEnum.GE, fieldName = "create_time") + @Schema(description = "创建时间-开始") + private OffsetDateTime createTimeStart; + + /// 创建时间-结束 + @QueryParam(type = QueryParam.CompareTypeEnum.LE, fieldName = "create_time") + @Schema(description = "创建时间-结束") + private OffsetDateTime createTimeEnd; + + /// 金额下限(最小货币单位) + @QueryParam(type = QueryParam.CompareTypeEnum.GE, fieldName = "amount") + @Schema(description = "金额下限(分)") + private Long amountMin; + + /// 金额上限(最小货币单位) + @QueryParam(type = QueryParam.CompareTypeEnum.LE, fieldName = "amount") + @Schema(description = "金额上限(分)") + private Long amountMax; +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/param/order/PayTradeQuery.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/param/order/PayTradeQuery.java new file mode 100644 index 000000000..0c71d7bac --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/param/order/PayTradeQuery.java @@ -0,0 +1,90 @@ +package cn.daxpay.open.payment.pay.param.order; + +import cn.daxpay.open.platform.core.annotation.QueryParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.OffsetDateTime; + +/// # 资金交易凭证查询参数(管理) +/// +@Data +@Accessors(chain = true) +@Schema(title = "资金交易凭证查询参数") +public class PayTradeQuery { + + /// 商户号 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "商户号") + private String mchNo; + + /// 应用号 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "应用号") + private String appId; + + /// 支付交易号 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付交易号") + private String tradeNo; + + /// 通道订单号 + @QueryParam(type = QueryParam.CompareTypeEnum.LIKE) + @Schema(description = "通道订单号") + private String outOrderNo; + + /// 资金状态 + /// @see cn.daxpay.open.payment.common.enums.PayFundStatusEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "资金状态") + private String status; + + /// 交易形态 + /// @see cn.daxpay.open.payment.common.enums.PayTradeTypeEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "交易形态") + private String tradeType; + + /// 支付通道 + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付通道") + private String channel; + + /// 支付方式 + /// @see cn.daxpay.open.platform.core.enums.pay.channel.PayMethodEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付方式") + private String method; + + /// 支付产品 + /// @see cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "支付产品") + private String product; + + /// 关联容器ID + @QueryParam(type = QueryParam.CompareTypeEnum.EQ) + @Schema(description = "关联容器ID") + private Long containerId; + + /// 创建时间-开始 + @QueryParam(type = QueryParam.CompareTypeEnum.GE, fieldName = "create_time") + @Schema(description = "创建时间-开始") + private OffsetDateTime createTimeStart; + + /// 创建时间-结束 + @QueryParam(type = QueryParam.CompareTypeEnum.LE, fieldName = "create_time") + @Schema(description = "创建时间-结束") + private OffsetDateTime createTimeEnd; + + /// 金额下限(最小货币单位) + @QueryParam(type = QueryParam.CompareTypeEnum.GE, fieldName = "amount") + @Schema(description = "金额下限(分)") + private Long amountMin; + + /// 金额上限(最小货币单位) + @QueryParam(type = QueryParam.CompareTypeEnum.LE, fieldName = "amount") + @Schema(description = "金额上限(分)") + private Long amountMax; +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/result/order/NormalPayOrderResult.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/result/order/NormalPayOrderResult.java new file mode 100644 index 000000000..b1f3c05ea --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/result/order/NormalPayOrderResult.java @@ -0,0 +1,158 @@ +package cn.daxpay.open.payment.pay.result.order; + +import cn.daxpay.open.platform.core.result.BaseResult; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.OffsetDateTime; + +/// # 普通支付业务单(管理) +/// +/// 列表场景仅填充容器(NormalPayOrder)字段; +/// 详情场景额外填充资金凭证(PayTrade)字段: tradeNo / outOrderNo / fundStatus 等 +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "普通支付业务单") +public class NormalPayOrderResult extends BaseResult { + + // ===== 容器(业务单)字段 ===== + + /// 商户号 + @Schema(description = "商户号") + private String mchNo; + + /// 应用号 + @Schema(description = "应用号") + private String appId; + + /// 商户业务单号 + @Schema(description = "商户业务单号") + private String bizOrderNo; + + /// 标题 + @Schema(description = "标题") + private String title; + + /// 描述 + @Schema(description = "描述") + private String description; + + /// 业务状态 + /// @see cn.daxpay.open.payment.common.enums.NormalPayOrderStatusEnum + @Schema(description = "业务状态") + private String status; + + /// 异步通知地址 + @Schema(description = "异步通知地址") + private String notifyUrl; + + /// 同步跳转地址 + @Schema(description = "同步跳转地址") + private String returnUrl; + + /// 商户附加参数 + @Schema(description = "商户附加参数") + private String attach; + + /// 业务单过期时间 + @Schema(description = "业务单过期时间") + private OffsetDateTime expiredTime; + + /// 业务单金额(最小货币单位) + @Schema(description = "业务单金额(分)") + private Long amount; + + /// 币种 + @Schema(description = "币种") + private String currency; + + /// 支付通道 + @Schema(description = "支付通道") + private String channel; + + /// 支付方式 + @Schema(description = "支付方式") + private String method; + + /// 支付产品 + @Schema(description = "支付产品") + private String product; + + /// 支付成功时间 + @Schema(description = "支付成功时间") + private OffsetDateTime payTime; + + /// 关闭时间 + @Schema(description = "关闭时间") + private OffsetDateTime closeTime; + + /// 通道商户号(路由回填) + @Schema(description = "通道商户号") + private String channelMchNo; + + /// 支付能力编码(路由回填) + @Schema(description = "支付能力编码") + private String capability; + + /// 客户端IP + @Schema(description = "客户端IP") + private String clientIp; + + /// 终端设备编码 + @Schema(description = "终端设备编码") + private String terminalNo; + + // ===== 资金凭证(PayTrade)联表字段, 仅详情时填充 ===== + + /// 资金交易号 + @Schema(description = "资金交易号") + private String tradeNo; + + /// 通道订单号 + @Schema(description = "通道订单号") + private String outOrderNo; + + /// 资金状态 + /// @see cn.daxpay.open.payment.common.enums.PayFundStatusEnum + @Schema(description = "资金状态") + private String fundStatus; + + /// 可退金额(最小货币单位) + @Schema(description = "可退金额(分)") + private Long refundableBalance; + + /// 支付参数体 + @Schema(description = "支付参数体") + private String payBody; + + /// 支付参数体类型 + @Schema(description = "支付参数体类型") + private String payBodyType; + + /// 付款用户ID + @Schema(description = "付款用户ID") + private String buyerId; + + /// 微信openid + @Schema(description = "微信openid") + private String openid; + + /// 通道方记录的支付产品 + @Schema(description = "通道方记录的支付产品") + private String tradeProduct; + + /// 通道方记录的交易方式 + @Schema(description = "通道方记录的交易方式") + private String tradeWay; + + /// 银行卡类型 + @Schema(description = "银行卡类型") + private String bankType; + + /// 错误信息 + @Schema(description = "错误信息") + private String errorMsg; +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/result/order/PayTradeResult.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/result/order/PayTradeResult.java new file mode 100644 index 000000000..974e376f3 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/result/order/PayTradeResult.java @@ -0,0 +1,167 @@ +package cn.daxpay.open.payment.pay.result.order; + +import cn.daxpay.open.platform.core.result.BaseResult; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.OffsetDateTime; + +/// # 资金交易凭证(管理) +/// +/// 列表场景仅填充凭证(PayTrade)字段; +/// 详情场景额外填充容器(NormalPayOrder)字段: bizOrderNo / title / containerStatus +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "资金交易凭证") +public class PayTradeResult extends BaseResult { + + // ===== 凭证(PayTrade)字段 ===== + + /// 商户号 + @Schema(description = "商户号") + private String mchNo; + + /// 应用号 + @Schema(description = "应用号") + private String appId; + + /// 支付交易号 + @Schema(description = "支付交易号") + private String tradeNo; + + /// 交易形态 + /// @see cn.daxpay.open.payment.common.enums.PayTradeTypeEnum + @Schema(description = "交易形态") + private String tradeType; + + /// 关联容器ID + @Schema(description = "关联容器ID") + private Long containerId; + + /// 支付产品 + @Schema(description = "支付产品") + private String product; + + /// 支付通道 + @Schema(description = "支付通道") + private String channel; + + /// 支付方式 + @Schema(description = "支付方式") + private String method; + + /// 其他支付方式 + @Schema(description = "其他支付方式") + private String otherMethod; + + /// 限制支付类型 + @Schema(description = "限制支付类型") + private String limitPay; + + /// 支付渠道(微信/支付宝/银联等) + @Schema(description = "支付渠道") + private String provider; + + /// 本次交易金额(最小货币单位) + @Schema(description = "本次交易金额(分)") + private Long amount; + + /// 币种 + @Schema(description = "币种") + private String currency; + + /// 可退金额(最小货币单位) + @Schema(description = "可退金额(分)") + private Long refundableBalance; + + /// 资金状态 + /// @see cn.daxpay.open.payment.common.enums.PayFundStatusEnum + @Schema(description = "资金状态") + private String status; + + /// 过期时间 + @Schema(description = "过期时间") + private OffsetDateTime expiredTime; + + /// 支付成功时间 + @Schema(description = "支付成功时间") + private OffsetDateTime payTime; + + /// 关闭时间 + @Schema(description = "关闭时间") + private OffsetDateTime closeTime; + + /// 订单来源 + @Schema(description = "订单来源") + private String source; + + /// 通道订单号 + @Schema(description = "通道订单号") + private String outOrderNo; + + /// 透传订单号 + @Schema(description = "透传订单号") + private String transOrderNo; + + /// 特殊通道关联订单号 + @Schema(description = "特殊通道关联订单号") + private String relationOrderNo; + + /// 付款用户ID + @Schema(description = "付款用户ID") + private String buyerId; + + /// 微信openid + @Schema(description = "微信openid") + private String openid; + + /// 通道方记录的支付产品 + @Schema(description = "通道方记录的支付产品") + private String tradeProduct; + + /// 通道方记录的交易方式 + @Schema(description = "通道方记录的交易方式") + private String tradeWay; + + /// 银行卡类型 + @Schema(description = "银行卡类型") + private String bankType; + + /// 付款码(被扫支付) + @Schema(description = "付款码") + private String barCode; + + /// 活动类型 + @Schema(description = "活动类型") + private String promotionType; + + /// 支付参数体 + @Schema(description = "支付参数体") + private String payBody; + + /// 支付参数体类型 + @Schema(description = "支付参数体类型") + private String payBodyType; + + /// 错误信息 + @Schema(description = "错误信息") + private String errorMsg; + + // ===== 容器(NormalPayOrder)联表字段, 仅详情时填充 ===== + + /// 商户业务单号 + @Schema(description = "商户业务单号") + private String bizOrderNo; + + /// 订单标题 + @Schema(description = "订单标题") + private String title; + + /// 容器业务状态 + /// @see cn.daxpay.open.payment.common.enums.NormalPayOrderStatusEnum + @Schema(description = "容器业务状态") + private String containerStatus; +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/admin/NormalPayOrderAdminService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/admin/NormalPayOrderAdminService.java new file mode 100644 index 000000000..bdb11f326 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/admin/NormalPayOrderAdminService.java @@ -0,0 +1,88 @@ +package cn.daxpay.open.payment.pay.service.admin; + +import cn.daxpay.open.platform.core.exception.DataNotExistException; +import cn.daxpay.open.platform.core.rest.param.PageParam; +import cn.daxpay.open.platform.core.rest.result.PageResult; +import cn.daxpay.open.payment.pay.convert.NormalPayOrderConvert; +import cn.daxpay.open.payment.pay.order.dao.NormalPayOrderManager; +import cn.daxpay.open.payment.pay.order.dao.PayTradeManager; +import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; +import cn.daxpay.open.payment.pay.order.entity.PayTrade; +import cn.daxpay.open.payment.pay.param.order.NormalPayOrderQuery; +import cn.daxpay.open.payment.pay.result.order.NormalPayOrderResult; +import cn.daxpay.open.payment.pay.service.PayCloseService; +import cn.daxpay.open.payment.pay.service.PaySyncService; +import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPaySyncResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/// # 普通支付业务单管理服务(管理端) +/// +/// 提供业务订单(容器)的分页/详情查询, 以及状态同步、关闭/撤销管理操作。 +/// 详情场景联表资金凭证(PayTrade)补充交易字段; 同步/关闭复用 [PaySyncService] / [PayCloseService]。 +@Slf4j +@Service +@RequiredArgsConstructor +public class NormalPayOrderAdminService { + + private final NormalPayOrderManager normalPayOrderManager; + private final PayTradeManager payTradeManager; + private final PaySyncService paySyncService; + private final PayCloseService payCloseService; + + /// 分页查询 + public PageResult page(PageParam pageParam, NormalPayOrderQuery query) { + Page page = normalPayOrderManager.page(pageParam, query); + // 手动转换, 避免侵入核心实体(不实现 ToResult) + var records = page.getRecords().stream() + .map(NormalPayOrderConvert.CONVERT::toResult) + .toList(); + return new PageResult() + .setRecords(records) + .setTotal(page.getTotal()) + .setSize(page.getSize()) + .setCurrent(page.getCurrent()); + } + + /// 详情查询(联表资金凭证补充交易字段) + public NormalPayOrderResult findById(Long id) { + NormalPayOrder entity = normalPayOrderManager.findById(id) + .orElseThrow(() -> new DataNotExistException("pay.error.payOrderNotExist")); + NormalPayOrderResult result = NormalPayOrderConvert.CONVERT.toResult(entity); + // 联表查询资金凭证, 补充交易字段 + PayTrade trade = payTradeManager.findByContainerId(id).orElse(null); + if (Objects.nonNull(trade)) { + result.setTradeNo(trade.getTradeNo()); + result.setOutOrderNo(trade.getOutOrderNo()); + result.setFundStatus(trade.getStatus()); + result.setRefundableBalance(trade.getRefundableBalance()); + result.setPayBody(trade.getPayBody()); + result.setPayBodyType(trade.getPayBodyType()); + result.setBuyerId(trade.getBuyerId()); + result.setOpenid(trade.getOpenid()); + result.setTradeProduct(trade.getTradeProduct()); + result.setTradeWay(trade.getTradeWay()); + result.setBankType(trade.getBankType()); + result.setErrorMsg(trade.getErrorMsg()); + } + return result; + } + + /// 同步支付状态(传入业务订单ID) + public NormalPaySyncResult sync(Long id) { + PayTrade trade = payTradeManager.findByContainerId(id) + .orElseThrow(() -> new DataNotExistException("pay.error.payOrderNotExist")); + return paySyncService.syncPayOrder(trade); + } + + /// 关闭/撤销订单(传入业务订单ID) + public void close(Long id, boolean useCancel) { + PayTrade trade = payTradeManager.findByContainerId(id) + .orElseThrow(() -> new DataNotExistException("pay.error.payOrderNotExist")); + payCloseService.closeOrder(trade, useCancel); + } +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/admin/PayTradeAdminService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/admin/PayTradeAdminService.java new file mode 100644 index 000000000..f8c754d26 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/admin/PayTradeAdminService.java @@ -0,0 +1,78 @@ +package cn.daxpay.open.payment.pay.service.admin; + +import cn.daxpay.open.platform.core.exception.DataNotExistException; +import cn.daxpay.open.platform.core.rest.param.PageParam; +import cn.daxpay.open.platform.core.rest.result.PageResult; +import cn.daxpay.open.payment.pay.convert.PayTradeAdminConvert; +import cn.daxpay.open.payment.pay.order.dao.NormalPayOrderManager; +import cn.daxpay.open.payment.pay.order.dao.PayTradeManager; +import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; +import cn.daxpay.open.payment.pay.order.entity.PayTrade; +import cn.daxpay.open.payment.pay.param.order.PayTradeQuery; +import cn.daxpay.open.payment.pay.result.order.PayTradeResult; +import cn.daxpay.open.payment.pay.service.PayCloseService; +import cn.daxpay.open.payment.pay.service.PaySyncService; +import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPaySyncResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/// # 资金交易凭证管理服务(管理端) +/// +/// 提供资金交易(凭证)的分页/详情查询, 以及状态同步、关闭/撤销管理操作。 +/// 详情场景联表容器(NormalPayOrder)补充业务字段; 同步/关闭复用 [PaySyncService] / [PayCloseService]。 +@Slf4j +@Service +@RequiredArgsConstructor +public class PayTradeAdminService { + + private final PayTradeManager payTradeManager; + private final NormalPayOrderManager normalPayOrderManager; + private final PaySyncService paySyncService; + private final PayCloseService payCloseService; + + /// 分页查询 + public PageResult page(PageParam pageParam, PayTradeQuery query) { + Page page = payTradeManager.page(pageParam, query); + var records = page.getRecords().stream() + .map(PayTradeAdminConvert.CONVERT::toResult) + .toList(); + return new PageResult() + .setRecords(records) + .setTotal(page.getTotal()) + .setSize(page.getSize()) + .setCurrent(page.getCurrent()); + } + + /// 详情查询(联表容器补充业务字段) + public PayTradeResult findById(Long id) { + PayTrade entity = payTradeManager.findById(id) + .orElseThrow(() -> new DataNotExistException("pay.error.payOrderNotExist")); + PayTradeResult result = PayTradeAdminConvert.CONVERT.toResult(entity); + // 联表查询容器, 补充业务字段 + NormalPayOrder normalOrder = normalPayOrderManager.findById(entity.getContainerId()).orElse(null); + if (Objects.nonNull(normalOrder)) { + result.setBizOrderNo(normalOrder.getBizOrderNo()); + result.setTitle(normalOrder.getTitle()); + result.setContainerStatus(normalOrder.getStatus()); + } + return result; + } + + /// 同步支付状态(传入资金交易ID) + public NormalPaySyncResult sync(Long id) { + PayTrade trade = payTradeManager.findById(id) + .orElseThrow(() -> new DataNotExistException("pay.error.payOrderNotExist")); + return paySyncService.syncPayOrder(trade); + } + + /// 关闭/撤销订单(传入资金交易ID) + public void close(Long id, boolean useCancel) { + PayTrade trade = payTradeManager.findById(id) + .orElseThrow(() -> new DataNotExistException("pay.error.payOrderNotExist")); + payCloseService.closeOrder(trade, useCancel); + } +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/unipay/controller/UniTradeController.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/unipay/controller/UniTradeController.java index fed299483..8b64271c4 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/unipay/controller/UniTradeController.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/unipay/controller/UniTradeController.java @@ -48,7 +48,7 @@ public class UniTradeController { @Operation(summary = "关闭和撤销接口") @PostMapping("/close") public DaxResult close(@RequestBody NormalPayCloseParam param){ - if ( permConfigService.hasApiPerm(PaymentApiEnum.CLOSE.getCode())){ + if ( !permConfigService.hasApiPerm(PaymentApiEnum.CLOSE.getCode())){ // 订单: 该商户没有此接口的权限 throw new OperationFailException(CommonCode.FAIL_CODE, "error.payment.order.merchantNoApiPermission"); }