package cc.mrbird.febs.mall.controller.dependentStation; import cc.mrbird.febs.common.annotation.Limit; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.entity.LimitType; import cc.mrbird.febs.mall.dto.*; import cc.mrbird.febs.mall.entity.MallOrderInfo; import cc.mrbird.febs.mall.service.IApiMallOrderInfoService; import cc.mrbird.febs.mall.service.IMallCountryDeliveryService; import cc.mrbird.febs.mall.vo.ApiOrderPayVo; import cc.mrbird.febs.mall.vo.OrderDetailVo; import cc.mrbird.febs.mall.vo.OrderListVo; import cc.mrbird.febs.pay.service.IXcxPayService; import cc.mrbird.febs.pay.service.LwPayService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * @author wzy * @date 2021-09-18 **/ @Slf4j @Validated @RestController @RequiredArgsConstructor @RequestMapping(value = "/api/order") @Api(value = "ApiMallOrderController", tags = "DS-订单接口类") public class ApiMallOrderController { private final IApiMallOrderInfoService mallOrderInfoService; private final IXcxPayService iXcxPayService; private final LwPayService lwPayService; private final IMallCountryDeliveryService countryDeliveryService; @ApiOperation(value = "创建订单--验证是否允许创建", notes = "创建订单--验证是否允许创建") @PostMapping(value = "/createOrderVerify") @Limit(key = "createOrderVerify", period = 1, count = 1, name = "注册", prefix = "limit",limitType = LimitType.IP) public FebsResponse createOrderVerify(@RequestBody ApiCreateOrderVerifyDto apiCreateOrderVerifyDto) { return mallOrderInfoService.createOrderVerify(apiCreateOrderVerifyDto); } @ApiOperation(value = "创建订单", notes = "创建订单") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiOrderPayVo.class) }) @PostMapping(value = "/createOrder") @Limit(key = "createOrder", period = 1, count = 1, name = "注册", prefix = "limit",limitType = LimitType.IP) public FebsResponse createOrder(@RequestBody @Validated AddOrderDto addOrderDto) { Long orderId = mallOrderInfoService.createOrder(addOrderDto); ApiOrderPayDto apiOrderPayDto = new ApiOrderPayDto(); apiOrderPayDto.setOrderId(orderId); apiOrderPayDto.setPayType(3); return mallOrderInfoService.payOrderByCoin(apiOrderPayDto); } @ApiOperation(value = "取消订单", notes = "取消订单") @PostMapping(value = "/cancelOrder/{id}") @Limit(key = "cancelOrder", period = 1, count = 1, name = "注册", prefix = "limit",limitType = LimitType.IP) public FebsResponse cancelOrder(@PathVariable("id") Long id) { mallOrderInfoService.cancelOrder(id); return new FebsResponse().success(); } @ApiOperation(value = "支付订单", notes = "支付订单") @PostMapping(value = "/payOrder") public FebsResponse payOrder(@RequestBody PayOrderDto payOrderDto) { Map result = mallOrderInfoService.payOrder(payOrderDto); Map map = new HashMap<>(); map.put("order", result); map.put("type", payOrderDto.getType()); return new FebsResponse().success().data(map).message("支付成功"); } @ApiOperation(value = "USDT支付订单", notes = "USDT支付订单") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiOrderPayVo.class) }) @PostMapping(value = "/payOrderByCoin", produces = "application/json") public FebsResponse payOrder(@RequestBody @Validated ApiOrderPayDto payDto) { return mallOrderInfoService.payOrderByCoin(payDto); } @ApiOperation(value = "订单列表", notes = "订单列表") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = OrderListVo.class) }) @PostMapping(value = "/orderList") public FebsResponse orderList(@RequestBody OrderListDto orderListDto) { return new FebsResponse().success().data(mallOrderInfoService.findOrderList(orderListDto)); } @ApiOperation(value = "订单详情", notes = "订单详情") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = OrderDetailVo.class) }) @GetMapping(value = "/orderDetails/{id}") public FebsResponse orderDetails(@PathVariable("id") Long id) { return new FebsResponse().success().data(mallOrderInfoService.findOrderDetailsById(id)); } @ApiOperation(value = "确认收货", notes = "确认收货") @PostMapping(value = "/confirm/{id}") public FebsResponse confirm(@PathVariable("id") Long id) { mallOrderInfoService.confirmOrder(id); return new FebsResponse().success().message("确认成功"); } @ApiOperation(value = "删除订单", notes = "删除订单") @PostMapping(value = "/delOrder/{id}") public FebsResponse delOrder(@PathVariable("id") Long id) { mallOrderInfoService.delOrder(id); return new FebsResponse().success().message("删除成功"); } @ApiOperation(value = "用户退款", notes = "用户退款") @PostMapping(value = "/refundOrder/{id}") public FebsResponse refundOrder(@PathVariable("id") Long id) { return mallOrderInfoService.refundOrder(id); } @ApiOperation(value = "用户退款--提交退款申请", notes = "用户退款--提交退款申请") @PostMapping(value = "/applyRefundOrder") public FebsResponse applyRefundOrder(@RequestBody ApplyRefundOrderDto applyRefundOrderDto) { return mallOrderInfoService.applyRefundOrder(applyRefundOrderDto); } @ApiOperation(value = "用户退款--取消退款申请", notes = "用户退款--取消退款申请") @PostMapping(value = "/cancelRefundOrder/{id}") public FebsResponse cancelRefundOrder(@PathVariable("id") Long id) { return mallOrderInfoService.cancelRefundOrder(id); } @ApiOperation(value = "提交退款申请", notes = "提交退款申请") @PostMapping(value = "/applyRefund") public FebsResponse applyRefund(@RequestBody AddRefundDto addRefundDto) { mallOrderInfoService.applyRefund(addRefundDto); return new FebsResponse().success().message("提交成功"); } @ApiOperation(value = "提交退款物流信息", notes = "提交退款物流信息") @PostMapping(value = "/refundExpress") public FebsResponse refundExpress(@RequestBody RefundExpressDto refundExpressDto) { mallOrderInfoService.refundExpress(refundExpressDto); return new FebsResponse().success().message("提交成功"); } @ApiOperation(value = "评价", notes = "评价") @PostMapping(value = "/goodsComment") public FebsResponse goodsComment(@RequestBody ApiAddCommentDtos addCommentDtos) { mallOrderInfoService.goodsComment(addCommentDtos); return new FebsResponse().success().message("评价成功"); } @ApiOperation(value = "获取微信订阅TemplateId") @GetMapping(value = "/getTemplateId") public FebsResponse getTemplateId() { return new FebsResponse().success().data(iXcxPayService.getTemplateId()); } // ==================== LWPAY 支付 ==================== /** * 创建订单并通过 LWPAY 支付 *

* 流程:创建订单 → 调 LWPAY 代收接口 → 返回支付 URL *

* 参数说明: * - bankCode: 银行编码,968=USDT-TRC20 * - network: 网络链,TRX/ETH/MATIC/BSC/SOL/ARBEVM(bankCode=968 时必填) */ @ApiOperation(value = "创建订单-LWPAY支付", notes = "创建订单并返回LWPAY支付URL") @PostMapping(value = "/createOrderByLwPay") @Limit(key = "createOrderByLwPay", period = 1, count = 1, name = "LWPAY下单", prefix = "limit", limitType = LimitType.IP) public FebsResponse createOrderByLwPay(@RequestBody @Validated LwPayCreateOrderDto lwPayDto) { // 1. 创建订单 AddOrderDto addOrderDto = lwPayDto.getOrder(); Long orderId = mallOrderInfoService.createOrder(addOrderDto); // 2. 获取订单详情 MallOrderInfo order = mallOrderInfoService.getById(orderId); if (order == null) { return new FebsResponse().fail().message("订单创建失败"); } // 3. 调用 LWPAY 代收接口 try { String payUrl = lwPayService.createPayment( order, lwPayDto.getBankCode(), lwPayDto.getNetwork() ); Map result = new HashMap<>(); result.put("orderNo", order.getOrderNo()); result.put("amount", order.getAmount()); result.put("payUrl", payUrl); return new FebsResponse().success().data(result).message("下单成功"); } catch (Exception e) { log.error("LWPAY 代收下单失败: orderId={}", orderId, e); return new FebsResponse().fail().message("支付通道异常: " + e.getMessage()); } } /** * LWPAY 支付结果通知(服务端回调) *

* LWPAY 在支付完成后会 POST 通知到此地址。 * 需在 LWPAY 商户后台配置 pay_notifyurl 为此地址。 *

* 注意:收到后必须响应 "OK",LWPAY 才会停止重试。 */ @ApiOperation(value = "LWPAY 支付回调", notes = "接收LWPAY异步通知") @PostMapping(value = "/lwPayNotify") public String lwPayNotify(HttpServletRequest request) { // 解析 form 参数 Map params = new HashMap<>(); Enumeration paramNames = request.getParameterNames(); while (paramNames.hasMoreElements()) { String name = paramNames.nextElement(); params.put(name, request.getParameter(name)); } log.info("LWPAY 回调参数: {}", params); boolean success = lwPayService.handleCallback(params); return success ? "OK" : "FAIL"; } /** * LWPAY 支付结果页面跳转 *

* 用户在 LWPAY 支付页面完成后跳回此地址。 * 需在 LWPAY 商户后台配置 pay_callbackurl 为此地址。 */ @ApiOperation(value = "LWPAY 支付跳转", notes = "LWPAY支付完成后的页面跳转") @GetMapping(value = "/lwPayReturn") public String lwPayReturn(HttpServletRequest request) { // 简单跳转到前端结果页 String orderId = request.getParameter("orderid"); String returncode = request.getParameter("returncode"); log.info("LWPAY 页面跳转: orderNo={}, returncode={}", orderId, returncode); return "redirect:/pages/payResult?orderNo=" + orderId + "&code=" + returncode; } @ApiOperation(value = "根据国家编码查询运费", notes = "根据国家编码查询对应运费") @ApiResponses({ @ApiResponse(code = 200, message = "success") }) @GetMapping(value = "/getShippingFee") public FebsResponse getShippingFee(@RequestParam String countryCode) { return countryDeliveryService.getShippingFeeByCountryCode(countryCode); } }