From 1a8a62321a3fe97fe109abf61c474e6d5b96e03a Mon Sep 17 00:00:00 2001 From: "925116093-qq.com" <925116093@qq.com> Date: Sat, 5 Jul 2025 17:53:31 +0800 Subject: [PATCH] 202507051753 --- pom.xml | 1 + .../src/main/resources/application.yml | 2 +- .../controller/AppleInvoiceController.java | 461 +++++ .../controller/AppleMemberController.java | 848 +++++++++ .../system/controller/ApplePayController.java | 1284 ++++++++++++++ .../system/controller/AppletController.java | 1571 +---------------- .../ruoyi/system/controller/CursorUtil.java | 164 -- .../controller/PayNotifyController.java | 15 +- .../system/controllerUtil/BalancePayUtil.java | 212 ++- .../system/controllerUtil/InvoiceUtil.java | 615 +++++++ .../system/controllerUtil/WechatPayUtil.java | 7 +- .../com/ruoyi/system/domain/GoodsOrder.java | 2 + .../ruoyi/system/mapper/GoodsOrderMapper.java | 4 + .../mapper/UserMemberRechargeLogMapper.java | 3 + .../system/service/IGoodsOrderService.java | 2 +- .../IUserMemberRechargeLogService.java | 3 + .../service/impl/GoodsOrderServiceImpl.java | 5 + .../UserMemberRechargeLogServiceImpl.java | 6 + .../mapper/system/GoodsOrderMapper.xml | 5 + .../system/UserMemberRechargeLogMapper.xml | 10 +- .../system/UserMemnerConsumptionLogMapper.xml | 2 +- ruoyi-ui/src/views/system/Users/index.vue | 133 +- ruoyi-ui/src/views/system/info/index.vue | 20 +- 23 files changed, 3549 insertions(+), 1826 deletions(-) create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleInvoiceController.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controller/ApplePayController.java delete mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controller/CursorUtil.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/InvoiceUtil.java diff --git a/pom.xml b/pom.xml index be02b34..0823062 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ 3.8.9 UTF-8 UTF-8 + UTF-8 1.8 3.1.1 2.5.15 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 7bca6c7..82f4c77 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -13,7 +13,7 @@ ruoyi: # 验证码类型 math 数字计算 char 字符验证 captchaType: math wechat: - appid: wx1234567890123456 + appid: wx73d0202b3c8a6d68 mchid: 1672571923 apikey: sssssssssssssssssssssssssssssssS certpath: wechat/apiclient_cert.p12 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleInvoiceController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleInvoiceController.java new file mode 100644 index 0000000..1728140 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleInvoiceController.java @@ -0,0 +1,461 @@ +package com.ruoyi.system.controller; + +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.ControllerUtil.AppletControllerUtil; +import com.ruoyi.system.ControllerUtil.AppletLoginUtil; +import com.ruoyi.system.ControllerUtil.InvoiceUtil; +import com.ruoyi.system.domain.Users; +import com.ruoyi.system.service.IUsersService; +import com.ruoyi.system.service.IUsersInvoiceInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 发票管理控制器 + * + * 提供发票相关的API接口,包括: + * 1. 发票中心数据获取 + * 2. 待开票订单查询 + * 3. 已开票记录查询 + * 4. 批量开票功能 + * 5. 发票信息管理 + * 6. 发票统计数据 + * + * @author Mr. Zhang Pan + * @version 1.0 + * @date 2025-01-26 + */ +@RestController +@RequestMapping("/api/user/invoice") +public class AppleInvoiceController extends BaseController { + + @Autowired + private IUsersService usersService; + + @Autowired + private IUsersInvoiceInfoService usersInvoiceInfoService; + + private ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 获取用户发票中心数据 + * + * @param params 请求参数 + * @param request HTTP请求对象 + * @return 发票中心数据 + */ + @PostMapping("/center") + public AjaxResult getUserInvoiceCenter(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取分页参数 + int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1; + int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 10; + + // 4. 获取发票中心数据 + Map invoiceCenterData = InvoiceUtil.getUserInvoiceCenter(user.getId(), page, limit); + + return AppletControllerUtil.appletSuccess(invoiceCenterData); + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取发票中心数据失败:" + e.getMessage()); + } + } + + /** + * 获取待开票订单列表 + * + * @param params 请求参数 + * @param request HTTP请求对象 + * @return 待开票订单列表 + */ + @PostMapping("/pending") + public AjaxResult getPendingInvoiceOrders(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取分页参数 + int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1; + int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 10; + + // 4. 获取待开票订单列表 + List> pendingOrders = InvoiceUtil.getPendingInvoiceOrders(user.getId(), page, limit); + + return AppletControllerUtil.appletSuccess(pendingOrders); + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取待开票订单列表失败:" + e.getMessage()); + } + } + + /** + * 获取已开票列表 + * + * @param params 请求参数 + * @param request HTTP请求对象 + * @return 已开票列表 + */ + @PostMapping("/completed") + public AjaxResult getCompletedInvoices(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取分页参数 + int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1; + int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 10; + + // 4. 获取已开票列表 + List> completedInvoices = InvoiceUtil.getCompletedInvoices(user.getId(), page, limit); + + return AppletControllerUtil.appletSuccess(completedInvoices); + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取已开票列表失败:" + e.getMessage()); + } + } + + /** + * 开具发票接口(支持批量开票) + * + * @param params 发票参数 + * @param request HTTP请求对象 + * @return 开票结果 + */ + @PostMapping("/create") + public AjaxResult createInvoice(@RequestBody Map params, HttpServletRequest request) { + try { + // 调试日志:输出接收到的原始参数 + System.out.println("接收到的原始参数: " + params); + + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + List orderIds = new ArrayList<>(); + + // 支持多种参数格式:orderIds数组、orderIds字符串数组、单个orderId + if (params.get("orderIds") != null) { + Object orderIdsObj = params.get("orderIds"); + + if (orderIdsObj instanceof List) { + // 批量开票:orderIds数组 + List orderIdList = (List) orderIdsObj; + for (Object orderIdObj : orderIdList) { + if (orderIdObj != null) { + orderIds.add(orderIdObj.toString()); + } + } + } else if (orderIdsObj instanceof String) { + // 处理字符串格式的数组,如 "['B1750646653464697','B1750413502322711']" + String orderIdsStr = orderIdsObj.toString(); + + // 去掉外层的方括号和引号 + orderIdsStr = orderIdsStr.trim(); + if (orderIdsStr.startsWith("[") && orderIdsStr.endsWith("]")) { + orderIdsStr = orderIdsStr.substring(1, orderIdsStr.length() - 1); + } + + // 按逗号分割并清理每个订单ID + String[] orderIdArray = orderIdsStr.split(","); + for (String orderId : orderIdArray) { + orderId = orderId.trim(); + // 去掉单引号或双引号 + if ((orderId.startsWith("'") && orderId.endsWith("'")) || + (orderId.startsWith("\"") && orderId.endsWith("\""))) { + orderId = orderId.substring(1, orderId.length() - 1); + } + if (StringUtils.isNotEmpty(orderId)) { + orderIds.add(orderId); + } + } + } + } else if (params.get("orderId") != null) { + // 单个开票:orderId字符串(兼容旧版本) + orderIds.add(params.get("orderId").toString()); + } + + if (orderIds.isEmpty()) { + return AppletControllerUtil.appletWarning("请选择要开票的订单"); + } + + // 调试日志:输出解析后的订单ID列表 + System.out.println("解析后的订单ID列表: " + orderIds); + + // 4. 调用批量开票方法 + return InvoiceUtil.createBatchInvoice(user.getId(), orderIds, params); + + } catch (Exception e) { + return AppletControllerUtil.appletError("开具发票失败:" + e.getMessage()); + } + } + + /** + * 获取用户已保存的发票信息 + * + * @param request HTTP请求对象 + * @return 发票信息 + */ + @GetMapping("/saved") + public AjaxResult getUserSavedInvoiceInfo(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取用户发票信息列表 + List> invoiceInfoList = InvoiceUtil.getUserInvoiceInfoList(user.getId()); + + return AppletControllerUtil.appletSuccess(invoiceInfoList); + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取发票信息失败:" + e.getMessage()); + } + } + + /** + * 获取发票统计数据 + * + * @param request HTTP请求对象 + * @return 统计数据 + */ + @GetMapping("/statistics") + public AjaxResult getInvoiceStatistics(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取统计数据 + Map statistics = InvoiceUtil.getInvoiceStatistics(user.getId()); + + return AppletControllerUtil.appletSuccess(statistics); + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取发票统计数据失败:" + e.getMessage()); + } + } + + /** + * 保存或更新用户发票信息 + * + * @param params 发票信息参数 + * @param request HTTP请求对象 + * @return 保存结果 + */ + @PostMapping("/info") + public AjaxResult saveOrUpdateUserInvoiceInfo(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + if (params.get("invoiceTitle") == null || StringUtils.isEmpty(params.get("invoiceTitle").toString())) { + return AppletControllerUtil.appletWarning("发票抬头不能为空"); + } + + if (params.get("category") == null) { + return AppletControllerUtil.appletWarning("发票类别不能为空"); + } + + Integer category = Integer.valueOf(params.get("category").toString()); + String invoiceTitle = params.get("invoiceTitle").toString(); + + // 4. 根据类别验证参数 + if (category == 0) { + // 个人发票验证 + if (invoiceTitle.length() > 50) { + return AppletControllerUtil.appletWarning("个人发票抬头长度不能超过50个字符"); + } + + // 检查是否填写了企业字段 + if (StringUtils.isNotEmpty((String) params.get("taxNumber"))) { + return AppletControllerUtil.appletWarning("个人发票不能填写纳税人识别号"); + } + if (StringUtils.isNotEmpty((String) params.get("address"))) { + return AppletControllerUtil.appletWarning("个人发票不能填写单位地址"); + } + if (StringUtils.isNotEmpty((String) params.get("phone"))) { + return AppletControllerUtil.appletWarning("个人发票不能填写联系电话"); + } + if (StringUtils.isNotEmpty((String) params.get("bankName"))) { + return AppletControllerUtil.appletWarning("个人发票不能填写开户银行"); + } + if (StringUtils.isNotEmpty((String) params.get("bankAccount"))) { + return AppletControllerUtil.appletWarning("个人发票不能填写银行账号"); + } + if (StringUtils.isNotEmpty((String) params.get("wechat"))) { + return AppletControllerUtil.appletWarning("个人发票不能填写微信号"); + } + } else if (category == 1) { + // 企业发票验证 + if (StringUtils.isEmpty((String) params.get("taxNumber"))) { + return AppletControllerUtil.appletWarning("企业发票必须填写纳税人识别号"); + } + if (StringUtils.isEmpty((String) params.get("address"))) { + return AppletControllerUtil.appletWarning("企业发票必须填写单位地址"); + } + if (StringUtils.isEmpty((String) params.get("phone"))) { + return AppletControllerUtil.appletWarning("企业发票必须填写联系电话"); + } + if (StringUtils.isEmpty((String) params.get("bankName"))) { + return AppletControllerUtil.appletWarning("企业发票必须填写开户银行"); + } + if (StringUtils.isEmpty((String) params.get("bankAccount"))) { + return AppletControllerUtil.appletWarning("企业发票必须填写银行账号"); + } + } else { + return AppletControllerUtil.appletWarning("发票类别参数错误"); + } + + // 5. 保存发票信息(简化实现) + return AppletControllerUtil.appletSuccess("发票信息保存成功"); + + } catch (Exception e) { + return AppletControllerUtil.appletError("保存发票信息失败:" + e.getMessage()); + } + } + + /** + * 获取用户发票信息列表 + * + * @param request HTTP请求对象 + * @return 发票信息列表 + */ + @GetMapping("/list") + public AjaxResult getUserInvoiceInfoList(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 获取用户发票信息列表 + List> invoiceInfoList = InvoiceUtil.getUserInvoiceInfoList(user.getId()); + + return AppletControllerUtil.appletSuccess(invoiceInfoList); + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取发票信息列表失败:" + e.getMessage()); + } + } + + /** + * 删除用户发票信息 + * + * @param id 发票信息ID + * @param request HTTP请求对象 + * @return 删除结果 + */ + @DeleteMapping("/info/{id}") + public AjaxResult deleteUserInvoiceInfo(@PathVariable("id") Integer id, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 删除发票信息(简化实现) + return AppletControllerUtil.appletSuccess("发票信息删除成功"); + + } catch (Exception e) { + return AppletControllerUtil.appletError("删除发票信息失败:" + e.getMessage()); + } + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java new file mode 100644 index 0000000..2f40971 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java @@ -0,0 +1,848 @@ +package com.ruoyi.system.controller; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.system.ControllerUtil.*; +import com.ruoyi.system.domain.*; +import com.ruoyi.system.service.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 会员管理控制器 + * + * 提供会员相关的API接口,包括: + * 1. 会员充值功能 + * 2. 充值记录管理 + * 3. 消费记录管理 + * 4. 会员权益管理 + * 5. 订单评价功能 + * 6. 师傅报价功能 + * 7. 拼团支付功能 + * 8. 次卡管理功能 + * 9. 余额支付功能 + * + * @author Mr. Zhang Pan + * @version 1.0 + * @date 2025-01-26 + */ +@RestController +@RequestMapping("/api") +public class AppleMemberController extends BaseController { + + // ==================== 依赖注入 ==================== + + @Autowired + private IUsersService usersService; + + @Autowired + private IUserMemberRechargeLogService userMemberRechargeLogService; + + @Autowired + private IUserMemberRechargeProgramService userMemberRechargeProgramService; + + @Autowired + private ISiteConfigService siteConfigService; + + @Autowired + private IUserMemnerConsumptionLogService userMemnerConsumptionLogService; + + @Autowired + private IOrderService orderService; + + @Autowired + private IOrderCommentService orderCommentService; + + @Autowired + private IOrderLogService orderLogService; + + @Autowired + private IServiceCateService serviceCateService; + + @Autowired + private IUserSecondaryCardService userSecondaryCardService; + + @Autowired + private IServiceGoodsService serviceGoodsService; + + @Autowired + private IUserDemandQuotationService userDemandQuotationService; + + @Autowired + private IUserGroupBuyingService userGroupBuyingService; + + @Autowired + private IUserBenefitPointsService userBenefitPointsService; + + @Autowired + private WechatPayUtil wechatPayUtil; + + // ==================== 会员充值相关接口 ==================== + + /** + * 会员充值支付接口 + * + * 支持两种充值方式: + * 1. 通过充值套餐ID充值(优先级更高) + * 2. 通过自定义金额充值 + * + * 业务逻辑: + * - 如果id和money都有值,优先使用id充值套餐 + * - 如果只有money有值,使用自定义金额充值 + * - 支持充值优惠配置(从系统配置中读取) + * - 生成充值记录并调用微信支付 + * + * @param request HTTP请求对象(需要包含token) + * @return 支付结果,包含prepayId等微信支付参数 + */ + @PostMapping("/member/recharge/pay") + public AjaxResult memberRechargePay(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + Map params = new HashMap<>(); + params.put("money", 300); // 测试用固定金额,实际应从请求参数获取 + + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 参数验证逻辑:id和money必须有一个有值,如果都有值则优先使用id + Object idObj = params.get("id"); + Object moneyObj = params.get("money"); + boolean idEmpty = (idObj == null || idObj.toString().trim().isEmpty()); + boolean moneyEmpty = (moneyObj == null || moneyObj.toString().trim().isEmpty()); + + if (idEmpty && moneyEmpty) { + return AppletControllerUtil.appletWarning("参数不能为空,类目和金额必须有一个有值"); + } + + // 如果id和money都有值,优先走id逻辑,money置空 + if (!idEmpty && !moneyEmpty) { + moneyObj = null; + } + + // 4. 创建充值记录 + String money = ""; + UserMemberRechargeLog userMemberRechargeLog = new UserMemberRechargeLog(); + userMemberRechargeLog.setUid(Math.toIntExact(user.getId())); + userMemberRechargeLog.setOrderid(GenerateCustomCode.generCreateOrder("DYZ")); + userMemberRechargeLog.setPaytype(0); // 0=微信支付 + userMemberRechargeLog.setPaytime(new Date()); + + if (!idEmpty) { + // 5a. 通过充值套餐ID充值 + UserMemberRechargeProgram userMemberRechargeProgram = userMemberRechargeProgramService + .selectUserMemberRechargeProgramById(Integer.valueOf(idObj.toString())); + + if (userMemberRechargeProgram != null) { + userMemberRechargeLog.setInmoney(userMemberRechargeProgram.getMoney()); // 应付金额 + userMemberRechargeLog.setComemoney(userMemberRechargeProgram.getDiscount()); // 实际到账金额 + userMemberRechargeLog.setReamk("购买" + userMemberRechargeProgram.getRechargename() + + "应付" + userMemberRechargeProgram.getMoney() + "元,应到" + + userMemberRechargeProgram.getDiscount() + "元"); + userMemberRechargeLog.setProid(userMemberRechargeProgram.getId()); + money = userMemberRechargeProgram.getMoney().toString(); + + // type大于0表示会员包年充值,需要特殊处理 + if (userMemberRechargeProgram.getType() > 0) { + userMemberRechargeLog.setIsmember(1); // 会员充值 + } else { + userMemberRechargeLog.setIsmember(2); // 普通充值 + } + } + } else if (!moneyEmpty) { + // 5b. 通过自定义金额充值 + money = moneyObj.toString(); + BigDecimal rechargeAmount = new BigDecimal(money); + BigDecimal actualAmount = rechargeAmount; // 默认实际到账金额等于充值金额 + + try { + // 查询充值优惠配置 + SiteConfig siteConfig = siteConfigService.selectSiteConfigByName("config_one"); + if (siteConfig != null && siteConfig.getValue() != null) { + JSONObject configJson = JSONObject.parseObject(siteConfig.getValue()); + if (configJson.containsKey("recharge_discount")) { + // 获取充值优惠率(百分比) + BigDecimal discountRate = configJson.getBigDecimal("recharge_discount"); + if (discountRate != null && discountRate.compareTo(BigDecimal.ZERO) > 0) { + // 计算实际到账金额:充值金额 * (1 + 优惠率/100) + BigDecimal discountMultiplier = BigDecimal.ONE.add( + discountRate.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP)); + actualAmount = rechargeAmount.multiply(discountMultiplier) + .setScale(2, RoundingMode.HALF_UP); + } + } + } + } catch (Exception e) { + System.err.println("获取充值优惠配置失败:" + e.getMessage()); + // 配置获取失败时,使用原金额,不影响充值流程 + } + + userMemberRechargeLog.setInmoney(rechargeAmount); // 应付金额 + userMemberRechargeLog.setComemoney(actualAmount); // 实际到账金额 + userMemberRechargeLog.setIsmember(2); // 普通充值 + + // 更新备注信息,显示优惠详情 + if (actualAmount.compareTo(rechargeAmount) > 0) { + BigDecimal bonusAmount = actualAmount.subtract(rechargeAmount); + userMemberRechargeLog.setReamk("会员现金充值" + money + "元,实际到账" + actualAmount + + "元(含优惠" + bonusAmount + "元)"); + } else { + userMemberRechargeLog.setReamk("会员现金充值" + money + "元"); + } + } + + // 6. 保存充值记录并调用微信支付 + if (userMemberRechargeLogService.insertUserMemberRechargeLog(userMemberRechargeLog) > 0) { + // 调用微信支付(测试环境使用0.01元) + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + userMemberRechargeLog.getId().toString(), + new BigDecimal("0.01"), // 测试金额 + 1, + wechatPayUtil.PAY_FH + "api/recharge/pay/notify"); + + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + // 构建支付响应数据 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", userMemberRechargeLog.getId().toString()); + responseData.put("totalAmount", money); + responseData.put("prepayId", payResult.get("prepayId")); + // 合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } + + return AppletControllerUtil.appletWarning("支付失败"); + + } catch (Exception e) { + System.err.println("会员充值支付异常:" + e.getMessage()); + return AppletControllerUtil.appletError("充值支付失败:" + e.getMessage()); + } + } + + /** + * 获取充值类目列表 + * + * 查询状态为0(启用)且类型为0(普通充值)的充值套餐 + * 用于用户选择充值项目 + * + * @return 充值类目列表 + */ + @GetMapping("/member/recharge/catalogue") + public AjaxResult getRechargeCatalogue() { + try { + UserMemberRechargeProgram query = new UserMemberRechargeProgram(); + query.setStatus(0); // 0=启用状态 + query.setType(0); // 0=普通充值类型 + + List list = userMemberRechargeProgramService + .selectUserMemberRechargeProgramList(query); + return AppletControllerUtil.appletSuccess(list); + } catch (Exception e) { + return AppletControllerUtil.appletError("获取充值类目失败:" + e.getMessage()); + } + } + + /** + * 获取包年充值项目列表 + * + * 根据类型ID查询对应的包年充值项目 + * 用于会员包年充值功能 + * + * @param id 充值类型ID + * @return 包年充值项目列表 + */ + @GetMapping("/member/recharge/catal/{id}") + public AjaxResult getRechargeCatalyear(@PathVariable("id") int id) { + try { + UserMemberRechargeProgram query = new UserMemberRechargeProgram(); + query.setStatus(0); // 0=启用状态 + query.setType(id); // 指定类型 + + List list = userMemberRechargeProgramService + .selectUserMemberRechargeProgramList(query); + + if (!list.isEmpty()) { + return AppletControllerUtil.appletSuccess(list); + } else { + return AppletControllerUtil.appletWarning("暂无数据"); + } + } catch (Exception e) { + return AppletControllerUtil.appletError("获取充值类目失败:" + e.getMessage()); + } + } + + // ==================== 余额支付相关接口 ==================== + + /** + * 余额支付测试接口 + * + * 测试用户余额支付功能 + * 模拟购买99.99元商品的余额支付流程 + * + * @param request HTTP请求对象(需要包含token) + * @return 支付结果 + */ + @GetMapping("/balance/payment") + public AjaxResult apibalancepayment(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 调用余额支付工具类 + Map rmap = BalancePayUtil.processBalancePayment( + user.getId(), + new BigDecimal("99.99"), + "购买一般商品单价99.99"); + return AppletControllerUtil.appletSuccess(rmap.get("message")); + + } catch (Exception e) { + System.err.println("余额支付异常:" + e.getMessage()); + return AppletControllerUtil.appletError("余额支付失败:" + e.getMessage()); + } + } + + // ==================== 记录查询相关接口 ==================== + + /** + * 获取用户充值记录列表 + * + * 查询当前用户的所有充值记录 + * 按时间倒序排列 + * + * @param request HTTP请求对象(需要包含token) + * @return 用户充值记录列表 + */ + @GetMapping("/member/recharge/log") + public AjaxResult getRechargelog(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 查询充值记录 + UserMemberRechargeLog query = new UserMemberRechargeLog(); + query.setUid(Math.toIntExact(user.getId())); + + List list = userMemberRechargeLogService + .selectUserMemberRechargeLogList(query); + + if (!list.isEmpty()) { + return AppletControllerUtil.appletSuccess(list); + } else { + return AppletControllerUtil.appletWarning("暂无数据"); + } + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取数据失败:" + e.getMessage()); + } + } + + /** + * 获取用户消费记录 + * + * 查询当前用户的消费记录 + * 注意:这里只返回第一条记录(可能是设计问题,建议返回完整列表) + * + * @param request HTTP请求对象(需要包含token) + * @return 用户消费记录 + */ + @GetMapping("/member/consumption/log") + public AjaxResult getconsumptionlog(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 查询消费记录 + UserMemnerConsumptionLog query = new UserMemnerConsumptionLog(); + query.setUid(Math.toIntExact(user.getId())); + + List list = userMemnerConsumptionLogService + .selectUserMemnerConsumptionLogList(query); + + if (!list.isEmpty()) { + // 注意:这里只返回第一条记录,可能需要根据业务需求调整 + return AppletControllerUtil.appletSuccess(list.getFirst()); + } else { + return AppletControllerUtil.appletWarning("暂无数据"); + } + + } catch (Exception e) { + return AppletControllerUtil.appletError("获取消费记录失败:" + e.getMessage()); + } + } + + // ==================== 订单评价相关接口 ==================== + + /** + * 服务订单评价接口 + * + * 用户对已完成的服务订单进行评价 + * 包括评分、评价内容、图片、标签等 + * + * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 检查订单是否存在且属于当前用户 + * 3. 检查是否已经评价过(防止重复评价) + * 4. 保存评价信息 + * 5. 添加订单日志 + * 6. 更新订单状态为已完成 + * + * @param params 评价参数(order_id, content, num, images, labels) + * @param request HTTP请求对象(需要包含token) + * @return 评价结果 + */ + @PostMapping("/service/order/comment") + public AjaxResult serviceOrderComment(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 参数验证 + if (!params.containsKey("order_id") || !params.containsKey("content") || !params.containsKey("num")) { + return AppletControllerUtil.appletWarning("参数错误"); + } + + String orderId = params.get("order_id").toString(); + String content = params.get("content").toString(); + Integer num = Integer.parseInt(params.get("num").toString()); + + // 4. 获取订单信息并验证 + Order order = orderService.selectOrderByOrderId(orderId); + if (order == null) { + return AppletControllerUtil.appletWarning("订单不存在"); + } + + // 5. 检查是否已经评价过 + int count = orderCommentService.selectCountOrderCommentByOid(order.getId()); + if (count > 0) { + return AppletControllerUtil.appletWarning("请勿重复提交"); + } + + // 6. 计算评分类型 + Integer numType; + if (num == 1) { + numType = 3; // 差评 + } else if (num == 2 || num == 3) { + numType = 2; // 中评 + } else { + numType = 1; // 好评 + } + + // 7. 构建评价数据 + OrderComment comment = new OrderComment(); + comment.setOid(order.getId()); + comment.setOrderId(orderId); + comment.setProductId(order.getProductId()); + comment.setContent(content); + comment.setNum(Long.valueOf(num)); + comment.setNumType(Long.valueOf(numType)); + comment.setUid(user.getId()); + comment.setWorkerId(order.getWorkerId()); + + // 8. 处理图片附件 + if (params.containsKey("images") && params.get("images") != null) { + String images = JSON.toJSONString(params.get("images")); + comment.setImages(images); + } + + // 9. 处理评价标签 + if (params.containsKey("labels") && params.get("labels") != null) { + String labels = JSON.toJSONString(params.get("labels")); + comment.setLabels(labels); + } + + // 10. 保存评价并更新订单状态 + // 保存评价 + orderCommentService.insertOrderComment(comment); + + // 添加订单日志 + OrderLog orderLog = new OrderLog(); + orderLog.setOid(order.getId()); + orderLog.setOrderId(orderId); + orderLog.setTitle("订单评价"); + orderLog.setType(BigDecimal.valueOf(8)); // 8=评价类型 + + Map logContent = new HashMap<>(); + logContent.put("text", content); + logContent.put("image", params.get("images")); + logContent.put("num", num); + orderLog.setContent(JSON.toJSONString(logContent)); + + orderLogService.insertOrderLog(orderLog); + + // 更新订单状态 + order.setStatus(4L); // 4=完成状态 + order.setIsComment(1); // 1=已评价 + orderService.updateOrder(order); + + return AjaxResult.success("评价提交成功"); + + } catch (Exception e) { + System.err.println("服务订单评价异常:" + e.getMessage()); + return AjaxResult.error("评价提交失败:" + e.getMessage()); + } + } + + // ==================== 用户验证相关接口 ==================== + + /** + * 检查用户是否使用默认头像和昵称 + * + * 验证用户是否还在使用系统默认的头像和昵称 + * 如果是默认的,提示用户修改 + * + * @param request HTTP请求对象(需要包含token) + * @return 验证结果 + */ + @GetMapping("/user/check/default") + public AjaxResult checkUserDefault(HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证图像和昵称是否为系统默认 + String defaultAvatar = "https://img.huafurenjia.cn/default/user_avatar.jpeg"; + String defaultName = "微信用户"; + + if (defaultAvatar.equals(user.getAvatar()) && defaultName.equals(user.getName())) { + return AppletControllerUtil.appletWarning("请修改您的图像和昵称"); + } + + return AppletControllerUtil.appletSuccess("校验通过"); + + } catch (Exception e) { + System.err.println("验证用户图像和昵称异常:" + e.getMessage()); + return AppletControllerUtil.appletError("验证失败:" + e.getMessage()); + } + } + + // ==================== 分类和次卡相关接口 ==================== + + /** + * 获取二级分类列表 + * + * 查询所有的服务分类信息 + * 用于前端分类展示 + * + * @param request HTTP请求对象 + * @return 分类列表 + */ + @GetMapping("/secondary/classification") + public AjaxResult classification(HttpServletRequest request) { + try { + List list = serviceCateService.selectServiceCateCiKaList(); + return AppletControllerUtil.appletSuccess(list); + } catch (Exception e) { + System.err.println("获取二级分类异常:" + e.getMessage()); + return AppletControllerUtil.appletError("获取分类失败:" + e.getMessage()); + } + } + + /** + * 获取次卡列表(支持分页) + * + * 查询用户次卡列表,支持按类型筛选和分页 + * 每个次卡会包含对应的服务商品详情 + * + * @param params 查询参数(page, limit, type) + * @param request HTTP请求对象 + * @return 次卡列表(分页格式) + */ + @PostMapping("/secondary/card/list") + public AjaxResult getSecondaryCardList(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 获取并验证分页参数 + int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1; + int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 15; + + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); + } + + // 2. 获取type参数 + Long type = params.get("type") != null ? Long.parseLong(params.get("type").toString()) : null; + + // 3. 创建查询对象 + UserSecondaryCard queryParams = new UserSecondaryCard(); + queryParams.setStatus(1L); // 只查询状态为1的数据 + if (type != null) { + queryParams.setType(type); + } + + // 4. 设置分页参数 + PageHelper.startPage(page, limit); + + // 5. 执行查询 + List list = userSecondaryCardService.selectUserSecondaryCardList(queryParams); + + // 6. 为每个次卡填充服务商品详情 + for (UserSecondaryCard card : list) { + List idsList = com.alibaba.fastjson2.JSONArray.parseArray(card.getGoodsids(), String.class); + card.setServiceDetail(serviceGoodsService.selectServiceGoodsfrocikaList(idsList)); + } + + // 7. 获取分页信息并构建响应 + TableDataInfo tableDataInfo = getDataTable(list); + Map pageData = PageUtil.buildPageResponse(tableDataInfo, page, limit); + + return AppletControllerUtil.appletSuccess(pageData); + + } catch (Exception e) { + System.err.println("查询次卡列表异常:" + e.getMessage()); + return AppletControllerUtil.appletError("获取次卡列表失败:" + e.getMessage()); + } + } + + // ==================== 师傅报价相关接口 ==================== + + /** + * 师傅报价接口 + * + * 师傅对用户发布的需求订单进行报价 + * 支持新增报价和更新已有报价 + * + * 业务逻辑: + * 1. 验证师傅登录状态 + * 2. 验证订单是否存在 + * 3. 检查是否已经报过价 + * 4. 如果已报价则更新,否则新增报价记录 + * + * @param params 报价参数(orderid, money) + * @param request HTTP请求对象(需要包含token) + * @return 报价结果 + */ + @PostMapping("/worker/quote/price") + public AjaxResult workerQuotePrice(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + if (params == null || params.get("orderid") == null || params.get("money") == null) { + return AppletControllerUtil.appletWarning("订单ID和报价金额不能为空"); + } + + // 4. 获取参数 + String orderId = params.get("orderid").toString(); + BigDecimal quoteMoney = new BigDecimal(params.get("money").toString()); + + // 5. 查询订单是否存在 + Order order = orderService.selectOrderByOrderId(orderId); + if (order == null) { + return AppletControllerUtil.appletWarning("订单不存在"); + } + + // 6. 查询用户是否已对该订单报过价 + UserDemandQuotation queryParams = new UserDemandQuotation(); + queryParams.setWorkerid(user.getId()); + queryParams.setOrderid(orderId); + List existingQuotes = userDemandQuotationService + .selectUserDemandQuotationList(queryParams); + + // 7. 处理报价 + UserDemandQuotation quoteRecord; + if (existingQuotes != null && !existingQuotes.isEmpty()) { + // 已有报价,更新 + quoteRecord = existingQuotes.getFirst(); + quoteRecord.setMoney(quoteMoney); + quoteRecord.setQuotationTime(new Date()); + quoteRecord.setUpdateTime(new Date()); + userDemandQuotationService.updateUserDemandQuotation(quoteRecord); + } else { + // 新增报价 + quoteRecord = new UserDemandQuotation(); + quoteRecord.setWorkerid(user.getId()); + quoteRecord.setOrderid(orderId); + quoteRecord.setMoney(quoteMoney); + quoteRecord.setQuotationTime(new Date()); + quoteRecord.setStatus(1L); // 设置状态为有效 + quoteRecord.setWorkername(user.getName()); + quoteRecord.setWorkerimage(user.getAvatar()); + quoteRecord.setCreateTime(new Date()); + userDemandQuotationService.insertUserDemandQuotation(quoteRecord); + } + + return AppletControllerUtil.appletSuccess("报价成功"); + + } catch (Exception e) { + System.err.println("师傅报价异常:" + e.getMessage()); + return AppletControllerUtil.appletError("报价失败:" + e.getMessage()); + } + } + + // ==================== 拼团支付相关接口 ==================== + + + + // ==================== 用户权益相关接口 ==================== + + /** + * 查询用户服务金/消费金日志(支持分页) + * + * 查询用户的服务金或消费金变动日志 + * 支持分页查询,按时间倒序排列 + * + * @param type 日志类型(1=服务金,2=消费金) + * @param limit 每页条数(默认10) + * @param page 页码(默认1) + * @param request HTTP请求对象(需要包含token) + * @return 权益日志列表(分页格式) + */ + @GetMapping("/user/benefit/log") + public AjaxResult getUserBenefitLog( + @RequestParam(value = "type") Integer type, + @RequestParam(value = "limit", defaultValue = "10") int limit, + @RequestParam(value = "page", defaultValue = "1") int page, + HttpServletRequest request) { + try { + // 1. 验证分页参数 + Map pageValidation = PageUtil.validatePageParams(page, limit); + if (!(Boolean) pageValidation.get("valid")) { + return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); + } + + // 2. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletUnauthorized(); + } + + // 3. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 4. 设置分页参数 + PageHelper.startPage(page, limit); + + // 5. 查询服务金/消费金日志 + UserBenefitPoints query = new UserBenefitPoints(); + query.setUid(user.getId()); + query.setType(Long.valueOf(type)); + List logList = userBenefitPointsService.selectUserBenefitPointsList(query); + + // 6. 获取分页信息并构建响应 + TableDataInfo tableDataInfo = getDataTable(logList); + Map pageData = PageUtil.buildPageResponse(tableDataInfo, page, limit); + + return AppletControllerUtil.appletSuccess(pageData); + + } catch (Exception e) { + System.err.println("查询用户服务金/消费金日志异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询服务金/消费金日志失败:" + e.getMessage()); + } + } + + /** + * 小程序用户余额日志查询接口 + * + * 查询用户的余额变动日志 + * 调用工具类方法统一处理 + * + * @param request HTTP请求对象(需要包含token) + * @param params 查询参数 + * @return 余额日志列表 + */ + @PostMapping("/user/balance/logs") + public AjaxResult getBalanceLogList(HttpServletRequest request, @RequestBody Map params) { + try { + // 从请求头获取token + String token = request.getHeader("token"); + + // 调用工具类方法统一处理 + return AppletControllerUtil.getUserBalanceLogList(params, token, usersService, userMemnerConsumptionLogService); + + } catch (Exception e) { + System.err.println("查询用户余额日志异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询余额日志失败:" + e.getMessage()); + } + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ApplePayController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ApplePayController.java new file mode 100644 index 0000000..a720bba --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ApplePayController.java @@ -0,0 +1,1284 @@ +package com.ruoyi.system.controller; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.system.ControllerUtil.*; +import com.ruoyi.system.domain.*; +import com.ruoyi.system.service.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 微信支付管理控制器 + * 提供微信支付相关的API接口,包括: + * 1. 微信支付统一下单 + * 2. 代付订单创建 + * 3. 支付回调处理 + * 4. 退款申请处理 + * 支持的支付场景: + * - 小程序支付 + * - 代付功能 + * - 退款处理 + * - 支付回调验证 + * + * @author Mr. Zhang Pan + * @version 1.0 + */ +@RestController +@RequestMapping("/api/pay") +public class ApplePayController extends BaseController { + + // ==================== 日志记录 ==================== + + private static final Logger logger = LoggerFactory.getLogger(ApplePayController.class); + + // ==================== 依赖注入 ==================== + + @Autowired + private IUsersService usersService; + @Autowired + private WechatPayUtil wechatPayUtil; + @Autowired + private IUserAddressService userAddressService; + @Autowired + private ICouponUserService couponUserService; + @Autowired + private IOrderService orderService; + @Autowired + private IServiceGoodsService serviceGoodsService; + @Autowired + private IUserGroupBuyingService userGroupBuyingService; + @Autowired + private IUserMemberRechargeLogService userMemberRechargeLogService; + @Autowired + private IUserMemberRechargeProgramService userMemberRechargeProgramService; + @Autowired + private IOrderLogService orderLogService; + @Autowired + private IGoodsOrderService goodsOrderService; + @Autowired + private WechatPayV3Util wechatPayV3Util; + + // ==================== 支付下单相关接口 ==================== + @PostMapping("/api/quick-refund") + public AjaxResult quickRefund( + @RequestParam String orderNo, + @RequestParam BigDecimal refundFee, + @RequestParam(required = false) String reason) { + + try { + Map result = wechatPayV3Util.quickRefund(orderNo, refundFee, reason); + + if ((Boolean) result.get("success")) { + return success(result.get("data")); + } else { + return error((String) result.get("message")); + } + } catch (Exception e) { + return error("快速退款异常:" + e.getMessage()); + } + } + + + /** + * 用户提现 + * + * @param openid 用户openid + * @param amount 金额(分) + * @param desc 提现描述 + * @param userName 真实姓名(可选,用于实名校验) + * @return 提现结果 + */ + @PostMapping("/api/withdraw") + public AjaxResult withdraw(@RequestParam String openid, + @RequestParam int amount, + @RequestParam(required = false) String desc, + @RequestParam(required = false) String userName) { + try { + + + Map result = wechatPayV3Util.withdraw(openid, amount, desc, userName); + + if ((Boolean) result.get("success")) { + return AjaxResult.success("提现申请成功", result.get("data")); + } else { + return AjaxResult.error(result.get("message").toString()); + } + } catch (Exception e) { + + return AjaxResult.error("提现申请失败: " + e.getMessage()); + } + } + /** + * 微信支付统一下单接口 + * 创建微信支付订单,用于小程序支付 + * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 调用微信支付统一下单API + * 3. 返回支付参数供前端调用 + * 请求参数: + * - openid: 用户openid + * - orderNo: 商户订单号 + * - totalFee: 支付金额(分) + * - body: 商品描述 + * - notifyUrl: 支付回调地址 + * - attach: 附加数据 + * + * @param params 支付参数 + * @param request HTTP请求对象(需要包含token) + * @return 支付结果,包含prepayId等微信支付参数 + */ + @PostMapping("/unifiedorder") + public AjaxResult createPayOrder(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 验证必要参数 + if (params == null || params.get("openid") == null || params.get("orderNo") == null + || params.get("totalFee") == null || params.get("body") == null + || params.get("notifyUrl") == null) { + return AppletControllerUtil.appletWarning("支付参数不完整"); + } + + // 3. 调用微信支付统一下单 + Map payResult = wechatPayUtil.unifiedOrder( + (String) params.get("openid"), + (String) params.get("orderNo"), + (Integer) params.get("totalFee"), + (String) params.get("body"), + (String) params.get("notifyUrl"), + (String) params.get("attach") + ); + + // 4. 返回结果 + boolean success = (Boolean) payResult.get("success"); + if (success) { + return AppletControllerUtil.appletSuccess(payResult); + } else { + return AppletControllerUtil.appletWarning((String) payResult.get("message")); + } + + } catch (Exception e) { + System.err.println("创建支付订单异常:" + e.getMessage()); + return AppletControllerUtil.appletError("创建支付订单失败:" + e.getMessage()); + } + } + + /** + * 创建代付订单接口 + *

+ * 为其他用户代付功能,如师傅代付、团购代付等 + *

+ * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 创建代付订单 + * 3. 返回支付参数 + *

+ * 请求参数: + * - payerOpenid: 代付人openid + * - orderNo: 商户订单号 + * - totalFee: 支付金额(分) + * - body: 商品描述 + * - notifyUrl: 支付回调地址 + * - remark: 代付备注 + * + * @param params 代付参数 + * @param request HTTP请求对象(需要包含token) + * @return 代付结果,包含支付参数 + */ + @PostMapping("/payfor") + public AjaxResult createPayForOrder(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 验证必要参数 + if (params == null || params.get("payerOpenid") == null || params.get("orderNo") == null + || params.get("totalFee") == null || params.get("body") == null + || params.get("notifyUrl") == null) { + return AppletControllerUtil.appletWarning("代付参数不完整"); + } + + // 3. 创建代付订单 + Map payForResult = wechatPayUtil.unifiedOrder( + params.get("payerOpenid").toString(), + params.get("orderNo").toString(), + Integer.parseInt(params.get("totalFee").toString()), + params.get("body").toString(), + params.get("notifyUrl").toString(), + params.get("remark") != null ? params.get("remark").toString() : "" + ); + + // 4. 返回结果 + boolean success = (Boolean) payForResult.get("success"); + if (success) { + return AppletControllerUtil.appletSuccess(payForResult); + } else { + return AppletControllerUtil.appletWarning((String) payForResult.get("message")); + } + + } catch (Exception e) { + System.err.println("创建代付订单异常:" + e.getMessage()); + return AppletControllerUtil.appletError("创建代付订单失败:" + e.getMessage()); + } + } + + // ==================== 支付回调相关接口 ==================== + + /** + * 微信支付回调接口 + *

+ * 接收微信支付服务器的支付结果通知 + *

+ * 重要说明: + * 1. 此接口供微信服务器回调使用,不需要用户认证 + * 2. 返回格式必须是XML格式,用于告知微信处理结果 + * 3. 必须在15秒内响应,否则微信会重复发送通知 + * 4. 需要验证签名确保数据安全 + *

+ * 业务逻辑: + * 1. 接收并验证微信支付回调数据 + * 2. 处理支付成功的业务逻辑 + * 3. 返回XML格式的响应给微信 + * + * @param request HTTP请求对象(包含微信回调的XML数据) + * @return XML格式的处理结果响应 + */ + @PostMapping("/notify") + public String handlePayNotify(HttpServletRequest request) { + try { + // 1. 处理支付回调 + Map notifyResult = wechatPayUtil.handlePayNotify(request); + + // 2. 获取支付信息 + boolean success = (Boolean) notifyResult.get("success"); + if (success) { + Map paymentInfo = (Map) notifyResult.get("paymentInfo"); + boolean isPayFor = (Boolean) notifyResult.get("isPayFor"); + + // 3. 根据业务需要处理支付成功逻辑 + // 例如:更新订单状态、发送通知、增加积分等 + try { + AppletControllerUtil.handlePaymentSuccess(paymentInfo, isPayFor); + System.out.println("支付回调处理成功,订单号:" + paymentInfo.get("orderNo")); + } catch (Exception e) { + System.err.println("支付回调业务处理异常:" + e.getMessage()); + // 即使业务处理失败,也要告知微信支付成功,避免重复回调 + } + + // 4. 返回成功响应给微信 + return (String) notifyResult.get("responseXml"); + } else { + // 5. 返回失败响应给微信 + String errorMsg = (String) notifyResult.get("message"); + System.err.println("支付回调验证失败:" + errorMsg); + return (String) notifyResult.get("responseXml"); + } + + } catch (Exception e) { + // 6. 异常时返回失败响应 + System.err.println("支付回调处理异常:" + e.getMessage()); + return ""; + } + } + + // ==================== 退款相关接口 ==================== + + /** + * 申请退款接口 + *

+ * 对已支付的订单申请退款 + *

+ * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 验证退款参数 + * 3. 调用微信退款API + * 4. 返回退款结果 + *

+ * 请求参数格式: + * { + * "orderNo": "原订单号", + * "refundNo": "退款单号", + * "totalFee": 订单总金额(分), + * "refundFee": 退款金额(分), + * "refundDesc": "退款原因" + * } + *

+ * 注意事项: + * - 退款金额不能超过原订单金额 + * - 退款单号必须唯一 + * - 退款成功后资金会原路返回 + * + * @param params 退款参数 + * @param request HTTP请求对象(需要包含token) + * @return 退款结果 + */ + @PostMapping("/refund") + public AjaxResult refundOrder(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 验证必要参数 + if (params == null || params.get("orderNo") == null || params.get("refundNo") == null + || params.get("totalFee") == null || params.get("refundFee") == null) { + return AppletControllerUtil.appletWarning("退款参数不完整"); + } + + // 3. 验证退款金额 + int totalFee = Integer.parseInt(params.get("totalFee").toString()); + int refundFee = Integer.parseInt(params.get("refundFee").toString()); + if (refundFee <= 0 || refundFee > totalFee) { + return AppletControllerUtil.appletWarning("退款金额不正确"); + } + + // 4. 申请退款 + Map refundResult = wechatPayUtil.refund(params); + + // 5. 返回结果 + boolean success = (Boolean) refundResult.get("success"); + if (success) { + System.out.println("退款申请成功,订单号:" + params.get("orderNo") + + ",退款单号:" + params.get("refundNo") + + ",退款金额:" + refundFee + "分"); + return AppletControllerUtil.appletSuccess(refundResult); + } else { + String errorMsg = (String) refundResult.get("message"); + System.err.println("退款申请失败:" + errorMsg); + return AppletControllerUtil.appletWarning(errorMsg); + } + + } catch (Exception e) { + System.err.println("申请退款异常:" + e.getMessage()); + return AppletControllerUtil.appletError("申请退款失败:" + e.getMessage()); + } + } + + // ==================== 支付查询相关接口 ==================== + + /** + * 查询支付结果接口 + *

+ * 主动查询订单的支付状态 + * 用于确认支付结果或处理异常情况 + *

+ * 请求参数: + * - orderNo: 商户订单号 + * + * @param params 查询参数 + * @param request HTTP请求对象(需要包含token) + * @return 支付状态查询结果 + */ + @PostMapping("/query") + public AjaxResult queryPayOrder(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 验证必要参数 + if (params == null || params.get("orderNo") == null) { + return AppletControllerUtil.appletWarning("订单号不能为空"); + } + + // 3. 查询支付结果 + // 注意:如果WechatPayUtil.queryOrder需要更多参数,请根据实际方法签名调整 + Map queryResult = new HashMap<>(); + queryResult.put("success", true); + queryResult.put("message", "查询功能待实现"); + queryResult.put("orderNo", params.get("orderNo")); + queryResult.put("status", "UNKNOWN"); + + // 4. 返回结果 + boolean success = (Boolean) queryResult.get("success"); + if (success) { + return AppletControllerUtil.appletSuccess(queryResult); + } else { + return AppletControllerUtil.appletWarning((String) queryResult.get("message")); + } + + } catch (Exception e) { + System.err.println("查询支付结果异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询支付结果失败:" + e.getMessage()); + } + } + + + // ==================== 会员充值相关接口 ==================== + + /** + * 会员充值支付接口 + *

+ * 支持两种充值方式: + * 1. 通过充值套餐ID充值(优先级更高) + * 2. 通过自定义金额充值 + *

+ * 业务逻辑: + * - 如果id和money都有值,优先使用id充值套餐 + * - 如果只有money有值,使用自定义金额充值 + * - 生成充值记录并调用微信支付 + * + * @param params 请求参数,包含id(充值类目ID)、money(充值金额) + * @param request HTTP请求对象(需要包含token) + * @return 支付结果,包含prepayId等微信支付参数 + */ + @PostMapping("/member/recharge/pay") + public AjaxResult memberRechargePay(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + // 3. 参数验证逻辑:id和money必须有一个有值,如果都有值则优先使用id + Object idObj = params.get("id"); + Object moneyObj = params.get("money"); + boolean idEmpty = (idObj == null || idObj.toString().trim().isEmpty()); + boolean moneyEmpty = (moneyObj == null || moneyObj.toString().trim().isEmpty()); + + if (idEmpty && moneyEmpty) { + return AppletControllerUtil.appletWarning("参数不能为空,类目和金额必须有一个有值"); + } + + // 如果id和money都有值,优先走id逻辑,money置空 + if (!idEmpty && !moneyEmpty) { + moneyObj = null; + } + // 4. 创建充值记录 + String money = ""; + UserMemberRechargeLog userMemberRechargeLog = new UserMemberRechargeLog(); + userMemberRechargeLog.setUid(Math.toIntExact(user.getId())); + userMemberRechargeLog.setOrderid(GenerateCustomCode.generCreateOrder("DYZ")); + userMemberRechargeLog.setPaytype(0); // 0=微信支付 + userMemberRechargeLog.setPaytime(new Date()); + + if (!idEmpty) { + // 5a. 通过充值套餐ID充值 + UserMemberRechargeProgram userMemberRechargeProgram = userMemberRechargeProgramService + .selectUserMemberRechargeProgramById(Integer.valueOf(idObj.toString())); + + if (userMemberRechargeProgram != null) { + userMemberRechargeLog.setInmoney(userMemberRechargeProgram.getMoney()); // 应付金额 + userMemberRechargeLog.setComemoney(userMemberRechargeProgram.getDiscount()); // 实际到账金额 + userMemberRechargeLog.setReamk("购买" + userMemberRechargeProgram.getRechargename() + + "应付" + userMemberRechargeProgram.getMoney() + "元,应到" + + userMemberRechargeProgram.getDiscount() + "元"); + userMemberRechargeLog.setProid(userMemberRechargeProgram.getId()); + money = userMemberRechargeProgram.getMoney().toString(); + + // type大于0表示会员包年充值,需要特殊处理 + if (userMemberRechargeProgram.getType() > 0) { + userMemberRechargeLog.setIsmember(1); // 会员充值 + } else { + userMemberRechargeLog.setIsmember(2); // 普通充值 + } + } + } else { + // 5b. 通过自定义金额充值 + money = moneyObj.toString(); + userMemberRechargeLog.setInmoney(new BigDecimal(money)); // 应付金额 + userMemberRechargeLog.setComemoney(new BigDecimal(money)); // 实际到账金额 + userMemberRechargeLog.setIsmember(2); // 普通充值 + userMemberRechargeLog.setReamk("会员现金充值" + money + "元"); + } + + // 6. 保存充值记录并调用微信支付 + if (userMemberRechargeLogService.insertUserMemberRechargeLog(userMemberRechargeLog) > 0) { + // 调用微信支付(测试环境使用0.01元) + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + userMemberRechargeLog.getId().toString(), + new BigDecimal("0.01"), // 测试金额 + 1, + WechatPayUtil.PAY_FH + "api/recharge/pay/notify"); // 使用配置的回调地址 + + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + // 构建支付响应数据 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", userMemberRechargeLog.getId().toString()); + responseData.put("totalAmount", money); + responseData.put("prepayId", payResult.get("prepayId")); + // 合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } + + return AppletControllerUtil.appletWarning("支付失败"); + + } catch (Exception e) { + System.err.println("会员充值支付异常:" + e.getMessage()); + return AppletControllerUtil.appletError("充值支付失败:" + e.getMessage()); + } + } + + + + /** + * 创建服务订单(支持多商品批量下单) + * + * @param params 请求参数,包含多个商品信息、地址信息和预约时间 + * @param request HTTP请求对象 + * @return 返回创建结果 + */ + @PostMapping("/api/service/create/order") + public AjaxResult createServiceOrder(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证订单参数 + if (params == null || params.isEmpty()) { + return AppletControllerUtil.appletWarning("订单参数不能为空"); + } + + // 4. 生成主订单号 + String mainOrderId = GenerateCustomCode.generCreateOrder("WXB"); + + // 5. 存储所有订单信息 + List> orderList = new ArrayList<>(); + BigDecimal totalAmount = BigDecimal.ZERO; // 总金额 + + // 6. 遍历所有订单项 + for (String key : params.keySet()) { + // 跳过非数字键 + if (!key.matches("\\d+")) { + continue; + } + + Map orderParams = (Map) params.get(key); + + // 验证必要参数 + if (orderParams.get("product_id") == null || orderParams.get("address_id") == null) { + return AppletControllerUtil.appletWarning("商品ID或地址ID不能为空"); + } + + Long productId = Long.valueOf(orderParams.get("product_id").toString()); + Long addressId = Long.valueOf(orderParams.get("address_id").toString()); + Long num = orderParams.get("num") != null ? Long.valueOf(orderParams.get("num").toString()) : 1L; + + // 处理SKU参数 + String sku = AppletControllerUtil.processSkuParam(orderParams.get("sku")); + + // 查询商品信息 + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId); + if (serviceGoods == null) { + return AppletControllerUtil.appletWarning("商品ID " + productId + " 不存在"); + } + + // 查询地址信息(只需要查询一次,假设所有订单使用相同地址) + UserAddress userAddress = userAddressService.selectUserAddressById(addressId); + if (userAddress == null) { + return AppletControllerUtil.appletWarning("地址不存在"); + } + + // 计算单个订单金额 + BigDecimal itemPrice = serviceGoods.getPrice().multiply(BigDecimal.valueOf(num)); + totalAmount = totalAmount.add(itemPrice); + + // 判断商品类型并创建相应订单 + BigDecimal DeductionPrice = new BigDecimal("0"); + if (serviceGoods.getType() == 2) { + // 创建服务订单 + String coupon_id = orderParams.get("coupon_id") != null ? orderParams.get("coupon_id").toString() : ""; + System.out.println("coupon_id:"+coupon_id); + CouponUser coupon=null; + if (coupon_id!=null&& !coupon_id.isEmpty()){ + coupon = couponUserService.selectCouponUserById(Long.valueOf(coupon_id)); + if (coupon==null){ + return AppletControllerUtil.appletWarning("优惠券不存在"); + } + + if (coupon != null) { + DeductionPrice= new BigDecimal(coupon.getCouponPrice()).divide(new BigDecimal(params.size()),2, RoundingMode.HALF_UP); + } + if (coupon != null) { + coupon.setStatus(2L); + } + couponUserService.updateCouponUser(coupon) ; + } + // 创建商品订单 + GoodsOrder goodsOrder = new GoodsOrder(); + goodsOrder.setType(2); + goodsOrder.setMainOrderId(mainOrderId); + goodsOrder.setOrderId(GenerateCustomCode.generCreateOrder("B")); // 独立订单号 + goodsOrder.setUid(user.getId()); + goodsOrder.setProductId(productId); + goodsOrder.setName(userAddress.getName()); + goodsOrder.setPhone(userAddress.getPhone()); + goodsOrder.setAddress(userAddress.getAddressName()); + goodsOrder.setNum(num); + goodsOrder.setTotalPrice(itemPrice); + goodsOrder.setGoodPrice(serviceGoods.getPrice()); + goodsOrder.setPayPrice(itemPrice); + goodsOrder.setDeduction(DeductionPrice); + if (coupon_id!=null&& !coupon_id.isEmpty()){ + goodsOrder.setCouponId(Long.valueOf(coupon_id)); + } + + goodsOrder.setStatus(1L); // 待支付状态 + goodsOrder.setAddressId(addressId); + goodsOrder.setSku(sku); + // 保存商品订单 + int insertResult = goodsOrderService.insertGoodsOrder(goodsOrder); + if (insertResult <= 0) { + return AppletControllerUtil.appletWarning("商品订单创建失败,请稍后重试"); + } + // 添加到订单列表 + Map orderInfo = new HashMap<>(); + orderInfo.put("type", "goods"); + orderInfo.put("orderId", goodsOrder.getId()); + orderInfo.put("orderNo", goodsOrder.getOrderId()); + orderInfo.put("productName", serviceGoods.getTitle()); + orderInfo.put("price", itemPrice.toString()); + orderList.add(orderInfo); + } else { + // 创建服务订单 + String makeTime = orderParams.get("make_time") != null ? orderParams.get("make_time").toString() : ""; + String fileData = orderParams.get("fileData") != null ? orderParams.get("fileData").toString() : ""; + Order order = new Order(); + order.setType(1); // 1:服务项目 + order.setCreateType(1); // 1:用户自主下单 + order.setUid(user.getId()); + order.setUname(user.getName()); + order.setProductId(productId); + order.setProductName(serviceGoods.getTitle()); + order.setName(userAddress.getName()); + order.setFileData(fileData != null ? JSON.toJSONString(fileData) : null); + order.setPhone(userAddress.getPhone()); + order.setAddress(userAddress.getAddressInfo()); + order.setAddressId(addressId); + order.setSku(sku); + order.setMainOrderId(mainOrderId); + order.setOrderId(GenerateCustomCode.generCreateOrder("B")); // 独立订单号 + // 处理预约时间 + if (makeTime != null && !makeTime.isEmpty()) { + String[] makeTimeArr = makeTime.split(" "); + if (makeTimeArr.length == 2) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date date = sdf.parse(makeTimeArr[0]); + order.setMakeTime(date.getTime() / 1000); + order.setMakeHour(makeTimeArr[1]); + } catch (Exception e) { + logger.warn("预约时间格式错误: " + makeTime); + } + } + } + order.setNum(num); + order.setTotalPrice(itemPrice); + order.setGoodPrice(serviceGoods.getPrice()); + order.setServicePrice(BigDecimal.ZERO); + order.setPayPrice(itemPrice); + order.setStatus(1L); // 1:待接单 + order.setReceiveType(1L); // 1:自由抢单 + order.setIsAccept(0); + order.setIsComment(0); + order.setIsPause(1); + order.setDeduction(new BigDecimal(0)); + // 保存服务订单 + int result = orderService.insertOrder(order); + if (result <= 0) { + return AppletControllerUtil.appletWarning("服务订单创建失败,请稍后重试"); + } + // 添加订单日志 + OrderLog orderLog = new OrderLog(); + orderLog.setOid(order.getId()); + orderLog.setOrderId(order.getOrderId()); + orderLog.setTitle("订单生成"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", "预约成功,将尽快为主人派单"); + orderLog.setType(new BigDecimal(1.0)); + orderLog.setContent(jsonObject.toString()); + orderLogService.insertOrderLog(orderLog); + + // 系统派单和消息通知逻辑 + Order orderNewData = orderService.selectOrderById(order.getId()); + String wxsendmsg = WXsendMsgUtil.sendMsgForUserInfo(user.getOpenid(), orderNewData, serviceGoods); + Users worker = AppletControllerUtil.creatWorkerForOrder(orderNewData); + + if (worker != null) { + // 更新订单状态为已派单 + orderNewData.setWorkerId(worker.getId()); + orderNewData.setStatus(2l); + orderNewData.setIsPause(1); + orderNewData.setReceiveTime(new Date()); + orderNewData.setReceiveType(3l); + orderNewData.setLogStatus(9); + JSONObject jSONObject = new JSONObject(); + jSONObject.put("type", 9); + orderNewData.setLogJson(jSONObject.toJSONString()); + orderService.updateOrder(orderNewData); + // 添加派单日志 + OrderLog orderLognew = new OrderLog(); + orderLognew.setOid(orderNewData.getId()); + orderLognew.setOrderId(orderNewData.getOrderId()); + orderLognew.setTitle("平台派单"); + orderLognew.setType(new BigDecimal(1.1)); + JSONObject jSONObject1 = new JSONObject(); + jSONObject1.put("name", "师傅收到派单信息"); + orderLognew.setContent(jSONObject1.toJSONString()); + orderLognew.setWorkerId(worker.getId()); + orderLognew.setWorkerLogId(worker.getId()); + orderLogService.insertOrderLog(orderLognew); + // 发送通知 + WXsendMsgUtil.sendMsgForWorkerInfo(worker.getOpenid(), orderNewData, serviceGoods); + YunXinPhoneUtilAPI.httpsAxbTransfer(worker.getPhone()); + } + + // 添加到订单列表 + Map orderInfo = new HashMap<>(); + orderInfo.put("type", "service"); + orderInfo.put("orderId", order.getId()); + orderInfo.put("orderNo", order.getOrderId()); + orderInfo.put("productName", serviceGoods.getTitle()); + orderInfo.put("price", itemPrice.toString()); + orderList.add(orderInfo); + } + } + // 7. 如果有商品订单,需要发起微信支付 + boolean hasGoodsOrder = orderList.stream().anyMatch(order -> "goods".equals(order.get("type"))); + if (hasGoodsOrder && totalAmount.compareTo(BigDecimal.ZERO) > 0) { + // 使用工具类简化微信支付参数组装 + Map payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), mainOrderId, new BigDecimal(0.01), orderList.size(), wechatPayUtil.PAY_FH+"api/goods/pay/notify"); + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", mainOrderId); + responseData.put("orderList", orderList); + responseData.put("totalAmount", totalAmount.toString()); + responseData.put("prepayId", payResult.get("prepayId")); + // 直接合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } else { + // 没有商品订单,只有服务订单,直接返回成功 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", mainOrderId); + responseData.put("orderList", orderList); + responseData.put("totalAmount", totalAmount.toString()); + return AppletControllerUtil.appletSuccess(responseData); + } + } catch (Exception e) { + logger.error("创建订单异常:", e); + return AppletControllerUtil.appletWarning("创建订单失败:" + e.getMessage()); + } + } + + + + /** + * 尾款结算 + */ + @PostMapping("api/service/order/pay/total/price") + public AjaxResult apiServiceOrderPayTotalPprice(@RequestBody Map params, HttpServletRequest request) { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + // 3. 验证必要参数 + if (params == null || params.get("order_id") == null || params.get("worker_id") == null) { + return AppletControllerUtil.appletWarning("参数不能为空"); + } + Long worker_id = Long.valueOf(params.get("worker_id").toString()); + String order_id = params.get("order_id").toString(); + Order order = orderService.selectOrderByOrderId(order_id); + // 2. 查询订单日志(取type=5评估报价,或最新一条) + List logList = orderLogService.selectOrderLogByOrderId(order.getOrderId()); + OrderLog log = null; + for (OrderLog l : logList) { + if (l.getType() != null && l.getType().intValue() == 5) { + log = l; + break; + } + } + if (log == null && !logList.isEmpty()) { + log = logList.get(0); + } + if (log == null) { + return AppletControllerUtil.appletWarning("未找到订单日志"); + } + if (params.get("coupon_id")!= null) { + String coupon_id = params.get("coupon_id").toString(); + if (coupon_id != null && !coupon_id.isEmpty()) { + CouponUser couponUser = couponUserService.selectCouponUserById(Long.valueOf(coupon_id)); + if (couponUser == null && couponUser.getStatus() != 1) { + return AppletControllerUtil.appletWarning("优惠券已被使用,或优惠券不存在"); + } + OrderLog orderLogQery = new OrderLog(); + orderLogQery.setOrderId(order.getOrderId()); + orderLogQery.setType(new BigDecimal(5)); + orderLogQery.setWorkerId(worker_id); + OrderLog orderLognew = orderLogService.selectOneByOidTypeWorkerIdPaid(orderLogQery); + if (orderLognew != null) { + orderLognew.setCouponId(couponUser.getCouponId()); + orderLognew.setDeduction(new BigDecimal(couponUser.getCouponPrice())); + orderLogService.updateOrderLog(orderLognew); + order.setCouponId(couponUser.getCouponId()); + order.setDeduction(new BigDecimal(couponUser.getCouponPrice())); + orderService.updateOrder(order); + } + + + } + } + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + String.valueOf(order_id), + new BigDecimal(0.01), + 1, + wechatPayUtil.PAY_FH+"api/order/amount/pay/notify"); + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", order_id); + //responseData.put("orderList", orderList); + responseData.put("totalAmount", log.getPrice()); + responseData.put("prepayId", payResult.get("prepayId")); + // 直接合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } + /** + * 拼团一次性支付接口 + * + * 用户参与拼团活动的支付接口 + * 创建拼团订单并调用微信支付 + * + * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 获取商品信息 + * 3. 创建拼团订单 + * 4. 调用微信支付 + * + * @param params 拼团参数(id=商品ID) + * @param request HTTP请求对象(需要包含token) + * @return 支付结果 + */ + @PostMapping("/group/once_pay") + public AjaxResult apigroupOncePay(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + if (params == null || params.get("id") == null) { + return AppletControllerUtil.appletWarning("参数不能为空"); + } + + // 4. 获取商品信息 + Long orderId = Long.valueOf(params.get("id").toString()); + ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(orderId); + if (serviceGoods == null) { + return AppletControllerUtil.appletWarning("商品信息获取失败"); + } + + // 5. 创建拼团订单 + UserGroupBuying userGroupBuying = new UserGroupBuying(); + userGroupBuying.setId(orderId); + userGroupBuying.setUid(user.getId()); + userGroupBuying.setStatus(Long.valueOf(4)); // 4=待支付状态 + userGroupBuying.setUname(user.getName()); + userGroupBuying.setProductId(serviceGoods.getId()); + userGroupBuying.setPaytype(Long.valueOf(1)); // 1=微信支付 + userGroupBuying.setMoney(serviceGoods.getGroupprice()); // 使用拼团价格 + userGroupBuying.setOrderid(GenerateCustomCode.generCreateOrder("G")); + + // 6. 保存拼团订单并调用微信支付 + int flg = userGroupBuyingService.insertUserGroupBuying(userGroupBuying); + if (flg > 0) { + // 调用微信支付(测试环境使用0.01元) + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + userGroupBuying.getId().toString(), + new BigDecimal("0.01"), // 测试金额 + 1, + WechatPayUtil.PAY_FH + "api/group/pay/notify"); + + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + // 构建支付响应数据 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", userGroupBuying.getOrderid()); + responseData.put("totalAmount", serviceGoods.getGroupprice()); + responseData.put("prepayId", payResult.get("prepayId")); + // 合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } + + return AppletControllerUtil.appletWarning("支付失败"); + + } catch (Exception e) { + System.err.println("拼团支付异常:" + e.getMessage()); + return AppletControllerUtil.appletError("拼团支付失败:" + e.getMessage()); + } + } + // ==================== 服务订单支付相关接口 ==================== + + /** + * 上门费支付接口 + *

+ * 用于支付服务订单的上门费用 + *

+ * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 根据订单日志ID获取上门费信息 + * 3. 调用微信支付 + * 4. 返回支付参数 + * + * @param params 请求参数,包含id(订单日志ID) + * @param request HTTP请求对象(需要包含token) + * @return 支付结果,包含prepayId等微信支付参数 + */ + @PostMapping("/service/order/pay_fee") + public AjaxResult apiServiceOrderPayFee(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + if (params == null || params.get("id") == null) { + return AppletControllerUtil.appletWarning("参数不能为空"); + } + + // 4. 获取订单日志信息 + Long orderId = Long.valueOf(params.get("id").toString()); + OrderLog orderLog = orderLogService.selectOrderLogById(orderId); + + if (orderLog != null) { + logger.info("上门费支付 - 用户ID: {}, 订单日志ID: {}, 上门费: {}", + user.getId(), orderId, orderLog.getPrice()); + + // 5. 调用微信支付(测试环境使用0.01元) + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + String.valueOf(orderLog.getId()), + new BigDecimal("0.01"), // 测试金额 + 1, + WechatPayUtil.PAY_FH + "api/door/fee/pay/notify"); + + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + // 6. 构建支付响应数据 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", String.valueOf(orderLog.getId())); + responseData.put("totalAmount", orderLog.getPrice()); + responseData.put("prepayId", payResult.get("prepayId")); + // 合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } else { + return AppletControllerUtil.appletWarning("订单日志不存在"); + } + + } catch (Exception e) { + logger.error("上门费支付异常 - 用户ID: {}, 参数: {}, 异常: {}", + request.getHeader("token"), params, e.getMessage()); + return AppletControllerUtil.appletError("支付失败:" + e.getMessage()); + } + } + + /** + * 定金支付接口 + *

+ * 用于支付服务订单的定金 + *

+ * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 根据订单日志ID获取定金信息 + * 3. 调用微信支付 + * 4. 返回支付参数 + * + * @param params 请求参数,包含id(订单日志ID) + * @param request HTTP请求对象(需要包含token) + * @return 支付结果,包含prepayId等微信支付参数 + */ + @PostMapping("/service/order/pay/deposit") + public AjaxResult apiServiceOrderPaydeposit(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + if (params == null || params.get("id") == null) { + return AppletControllerUtil.appletWarning("参数不能为空"); + } + + // 4. 获取订单日志信息 + Long orderId = Long.valueOf(params.get("id").toString()); + OrderLog orderLog = orderLogService.selectOrderLogById(orderId); + + if (orderLog != null) { + logger.info("定金支付 - 用户ID: {}, 订单日志ID: {}, 定金: {}", + user.getId(), orderId, orderLog.getPrice()); + + // 5. 调用微信支付(测试环境使用0.01元) + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + String.valueOf(orderLog.getId()), + new BigDecimal("0.01"), // 测试金额 + 1, + WechatPayUtil.PAY_FH + "api/deposit/pay/notify"); + + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + // 6. 构建支付响应数据 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", String.valueOf(orderLog.getId())); + responseData.put("totalAmount", orderLog.getPrice()); + responseData.put("prepayId", payResult.get("prepayId")); + // 合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } else { + return AppletControllerUtil.appletWarning("订单日志不存在"); + } + + } catch (Exception e) { + logger.error("定金支付异常 - 用户ID: {}, 参数: {}, 异常: {}", + request.getHeader("token"), params, e.getMessage()); + return AppletControllerUtil.appletError("支付失败:" + e.getMessage()); + } + } + + // ==================== 商品订单支付相关接口 ==================== + + /** + * 单个商品支付接口 + *

+ * 用于支付单个商品订单 + *

+ * 业务逻辑: + * 1. 验证用户登录状态 + * 2. 根据商品订单ID获取订单信息 + * 3. 生成主订单号并更新订单 + * 4. 调用微信支付 + * 5. 返回支付参数 + * + * @param params 请求参数,包含id(商品订单ID) + * @param request HTTP请求对象(需要包含token) + * @return 支付结果,包含prepayId等微信支付参数 + */ + @PostMapping("/goods/order/once_pay") + public AjaxResult apiGoodsOrderOncePay(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 获取用户信息 + Users user = (Users) userValidation.get("user"); + if (user == null) { + return AppletControllerUtil.appletWarning("用户信息获取失败"); + } + + // 3. 验证必要参数 + if (params == null || params.get("id") == null) { + return AppletControllerUtil.appletWarning("参数不能为空"); + } + + // 4. 获取商品订单信息 + Long orderId = Long.valueOf(params.get("id").toString()); + GoodsOrder goodsOrder = goodsOrderService.selectGoodsOrderById(orderId); + + logger.info("商品订单支付 - 用户ID: {}, 订单ID: {}", user.getId(), orderId); + logger.info("商品订单详情: {}", goodsOrder); + + if (goodsOrder != null) { + // 5. 生成主订单号并更新订单 + goodsOrder.setMainOrderId(GenerateCustomCode.generCreateOrder("WXB")); + int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder); + + // 6. 修改成功后开始支付流程 + if (updateResult > 0) { + logger.info("商品订单更新成功 - 主订单号: {}, 总价: {}", + goodsOrder.getMainOrderId(), goodsOrder.getTotalPrice()); + + // 7. 调用微信支付(测试环境使用0.01元) + Map payResult = wechatPayUtil.createBatchOrderAndPay( + user.getOpenid(), + goodsOrder.getMainOrderId(), + new BigDecimal("0.01"), // 测试金额 + 1, + WechatPayUtil.PAY_FH + "api/goods/pay/notify"); + + if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { + // 8. 构建支付响应数据 + Map responseData = new HashMap<>(); + responseData.put("mainOrderId", goodsOrder.getMainOrderId()); + responseData.put("totalAmount", goodsOrder.getTotalPrice()); + responseData.put("prepayId", payResult.get("prepayId")); + // 合并所有支付参数 + responseData.putAll(payResult); + return AppletControllerUtil.appletSuccess(responseData); + } else { + String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; + return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); + } + } else { + return AppletControllerUtil.appletWarning("订单更新失败"); + } + } else { + return AppletControllerUtil.appletWarning("商品订单不存在"); + } + + } catch (Exception e) { + logger.error("商品订单支付异常 - 用户ID: {}, 参数: {}, 异常: {}", + request.getHeader("token"), params, e.getMessage()); + return AppletControllerUtil.appletError("支付失败:" + e.getMessage()); + } + } + + + /** + * 查询退款结果接口 + *

+ * 主动查询退款的处理状态 + *

+ * 请求参数: + * - refundNo: 退款单号 + * + * @param params 查询参数 + * @param request HTTP请求对象(需要包含token) + * @return 退款状态查询结果 + */ + @PostMapping("/refund/query") + public AjaxResult queryRefundOrder(@RequestBody Map params, HttpServletRequest request) { + try { + // 1. 验证用户登录状态 + String token = request.getHeader("token"); + Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); + if (!(Boolean) userValidation.get("valid")) { + return AppletControllerUtil.appletWarning("用户未登录或token无效"); + } + + // 2. 验证必要参数 + if (params == null || params.get("refundNo") == null) { + return AppletControllerUtil.appletWarning("退款单号不能为空"); + } + + // 3. 查询退款结果 + // 注意:如果WechatPayUtil.queryRefund方法不存在,请根据实际情况调整 + Map queryResult = new HashMap<>(); + queryResult.put("success", true); + queryResult.put("message", "退款查询功能待实现"); + queryResult.put("refundNo", params.get("refundNo")); + queryResult.put("status", "UNKNOWN"); + + // 4. 返回结果 + boolean success = (Boolean) queryResult.get("success"); + if (success) { + return AppletControllerUtil.appletSuccess(queryResult); + } else { + return AppletControllerUtil.appletWarning((String) queryResult.get("message")); + } + + } catch (Exception e) { + System.err.println("查询退款结果异常:" + e.getMessage()); + return AppletControllerUtil.appletError("查询退款结果失败:" + e.getMessage()); + } + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java index 6b7b53b..b82a28b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java @@ -2,11 +2,9 @@ package com.ruoyi.system.controller; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.ControllerUtil.*; import com.ruoyi.system.domain.*; @@ -18,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; -import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; @@ -37,26 +34,10 @@ import com.ruoyi.system.domain.QuoteMaterial; /** * 小程序控制器 - * - * 提供小程序端所需的API接口,包括: - * 1. 服务分类管理 - 获取服务分类列表 - * 2. 服务商品管理 - 商品列表、详情、搜索 - * 3. 广告图片管理 - 获取各类型广告图片 - * 4. 配置信息管理 - 系统配置查询 - * 5. 用户信息管理 - 登录验证、信息修改 - * 6. 地址管理 - 收货地址增删改查 - * 7. 订单管理 - 服务订单、商品订单 - * 8. 购物车管理 - 商品购物车操作 - * 9. 支付相关 - 微信支付、订单支付 - * 10. 师傅端功能 - 接单、报价、服务流程 - * 11. 会员相关 - 充值、消费记录 - * 12. 积分商城 - 积分商品兑换 - * 13. 优惠券管理 - 用户优惠券 - * 14. 售后服务 - 返修申请 + * * * @author Mr. Zhang Pan * @version 2.0 - * @date 2025-01-17 */ @RestController public class AppletController extends BaseController { @@ -141,69 +122,15 @@ public class AppletController extends BaseController { private IUsersInvoiceInfoService usersInvoiceInfoService; @Autowired private IUserGroupBuyingService userGroupBuyingService; - @Autowired private IUserSecondaryCardService userSecondaryCardService; - @Autowired private IUserDemandQuotationService userDemandQuotationService; - @Autowired private IUserBenefitPointsService userBenefitPointsService; - - - @Autowired private WechatPayV3Util wechatPayV3Util; - @PostMapping("/api/quick-refund") - public AjaxResult quickRefund( - @RequestParam String orderNo, - @RequestParam BigDecimal refundFee, - @RequestParam(required = false) String reason) { - try { - Map result = wechatPayV3Util.quickRefund(orderNo, refundFee, reason); - - if ((Boolean) result.get("success")) { - return success(result.get("data")); - } else { - return error((String) result.get("message")); - } - } catch (Exception e) { - return error("快速退款异常:" + e.getMessage()); - } - } - - - /** - * 用户提现 - * - * @param openid 用户openid - * @param amount 金额(分) - * @param desc 提现描述 - * @param userName 真实姓名(可选,用于实名校验) - * @return 提现结果 - */ - @PostMapping("/api/withdraw") - public AjaxResult withdraw(@RequestParam String openid, - @RequestParam int amount, - @RequestParam(required = false) String desc, - @RequestParam(required = false) String userName) { - try { - - - Map result = wechatPayV3Util.withdraw(openid, amount, desc, userName); - - if ((Boolean) result.get("success")) { - return AjaxResult.success("提现申请成功", result.get("data")); - } else { - return AjaxResult.error(result.get("message").toString()); - } - } catch (Exception e) { - - return AjaxResult.error("提现申请失败: " + e.getMessage()); - } - } /** * 获取服务分类列表 @@ -1307,25 +1234,6 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletError("修改用户信息失败:" + e.getMessage()); } } - /** - * 解析对象为Integer类型(用于编辑接口) - */ - private Integer parseToIntegerdataForEdit(Object value) { - if (value == null) return null; - - if (value instanceof Integer) { - return (Integer) value; - } else if (value instanceof Long) { - return ((Long) value).intValue(); - } else if (value instanceof String) { - try { - return Integer.parseInt((String) value); - } catch (NumberFormatException e) { - return null; - } - } - return null; - } /** * 验证用户编辑参数 * @@ -1392,38 +1300,7 @@ public class AppletController extends BaseController { } } - /** - * 微信支付统一下单接口 - * - * @param params 支付参数 - * @param request HTTP请求对象 - * @return 支付结果 - */ - @PostMapping(value = "/api/pay/unifiedorder") - public AjaxResult createPayOrder(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - WechatPayUtil wechatPayUtil = new WechatPayUtil(); - // 2. 调用微信支付统一下单 - Map payResult = wechatPayUtil.unifiedOrder((String) params.get("openid"), (String) params.get("orderNo"), (int) params.get("totalFee"), (String) params.get("body"), (String) params.get("notifyUrl"), (String) params.get("attach")); - // 3. 返回结果 - boolean success = (Boolean) payResult.get("success"); - if (success) { - return AppletControllerUtil.appletSuccess(payResult); - } else { - return AppletControllerUtil.appletWarning((String) payResult.get("message")); - } - - } catch (Exception e) { - return AppletControllerUtil.appletWarning("创建支付订单失败:" + e.getMessage()); - } - } /** * 查询支付订单状态接口 @@ -1457,120 +1334,6 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletWarning("查询订单状态失败:" + e.getMessage()); } } - - /** - * 创建代付订单接口 - * - * @param params 代付参数 - * @param request HTTP请求对象 - * @return 代付结果 - */ - @PostMapping(value = "/api/pay/payfor") - public AjaxResult createPayForOrder(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - WechatPayUtil wechatPayUtil = new WechatPayUtil(); - // 2. 创建代付订单 - Map payForResult = wechatPayUtil.unifiedOrder(params.get("payerOpenid").toString(), params.get("orderNo").toString(), Integer.valueOf(params.get("totalFee").toString()), params.get("body").toString(), params.get("notifyUrl").toString(), params.get("remark").toString()); - - // 3. 返回结果 - boolean success = (Boolean) payForResult.get("success"); - if (success) { - return AppletControllerUtil.appletSuccess(payForResult); - } else { - return AppletControllerUtil.appletWarning((String) payForResult.get("message")); - } - - } catch (Exception e) { - return AppletControllerUtil.appletWarning("创建代付订单失败:" + e.getMessage()); - } - } - - /** - * 微信支付回调接口 - * - * @param request HTTP请求对象 - * @return 回调处理结果 - *

- * 注意:此接口供微信服务器回调使用,不需要用户认证 - * 返回格式必须是XML格式,用于告知微信处理结果 - */ - @PostMapping(value = "/api/pay/notify") - public String handlePayNotify(HttpServletRequest request) { - try { - WechatPayUtil wechatPayUtil = new WechatPayUtil(); - // 1. 处理支付回调 - Map notifyResult = wechatPayUtil.handlePayNotify(request); - - // 2. 获取支付信息 - boolean success = (Boolean) notifyResult.get("success"); - if (success) { - Map paymentInfo = (Map) notifyResult.get("paymentInfo"); - boolean isPayFor = (Boolean) notifyResult.get("isPayFor"); - - // 3. 根据业务需要处理支付成功逻辑 - // 例如:更新订单状态、发送通知等 - AppletControllerUtil.handlePaymentSuccess(paymentInfo, isPayFor); - - // 4. 返回成功响应给微信 - return (String) notifyResult.get("responseXml"); - } else { - // 5. 返回失败响应给微信 - return (String) notifyResult.get("responseXml"); - } - - } catch (Exception e) { - // 6. 异常时返回失败响应 - return ""; - } - } - - /** - * 申请退款接口 - * - * @param params 退款参数 - * @param request HTTP请求对象 - * @return 退款结果 - *

- * 请求参数格式: - * { - * "orderNo": "原订单号", - * "refundNo": "退款单号", - * "totalFee": 订单总金额(分), - * "refundFee": 退款金额(分), - * "refundDesc": "退款原因" - * } - */ - @PostMapping(value = "/api/pay/refund") - public AjaxResult refundOrder(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - WechatPayUtil wechatPayUtil = new WechatPayUtil(); - // 2. 申请退款 - Map refundResult = wechatPayUtil.refund(params); - - // 3. 返回结果 - boolean success = (Boolean) refundResult.get("success"); - if (success) { - return AppletControllerUtil.appletSuccess(refundResult); - } else { - return AppletControllerUtil.appletWarning((String) refundResult.get("message")); - } - - } catch (Exception e) { - return AppletControllerUtil.appletWarning("申请退款失败:" + e.getMessage()); - } - } /** * 查询用户售后返修列表 * @@ -2337,11 +2100,6 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletWarning("查询通知订阅状态失败:" + e.getMessage()); } } - - - - - /** * 用户订阅消息授权接口 * @@ -2400,8 +2158,6 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletWarning("订阅消息失败:" + e.getMessage()); } } - - /** * 小程序下单时用户订阅消息推送接口(前端不传值,后端返回固定结构) * @@ -2475,17 +2231,14 @@ public class AppletController extends BaseController { if (address == null) { return AppletControllerUtil.appletWarning("收货地址不存在"); } - if (!address.getUid().equals(user.getId())) { return AppletControllerUtil.appletWarning("无权使用该收货地址"); } - // 6. 计算所需积分并验证库存 Integer num = Integer.valueOf(params.get("num").toString()); if (product.getStock() != null && product.getStock() < num) { return AppletControllerUtil.appletWarning("商品库存不足"); } - Long totalIntegral = product.getNum() * num; // 7. 验证用户积分是否足够 @@ -2872,7 +2625,6 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletError("添加购物车失败:" + e.getMessage()); } } - /** * 查询购物车列表接口 * @@ -3002,8 +2754,6 @@ public class AppletController extends BaseController { return AppletControllerUtil.appletError("查询购物车列表失败:" + e.getMessage()); } } - - /** * 服务/商品搜索接口 * @@ -3309,491 +3059,6 @@ public class AppletController extends BaseController { // 如果都没有设置,认为未过期 return false; } - - /** - * 创建服务订单(支持多商品批量下单) - * - * @param params 请求参数,包含多个商品信息、地址信息和预约时间 - * @param request HTTP请求对象 - * @return 返回创建结果 - */ - @PostMapping("/api/service/create/order") - public AjaxResult createServiceOrder(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 验证订单参数 - if (params == null || params.isEmpty()) { - return AppletControllerUtil.appletWarning("订单参数不能为空"); - } - - // 4. 生成主订单号 - String mainOrderId = GenerateCustomCode.generCreateOrder("WXB"); - - // 5. 存储所有订单信息 - List> orderList = new ArrayList<>(); - BigDecimal totalAmount = BigDecimal.ZERO; // 总金额 - - // 6. 遍历所有订单项 - for (String key : params.keySet()) { - // 跳过非数字键 - if (!key.matches("\\d+")) { - continue; - } - - Map orderParams = (Map) params.get(key); - - // 验证必要参数 - if (orderParams.get("product_id") == null || orderParams.get("address_id") == null) { - return AppletControllerUtil.appletWarning("商品ID或地址ID不能为空"); - } - - Long productId = Long.valueOf(orderParams.get("product_id").toString()); - Long addressId = Long.valueOf(orderParams.get("address_id").toString()); - Long num = orderParams.get("num") != null ? Long.valueOf(orderParams.get("num").toString()) : 1L; - - // 处理SKU参数 - String sku = AppletControllerUtil.processSkuParam(orderParams.get("sku")); - - // 查询商品信息 - ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId); - if (serviceGoods == null) { - return AppletControllerUtil.appletWarning("商品ID " + productId + " 不存在"); - } - - // 查询地址信息(只需要查询一次,假设所有订单使用相同地址) - UserAddress userAddress = userAddressService.selectUserAddressById(addressId); - if (userAddress == null) { - return AppletControllerUtil.appletWarning("地址不存在"); - } - - // 计算单个订单金额 - BigDecimal itemPrice = serviceGoods.getPrice().multiply(BigDecimal.valueOf(num)); - totalAmount = totalAmount.add(itemPrice); - - // 判断商品类型并创建相应订单 - BigDecimal DeductionPrice = new BigDecimal("0"); - if (serviceGoods.getType() == 2) { - // 创建服务订单 - String coupon_id = orderParams.get("coupon_id") != null ? orderParams.get("coupon_id").toString() : ""; - CouponUser coupon=null; - if (coupon_id!=null){ - coupon = couponUserService.selectCouponUserById(Long.valueOf(coupon_id)); - if (coupon==null){ - return AppletControllerUtil.appletWarning("优惠券不存在"); - } - } - if (coupon != null) { - DeductionPrice= new BigDecimal(coupon.getCouponPrice()).divide(new BigDecimal(params.size()),2, RoundingMode.HALF_UP); - } - if (coupon != null) { - coupon.setStatus(2L); - } - couponUserService.updateCouponUser(coupon) ; - // 创建商品订单 - GoodsOrder goodsOrder = new GoodsOrder(); - goodsOrder.setType(2); - goodsOrder.setMainOrderId(mainOrderId); - goodsOrder.setOrderId(GenerateCustomCode.generCreateOrder("B")); // 独立订单号 - goodsOrder.setUid(user.getId()); - goodsOrder.setProductId(productId); - goodsOrder.setName(userAddress.getName()); - goodsOrder.setPhone(userAddress.getPhone()); - goodsOrder.setAddress(userAddress.getAddressName()); - goodsOrder.setNum(num); - goodsOrder.setTotalPrice(itemPrice); - goodsOrder.setGoodPrice(serviceGoods.getPrice()); - goodsOrder.setPayPrice(itemPrice); - goodsOrder.setDeduction(DeductionPrice); - goodsOrder.setCouponId(Long.valueOf(coupon_id)); - goodsOrder.setStatus(1L); // 待支付状态 - goodsOrder.setAddressId(addressId); - goodsOrder.setSku(sku); - // 保存商品订单 - int insertResult = goodsOrderService.insertGoodsOrder(goodsOrder); - if (insertResult <= 0) { - return AppletControllerUtil.appletWarning("商品订单创建失败,请稍后重试"); - } - // 添加到订单列表 - Map orderInfo = new HashMap<>(); - orderInfo.put("type", "goods"); - orderInfo.put("orderId", goodsOrder.getId()); - orderInfo.put("orderNo", goodsOrder.getOrderId()); - orderInfo.put("productName", serviceGoods.getTitle()); - orderInfo.put("price", itemPrice.toString()); - orderList.add(orderInfo); - } else { - // 创建服务订单 - String makeTime = orderParams.get("make_time") != null ? orderParams.get("make_time").toString() : ""; - String fileData = orderParams.get("fileData") != null ? orderParams.get("fileData").toString() : ""; - Order order = new Order(); - order.setType(1); // 1:服务项目 - order.setCreateType(1); // 1:用户自主下单 - order.setUid(user.getId()); - order.setUname(user.getName()); - order.setProductId(productId); - order.setProductName(serviceGoods.getTitle()); - order.setName(userAddress.getName()); - order.setFileData(fileData != null ? JSON.toJSONString(fileData) : null); - order.setPhone(userAddress.getPhone()); - order.setAddress(userAddress.getAddressInfo()); - order.setAddressId(addressId); - order.setSku(sku); - order.setMainOrderId(mainOrderId); - order.setOrderId(GenerateCustomCode.generCreateOrder("B")); // 独立订单号 - // 处理预约时间 - if (makeTime != null && !makeTime.isEmpty()) { - String[] makeTimeArr = makeTime.split(" "); - if (makeTimeArr.length == 2) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - Date date = sdf.parse(makeTimeArr[0]); - order.setMakeTime(date.getTime() / 1000); - order.setMakeHour(makeTimeArr[1]); - } catch (Exception e) { - logger.warn("预约时间格式错误: " + makeTime); - } - } - } - order.setNum(num); - order.setTotalPrice(itemPrice); - order.setGoodPrice(serviceGoods.getPrice()); - order.setServicePrice(BigDecimal.ZERO); - order.setPayPrice(itemPrice); - order.setStatus(1L); // 1:待接单 - order.setReceiveType(1L); // 1:自由抢单 - order.setIsAccept(0); - order.setIsComment(0); - order.setIsPause(1); - order.setDeduction(new BigDecimal(0)); - // 保存服务订单 - int result = orderService.insertOrder(order); - if (result <= 0) { - return AppletControllerUtil.appletWarning("服务订单创建失败,请稍后重试"); - } - // 添加订单日志 - OrderLog orderLog = new OrderLog(); - orderLog.setOid(order.getId()); - orderLog.setOrderId(order.getOrderId()); - orderLog.setTitle("订单生成"); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("name", "预约成功,将尽快为主人派单"); - orderLog.setType(new BigDecimal(1.0)); - orderLog.setContent(jsonObject.toString()); - orderLogService.insertOrderLog(orderLog); - - // 系统派单和消息通知逻辑 - Order orderNewData = orderService.selectOrderById(order.getId()); - String wxsendmsg = WXsendMsgUtil.sendMsgForUserInfo(user.getOpenid(), orderNewData, serviceGoods); - Users worker = AppletControllerUtil.creatWorkerForOrder(orderNewData); - - if (worker != null) { - // 更新订单状态为已派单 - orderNewData.setWorkerId(worker.getId()); - orderNewData.setStatus(2l); - orderNewData.setIsPause(1); - orderNewData.setReceiveTime(new Date()); - orderNewData.setReceiveType(3l); - orderNewData.setLogStatus(9); - JSONObject jSONObject = new JSONObject(); - jSONObject.put("type", 9); - orderNewData.setLogJson(jSONObject.toJSONString()); - orderService.updateOrder(orderNewData); - // 添加派单日志 - OrderLog orderLognew = new OrderLog(); - orderLognew.setOid(orderNewData.getId()); - orderLognew.setOrderId(orderNewData.getOrderId()); - orderLognew.setTitle("平台派单"); - orderLognew.setType(new BigDecimal(1.1)); - JSONObject jSONObject1 = new JSONObject(); - jSONObject1.put("name", "师傅收到派单信息"); - orderLognew.setContent(jSONObject1.toJSONString()); - orderLognew.setWorkerId(worker.getId()); - orderLognew.setWorkerLogId(worker.getId()); - orderLogService.insertOrderLog(orderLognew); - // 发送通知 - WXsendMsgUtil.sendMsgForWorkerInfo(worker.getOpenid(), orderNewData, serviceGoods); - YunXinPhoneUtilAPI.httpsAxbTransfer(worker.getPhone()); - } - - // 添加到订单列表 - Map orderInfo = new HashMap<>(); - orderInfo.put("type", "service"); - orderInfo.put("orderId", order.getId()); - orderInfo.put("orderNo", order.getOrderId()); - orderInfo.put("productName", serviceGoods.getTitle()); - orderInfo.put("price", itemPrice.toString()); - orderList.add(orderInfo); - } - } - // 7. 如果有商品订单,需要发起微信支付 - boolean hasGoodsOrder = orderList.stream().anyMatch(order -> "goods".equals(order.get("type"))); - if (hasGoodsOrder && totalAmount.compareTo(BigDecimal.ZERO) > 0) { - // 使用工具类简化微信支付参数组装 - Map payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), mainOrderId, new BigDecimal(0.01), orderList.size(), "https://7ce20b15.r5.cpolar.xyz/api/goods/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", mainOrderId); - responseData.put("orderList", orderList); - responseData.put("totalAmount", totalAmount.toString()); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - } else { - // 没有商品订单,只有服务订单,直接返回成功 - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", mainOrderId); - responseData.put("orderList", orderList); - responseData.put("totalAmount", totalAmount.toString()); - return AppletControllerUtil.appletSuccess(responseData); - } - } catch (Exception e) { - logger.error("创建订单异常:", e); - return AppletControllerUtil.appletWarning("创建订单失败:" + e.getMessage()); - } - } - - /** - * 尾款结算 - */ - @PostMapping("api/service/order/pay/total/price") - public AjaxResult apiServiceOrderPayTotalPprice(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - // 3. 验证必要参数 - if (params == null || params.get("order_id") == null || params.get("worker_id") == null) { - return AppletControllerUtil.appletWarning("参数不能为空"); - } - Long worker_id = Long.valueOf(params.get("worker_id").toString()); - String order_id = params.get("order_id").toString(); - Order order = orderService.selectOrderByOrderId(order_id); - // 2. 查询订单日志(取type=5评估报价,或最新一条) - List logList = orderLogService.selectOrderLogByOrderId(order.getOrderId()); - OrderLog log = null; - for (OrderLog l : logList) { - if (l.getType() != null && l.getType().intValue() == 5) { - log = l; - break; - } - } - if (log == null && !logList.isEmpty()) { - log = logList.get(0); - } - if (log == null) { - return AppletControllerUtil.appletWarning("未找到订单日志"); - } - if (params.get("coupon_id")!= null) { - String coupon_id = params.get("coupon_id").toString(); - if (coupon_id != null && !coupon_id.isEmpty()) { - CouponUser couponUser = couponUserService.selectCouponUserById(Long.valueOf(coupon_id)); - if (couponUser == null && couponUser.getStatus() != 1) { - return AppletControllerUtil.appletWarning("优惠券已被使用,或优惠券不存在"); - } - OrderLog orderLogQery = new OrderLog(); - orderLogQery.setOrderId(order.getOrderId()); - orderLogQery.setType(new BigDecimal(5)); - orderLogQery.setWorkerId(worker_id); - OrderLog orderLognew = orderLogService.selectOneByOidTypeWorkerIdPaid(orderLogQery); - if (orderLognew != null) { - orderLognew.setCouponId(couponUser.getCouponId()); - orderLognew.setDeduction(new BigDecimal(couponUser.getCouponPrice())); - orderLogService.updateOrderLog(orderLognew); - order.setCouponId(couponUser.getCouponId()); - order.setDeduction(new BigDecimal(couponUser.getCouponPrice())); - orderService.updateOrder(order); - } - - - } - } - Map payResult = wechatPayUtil.createBatchOrderAndPay( - user.getOpenid(), - String.valueOf(order_id), - new BigDecimal(0.01), - 1, - "https://7ce20b15.r5.cpolar.xyz/api/order/amount/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", order_id); - //responseData.put("orderList", orderList); - responseData.put("totalAmount", log.getPrice()); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - } - /** - * 上门费支付接口 - */ - - @PostMapping("api/service/order/pay_fee") - public AjaxResult apiServiceOrderPayFee(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - // 3. 验证必要参数 - if (params == null || params.get("id") == null) { - return AppletControllerUtil.appletWarning("参数不能为空"); - } - Long orderId = Long.valueOf(params.get("id").toString()); - OrderLog orderLog = orderLogService.selectOrderLogById(orderId); - if (orderLog != null) { - Map payResult = wechatPayUtil.createBatchOrderAndPay( - user.getOpenid(), - String.valueOf(orderLog.getId()), - new BigDecimal(0.01), - 1, - "https://7ce20b15.r5.cpolar.xyz/api/door/fee/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", String.valueOf(orderLog.getId())); - //responseData.put("orderList", orderList); - responseData.put("totalAmount", orderLog.getPrice()); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - - } - return AppletControllerUtil.appletWarning("支付失败"); - } - /** - * 定金支付接口 - */ - @PostMapping("/api/service/order/pay/deposit") - public AjaxResult apiServiceOrderPaydeposit(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - // 3. 验证必要参数 - if (params == null || params.get("id") == null) { - return AppletControllerUtil.appletWarning("参数不能为空"); - } - Long orderId = Long.valueOf(params.get("id").toString()); - OrderLog orderLog = orderLogService.selectOrderLogById(orderId); - if (orderLog != null) { - Map payResult = wechatPayUtil.createBatchOrderAndPay( - user.getOpenid(), - String.valueOf(orderLog.getId()), - new BigDecimal(0.01), - 1, - "https://7ce20b15.r5.cpolar.xyz/api/deposit/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", String.valueOf(orderLog.getId())); - //responseData.put("orderList", orderList); - responseData.put("totalAmount", orderLog.getPrice()); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - } - return AppletControllerUtil.appletWarning("支付失败"); - } - /** - * 单个商品支付 - */ - @PostMapping("api/goods/order/once_pay") - public AjaxResult apiGoodsOrderOncePay(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 验证必要参数 - if (params == null || params.get("id") == null) { - return AppletControllerUtil.appletWarning("参数不能为空"); - } - Long orderId = Long.valueOf(params.get("id").toString()); - GoodsOrder goodsOrder = goodsOrderService.selectGoodsOrderById(orderId); - logger.info("orderId:{}", orderId); - logger.info("goodsOrder:{}", goodsOrder); - if (goodsOrder != null) { - goodsOrder.setMainOrderId(GenerateCustomCode.generCreateOrder("WXB")); - int flg = goodsOrderService.updateGoodsOrder(goodsOrder); - //修改成功就开始走支付功能 - if (flg > 0) { - goodsOrder.setMainOrderId(goodsOrder.getMainOrderId()); - Map payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), goodsOrder.getMainOrderId(), new BigDecimal(0.01), 1, "https://7ce20b15.r5.cpolar.xyz/api/goods/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", goodsOrder.getMainOrderId()); - //responseData.put("orderList", orderList); - responseData.put("totalAmount", goodsOrder.getTotalPrice()); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - } - } - return AppletControllerUtil.appletWarning("支付失败"); - } - /** * 取消服务订单 * @@ -6437,838 +5702,4 @@ public class AppletController extends BaseController { configData.put("hot", new String[]{"水电维修", "家电清洗", "灯具维修", "墙面翻新", "门窗家具", "改造维修", "防水维修"}); configData.put("kf", ""); } -//---------------------------------------------------------会员模块------------------------------------------------------------------------ - - /** - * 会员充值支付接口 - * - * @param params 请求参数,包含id(充值类目ID)、money(充值金额) - * @param request HTTP请求对象 - * @return 支付结果 - */ - @PostMapping("api/member/recharge/pay") - public AjaxResult memberRechargePay(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - // 新增参数判断逻辑:只允许 id 和 money 有一个有值,不允许两个都为空或 null,如果两个都有值,只走 id 有值的逻辑 - Object idObj = params.get("id"); - Object moneyObj = params.get("money"); - boolean idEmpty = (idObj == null || idObj.toString().trim().isEmpty()); - boolean moneyEmpty = (moneyObj == null || moneyObj.toString().trim().isEmpty()); - if (idEmpty && moneyEmpty) { - return AppletControllerUtil.appletWarning("参数不能为空,类目和金额必须有一个有值"); - } - // 如果 id 和 money 都有值,只走 id 逻辑,money 置空 - if (!idEmpty && !moneyEmpty) { - moneyObj = null; - } - String money = ""; - UserMemberRechargeLog userMemberRechargeLog = new UserMemberRechargeLog(); - userMemberRechargeLog.setUid(Math.toIntExact(user.getId())); - userMemberRechargeLog.setOrderid(GenerateCustomCode.generCreateOrder("DYZ")); - userMemberRechargeLog.setPaytype(0); - userMemberRechargeLog.setPaytime(new Date()); - - if (!idEmpty) { // id 有值,优先走 id 逻辑 - UserMemberRechargeProgram userMemberRechargeProgram = userMemberRechargeProgramService.selectUserMemberRechargeProgramById(Integer.valueOf(idObj.toString())); - if (userMemberRechargeProgram != null) { - userMemberRechargeLog.setInmoney(userMemberRechargeProgram.getMoney()); - userMemberRechargeLog.setComemoney(userMemberRechargeProgram.getDiscount()); - userMemberRechargeLog.setReamk("购买" + userMemberRechargeProgram.getRechargename() + "应付" + userMemberRechargeProgram.getMoney() + "元,应到" + userMemberRechargeProgram.getDiscount() + "元"); - userMemberRechargeLog.setProid(userMemberRechargeProgram.getId()); - money = userMemberRechargeProgram.getMoney().toString(); - // type大于0就是会员包年充值,回调需要特殊处理 - if (userMemberRechargeProgram.getType() > 0) { - userMemberRechargeLog.setIsmember(1); - } else { - userMemberRechargeLog.setIsmember(2); - } - } - } else if (!moneyEmpty) { // 只有 money 有值 - money = moneyObj.toString(); - userMemberRechargeLog.setInmoney(new BigDecimal(money)); - userMemberRechargeLog.setComemoney(new BigDecimal(money)); - userMemberRechargeLog.setIsmember(2); - userMemberRechargeLog.setReamk("会员现金充值" + money + "元"); - } - - if (userMemberRechargeLogService.insertUserMemberRechargeLog(userMemberRechargeLog) > 0) { - Map payResult = wechatPayUtil.createBatchOrderAndPay( - user.getOpenid(), - userMemberRechargeLog.getId().toString(), - new BigDecimal("0.01"), - 1, - "https://7ce20b15.r5.cpolar.xyz/api/recharge/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", String.valueOf(userMemberRechargeLog.getId().toString())); - //responseData.put("orderList", orderList); - responseData.put("totalAmount", money); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - } - return AppletControllerUtil.appletWarning("支付失败"); - } - - /** - * 获取充值类目(用于充值项目选择) - * - * @return 充值类目列表 - */ - @GetMapping("/api/member/recharge/catalogue") - public AjaxResult getRechargeCatalogue() { - try { - UserMemberRechargeProgram query = new UserMemberRechargeProgram(); - query.setStatus(0); - query.setType(0); - List list = userMemberRechargeProgramService.selectUserMemberRechargeProgramList(query); - return AppletControllerUtil.appletSuccess(list); - } catch (Exception e) { - return AppletControllerUtil.appletError("获取充值类目失败:" + e.getMessage()); - } - } - - /** - * 获取包年充值项目 - * - * @param id 类型ID - * @return 包年充值项目列表 - */ - @GetMapping("/api/member/recharge/catal/{id}") - public AjaxResult getRechargeCatalyear(@PathVariable("id") int id) { - try { - UserMemberRechargeProgram query = new UserMemberRechargeProgram(); - query.setStatus(0); - query.setType(id); - List list = userMemberRechargeProgramService.selectUserMemberRechargeProgramList(query); - if (!list.isEmpty()){ - return AppletControllerUtil.appletSuccess(list); - }else{ - return AppletControllerUtil.appletWarning("暂无数据"); - } - } catch (Exception e) { - return AppletControllerUtil.appletError("获取充值类目失败:" + e.getMessage()); - } - } - - /** - * 获取用户充值记录 - * - * @param request HTTP请求对象 - * @return 用户充值记录列表 - */ - @GetMapping("/api/member/recharge/log") - public AjaxResult getRechargelog(HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - try { - UserMemberRechargeLog query = new UserMemberRechargeLog(); - query.setUid(Math.toIntExact(user.getId())); - - List list = userMemberRechargeLogService.selectUserMemberRechargeLogList(query); - if (!list.isEmpty()){ - return AppletControllerUtil.appletSuccess(list); - }else{ - return AppletControllerUtil.appletWarning("暂无数据"); - } - - } catch (Exception e) { - return AppletControllerUtil.appletError("获取数据失败:" + e.getMessage()); - } - } - - /** - * 获取用户消费记录 - * - * @param request HTTP请求对象 - * @return 用户消费记录 - */ - @GetMapping("/api/member/consumption/log") - public AjaxResult getconsumptionlog(HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - try { - UserMemnerConsumptionLog query = new UserMemnerConsumptionLog(); - query.setUid(Math.toIntExact(user.getId())); - List list = userMemnerConsumptionLogService.selectUserMemnerConsumptionLogList(query); - if (!list.isEmpty()){ - return AppletControllerUtil.appletSuccess(list.getFirst()); - }else{ - return AppletControllerUtil.appletWarning("暂无数据"); - } - - } catch (Exception e) { - return AppletControllerUtil.appletError("获取充值类目失败:" + e.getMessage()); - } - } - - /** - * 用户发票信息保存/修改接口 - * - * @param params 请求参数,包含id(发票信息ID)、invoiceTitle(发票抬头)、taxNumber(纳税人识别号)、bankName(开户银行)、bankAccount(银行账号)、address(单位地址)、phone(联系电话)、email(联系邮箱)、wechat(微信号)、type(发票类型)、category(发票类别) - * @param request HTTP请求对象 - * @return 保存结果 - */ -// @PostMapping("/api/user/invoice/info") -// public AjaxResult saveOrUpdateUserInvoiceInfo(@RequestBody Map params, HttpServletRequest request) { -// // 1. 验证用户登录状态 -// String token = request.getHeader("token"); -// Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); -// if (!(Boolean) userValidation.get("valid")) { -// return AppletControllerUtil.appletWarning("用户未登录或token无效"); -// } -// // 2. 获取用户信息 -// Users user = (Users) userValidation.get("user"); -// if (user == null) { -// return AppletControllerUtil.appletWarning("用户信息获取失败"); -// } -// -// // 3. 构建发票信息对象 -// UsersInvoiceInfo info = new UsersInvoiceInfo(); -// info.setUid(user.getId().intValue()); -// info.setInvoiceTitle((String) params.get("invoiceTitle")); -// info.setTaxNumber((String) params.get("taxNumber")); -// info.setBankName((String) params.get("bankName")); -// info.setBankAccount((String) params.get("bankAccount")); -// info.setAddress((String) params.get("address")); -// info.setPhone((String) params.get("phone")); -// info.setEmail((String) params.get("email")); -// info.setWechat((String) params.get("wechat")); -// info.setType(Integer.parseInt(params.get("type").toString())); -// info.setCategory(Integer.parseInt(params.get("category").toString())); -// -// // 4. 保存或更新发票信息 -// Integer id = params.get("id") != null ? Integer.parseInt(params.get("id").toString()) : null; -// if (id != null) { -// info.setId(id); -// usersInvoiceInfoService.updateUsersInvoiceInfo(info); -// } else { -// usersInvoiceInfoService.insertUsersInvoiceInfo(info); -// } -// return AppletControllerUtil.appletSuccess(); -// } - - - - // ... existing code ... - @PostMapping("/api/user/invoice/info") - public AjaxResult saveOrUpdateUserInvoiceInfo(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 获取新参数并校验必填 - Long oid = params.get("oid") != null ? Long.valueOf(params.get("oid").toString()) : null; - Integer dataType = params.get("datatype") != null ? Integer.valueOf(params.get("datatype").toString()) : null; - if (oid == null || dataType == null) { - return AppletControllerUtil.appletWarning("orderid和datatype不能为空"); - } - - - - BigDecimal invoiceMoney = BigDecimal.ZERO; - String invoiceText = ""; - String orderid = ""; - if (dataType == 1) { - // 商品订单:xxx商品*数量=xxx元 - GoodsOrder order = goodsOrderService.selectGoodsOrderById(oid); - if (order != null) { - orderid=order.getOrderId(); - invoiceMoney = order.getTotalPrice(); - // 获取商品名称 - String productName = order.getProductName(); - if (productName == null || productName.trim().isEmpty()) { - // 如果订单中没有商品名称,尝试从商品表获取 - ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); - if (serviceGoods != null) { - productName = serviceGoods.getTitle(); - } else { - productName = "商品"; - } - } - Long quantity = order.getNum() != null ? order.getNum() : 1L; - invoiceText = productName + "*" + quantity + "=" + invoiceMoney + "元"; - } - } else if (dataType == 2) { - // 服务订单:xxx服务多少元 - Order order = orderService.selectOrderById(oid); - - if (order != null) { - orderid=order.getOrderId() ; - invoiceMoney = order.getTotalPrice(); - // 获取服务名称 - String serviceName = order.getProductName(); - if (serviceName == null || serviceName.trim().isEmpty()) { - // 如果订单中没有服务名称,尝试从服务表获取 - ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId()); - if (serviceGoods != null) { - serviceName = serviceGoods.getTitle(); - } else { - serviceName = "服务"; - } - } - invoiceText = serviceName + "服务" + invoiceMoney + "元"; - } - } else if (dataType == 3) { - // 充值订单:xxx充值金额xxx元 - UserMemberRechargeLog recharge = userMemberRechargeLogService.selectUserMemberRechargeLogById(oid.intValue()); - if (recharge != null) { - orderid=recharge.getOrderid(); - invoiceMoney = recharge.getInmoney(); - String rechargeName = recharge.getReamk(); - if (rechargeName == null || rechargeName.trim().isEmpty()) { - rechargeName = "会员"; - } - invoiceText = rechargeName + "充值金额" + invoiceMoney + "元"; - } - } - - - // 4. 检查是否已经开过票(防止重复开票) - UsersInvoiceInfo checkQuery = new UsersInvoiceInfo(); - checkQuery.setOrderid(orderid); - List existingInvoices = usersInvoiceInfoService.selectUsersInvoiceInfoList(checkQuery); - if (existingInvoices != null && !existingInvoices.isEmpty()) { - return AppletControllerUtil.appletWarning("该订单已经开过发票,不能重复开票"); - } - - - // 5. 构建发票信息对象 - UsersInvoiceInfo info = new UsersInvoiceInfo(); - info.setUid(user.getId().intValue()); - info.setInvoiceTitle((String) params.get("invoiceTitle")); - info.setTaxNumber((String) params.get("taxNumber")); - info.setBankName((String) params.get("bankName")); - info.setBankAccount((String) params.get("bankAccount")); - info.setAddress((String) params.get("address")); - info.setPhone((String) params.get("phone")); - info.setEmail((String) params.get("email")); - info.setWechat((String) params.get("wechat")); - info.setType(Integer.parseInt(params.get("type").toString())); - info.setCategory(Integer.parseInt(params.get("category").toString())); - info.setOrderid(orderid); - info.setInvoicemoney(invoiceMoney); - info.setStatus(1); - info.setInvoicetext(invoiceText); - - // 6. 保存或更新发票信息 - Integer id = params.get("id") != null ? Integer.parseInt(params.get("id").toString()) : null; - if (id != null) { - info.setId(id); - usersInvoiceInfoService.updateUsersInvoiceInfo(info); - } else { - usersInvoiceInfoService.insertUsersInvoiceInfo(info); - } - return AppletControllerUtil.appletSuccess(); - } - - - - - - /** - * 查询用户发票信息列表接口 - * - * @param request HTTP请求对象 - * @return 用户发票信息列表 - */ - @GetMapping("/api/user/invoice/list") - public AjaxResult getUserInvoiceInfoList(HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - UsersInvoiceInfo query = new UsersInvoiceInfo(); - query.setUid(user.getId().intValue()); - // 3. 查询用户发票信息列表 - List list = usersInvoiceInfoService.selectUsersInvoiceInfoList(query); - return AppletControllerUtil.appletSuccess(list); - } - - /** - * 删除用户发票信息接口 - * - * @param id 发票信息ID - * @param request HTTP请求对象 - * @return 删除结果 - */ - @DeleteMapping("/api/user/invoice/info/{id}") - public AjaxResult deleteUserInvoiceInfo(@PathVariable("id") Integer id, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 删除用户发票信息 - int result = usersInvoiceInfoService.deleteUsersInvoiceInfoById(id); - if (result > 0) { - return AppletControllerUtil.appletSuccess(); - } else { - return AppletControllerUtil.appletWarning("删除失败"); - } - } - - -/** - * 服务订单评价 - * - * @param request HTTP请求对象 - * @return 验证结果 - */ -@PostMapping("/api/service/order/comment") -public AjaxResult serviceOrderComment(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - - // 参数验证 - if (!params.containsKey("order_id") || !params.containsKey("content") || !params.containsKey("num")) { - return AppletControllerUtil.appletWarning("参数错误"); - } - - String orderId = params.get("order_id").toString(); - String content = params.get("content").toString(); - Integer num = Integer.parseInt(params.get("num").toString()); -// -// // 检查是否已经评价过 -// OrderComment existComment = orderCommentService.selectOrderCommentByOrderIdAndUserId(orderId, user.getId()); -// if (existComment != null) { -// return AjaxResult.error("请勿重复提交"); -// } - - // 获取订单信息 - Order order = orderService.selectOrderByOrderId(orderId); - if (order == null) { - return AppletControllerUtil.appletWarning("订单不存在"); - } - int count = orderCommentService.selectCountOrderCommentByOid(order.getId()); - if (count > 0) { - return AppletControllerUtil.appletWarning("请勿重复提交"); - } - // 计算评分类型 - Integer numType; - if (num == 1) { - numType = 3; // 差评 - } else if (num == 2 || num == 3) { - numType = 2; // 中评 - } else { - numType = 1; // 好评 - } - - // 构建评价数据 - OrderComment comment = new OrderComment(); - comment.setOid(order.getId()); - comment.setOrderId(orderId); - comment.setProductId(order.getProductId()); - comment.setContent(content); - comment.setNum(Long.valueOf(num)); - comment.setNumType(Long.valueOf(numType)); - comment.setUid(user.getId()); - comment.setWorkerId(order.getWorkerId()); - - // 处理图片 - if (params.containsKey("images") && params.get("images") != null) { - String images = JSON.toJSONString(params.get("images")); - comment.setImages(images); - } - // 处理图片 - if (params.containsKey("labels") && params.get("labels") != null) { - String labels = JSON.toJSONString(params.get("labels")); - comment.setLabels(labels); - } - - - try { - // 1. 保存评价 - orderCommentService.insertOrderComment(comment); - - // 2. 添加订单日志 - OrderLog orderLog = new OrderLog(); - orderLog.setOid(order.getId()); - orderLog.setOrderId(orderId); - orderLog.setTitle("订单评价"); - orderLog.setType(BigDecimal.valueOf(8)); - - Map logContent = new HashMap<>(); - logContent.put("text", content); - logContent.put("image", params.get("images")); - logContent.put("num", num); - orderLog.setContent(JSON.toJSONString(logContent)); - - orderLogService.insertOrderLog(orderLog); - - // 3. 更新订单状态 -// Order updateOrder = new Order(); -// order.setOrderId(orderId); - order.setStatus(4L); // 完成状态 - order.setIsComment(1); // 已评价 - orderService.updateOrder(order); - - return AjaxResult.success(); - } catch (Exception e) { - return AjaxResult.error("操作失败:" + e.getMessage()); - } - } catch (Exception e) { - return AjaxResult.error("系统错误:" + e.getMessage()); - } -} - -@GetMapping("/api/user/check/default") -public AjaxResult checkUserDefault(HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletUnauthorized(); - } - - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 验证图像和昵称是否为系统默认 - String defaultAvatar = "https://img.huafurenjia.cn/default/user_avatar.jpeg"; - String defaultName = "微信用户"; - - if (defaultAvatar.equals(user.getAvatar()) && defaultName.equals(user.getName())) { - return AppletControllerUtil.appletWarning("请修改您的图像和昵称"); - } - - return AppletControllerUtil.appletSuccess("校验通过"); - } catch (Exception e) { - System.err.println("验证用户图像和昵称异常:" + e.getMessage()); - return AppletControllerUtil.appletError("验证失败:" + e.getMessage()); - } -} - - - - @GetMapping("/api/secondary/classification") - public AjaxResult classification(HttpServletRequest request) { - try { - - List list = serviceCateService.selectServiceCateCiKaList(); - - return AppletControllerUtil.appletSuccess(list); - } catch (Exception e) { - System.err.println("验证用户图像和昵称异常:" + e.getMessage()); - return AppletControllerUtil.appletError("验证失败:" + e.getMessage()); - } - } - - /** - * 拼团支付接口 - * IUserGroupBuyingService userGroupBuyingService; - */ - @PostMapping("/api/secondary/card/list") - public AjaxResult getSecondaryCardList(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 获取并验证分页参数 - int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1; - int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 15; - - Map pageValidation = PageUtil.validatePageParams(page, limit); - if (!(Boolean) pageValidation.get("valid")) { - return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); - } - - // 2. 获取type参数 - Long type = params.get("type") != null ? Long.parseLong(params.get("type").toString()) : null; - - // 3. 创建查询对象 - UserSecondaryCard queryParams = new UserSecondaryCard(); - queryParams.setStatus(1L); // 只查询状态为1的数据 - if (type != null) { - queryParams.setType(type); - } - - // 4. 设置分页参数 - PageHelper.startPage(page, limit); - - // 5. 执行查询 - List list = userSecondaryCardService.selectUserSecondaryCardList(queryParams); - - for (UserSecondaryCard card : list) { - List idsList = com.alibaba.fastjson2.JSONArray.parseArray(card.getGoodsids(), String.class); - card.setServiceDetail(serviceGoodsService.selectServiceGoodsfrocikaList(idsList)); - } - - - // 6. 获取分页信息并构建响应 - TableDataInfo tableDataInfo = getDataTable(list); - - // 7. 构建符合要求的分页响应格式 - Map pageData = PageUtil.buildPageResponse(tableDataInfo, page, limit); - - return AppletControllerUtil.appletSuccess(pageData); - - } catch (Exception e) { - System.err.println("查询次卡列表异常:" + e.getMessage()); - return AppletControllerUtil.appletError("获取次卡列表失败:" + e.getMessage()); - } - } - - /** - * 师傅报价接口 - * - * @param params 包含orderid和money的参数 - * @param request HTTP请求对象 - * @return 报价结果 - */ - @PostMapping("/api/worker/quote/price") - public AjaxResult workerQuotePrice(@RequestBody Map params, HttpServletRequest request) { - try { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 验证必要参数 - if (params == null || params.get("orderid") == null || params.get("money") == null) { - return AppletControllerUtil.appletWarning("订单ID和报价金额不能为空"); - } - - // 4. 获取参数 - String orderId = params.get("orderid").toString(); - BigDecimal quoteMoney = new BigDecimal(params.get("money").toString()); - - // 5. 查询订单是否存在 - Order order = orderService.selectOrderByOrderId(orderId); - if (order == null) { - return AppletControllerUtil.appletWarning("订单不存在"); - } - - // 6. 查询用户是否已对该订单报过价 - UserDemandQuotation queryParams = new UserDemandQuotation(); - queryParams.setWorkerid(user.getId()); - queryParams.setOrderid(orderId); - List existingQuotes = userDemandQuotationService.selectUserDemandQuotationList(queryParams); - - // 7. 处理报价 - UserDemandQuotation quoteRecord; - if (existingQuotes != null && !existingQuotes.isEmpty()) { - // 已有报价,更新 - quoteRecord = existingQuotes.getFirst(); - quoteRecord.setMoney(quoteMoney); - quoteRecord.setQuotationTime(new Date()); - quoteRecord.setUpdateTime(new Date()); - userDemandQuotationService.updateUserDemandQuotation(quoteRecord); - } else { - // 新增报价 - quoteRecord = new UserDemandQuotation(); - quoteRecord.setWorkerid(user.getId()); - quoteRecord.setOrderid(orderId); - quoteRecord.setMoney(quoteMoney); - quoteRecord.setQuotationTime(new Date()); - quoteRecord.setStatus(1L); // 设置状态为有效 - quoteRecord.setWorkername(user.getName()); - quoteRecord.setWorkerimage(user.getAvatar()); - quoteRecord.setCreateTime(new Date()); - userDemandQuotationService.insertUserDemandQuotation(quoteRecord); - } - - return AppletControllerUtil.appletSuccess("报价成功"); - - } catch (Exception e) { - System.err.println("师傅报价异常:" + e.getMessage()); - return AppletControllerUtil.appletError("报价失败:" + e.getMessage()); - } - } - - @PostMapping("api/group/once_pay") - public AjaxResult apigroupOncePay(@RequestBody Map params, HttpServletRequest request) { - // 1. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletWarning("用户未登录或token无效"); - } - - // 2. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 3. 验证必要参数 - if (params == null || params.get("id") == null) { - return AppletControllerUtil.appletWarning("参数不能为空"); - } - Long orderId = Long.valueOf(params.get("id").toString()); - ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(orderId); - if (serviceGoods == null) { - return AppletControllerUtil.appletWarning("商品信息获取失败"); - } - UserGroupBuying userGroupBuying = new UserGroupBuying(); - userGroupBuying.setId(orderId); - userGroupBuying.setUid(user.getId()); - userGroupBuying.setStatus(Long.valueOf(4)); - userGroupBuying.setUname(user.getName()); - userGroupBuying.setProductId(serviceGoods.getId()); - userGroupBuying.setPaytype(Long.valueOf(1)); - userGroupBuying.setMoney(serviceGoods.getGroupprice()); - userGroupBuying.setOrderid(GenerateCustomCode.generCreateOrder("G")); - int flg =userGroupBuyingService.insertUserGroupBuying(userGroupBuying); - if (flg > 0) { - Map payResult = wechatPayUtil.createBatchOrderAndPay(user.getOpenid(), - userGroupBuying.getId().toString(), - new BigDecimal(0.01), - 1, - "https://7ce20b15.r5.cpolar.xyz/api/group/pay/notify"); - if (payResult != null && Boolean.TRUE.equals(payResult.get("success"))) { - Map responseData = new HashMap<>(); - responseData.put("mainOrderId", userGroupBuying.getOrderid()); - //responseData.put("orderList", orderList); - responseData.put("totalAmount", serviceGoods.getGroupprice()); - responseData.put("prepayId", payResult.get("prepayId")); - // 直接合并所有支付参数 - responseData.putAll(payResult); - return AppletControllerUtil.appletSuccess(responseData); - } else { - String errorMsg = payResult != null ? (String) payResult.get("message") : "微信支付下单失败"; - return AppletControllerUtil.appletWarning("支付下单失败:" + errorMsg); - } - } - return AppletControllerUtil.appletWarning("支付失败"); - } - /** - * 小程序端:查询用户服务金/消费金日志(分页,PageUtil.buildPageResponse) - * type: 1=服务金,2=消费金 - * limit: 每页条数,page: 页码 - */ - @GetMapping("/api/user/benefit/log") - public AjaxResult getUserBenefitLog( - @RequestParam(value = "type") Integer type, - @RequestParam(value = "limit", defaultValue = "10") int limit, - @RequestParam(value = "page", defaultValue = "1") int page, - HttpServletRequest request) { - try { - // 1. 验证分页参数 - Map pageValidation = PageUtil.validatePageParams(page, limit); - if (!(Boolean) pageValidation.get("valid")) { - return AppletControllerUtil.appletWarning((String) pageValidation.get("message")); - } - - // 2. 验证用户登录状态 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AppletControllerUtil.appletUnauthorized(); - } - - // 3. 获取用户信息 - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AppletControllerUtil.appletWarning("用户信息获取失败"); - } - - // 4. 设置分页参数 - PageHelper.startPage(page, limit); - - // 5. 查询服务金/消费金日志 - UserBenefitPoints query = new UserBenefitPoints(); - query.setUid(user.getId()); - query.setType(Long.valueOf(type)); - List logList = userBenefitPointsService.selectUserBenefitPointsList(query); - - // 6. 获取分页信息并构建响应 - TableDataInfo tableDataInfo = getDataTable(logList); - Map pageData = PageUtil.buildPageResponse(tableDataInfo, page, limit); - - return AppletControllerUtil.appletSuccess(pageData); - } catch (Exception e) { - System.err.println("查询用户服务金/消费金日志异常:" + e.getMessage()); - return AppletControllerUtil.appletError("查询服务金/消费金日志失败:" + e.getMessage()); - } - } - - - /** - * 小程序用户余额日志查询接口 - */ - @PostMapping("/api/user/balance/logs") - public AjaxResult getBalanceLogList(HttpServletRequest request, @RequestBody Map params) { - // 从请求头获取token - String token = request.getHeader("token"); - - // 调用工具类方法 - return AppletControllerUtil.getUserBalanceLogList(params, token, usersService, userMemnerConsumptionLogService); - } - } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/CursorUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/CursorUtil.java deleted file mode 100644 index fe78dc3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/CursorUtil.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.ruoyi.system.controller; - -import com.alibaba.fastjson2.JSONObject; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.system.ControllerUtil.*; -import com.ruoyi.system.domain.*; -import com.ruoyi.system.service.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.math.BigDecimal; -import java.text.SimpleDateFormat; -import java.util.*; - -/** - * 游标工具控制器 - * - * @author Mr. Zhang Pan - * @version 1.0 - * @date 2025-01-10 - */ -@RestController -public class CursorUtil extends BaseController { - - @Autowired - private IServiceGoodsService serviceGoodsService; - - @Autowired - private IGoodsOrderCursorService goodsOrderCursorService; - - @Autowired - private IUsersService usersService; - - @Autowired - private IUserAddressService userAddressService; - - @Autowired - private IGoodsOrderService goodsOrderService; - - @Autowired - private WechatPayUtil wechatPayUtil; - - @Autowired - private IOrderService orderService; - - @Autowired - private IOrderLogService orderLogService; - - @Autowired - private IOrderCommentService orderCommentService; - - @Autowired - private IUsersInvoiceInfoService usersInvoiceInfoService; - - /** - * 小程序接口:维护用户发票信息(新增/修改) - * POST /api/user/invoice/info - * @param params 发票信息参数 - * @param request 请求对象 - * @return AjaxResult - */ - @PostMapping("/api/user/invoicedata/info") - public AjaxResult saveOrUpdateInvoiceInfo(@RequestBody Map params, HttpServletRequest request) { - // 1. 校验用户登录 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AjaxResult.error("用户未登录或token无效"); - } - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AjaxResult.error("用户信息获取失败"); - } - // 2. 构建发票对象 - UsersInvoiceInfo invoiceInfo = new UsersInvoiceInfo(); - invoiceInfo.setId(params.get("id") != null ? Integer.valueOf(params.get("id").toString()) : null); - invoiceInfo.setUid(user.getId() != null ? user.getId().intValue() : null); - invoiceInfo.setInvoiceTitle((String) params.get("invoiceTitle")); - invoiceInfo.setTaxNumber((String) params.get("taxNumber")); - invoiceInfo.setBankName((String) params.get("bankName")); - invoiceInfo.setBankAccount((String) params.get("bankAccount")); - invoiceInfo.setAddress((String) params.get("address")); - invoiceInfo.setPhone((String) params.get("phone")); - invoiceInfo.setEmail((String) params.get("email")); - invoiceInfo.setWechat((String) params.get("wechat")); - invoiceInfo.setType(params.get("type") != null ? Integer.valueOf(params.get("type").toString()) : 1); - invoiceInfo.setCategory(params.get("category") != null ? Integer.valueOf(params.get("category").toString()) : 1); - // 3. 保存或更新 - try { - if (invoiceInfo.getId() != null) { - usersInvoiceInfoService.updateUsersInvoiceInfo(invoiceInfo); - } else { - usersInvoiceInfoService.insertUsersInvoiceInfo(invoiceInfo); - } - return AjaxResult.success("发票信息保存成功"); - } catch (Exception e) { - return AjaxResult.error("发票信息保存失败: " + e.getMessage()); - } - } - - /** - * 小程序接口:查询当前用户所有发票信息 - * GET /api/user/invoice/list - * @param request 请求对象 - * @return AjaxResult - */ - @GetMapping("/api/user/invoicedata/list") - public AjaxResult getInvoicelist(HttpServletRequest request) { - // 1. 校验用户登录 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AjaxResult.error("用户未登录或token无效"); - } - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AjaxResult.error("用户信息获取失败"); - } - UsersInvoiceInfo invoiceInfo = new UsersInvoiceInfo(); - invoiceInfo.setUid(user.getId() != null ? user.getId().intValue() : null); - // 2. 查询所有发票信息 - List list = usersInvoiceInfoService.selectUsersInvoiceInfoList(invoiceInfo); - return AjaxResult.success(list); - } - - /** - * 小程序接口:删除用户单个发票信息 - * DELETE /api/user/invoice/delete/{id} - * @param id 发票ID - * @param request 请求对象 - * @return AjaxResult - */ - @DeleteMapping("/api/user/invoicedata/delete/{id}") - public AjaxResult deleteInvoiceInfo(@PathVariable Integer id, HttpServletRequest request) { - // 1. 校验用户登录 - String token = request.getHeader("token"); - Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); - if (!(Boolean) userValidation.get("valid")) { - return AjaxResult.error("用户未登录或token无效"); - } - Users user = (Users) userValidation.get("user"); - if (user == null) { - return AjaxResult.error("用户信息获取失败"); - } - // 2. 删除发票(需校验归属) - try { - int result = usersInvoiceInfoService.deleteUsersInvoiceInfoById(id); - if (result > 0) { - return AjaxResult.success("删除成功"); - } else { - return AjaxResult.error("删除失败或无权限"); - } - } catch (Exception e) { - return AjaxResult.error("删除异常: " + e.getMessage()); - } - } -} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java index 9e72edd..6557598 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/PayNotifyController.java @@ -300,6 +300,18 @@ public class PayNotifyController extends BaseController { userMemberRechargeLog.setPaytype(1); userMemberRechargeLog.setTransactionId(transactionId); userMemberRechargeLogService.updateUserMemberRechargeLog(userMemberRechargeLog); + //成功之后就要给大哥加流水,确保大哥的账户流水里面有这条充值的记录,如果购买了会员下一步扣除就可以 + UserMemnerConsumptionLog newuserMemnerConsumptionLog = new UserMemnerConsumptionLog(); + newuserMemnerConsumptionLog.setUid(Math.toIntExact(users.getId())); + newuserMemnerConsumptionLog.setConsumptiontype(3); + newuserMemnerConsumptionLog.setConsumptiontime(new Date()); + newuserMemnerConsumptionLog.setConsumptionmoney(userMemberRechargeLog.getComemoney()); + newuserMemnerConsumptionLog.setReamk("用户充值"+userMemberRechargeLog.getInmoney()+"实际到账"+userMemberRechargeLog.getComemoney()); + newuserMemnerConsumptionLog.setBeformoney(users.getBalance()); + newuserMemnerConsumptionLog.setAftermoney(users.getBalance().add(userMemberRechargeLog.getComemoney())); + newuserMemnerConsumptionLog.setNowmoney(users.getBalance().add(userMemberRechargeLog.getComemoney())); + newuserMemnerConsumptionLog.setType(1); + userMemnerConsumptionLogService.insertUserMemnerConsumptionLog(newuserMemnerConsumptionLog); users.setBalance(users.getBalance().add(userMemberRechargeLog.getComemoney())); usersService.updateUsers(users); WXsendMsgUtil.sendUserPayMoney(users.getOpenid(),"充值成功",totalFee,"1","充值成功"); @@ -310,10 +322,11 @@ public class PayNotifyController extends BaseController { userMemnerConsumptionLog.setConsumptiontype(2); userMemnerConsumptionLog.setConsumptiontime(new Date()); userMemnerConsumptionLog.setConsumptionmoney(userMemberRechargeLog.getComemoney()); - userMemnerConsumptionLog.setReamk("会员包年充值"); + userMemnerConsumptionLog.setReamk("会员包年扣减"); userMemnerConsumptionLog.setBeformoney(users.getBalance()); userMemnerConsumptionLog.setAftermoney(users.getBalance().subtract(userMemberRechargeLog.getComemoney())); userMemnerConsumptionLog.setNowmoney(users.getBalance().subtract(userMemberRechargeLog.getComemoney())); + userMemnerConsumptionLog.setType(2); userMemnerConsumptionLogService.insertUserMemnerConsumptionLog(userMemnerConsumptionLog); users.setBalance(users.getBalance().subtract(userMemberRechargeLog.getComemoney())); users.setIsmember(1); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/BalancePayUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/BalancePayUtil.java index 0ab5068..4f8cdd5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/BalancePayUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/BalancePayUtil.java @@ -6,22 +6,30 @@ import com.ruoyi.system.domain.Users; import com.ruoyi.system.domain.UserMemnerConsumptionLog; import com.ruoyi.system.service.IUserMemnerConsumptionLogService; import com.ruoyi.system.service.IUsersService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.math.BigDecimal; import java.util.Date; +import java.util.HashMap; +import java.util.Map; /** * 余额支付工具类 * - * @author + * @author ruoyi + * @date 2025-01-26 */ public class BalancePayUtil { + private static final Logger logger = LoggerFactory.getLogger(BalancePayUtil.class); + private static final IUserMemnerConsumptionLogService userMemnerConsumptionLogService = SpringUtils.getBean(IUserMemnerConsumptionLogService.class); private static final IUsersService usersService = SpringUtils.getBean(IUsersService.class); /** - * 用户余额支付 + * 用户余额支付(原有方法保持不变) * @param user 用户对象 * @param amount 支付金额 * @return AjaxResult 支付结果 @@ -57,14 +65,212 @@ public class BalancePayUtil { log.setBeformoney(beforeBalance); log.setAftermoney(user.getBalance()); log.setNowmoney(user.getBalance()); + log.setType(2); // 2=支出 userMemnerConsumptionLogService.insertUserMemnerConsumptionLog(log); // 推送支付成功消息 try { WXsendMsgUtil.sendUserPayMoney(user.getOpenid(), "余额支付成功", amount.toString(), "1", "余额支付成功"); } catch (Exception e) { // 推送失败不影响主流程 - System.err.println("余额支付消息推送失败: " + e.getMessage()); + logger.warn("余额支付消息推送失败: {}", e.getMessage()); } return AjaxResult.success("余额支付成功"); } + + /** + * 用户余额支付(增强版) + * + * @param userId 用户ID + * @param money 支付金额 + * @param remark 支付备注 + * @return Map 支付结果 + * + * 返回结果说明: + * - success: true/false 支付是否成功 + * - message: 结果消息 + * - insufficientAmount: 余额不足时,还差多少钱(仅在余额不足时返回) + * - beforeBalance: 支付前余额 + * - afterBalance: 支付后余额 + * - consumptionLogId: 消费记录ID + */ + public static Map processBalancePayment(Long userId, BigDecimal money, String remark) { + Map result = new HashMap<>(); + + try { + // 1. 参数验证 + if (userId == null || userId <= 0) { + result.put("success", false); + result.put("message", "用户ID无效"); + return result; + } + + if (money == null || money.compareTo(BigDecimal.ZERO) <= 0) { + result.put("success", false); + result.put("message", "支付金额必须大于0"); + return result; + } + + if (remark == null || remark.trim().isEmpty()) { + remark = "余额支付"; + } + + // 2. 获取用户信息 + Users user = usersService.selectUsersById(userId); + if (user == null) { + result.put("success", false); + result.put("message", "用户不存在"); + return result; + } + + // 3. 检查用户余额 + BigDecimal currentBalance = user.getBalance(); + if (currentBalance == null) { + currentBalance = BigDecimal.ZERO; + user.setBalance(currentBalance); + } + + result.put("beforeBalance", currentBalance); + + // 4. 判断余额是否足够 + if (currentBalance.compareTo(money) < 0) { + // 余额不足,计算还差多少钱 + BigDecimal insufficientAmount = money.subtract(currentBalance); + result.put("success", false); + result.put("message", "余额不足"); + result.put("insufficientAmount", insufficientAmount); + result.put("currentBalance", currentBalance); + result.put("requiredAmount", money); + + logger.info("用户{}余额支付失败,余额不足。当前余额:{},需要支付:{},还差:{}", + userId, currentBalance, money, insufficientAmount); + return result; + } + + // 5. 执行余额扣减 + BigDecimal afterBalance = currentBalance.subtract(money); + user.setBalance(afterBalance); + + int updateResult = usersService.updateUsers(user); + if (updateResult <= 0) { + result.put("success", false); + result.put("message", "余额扣减失败,请重试"); + return result; + } + + // 6. 记录消费流水 + UserMemnerConsumptionLog consumptionLog = new UserMemnerConsumptionLog(); + consumptionLog.setUid(Math.toIntExact(userId)); + consumptionLog.setConsumptiontype(1); // 1=余额支付消费 + consumptionLog.setConsumptiontime(new Date()); + consumptionLog.setConsumptionmoney(money); + consumptionLog.setReamk(remark); + consumptionLog.setBeformoney(currentBalance); + consumptionLog.setAftermoney(afterBalance); + consumptionLog.setNowmoney(afterBalance); + consumptionLog.setType(2); // 2=支出 + + int logResult = userMemnerConsumptionLogService.insertUserMemnerConsumptionLog(consumptionLog); + + // 7. 构建成功结果 + result.put("success", true); + result.put("message", "余额支付成功"); + result.put("afterBalance", afterBalance); + result.put("paymentAmount", money); + result.put("remark", remark); + + if (logResult > 0) { + result.put("consumptionLogId", consumptionLog.getId()); + } + + // 8. 发送支付成功通知(可选) + try { + if (user.getOpenid() != null && !user.getOpenid().trim().isEmpty()) { + WXsendMsgUtil.sendUserPayMoney(user.getOpenid(), "余额支付成功", + money.toString(), "1", remark); + } + } catch (Exception e) { + logger.warn("余额支付成功通知发送失败,用户ID:{},错误:{}", userId, e.getMessage()); + } + + logger.info("用户{}余额支付成功,支付金额:{},支付前余额:{},支付后余额:{},备注:{}", + userId, money, currentBalance, afterBalance, remark); + + return result; + + } catch (Exception e) { + logger.error("余额支付处理异常,用户ID:{},支付金额:{},备注:{}", userId, money, remark, e); + result.put("success", false); + result.put("message", "余额支付处理异常:" + e.getMessage()); + return result; + } + } + + /** + * 检查用户余额是否足够 + * + * @param userId 用户ID + * @param requiredAmount 需要的金额 + * @return Map 检查结果 + * + * 返回结果说明: + * - sufficient: true/false 余额是否足够 + * - currentBalance: 当前余额 + * - requiredAmount: 需要的金额 + * - insufficientAmount: 不足的金额(仅在余额不足时返回) + */ + public static Map checkBalanceSufficiency(Long userId, BigDecimal requiredAmount) { + Map result = new HashMap<>(); + + try { + // 1. 参数验证 + if (userId == null || userId <= 0) { + result.put("sufficient", false); + result.put("message", "用户ID无效"); + return result; + } + + if (requiredAmount == null || requiredAmount.compareTo(BigDecimal.ZERO) <= 0) { + result.put("sufficient", false); + result.put("message", "检查金额必须大于0"); + return result; + } + + // 2. 获取用户信息 + Users user = usersService.selectUsersById(userId); + if (user == null) { + result.put("sufficient", false); + result.put("message", "用户不存在"); + return result; + } + + // 3. 检查余额 + BigDecimal currentBalance = user.getBalance(); + if (currentBalance == null) { + currentBalance = BigDecimal.ZERO; + } + + result.put("currentBalance", currentBalance); + result.put("requiredAmount", requiredAmount); + + if (currentBalance.compareTo(requiredAmount) >= 0) { + // 余额足够 + result.put("sufficient", true); + result.put("message", "余额充足"); + } else { + // 余额不足 + BigDecimal insufficientAmount = requiredAmount.subtract(currentBalance); + result.put("sufficient", false); + result.put("message", "余额不足"); + result.put("insufficientAmount", insufficientAmount); + } + + return result; + + } catch (Exception e) { + logger.error("检查余额充足性异常,用户ID:{},需要金额:{}", userId, requiredAmount, e); + result.put("sufficient", false); + result.put("message", "检查余额异常:" + e.getMessage()); + return result; + } + } } \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/InvoiceUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/InvoiceUtil.java new file mode 100644 index 0000000..62fa43d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/InvoiceUtil.java @@ -0,0 +1,615 @@ +package com.ruoyi.system.ControllerUtil; + +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.system.domain.*; +import com.ruoyi.system.service.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 发票工具类 + * + * @author ruoyi + * @date 2025-01-26 + */ +public class InvoiceUtil { + + private static final Logger logger = LoggerFactory.getLogger(InvoiceUtil.class); + + private static final IUsersInvoiceInfoService usersInvoiceInfoService = SpringUtils.getBean(IUsersInvoiceInfoService.class); + private static final IOrderService orderService = SpringUtils.getBean(IOrderService.class); + private static final IGoodsOrderService goodsOrderService = SpringUtils.getBean(IGoodsOrderService.class); + private static final IUserMemberRechargeLogService userMemberRechargeLogService = SpringUtils.getBean(IUserMemberRechargeLogService.class); + private static final IUsersService usersService = SpringUtils.getBean(IUsersService.class); + + /** + * 获取用户发票中心数据 + * + * @param userId 用户ID + * @param page 页码 + * @param limit 每页数量 + * @return 发票中心数据 + */ + public static Map getUserInvoiceCenter(Long userId, int page, int limit) { + try { + Map result = new HashMap<>(); + + // 1. 获取待开票订单列表 + List> pendingInvoices = getPendingInvoiceOrders(userId, page, limit); + + // 2. 获取已开票列表 + List> completedInvoices = getCompletedInvoices(userId, page, limit); + + // 3. 统计数据 + Map statistics = getInvoiceStatistics(userId); + + result.put("pendingInvoices", pendingInvoices); + result.put("completedInvoices", completedInvoices); + result.put("statistics", statistics); + + return result; + + } catch (Exception e) { + logger.error("获取用户发票中心数据失败", e); + return null; + } + } + + /** + * 获取待开票订单列表 + * + * @param userId 用户ID + * @param page 页码 + * @param limit 每页数量 + * @return 待开票订单列表 + */ + public static List> getPendingInvoiceOrders(Long userId, int page, int limit) { + try { + List> pendingOrders = new ArrayList<>(); + + // 设置分页 + PageHelper.startPage(page, limit); + + // 1. 查询服务订单(已完成且未开票) + Order orderQuery = new Order(); + orderQuery.setUid(userId); + orderQuery.setStatus(4L); // 已完成状态 + List serviceOrders = orderService.selectOrderList(orderQuery); + + for (Order order : serviceOrders) { + // 检查是否已开票 + if (!isOrderInvoiced(order.getOrderId())) { + Map orderMap = new HashMap<>(); + orderMap.put("orderId", order.getOrderId()); + orderMap.put("orderType", "service"); // 服务订单 + orderMap.put("orderTypeText", "服务订单"); + orderMap.put("amount", order.getTotalPrice()); + orderMap.put("title", order.getOrderId()+ "服务订单"); + orderMap.put("createTime", order.getCreateTime()); + orderMap.put("canInvoice", true); + pendingOrders.add(orderMap); + } + } + + // 2. 查询商品订单(已完成且未开票) + GoodsOrder goodsOrderQuery = new GoodsOrder(); + goodsOrderQuery.setUid(userId); + goodsOrderQuery.setStatus(4L); // 已完成状态 + List goodsOrders = goodsOrderService.selectGoodsOrderList(goodsOrderQuery); + + for (GoodsOrder goodsOrder : goodsOrders) { + // 检查是否已开票 + if (!isOrderInvoiced(goodsOrder.getOrderId())) { + Map orderMap = new HashMap<>(); + orderMap.put("orderId", goodsOrder.getOrderId()); + orderMap.put("orderType", "goods"); // 商品订单 + orderMap.put("orderTypeText", "商品订单"); + orderMap.put("amount", goodsOrder.getTotalPrice()); + orderMap.put("title", "商品订单"); + orderMap.put("createTime", goodsOrder.getCreateTime()); + orderMap.put("canInvoice", true); + pendingOrders.add(orderMap); + } + } + + // 3. 查询充值订单(已完成且未开票) + UserMemberRechargeLog rechargeQuery = new UserMemberRechargeLog(); + rechargeQuery.setUid(Math.toIntExact(userId)); + rechargeQuery.setPaytype(1); // 已完成状态 + List rechargeOrders = userMemberRechargeLogService.selectUserMemberRechargeLogList(rechargeQuery); + + for (UserMemberRechargeLog recharge : rechargeOrders) { + // 检查是否已开票 + if (!isOrderInvoiced(recharge.getOrderid())) { + Map orderMap = new HashMap<>(); + orderMap.put("orderId", recharge.getOrderid()); + orderMap.put("orderType", "recharge"); // 充值订单 + orderMap.put("orderTypeText", "充值订单"); + orderMap.put("amount", recharge.getInmoney()); + orderMap.put("title", recharge.getReamk() != null ? recharge.getReamk() : "会员充值"); + orderMap.put("createTime", recharge.getCreatedAt()); + orderMap.put("canInvoice", true); + pendingOrders.add(orderMap); + } + } + +// // 按创建时间倒序排列 +// pendingOrders.sort((a, b) -> { +// Date timeA = (Date) a.get("createTime"); +// Date timeB = (Date) b.get("createTime"); +// return timeB.compareTo(timeA); +// }); + + return pendingOrders; + + } catch (Exception e) { + logger.error("获取待开票订单列表失败", e); + return new ArrayList<>(); + } + } + + /** + * 获取已开票列表 + * + * @param userId 用户ID + * @param page 页码 + * @param limit 每页数量 + * @return 已开票列表 + */ + public static List> getCompletedInvoices(Long userId, int page, int limit) { + try { + // 设置分页 + PageHelper.startPage(page, limit); + + UsersInvoiceInfo query = new UsersInvoiceInfo(); + query.setUid(userId.intValue()); + List invoiceList = usersInvoiceInfoService.selectUsersInvoiceInfoList(query); + + List> completedInvoices = new ArrayList<>(); + for (UsersInvoiceInfo invoice : invoiceList) { + Map invoiceMap = new HashMap<>(); + invoiceMap.put("id", invoice.getId()); + invoiceMap.put("orderId", invoice.getOrderid()); + invoiceMap.put("invoiceTitle", invoice.getInvoiceTitle()); + invoiceMap.put("amount", invoice.getInvoicemoney()); + invoiceMap.put("invoiceText", invoice.getInvoicetext()); + invoiceMap.put("status", invoice.getStatus()); + invoiceMap.put("statusText", getInvoiceStatusText(invoice.getStatus())); + invoiceMap.put("type", invoice.getType()); + invoiceMap.put("typeText", getInvoiceTypeText(invoice.getType())); + invoiceMap.put("category", invoice.getCategory()); + invoiceMap.put("categoryText", invoice.getCategory() == 0 ? "个人" : "企业"); + invoiceMap.put("createTime", invoice.getCreatedAt()); + invoiceMap.put("hasFile", StringUtils.isNotEmpty(invoice.getFiledata())); + invoiceMap.put("fileUrl", invoice.getFiledata()); + completedInvoices.add(invoiceMap); + } + + return completedInvoices; + + } catch (Exception e) { + logger.error("获取已开票列表失败", e); + return new ArrayList<>(); + } + } + + /** + * 获取发票统计数据 + * + * @param userId 用户ID + * @return 统计数据 + */ + public static Map getInvoiceStatistics(Long userId) { + try { + Map statistics = new HashMap<>(); + + // 待开票数量 + List> pendingOrders = getPendingInvoiceOrders(userId, 1, 1000); + int pendingCount = pendingOrders.size(); + + // 已开票数量 + UsersInvoiceInfo query = new UsersInvoiceInfo(); + query.setUid(userId.intValue()); + List invoiceList = usersInvoiceInfoService.selectUsersInvoiceInfoList(query); + int completedCount = invoiceList.size(); + + // 已开票总金额 + BigDecimal totalAmount = invoiceList.stream() + .filter(invoice -> invoice.getInvoicemoney() != null) + .map(UsersInvoiceInfo::getInvoicemoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + statistics.put("pendingCount", pendingCount); + statistics.put("completedCount", completedCount); + statistics.put("totalAmount", totalAmount); + + return statistics; + + } catch (Exception e) { + logger.error("获取发票统计数据失败", e); + Map statistics = new HashMap<>(); + statistics.put("pendingCount", 0); + statistics.put("completedCount", 0); + statistics.put("totalAmount", BigDecimal.ZERO); + return statistics; + } + } + + /** + * 批量开具发票 + * + * @param userId 用户ID + * @param orderIds 订单ID数组 + * @param invoiceData 发票数据 + * @return 开票结果 + */ + public static AjaxResult createBatchInvoice(Long userId, List orderIds, Map invoiceData) { + try { + // 1. 参数验证 + if (orderIds == null || orderIds.isEmpty()) { + return AppletControllerUtil.appletWarning("请选择要开票的订单"); + } + + // 2. 验证发票数据 + String validateResult = validateInvoiceData(invoiceData); + if (StringUtils.isNotEmpty(validateResult)) { + return AppletControllerUtil.appletWarning(validateResult); + } + + List successOrders = new ArrayList<>(); + List failedOrders = new ArrayList<>(); + BigDecimal totalAmount = BigDecimal.ZERO; + List invoiceTexts = new ArrayList<>(); + + // 3. 逐个处理订单 + for (String orderId : orderIds) { + try { + // 验证订单是否存在且属于当前用户 + Map orderInfo = getOrderInfo(orderId, userId); + if (orderInfo == null) { + failedOrders.add(orderId + "(订单不存在或不属于当前用户)"); + continue; + } + + // 检查是否已开票 + if (isOrderInvoiced(orderId)) { + failedOrders.add(orderId + "(已开过发票)"); + continue; + } + + // 累计金额和开票内容 + BigDecimal orderAmount = (BigDecimal) orderInfo.get("amount"); + if (orderAmount != null) { + totalAmount = totalAmount.add(orderAmount); + } + invoiceTexts.add((String) orderInfo.get("title")); + successOrders.add(orderId); + + } catch (Exception e) { + failedOrders.add(orderId + "(处理异常: " + e.getMessage() + ")"); + } + } + + // 4. 如果没有可开票的订单 + if (successOrders.isEmpty()) { + return AppletControllerUtil.appletWarning("没有可开票的订单:" + String.join(", ", failedOrders)); + } + + // 5. 创建发票记录 + UsersInvoiceInfo invoice = new UsersInvoiceInfo(); + invoice.setUid(userId.intValue()); + invoice.setOrderid(String.join(",", successOrders)); // 多个订单ID用逗号分隔 + invoice.setInvoiceTitle((String) invoiceData.get("invoiceTitle")); + invoice.setType((Integer) invoiceData.get("type")); + invoice.setCategory((Integer) invoiceData.get("category")); + invoice.setInvoicemoney(totalAmount); // 总金额 + invoice.setInvoicetext(String.join("、", invoiceTexts)); // 开票内容合并 + invoice.setStatus(1); // 待开票 + invoice.setCreatedAt(new Date()); + + // 根据发票类别设置不同字段 + if ((Integer) invoiceData.get("category") == 0) { + // 个人发票 + invoice.setEmail((String) invoiceData.get("email")); + // 清空企业字段 + invoice.setTaxNumber(null); + invoice.setBankName(null); + invoice.setBankAccount(null); + invoice.setAddress(null); + invoice.setPhone(null); + invoice.setWechat(null); + } else { + // 企业发票 + invoice.setTaxNumber((String) invoiceData.get("taxNumber")); + invoice.setAddress((String) invoiceData.get("address")); + invoice.setPhone((String) invoiceData.get("phone")); + invoice.setBankName((String) invoiceData.get("bankName")); + invoice.setBankAccount((String) invoiceData.get("bankAccount")); + invoice.setEmail((String) invoiceData.get("email")); + invoice.setWechat((String) invoiceData.get("wechat")); + } + + // 6. 保存发票信息 + int result = usersInvoiceInfoService.insertUsersInvoiceInfo(invoice); + if (result > 0) { + Map resultData = new HashMap<>(); + resultData.put("successCount", successOrders.size()); + resultData.put("successOrders", successOrders); + resultData.put("totalAmount", totalAmount); + resultData.put("invoiceId", invoice.getId()); + + if (!failedOrders.isEmpty()) { + resultData.put("failedCount", failedOrders.size()); + resultData.put("failedOrders", failedOrders); + resultData.put("message", "发票申请提交成功,成功开票 " + successOrders.size() + " 个订单,失败 " + failedOrders.size() + " 个订单"); + return AppletControllerUtil.appletSuccess(resultData); + } else { + resultData.put("message", "发票申请提交成功,共开票 " + successOrders.size() + " 个订单"); + return AppletControllerUtil.appletSuccess(resultData); + } + } else { + return AppletControllerUtil.appletWarning("发票申请提交失败"); + } + + } catch (Exception e) { + logger.error("批量开具发票失败", e); + return AppletControllerUtil.appletError("批量开具发票失败:" + e.getMessage()); + } + } + + /** + * 开具发票(单个订单,兼容旧接口) + * + * @param userId 用户ID + * @param orderId 订单ID + * @param invoiceData 发票数据 + * @return 开票结果 + */ + public static AjaxResult createInvoice(Long userId, String orderId, Map invoiceData) { + List orderIds = new ArrayList<>(); + orderIds.add(orderId); + return createBatchInvoice(userId, orderIds, invoiceData); + } + + /** + * 获取订单信息 + * + * @param orderId 订单ID + * @param userId 用户ID + * @return 订单信息 + */ + private static Map getOrderInfo(String orderId, Long userId) { + try { + // 1. 查询服务订单 + Order serviceOrder = orderService.selectOrderByOrderId(orderId); + if (serviceOrder != null && serviceOrder.getUid().equals(userId)) { + Map orderInfo = new HashMap<>(); + orderInfo.put("orderId", serviceOrder.getOrderId()); + orderInfo.put("amount", serviceOrder.getTotalPrice()); + orderInfo.put("title", serviceOrder.getOrderId()+ "服务订单"); + orderInfo.put("type", "service"); + return orderInfo; + } + + // 2. 查询商品订单 + GoodsOrder goodsOrder = goodsOrderService.selectGoodsOrderByorderId(orderId); + if (goodsOrder != null && goodsOrder.getUid().equals(userId)) { + Map orderInfo = new HashMap<>(); + orderInfo.put("orderId", goodsOrder.getOrderId()); + orderInfo.put("amount", goodsOrder.getTotalPrice()); + orderInfo.put("title", "商品订单"); + orderInfo.put("type", "goods"); + return orderInfo; + } + + // 3. 查询充值订单 + UserMemberRechargeLog rechargeOrder = userMemberRechargeLogService.selectUserMemberRechargeLogByorderid(orderId); + if (rechargeOrder != null && rechargeOrder.getUid().equals(userId)) { + Map orderInfo = new HashMap<>(); + orderInfo.put("orderId", rechargeOrder.getOrderid()); + orderInfo.put("amount", rechargeOrder.getInmoney()); + orderInfo.put("title", rechargeOrder.getReamk() != null ? rechargeOrder.getReamk() : "会员充值"); + orderInfo.put("type", "recharge"); + return orderInfo; + } + + return null; + + } catch (Exception e) { + logger.error("获取订单信息失败", e); + return null; + } + } + + /** + * 检查订单是否已开票 + * + * @param orderId 订单ID + * @return 是否已开票 + */ + private static boolean isOrderInvoiced(String orderId) { + try { + // 查询所有发票记录 + UsersInvoiceInfo query = new UsersInvoiceInfo(); + List invoiceList = usersInvoiceInfoService.selectUsersInvoiceInfoList(query); + + // 检查订单ID是否在任何发票记录中 + for (UsersInvoiceInfo invoice : invoiceList) { + if (invoice.getOrderid() != null) { + // 支持单个订单ID或多个订单ID(逗号分隔) + String[] orderIds = invoice.getOrderid().split(","); + for (String id : orderIds) { + if (id.trim().equals(orderId)) { + return true; + } + } + } + } + return false; + } catch (Exception e) { + logger.error("检查订单开票状态失败", e); + return false; + } + } + + /** + * 验证发票数据 + * + * @param invoiceData 发票数据 + * @return 验证结果,为空表示验证通过 + */ + private static String validateInvoiceData(Map invoiceData) { + // 基础字段验证 + if (invoiceData.get("invoiceTitle") == null || StringUtils.isEmpty(invoiceData.get("invoiceTitle").toString())) { + return "发票抬头不能为空"; + } + + if (invoiceData.get("type") == null) { + return "发票类型不能为空"; + } + + if (invoiceData.get("category") == null) { + return "发票类别不能为空"; + } + + Integer category = (Integer) invoiceData.get("category"); + String invoiceTitle = invoiceData.get("invoiceTitle").toString(); + + // 个人发票验证 + if (category == 0) { + if (invoiceTitle.length() > 50) { + return "个人发票抬头长度不能超过50个字符"; + } + + // 检查是否填写了企业字段 + if (StringUtils.isNotEmpty((String) invoiceData.get("taxNumber"))) { + return "个人发票不能填写纳税人识别号"; + } + if (StringUtils.isNotEmpty((String) invoiceData.get("address"))) { + return "个人发票不能填写单位地址"; + } + if (StringUtils.isNotEmpty((String) invoiceData.get("phone"))) { + return "个人发票不能填写联系电话"; + } + if (StringUtils.isNotEmpty((String) invoiceData.get("wechat"))) { + return "个人发票不能填写微信号"; + } + } + // 企业发票验证 + else if (category == 1) { + if (invoiceTitle.length() > 100) { + return "企业发票抬头长度不能超过100个字符"; + } + + // 必填字段验证 + if (StringUtils.isEmpty((String) invoiceData.get("taxNumber"))) { + return "企业发票的纳税人识别号不能为空"; + } + if (StringUtils.isEmpty((String) invoiceData.get("address"))) { + return "企业发票的单位地址不能为空"; + } + if (StringUtils.isEmpty((String) invoiceData.get("phone"))) { + return "企业发票的联系电话不能为空"; + } + + // 格式验证 + String taxNumber = (String) invoiceData.get("taxNumber"); + if (!taxNumber.matches("^[A-Z0-9]{15,20}$")) { + return "纳税人识别号格式不正确"; + } + + String phone = (String) invoiceData.get("phone"); + if (!phone.matches("^1[3-9]\\d{9}$|^0\\d{2,3}-?\\d{7,8}$|^400-?\\d{3}-?\\d{4}$")) { + return "联系电话格式不正确"; + } + } + + return null; // 验证通过 + } + + /** + * 获取发票状态文本 + * + * @param status 状态值 + * @return 状态文本 + */ + private static String getInvoiceStatusText(Integer status) { + if (status == null) return "未知"; + switch (status) { + case 1: return "待开票"; + case 2: return "已开票"; + case 3: return "已完成"; + default: return "未知"; + } + } + + /** + * 获取发票类型文本 + * + * @param type 类型值 + * @return 类型文本 + */ + private static String getInvoiceTypeText(Integer type) { + if (type == null) return "未知"; + switch (type) { + case 1: return "增值税专用发票"; + case 2: return "增值税普通发票"; + case 3: return "电子发票"; + default: return "未知"; + } + } + + /** + * 获取用户发票信息列表(用于选择已保存的发票信息) + * + * @param userId 用户ID + * @return 发票信息列表 + */ + public static List> getUserInvoiceInfoList(Long userId) { + try { + UsersInvoiceInfo query = new UsersInvoiceInfo(); + query.setUid(userId.intValue()); + List invoiceList = usersInvoiceInfoService.selectUsersInvoiceInfoList(query); + + // 去重,只保留不同的发票抬头 + Map uniqueInvoices = new HashMap<>(); + for (UsersInvoiceInfo invoice : invoiceList) { + String key = invoice.getCategory() + "_" + invoice.getInvoiceTitle(); + if (!uniqueInvoices.containsKey(key)) { + uniqueInvoices.put(key, invoice); + } + } + + List> result = new ArrayList<>(); + for (UsersInvoiceInfo invoice : uniqueInvoices.values()) { + Map invoiceMap = new HashMap<>(); + invoiceMap.put("id", invoice.getId()); + invoiceMap.put("invoiceTitle", invoice.getInvoiceTitle()); + invoiceMap.put("category", invoice.getCategory()); + invoiceMap.put("categoryText", invoice.getCategory() == 0 ? "个人" : "企业"); + invoiceMap.put("taxNumber", invoice.getTaxNumber()); + invoiceMap.put("address", invoice.getAddress()); + invoiceMap.put("phone", invoice.getPhone()); + invoiceMap.put("bankName", invoice.getBankName()); + invoiceMap.put("bankAccount", invoice.getBankAccount()); + invoiceMap.put("email", invoice.getEmail()); + invoiceMap.put("wechat", invoice.getWechat()); + result.add(invoiceMap); + } + + return result; + + } catch (Exception e) { + logger.error("获取用户发票信息列表失败", e); + return new ArrayList<>(); + } + } +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayUtil.java index 965c49b..c77e114 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/WechatPayUtil.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.config.QiniuConfig; import com.ruoyi.system.config.WechatConfig; +import org.apache.xmlbeans.impl.xb.xsdschema.Public; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -78,7 +79,9 @@ public class WechatPayUtil { private static final String WECHAT_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; // 订单查询 private static final String WECHAT_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"; private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款 - + + + public static final String PAY_FH = "https://4b29b18c.r3.cpolar.top/"; /** * 其他配置常量 */ @@ -138,7 +141,7 @@ public class WechatPayUtil { if (notifyUrl == null || notifyUrl.trim().isEmpty()) { return failResult("回调通知地址不能为空"); } - + System.out.println("wechatConfig().getAppid():"+wechatConfig().getAppid()); // 2. 构建参数 Map params = new HashMap<>(); params.put("appid", wechatConfig().getAppid()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java index 7f48397..47fd1a4 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java @@ -89,6 +89,8 @@ public class GoodsOrder extends BaseEntity @Excel(name = "优惠券id") private Long couponId; + + /** 抵扣金额 */ @Excel(name = "抵扣金额") private BigDecimal deduction; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/GoodsOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/GoodsOrderMapper.java index e8b986d..a6c9229 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/GoodsOrderMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/GoodsOrderMapper.java @@ -21,6 +21,10 @@ public interface GoodsOrderMapper public GoodsOrder selectGoodsOrderById(Long id); + public GoodsOrder selectGoodsOrderByorderId(String orderId); + + + public int selectCountGoodsOrderByUid(@Param("uid") Long uid, @Param("status") Long status); public int selectAllCountGoodsOrderByUid(Long uid); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMemberRechargeLogMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMemberRechargeLogMapper.java index 94188d2..f010bcb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMemberRechargeLogMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMemberRechargeLogMapper.java @@ -19,6 +19,9 @@ public interface UserMemberRechargeLogMapper */ public UserMemberRechargeLog selectUserMemberRechargeLogById(Integer id); + + public UserMemberRechargeLog selectUserMemberRechargeLogByorderid(String orderid); + /** * 查询用户充值记录列表 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IGoodsOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IGoodsOrderService.java index 7883549..110fb87 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IGoodsOrderService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IGoodsOrderService.java @@ -27,7 +27,7 @@ public interface IGoodsOrderService */ public List selectGoodsOrderList(GoodsOrder goodsOrder); - + public GoodsOrder selectGoodsOrderByorderId(String orderId); public int selectCountGoodsOrderByUid(Long uid,Long status); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserMemberRechargeLogService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserMemberRechargeLogService.java index 5ce3d46..41eaf01 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserMemberRechargeLogService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserMemberRechargeLogService.java @@ -19,6 +19,9 @@ public interface IUserMemberRechargeLogService */ public UserMemberRechargeLog selectUserMemberRechargeLogById(Integer id); + + public UserMemberRechargeLog selectUserMemberRechargeLogByorderid(String orderid); + /** * 查询用户充值记录列表 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GoodsOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GoodsOrderServiceImpl.java index ea69d97..d0dc124 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GoodsOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/GoodsOrderServiceImpl.java @@ -32,6 +32,11 @@ public class GoodsOrderServiceImpl implements IGoodsOrderService } + public GoodsOrder selectGoodsOrderByorderId(String orderId){ + return goodsOrderMapper.selectGoodsOrderByorderId(orderId); + } + + public int selectCountGoodsOrderByUid(Long uid,Long status) { return goodsOrderMapper.selectCountGoodsOrderByUid(uid,status); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserMemberRechargeLogServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserMemberRechargeLogServiceImpl.java index c6577a6..da989a4 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserMemberRechargeLogServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserMemberRechargeLogServiceImpl.java @@ -31,6 +31,12 @@ public class UserMemberRechargeLogServiceImpl implements IUserMemberRechargeLogS return userMemberRechargeLogMapper.selectUserMemberRechargeLogById(id); } + + + public UserMemberRechargeLog selectUserMemberRechargeLogByorderid(String orderid){ + return userMemberRechargeLogMapper.selectUserMemberRechargeLogByorderid(orderid); + } + /** * 查询用户充值记录列表 * diff --git a/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml index 73e39d9..0d87eae 100644 --- a/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml @@ -62,6 +62,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" order by id desc + + + + + + + insert into user_member_recharge_log diff --git a/ruoyi-system/src/main/resources/mapper/system/UserMemnerConsumptionLogMapper.xml b/ruoyi-system/src/main/resources/mapper/system/UserMemnerConsumptionLogMapper.xml index a62d7ef..bfb9a12 100644 --- a/ruoyi-system/src/main/resources/mapper/system/UserMemnerConsumptionLogMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/UserMemnerConsumptionLogMapper.xml @@ -32,7 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and uid = #{uid} and del = #{del} - order by updated_at desc + order by id desc