202507051753
This commit is contained in:
parent
faf16add2c
commit
1a8a62321a
1
pom.xml
1
pom.xml
|
|
@ -16,6 +16,7 @@
|
|||
<ruoyi.version>3.8.9</ruoyi.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||
<java.version>1.8</java.version>
|
||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
||||
<spring-boot.version>2.5.15</spring-boot.version>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ ruoyi:
|
|||
# 验证码类型 math 数字计算 char 字符验证
|
||||
captchaType: math
|
||||
wechat:
|
||||
appid: wx1234567890123456
|
||||
appid: wx73d0202b3c8a6d68
|
||||
mchid: 1672571923
|
||||
apikey: sssssssssssssssssssssssssssssssS
|
||||
certpath: wechat/apiclient_cert.p12
|
||||
|
|
|
|||
|
|
@ -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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<Map<String, Object>> 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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<Map<String, Object>> 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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 调试日志:输出接收到的原始参数
|
||||
System.out.println("接收到的原始参数: " + params);
|
||||
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<String> 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<String, Object> 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<Map<String, Object>> 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<String, Object> 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<String, Object> 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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<String, Object> 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<Map<String, Object>> 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<String, Object> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, Object> params = new HashMap<>();
|
||||
params.put("money", 300); // 测试用固定金额,实际应从请求参数获取
|
||||
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> 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<UserMemberRechargeProgram> 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<UserMemberRechargeProgram> 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<String, Object> 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<String, Object> 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<String, Object> 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<UserMemberRechargeLog> 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<String, Object> 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<UserMemnerConsumptionLog> 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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> 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<ServiceCate> 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<String, Object> 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<String, Object> 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<UserSecondaryCard> list = userSecondaryCardService.selectUserSecondaryCardList(queryParams);
|
||||
|
||||
// 6. 为每个次卡填充服务商品详情
|
||||
for (UserSecondaryCard card : list) {
|
||||
List<String> idsList = com.alibaba.fastjson2.JSONArray.parseArray(card.getGoodsids(), String.class);
|
||||
card.setServiceDetail(serviceGoodsService.selectServiceGoodsfrocikaList(idsList));
|
||||
}
|
||||
|
||||
// 7. 获取分页信息并构建响应
|
||||
TableDataInfo tableDataInfo = getDataTable(list);
|
||||
Map<String, Object> 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<String, Object> params, HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<UserDemandQuotation> 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<String, Object> pageValidation = PageUtil.validatePageParams(page, limit);
|
||||
if (!(Boolean) pageValidation.get("valid")) {
|
||||
return AppletControllerUtil.appletWarning((String) pageValidation.get("message"));
|
||||
}
|
||||
|
||||
// 2. 验证用户登录状态
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<UserBenefitPoints> logList = userBenefitPointsService.selectUserBenefitPointsList(query);
|
||||
|
||||
// 6. 获取分页信息并构建响应
|
||||
TableDataInfo tableDataInfo = getDataTable(logList);
|
||||
Map<String, Object> 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<String, Object> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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<String, Object> params, HttpServletRequest request) {
|
||||
// 1. 校验用户登录
|
||||
String token = request.getHeader("token");
|
||||
Map<String, Object> 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<String, Object> 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<UsersInvoiceInfo> 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<String, Object> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<String, Object> 支付结果
|
||||
*
|
||||
* 返回结果说明:
|
||||
* - success: true/false 支付是否成功
|
||||
* - message: 结果消息
|
||||
* - insufficientAmount: 余额不足时,还差多少钱(仅在余额不足时返回)
|
||||
* - beforeBalance: 支付前余额
|
||||
* - afterBalance: 支付后余额
|
||||
* - consumptionLogId: 消费记录ID
|
||||
*/
|
||||
public static Map<String, Object> processBalancePayment(Long userId, BigDecimal money, String remark) {
|
||||
Map<String, Object> 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<String, Object> 检查结果
|
||||
*
|
||||
* 返回结果说明:
|
||||
* - sufficient: true/false 余额是否足够
|
||||
* - currentBalance: 当前余额
|
||||
* - requiredAmount: 需要的金额
|
||||
* - insufficientAmount: 不足的金额(仅在余额不足时返回)
|
||||
*/
|
||||
public static Map<String, Object> checkBalanceSufficiency(Long userId, BigDecimal requiredAmount) {
|
||||
Map<String, Object> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, Object> getUserInvoiceCenter(Long userId, int page, int limit) {
|
||||
try {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 1. 获取待开票订单列表
|
||||
List<Map<String, Object>> pendingInvoices = getPendingInvoiceOrders(userId, page, limit);
|
||||
|
||||
// 2. 获取已开票列表
|
||||
List<Map<String, Object>> completedInvoices = getCompletedInvoices(userId, page, limit);
|
||||
|
||||
// 3. 统计数据
|
||||
Map<String, Object> 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<Map<String, Object>> getPendingInvoiceOrders(Long userId, int page, int limit) {
|
||||
try {
|
||||
List<Map<String, Object>> pendingOrders = new ArrayList<>();
|
||||
|
||||
// 设置分页
|
||||
PageHelper.startPage(page, limit);
|
||||
|
||||
// 1. 查询服务订单(已完成且未开票)
|
||||
Order orderQuery = new Order();
|
||||
orderQuery.setUid(userId);
|
||||
orderQuery.setStatus(4L); // 已完成状态
|
||||
List<Order> serviceOrders = orderService.selectOrderList(orderQuery);
|
||||
|
||||
for (Order order : serviceOrders) {
|
||||
// 检查是否已开票
|
||||
if (!isOrderInvoiced(order.getOrderId())) {
|
||||
Map<String, Object> 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<GoodsOrder> goodsOrders = goodsOrderService.selectGoodsOrderList(goodsOrderQuery);
|
||||
|
||||
for (GoodsOrder goodsOrder : goodsOrders) {
|
||||
// 检查是否已开票
|
||||
if (!isOrderInvoiced(goodsOrder.getOrderId())) {
|
||||
Map<String, Object> 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<UserMemberRechargeLog> rechargeOrders = userMemberRechargeLogService.selectUserMemberRechargeLogList(rechargeQuery);
|
||||
|
||||
for (UserMemberRechargeLog recharge : rechargeOrders) {
|
||||
// 检查是否已开票
|
||||
if (!isOrderInvoiced(recharge.getOrderid())) {
|
||||
Map<String, Object> 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<Map<String, Object>> getCompletedInvoices(Long userId, int page, int limit) {
|
||||
try {
|
||||
// 设置分页
|
||||
PageHelper.startPage(page, limit);
|
||||
|
||||
UsersInvoiceInfo query = new UsersInvoiceInfo();
|
||||
query.setUid(userId.intValue());
|
||||
List<UsersInvoiceInfo> invoiceList = usersInvoiceInfoService.selectUsersInvoiceInfoList(query);
|
||||
|
||||
List<Map<String, Object>> completedInvoices = new ArrayList<>();
|
||||
for (UsersInvoiceInfo invoice : invoiceList) {
|
||||
Map<String, Object> 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<String, Object> getInvoiceStatistics(Long userId) {
|
||||
try {
|
||||
Map<String, Object> statistics = new HashMap<>();
|
||||
|
||||
// 待开票数量
|
||||
List<Map<String, Object>> pendingOrders = getPendingInvoiceOrders(userId, 1, 1000);
|
||||
int pendingCount = pendingOrders.size();
|
||||
|
||||
// 已开票数量
|
||||
UsersInvoiceInfo query = new UsersInvoiceInfo();
|
||||
query.setUid(userId.intValue());
|
||||
List<UsersInvoiceInfo> 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<String, Object> 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<String> orderIds, Map<String, Object> 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<String> successOrders = new ArrayList<>();
|
||||
List<String> failedOrders = new ArrayList<>();
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
List<String> invoiceTexts = new ArrayList<>();
|
||||
|
||||
// 3. 逐个处理订单
|
||||
for (String orderId : orderIds) {
|
||||
try {
|
||||
// 验证订单是否存在且属于当前用户
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> invoiceData) {
|
||||
List<String> orderIds = new ArrayList<>();
|
||||
orderIds.add(orderId);
|
||||
return createBatchInvoice(userId, orderIds, invoiceData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单信息
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @param userId 用户ID
|
||||
* @return 订单信息
|
||||
*/
|
||||
private static Map<String, Object> getOrderInfo(String orderId, Long userId) {
|
||||
try {
|
||||
// 1. 查询服务订单
|
||||
Order serviceOrder = orderService.selectOrderByOrderId(orderId);
|
||||
if (serviceOrder != null && serviceOrder.getUid().equals(userId)) {
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> 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<UsersInvoiceInfo> 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<String, Object> 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<Map<String, Object>> getUserInvoiceInfoList(Long userId) {
|
||||
try {
|
||||
UsersInvoiceInfo query = new UsersInvoiceInfo();
|
||||
query.setUid(userId.intValue());
|
||||
List<UsersInvoiceInfo> invoiceList = usersInvoiceInfoService.selectUsersInvoiceInfoList(query);
|
||||
|
||||
// 去重,只保留不同的发票抬头
|
||||
Map<String, UsersInvoiceInfo> uniqueInvoices = new HashMap<>();
|
||||
for (UsersInvoiceInfo invoice : invoiceList) {
|
||||
String key = invoice.getCategory() + "_" + invoice.getInvoiceTitle();
|
||||
if (!uniqueInvoices.containsKey(key)) {
|
||||
uniqueInvoices.put(key, invoice);
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
for (UsersInvoiceInfo invoice : uniqueInvoices.values()) {
|
||||
Map<String, Object> 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<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, String> params = new HashMap<>();
|
||||
params.put("appid", wechatConfig().getAppid());
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ public class GoodsOrder extends BaseEntity
|
|||
@Excel(name = "优惠券id")
|
||||
private Long couponId;
|
||||
|
||||
|
||||
|
||||
/** 抵扣金额 */
|
||||
@Excel(name = "抵扣金额")
|
||||
private BigDecimal deduction;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ public interface UserMemberRechargeLogMapper
|
|||
*/
|
||||
public UserMemberRechargeLog selectUserMemberRechargeLogById(Integer id);
|
||||
|
||||
|
||||
public UserMemberRechargeLog selectUserMemberRechargeLogByorderid(String orderid);
|
||||
|
||||
/**
|
||||
* 查询用户充值记录列表
|
||||
*
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public interface IGoodsOrderService
|
|||
*/
|
||||
public List<GoodsOrder> selectGoodsOrderList(GoodsOrder goodsOrder);
|
||||
|
||||
|
||||
public GoodsOrder selectGoodsOrderByorderId(String orderId);
|
||||
|
||||
public int selectCountGoodsOrderByUid(Long uid,Long status);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ public interface IUserMemberRechargeLogService
|
|||
*/
|
||||
public UserMemberRechargeLog selectUserMemberRechargeLogById(Integer id);
|
||||
|
||||
|
||||
public UserMemberRechargeLog selectUserMemberRechargeLogByorderid(String orderid);
|
||||
|
||||
/**
|
||||
* 查询用户充值记录列表
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@ public class UserMemberRechargeLogServiceImpl implements IUserMemberRechargeLogS
|
|||
return userMemberRechargeLogMapper.selectUserMemberRechargeLogById(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public UserMemberRechargeLog selectUserMemberRechargeLogByorderid(String orderid){
|
||||
return userMemberRechargeLogMapper.selectUserMemberRechargeLogByorderid(orderid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户充值记录列表
|
||||
*
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
order by id desc
|
||||
</select>
|
||||
|
||||
<select id="selectGoodsOrderByorderId" parameterType="String" resultMap="GoodsOrderResult">
|
||||
<include refid="selectGoodsOrderVo"/>
|
||||
where order_id = #{orderId} limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectGoodsOrderById" parameterType="Long" resultMap="GoodsOrderResult">
|
||||
<include refid="selectGoodsOrderVo"/>
|
||||
where id = #{id}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<where>
|
||||
<if test="uid != null "> and uid = #{uid}</if>
|
||||
</where>
|
||||
order by updated_at desc
|
||||
order by id desc
|
||||
</select>
|
||||
|
||||
<select id="selectUserMemberRechargeLogById" parameterType="Integer" resultMap="UserMemberRechargeLogResult">
|
||||
|
|
@ -41,6 +41,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
where id = #{id}
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
<select id="selectUserMemberRechargeLogByorderid" parameterType="String" resultMap="UserMemberRechargeLogResult">
|
||||
<include refid="selectUserMemberRechargeLogVo"/>
|
||||
where orderid = #{orderid} limit 1
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertUserMemberRechargeLog" parameterType="UserMemberRechargeLog" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into user_member_recharge_log
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="uid != null "> and uid = #{uid}</if>
|
||||
<if test="del != null "> and del = #{del}</if>
|
||||
</where>
|
||||
order by updated_at desc
|
||||
order by id desc
|
||||
</select>
|
||||
|
||||
<select id="selectUserMemnerConsumptionLogById" parameterType="Integer" resultMap="UserMemnerConsumptionLogResult">
|
||||
|
|
|
|||
|
|
@ -248,9 +248,9 @@
|
|||
<!-- 日志记录弹窗 -->
|
||||
<el-dialog :title="logTitle" :visible.sync="logVisible" width="1000px" append-to-body>
|
||||
<!-- 统计信息卡片 -->
|
||||
<el-row :gutter="16" class="mb8">
|
||||
<el-row :gutter="12" class="mb8">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="summary-card income-card">
|
||||
<div class="summary-card income-card">
|
||||
<div class="summary-content">
|
||||
<div class="summary-icon">
|
||||
<i class="el-icon-plus"></i>
|
||||
|
|
@ -260,10 +260,10 @@
|
|||
<div class="summary-value">¥{{ formatMoney(totalIncome) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="summary-card expense-card">
|
||||
<div class="summary-card expense-card">
|
||||
<div class="summary-content">
|
||||
<div class="summary-icon">
|
||||
<i class="el-icon-minus"></i>
|
||||
|
|
@ -273,10 +273,10 @@
|
|||
<div class="summary-value">¥{{ formatMoney(totalExpense) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="summary-card net-card">
|
||||
<div class="summary-card net-card">
|
||||
<div class="summary-content">
|
||||
<div class="summary-icon">
|
||||
<i class="el-icon-d-arrow-right"></i>
|
||||
|
|
@ -288,7 +288,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
|
@ -301,14 +301,7 @@
|
|||
<el-option label="支出" value="2"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="6" v-if="currentType === null">
|
||||
<el-select v-model="logFilter.consumptionType" placeholder="消费类别" clearable @change="filterLogs">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="商城消费" value="0"></el-option>
|
||||
<el-option label="服务类消费" value="1"></el-option>
|
||||
<el-option label="其他消费" value="2"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-date-picker
|
||||
v-model="logFilter.dateRange"
|
||||
|
|
@ -337,7 +330,7 @@
|
|||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="变动类型" align="center" width="80">
|
||||
<el-table-column label="变动类型" align="center" width="130">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="getChangeTypeTag(scope.row)"
|
||||
|
|
@ -395,16 +388,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="消费类别" align="center" width="100" v-if="currentType === null">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="getConsumptionTypeTag(scope.row.consumptiontype)"
|
||||
size="small"
|
||||
>
|
||||
{{ getConsumptionTypeText(scope.row.consumptiontype) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column label="变动说明" align="center" prop="reamk" min-width="200" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -415,7 +399,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="变动时间" align="center" width="160">
|
||||
<el-table-column label="变动时间" align="center" width="180">
|
||||
<template slot-scope="scope">
|
||||
<div class="time-content">
|
||||
<i class="el-icon-time"></i>
|
||||
|
|
@ -486,11 +470,7 @@
|
|||
<el-descriptions-item label="订单金额" v-if="logDetail.ordermoney">
|
||||
¥{{ parseFloat(logDetail.ordermoney).toFixed(2) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="消费类别" v-if="logDetail.consumptiontype !== undefined">
|
||||
<el-tag :type="getConsumptionTypeTag(logDetail.consumptiontype)" size="small">
|
||||
{{ getConsumptionTypeText(logDetail.consumptiontype) }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="变动时间" :span="2">
|
||||
{{ formatDateTime(logDetail) }}
|
||||
</el-descriptions-item>
|
||||
|
|
@ -590,7 +570,6 @@ export default {
|
|||
// 筛选条件
|
||||
logFilter: {
|
||||
type: '',
|
||||
consumptionType: '',
|
||||
dateRange: []
|
||||
},
|
||||
// 统计数据
|
||||
|
|
@ -825,12 +804,7 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
// 按消费类别筛选(仅余额变动)
|
||||
if (this.logFilter.consumptionType && this.currentType === null) {
|
||||
filtered = filtered.filter(item => {
|
||||
return item.consumptiontype === parseInt(this.logFilter.consumptionType);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 按日期范围筛选
|
||||
if (this.logFilter.dateRange && this.logFilter.dateRange.length === 2) {
|
||||
|
|
@ -873,7 +847,8 @@ export default {
|
|||
// 获取变动类型标签
|
||||
getChangeTypeTag(row) {
|
||||
if (this.currentType === null) {
|
||||
return 'info'; // 余额变动
|
||||
// 余额变动:type=1收入(绿色),type=2支出(红色)
|
||||
return row.type === 1 ? 'success' : 'danger';
|
||||
}
|
||||
if (row.type === 1) { // 服务金变动
|
||||
return 'success';
|
||||
|
|
@ -884,6 +859,12 @@ export default {
|
|||
// 获取变动类型文本
|
||||
getChangeTypeText(row) {
|
||||
if (this.currentType === null) {
|
||||
// 余额变动:根据type判断增加或减少
|
||||
if (row.type === 1) {
|
||||
return '余额变动--增加';
|
||||
} else if (row.type === 2) {
|
||||
return '余额变动--减少';
|
||||
}
|
||||
return '余额变动';
|
||||
}
|
||||
if (row.type === 1) {
|
||||
|
|
@ -895,9 +876,9 @@ export default {
|
|||
// 获取变动金额
|
||||
getAmountValue(row) {
|
||||
if (this.currentType === null) {
|
||||
// 余额变动
|
||||
// 余额变动:type=1收入(正数),type=2支出(负数)
|
||||
if (row.consumptionmoney) {
|
||||
return row.type === 1 ? row.consumptionmoney : -row.consumptionmoney;
|
||||
return row.type === 1 ? parseFloat(row.consumptionmoney) : -parseFloat(row.consumptionmoney);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -925,30 +906,31 @@ export default {
|
|||
// 服务金/消费金变动
|
||||
return parseFloat(row.aftremoney || 0).toFixed(2);
|
||||
},
|
||||
// 获取消费类别标签
|
||||
getConsumptionTypeTag(type) {
|
||||
if (type === 0) {
|
||||
return 'info'; // 商城消费
|
||||
} else if (type === 1) {
|
||||
return 'success'; // 服务类消费
|
||||
} else {
|
||||
return 'warning'; // 其他消费
|
||||
}
|
||||
},
|
||||
// 获取消费类别文本
|
||||
getConsumptionTypeText(type) {
|
||||
if (type === 0) {
|
||||
return '商城消费';
|
||||
} else if (type === 1) {
|
||||
return '服务类消费';
|
||||
} else {
|
||||
return '其他消费';
|
||||
}
|
||||
},
|
||||
|
||||
// 格式化日期时间
|
||||
formatDateTime(row) {
|
||||
const dateTime = row.createTime || row.createdAt || row.dotime || row.consumptiontime;
|
||||
return this.parseTime(dateTime, '{y}-{m}-{d} {h}:{i}:{s}');
|
||||
if (!dateTime) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
// 尝试解析时间,如果包含时分秒信息则显示完整时间,否则只显示日期
|
||||
const date = new Date(dateTime);
|
||||
if (isNaN(date.getTime())) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
// 检查原始时间字符串是否包含时分秒信息
|
||||
const timeStr = dateTime.toString();
|
||||
const hasTimeInfo = timeStr.includes(':') || timeStr.includes('T') || timeStr.length > 10;
|
||||
|
||||
if (hasTimeInfo) {
|
||||
// 如果有时分秒信息,显示完整的日期时间(精确到秒)
|
||||
return this.parseTime(dateTime, '{y}-{m}-{d} {h}:{i}:{s}');
|
||||
} else {
|
||||
// 如果只有日期信息,只显示日期
|
||||
return this.parseTime(dateTime, '{y}-{m}-{d}');
|
||||
}
|
||||
},
|
||||
/** 显示余额变动记录 */
|
||||
showBalanceLogs(userId) {
|
||||
|
|
@ -963,7 +945,6 @@ export default {
|
|||
resetLogFilters() {
|
||||
this.logFilter = {
|
||||
type: '',
|
||||
consumptionType: '',
|
||||
dateRange: []
|
||||
};
|
||||
this.logQuery.pageNum = 1;
|
||||
|
|
@ -1048,10 +1029,18 @@ export default {
|
|||
.summary-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.06);
|
||||
min-height: 60px;
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.08);
|
||||
min-height: 45px;
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.summary-card:hover {
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.12);
|
||||
border-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.summary-content {
|
||||
|
|
@ -1060,8 +1049,8 @@ export default {
|
|||
}
|
||||
|
||||
.summary-icon {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
font-size: 16px;
|
||||
margin-right: 6px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
|
|
@ -1071,13 +1060,13 @@ export default {
|
|||
}
|
||||
|
||||
.summary-title {
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
color: #606266;
|
||||
margin-bottom: 2px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@
|
|||
<el-col :span="6">
|
||||
<el-form-item label="发票类别" prop="category">
|
||||
<el-select v-model="queryParams.category" placeholder="请选择发票类别" clearable>
|
||||
<el-option label="个人" :value="1" />
|
||||
<el-option label="企业" :value="2" />
|
||||
<el-option label="个人" :value="0" />
|
||||
<el-option label="企业" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
@ -162,8 +162,8 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="发票类别" align="center" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.category === 1 ? 'info' : 'warning'" size="small">
|
||||
{{ scope.row.category === 1 ? '个人' : '企业' }}
|
||||
<el-tag :type="scope.row.category === 0 ? 'info' : 'warning'" size="small">
|
||||
{{ scope.row.category === 0 ? '个人' : '企业' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -294,8 +294,8 @@
|
|||
<el-col :span="12">
|
||||
<el-form-item label="发票类别" prop="category">
|
||||
<el-select v-model="form.category" placeholder="请选择发票类别">
|
||||
<el-option label="个人" :value="1" />
|
||||
<el-option label="企业" :value="2" />
|
||||
<el-option label="个人" :value="0" />
|
||||
<el-option label="企业" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
@ -317,7 +317,7 @@
|
|||
</el-form-item>
|
||||
|
||||
<!-- 企业信息 -->
|
||||
<div v-if="form.category === 2">
|
||||
<div v-if="form.category === 1">
|
||||
<el-divider content-position="left">企业税务信息</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
|
|
@ -439,8 +439,8 @@
|
|||
</div>
|
||||
<div class="detail-item">
|
||||
<label>发票类别:</label>
|
||||
<el-tag :type="detailForm.category === 1 ? 'info' : 'warning'" size="small">
|
||||
{{ detailForm.category === 1 ? '个人' : '企业' }}
|
||||
<el-tag :type="detailForm.category === 0 ? 'info' : 'warning'" size="small">
|
||||
{{ detailForm.category === 0 ? '个人' : '企业' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
|
|
@ -475,7 +475,7 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div v-if="detailForm.category === 2" class="detail-section">
|
||||
<div v-if="detailForm.category === 1" class="detail-section">
|
||||
<h4>企业税务信息</h4>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
|
|
|
|||
Loading…
Reference in New Issue