2025008071805

This commit is contained in:
张潘 2025-08-19 18:27:30 +08:00
parent 840e32f7ca
commit 1aab36f046
30 changed files with 3041 additions and 1280 deletions

View File

@ -77,6 +77,12 @@
<artifactId>xmlbeans</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.2</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -10,15 +10,22 @@ import com.ruoyi.system.domain.Users;
import com.ruoyi.system.domain.UsersInvoiceInfo;
import com.ruoyi.system.service.IUsersService;
import com.ruoyi.system.service.IUsersInvoiceInfoService;
import com.ruoyi.system.service.IPayMoneyLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 发票管理控制器
@ -45,10 +52,13 @@ public class AppleInvoiceController extends BaseController {
@Autowired
private IUsersInvoiceInfoService usersInvoiceInfoService;
@Autowired
private IPayMoneyLogService payMoneyLogService;
private ObjectMapper objectMapper = new ObjectMapper();
/**
* 获取用户发票中心数据
* 获取用户发票中心数据基于支付记录数据源
*
* @param params 请求参数
* @param request HTTP请求对象
@ -74,8 +84,8 @@ public class AppleInvoiceController extends BaseController {
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);
// 4. 基于支付记录获取发票中心数据
Map<String, Object> invoiceCenterData = getInvoiceCenterDataFromPayLogs(user.getId(), page, limit);
return AppletControllerUtil.appletSuccess(invoiceCenterData);
@ -83,9 +93,207 @@ public class AppleInvoiceController extends BaseController {
return AppletControllerUtil.appletError("获取发票中心数据失败:" + e.getMessage());
}
}
/**
* 基于支付记录获取发票中心数据
*
* @param userId 用户ID
* @param page 页码
* @param limit 每页数量
* @return 发票中心数据
*/
private Map<String, Object> getInvoiceCenterDataFromPayLogs(Long userId, int page, int limit) {
Map<String, Object> result = new HashMap<>();
try {
// 1. 获取所有支付记录统计按订单ID分组
List<Map<String, Object>> allOrderStats = payMoneyLogService.getOrderPriceStatistics(userId);
// 2. 获取已开票记录
List<Map<String, Object>> completedInvoices = getCompletedInvoicesFromPayLogs(userId, page, limit);
// 3. 获取待开票订单过滤掉已开票的
List<Map<String, Object>> pendingInvoices = getPendingInvoicesFromPayLogs(allOrderStats, completedInvoices, page, limit);
// 4. 统计数据
Map<String, Object> statistics = getInvoiceStatisticsFromPayLogs(pendingInvoices, completedInvoices);
result.put("pendingInvoices", pendingInvoices);
result.put("completedInvoices", completedInvoices);
result.put("statistics", statistics);
} catch (Exception e) {
logger.error("获取发票中心数据失败", e);
// 返回空数据
result.put("pendingInvoices", new ArrayList<>());
result.put("completedInvoices", new ArrayList<>());
result.put("statistics", new HashMap<>());
}
return result;
}
/**
* 从支付记录获取已开票列表
*/
private List<Map<String, Object>> getCompletedInvoicesFromPayLogs(Long userId, int page, int limit) {
try {
// 设置分页
com.github.pagehelper.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<>();
}
}
/**
* 从支付记录获取待开票订单
*/
private List<Map<String, Object>> getPendingInvoicesFromPayLogs(
List<Map<String, Object>> allOrderStats,
List<Map<String, Object>> completedInvoices,
int page, int limit) {
try {
List<Map<String, Object>> pendingInvoices = new ArrayList<>();
// 获取已开票的订单ID集合
Set<String> invoicedOrderIds = new HashSet<>();
for (Map<String, Object> invoice : completedInvoices) {
String orderId = (String) invoice.get("orderId");
if (orderId != null) {
// 支持多个订单ID逗号分隔
String[] orderIds = orderId.split(",");
for (String id : orderIds) {
invoicedOrderIds.add(id.trim());
}
}
}
// 过滤出未开票的订单
for (Map<String, Object> orderStat : allOrderStats) {
String orderId = (String) orderStat.get("orderId");
if (orderId != null && !invoicedOrderIds.contains(orderId)) {
BigDecimal totalPrice = (BigDecimal) orderStat.get("totalPrice");
if (totalPrice != null && totalPrice.compareTo(BigDecimal.ZERO) > 0) {
Map<String, Object> pendingOrder = new HashMap<>();
pendingOrder.put("orderId", orderId);
pendingOrder.put("orderType", "payment"); // 支付记录订单
pendingOrder.put("orderTypeText", "支付记录");
pendingOrder.put("amount", totalPrice);
pendingOrder.put("title", "订单支付" + totalPrice + "");
pendingOrder.put("createTime", new java.util.Date()); // 使用当前时间作为默认值
pendingOrder.put("canInvoice", true);
pendingInvoices.add(pendingOrder);
}
}
}
// 分页处理
int startIndex = (page - 1) * limit;
int endIndex = Math.min(startIndex + limit, pendingInvoices.size());
if (startIndex < pendingInvoices.size()) {
return pendingInvoices.subList(startIndex, endIndex);
}
return new ArrayList<>();
} catch (Exception e) {
logger.error("获取待开票订单失败", e);
return new ArrayList<>();
}
}
/**
* 基于支付记录获取发票统计数据
*/
private Map<String, Object> getInvoiceStatisticsFromPayLogs(
List<Map<String, Object>> pendingInvoices,
List<Map<String, Object>> completedInvoices) {
Map<String, Object> statistics = new HashMap<>();
try {
// 待开票数量
int pendingCount = pendingInvoices.size();
// 已开票数量
int completedCount = completedInvoices.size();
// 已开票总金额
BigDecimal totalAmount = completedInvoices.stream()
.filter(invoice -> invoice.get("amount") != null)
.map(invoice -> (BigDecimal) invoice.get("amount"))
.reduce(BigDecimal.ZERO, BigDecimal::add);
statistics.put("pendingCount", pendingCount);
statistics.put("completedCount", completedCount);
statistics.put("totalAmount", totalAmount);
} catch (Exception e) {
logger.error("获取发票统计数据失败", e);
statistics.put("pendingCount", 0);
statistics.put("completedCount", 0);
statistics.put("totalAmount", BigDecimal.ZERO);
}
return statistics;
}
/**
* 获取发票状态文本
*/
private String getInvoiceStatusText(Integer status) {
if (status == null) return "未知";
switch (status) {
case 0: return "待开票";
case 1: return "已开票";
case 2: return "已作废";
default: return "未知";
}
}
/**
* 获取发票类型文本
*/
private String getInvoiceTypeText(Integer type) {
if (type == null) return "未知";
switch (type) {
case 0: return "普通发票";
case 1: return "专用发票";
default: return "未知";
}
}
/**
* 获取待开票订单列表
* 获取待开票订单列表基于支付记录数据源
*
* @param params 请求参数
* @param request HTTP请求对象
@ -111,8 +319,10 @@ public class AppleInvoiceController extends BaseController {
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);
// 4. 基于支付记录获取待开票订单列表
List<Map<String, Object>> allOrderStats = payMoneyLogService.getOrderPriceStatistics(user.getId());
List<Map<String, Object>> completedInvoices = getCompletedInvoicesFromPayLogs(user.getId(), 1, 1000);
List<Map<String, Object>> pendingOrders = getPendingInvoicesFromPayLogs(allOrderStats, completedInvoices, page, limit);
return AppletControllerUtil.appletSuccess(pendingOrders);
@ -122,7 +332,7 @@ public class AppleInvoiceController extends BaseController {
}
/**
* 获取已开票列表
* 获取已开票列表基于支付记录数据源
*
* @param params 请求参数
* @param request HTTP请求对象
@ -148,8 +358,8 @@ public class AppleInvoiceController extends BaseController {
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);
// 4. 基于支付记录获取已开票列表
List<Map<String, Object>> completedInvoices = getCompletedInvoicesFromPayLogs(user.getId(), page, limit);
return AppletControllerUtil.appletSuccess(completedInvoices);
@ -158,9 +368,200 @@ public class AppleInvoiceController extends BaseController {
}
}
// /**
// * 开具发票接口
// *
// * @param params 发票参数
// * @param request HTTP请求对象
// * @return 开票结果
// */
// @PostMapping("/create")
// public AjaxResult createInvoice(@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.appletdengluWarning("");
// }
//
// // 2. 获取用户信息
// Users user = (Users) userValidation.get("user");
// if (user == null) {
// return AppletControllerUtil.appletdengluWarning("");
// }
//
// // 3. 获取订单ID
// String orderId = params.get("orderId") != null ? params.get("orderId").toString() : null;
// if (StringUtils.isEmpty(orderId)) {
// return AppletControllerUtil.appletWarning("订单ID不能为空");
// }
//
// // 4. 调用IPayMoneyLogService查询开票金额
// List<Map<String, Object>> orderStats = payMoneyLogService.getOrderPriceStatistics();
// BigDecimal invoiceAmount = null;
//
// for (Map<String, Object> orderStat : orderStats) {
// String statOrderId = (String) orderStat.get("orderId");
// if (orderId.equals(statOrderId)) {
// invoiceAmount = (BigDecimal) orderStat.get("totalPrice");
// break;
// }
// }
//
// if (invoiceAmount == null || invoiceAmount.compareTo(BigDecimal.ZERO) <= 0) {
// return AppletControllerUtil.appletWarning("订单不存在或金额为0无法开票");
// }
//
// // 5. 直接调用开票方法
// AjaxResult invoiceResult = InvoiceUtil.createBatchInvoice(user.getId(), List.of(orderId), params);
//
// return invoiceResult;
//
// } 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 {
// // 1. 验证用户登录状态
// String token = request.getHeader("token");
// Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
// if (!(Boolean) userValidation.get("valid")) {
// return AppletControllerUtil.appletdengluWarning("");
// }
//
// // 2. 获取用户信息
// Users user = (Users) userValidation.get("user");
// if (user == null) {
// return AppletControllerUtil.appletdengluWarning("");
// }
//
// // 3. 获取订单ID数组
// Object orderIdsObj = params.get("orderIds");
// if (orderIdsObj == null) {
// return AppletControllerUtil.appletWarning("订单ID列表不能为空");
// }
//
// List<String> orderIds;
// if (orderIdsObj instanceof List) {
// orderIds = (List<String>) orderIdsObj;
// } else if (orderIdsObj instanceof String) {
// // 如果是字符串尝试解析
// String orderIdsStr = orderIdsObj.toString();
// orderIds = objectMapper.readValue(orderIdsStr, new TypeReference<List<String>>() {});
// } else {
// return AppletControllerUtil.appletWarning("订单ID格式错误");
// }
//
// if (orderIds.isEmpty()) {
// return AppletControllerUtil.appletWarning("订单ID列表不能为空");
// }
//
// // 4. 调用IPayMoneyLogService查询开票金额
// List<Map<String, Object>> orderStats = payMoneyLogService.getOrderPriceStatistics();
// List<String> validOrderIds = new ArrayList<>();
// BigDecimal totalAmount = BigDecimal.ZERO;
//
// for (String orderId : orderIds) {
// for (Map<String, Object> orderStat : orderStats) {
// String statOrderId = (String) orderStat.get("orderId");
// if (orderId.equals(statOrderId)) {
// BigDecimal amount = (BigDecimal) orderStat.get("totalPrice");
// if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
// validOrderIds.add(orderId);
// totalAmount = totalAmount.add(amount);
// }
// break;
// }
// }
// }
//
// if (validOrderIds.isEmpty()) {
// return AppletControllerUtil.appletWarning("没有找到有效的订单或金额为0无法开票");
// }
//
// // 5. 直接调用开票方法
// AjaxResult invoiceResult = InvoiceUtil.createBatchInvoice(user.getId(), validOrderIds, params);
//
// return invoiceResult;
//
// } 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 {
// // 1. 验证用户登录状态
// String token = request.getHeader("token");
// Map<String, Object> userValidation = AppletLoginUtil.validateUserToken(token, usersService);
// if (!(Boolean) userValidation.get("valid")) {
// return AppletControllerUtil.appletdengluWarning("");
// }
//
// // 2. 获取用户信息
// Users user = (Users) userValidation.get("user");
// if (user == null) {
// return AppletControllerUtil.appletdengluWarning("");
// }
//
// // 3. 获取订单ID数组
// Object orderIdsObj = params.get("orderIds");
// if (orderIdsObj == null) {
// return AppletControllerUtil.appletWarning("订单ID列表不能为空");
// }
//
// List<String> orderIds;
// if (orderIdsObj instanceof List) {
// orderIds = (List<String>) orderIdsObj;
// } else if (orderIdsObj instanceof String) {
// // 如果是字符串尝试解析
// String orderIdsStr = orderIdsObj.toString();
// orderIds = objectMapper.readValue(orderIdsStr, new TypeReference<List<String>>() {});
// } else {
// return AppletControllerUtil.appletWarning("订单ID格式错误");
// }
//
// if (orderIds.isEmpty()) {
// return AppletControllerUtil.appletWarning("订单ID列表不能为空");
// }
//
// // 4. 直接调用开票方法不做复杂的验证
// // InvoiceUtil.createBatchInvoice 自己处理订单验证
// AjaxResult invoiceResult = InvoiceUtil.createBatchInvoice(user.getId(), orderIds, params);
//
// return invoiceResult;
//
// } catch (Exception e) {
// return AppletControllerUtil.appletError("开具发票失败:" + e.getMessage());
// }
// }
/**
* 开具发票接口支持批量开票
*
*
* @param params 发票参数
* @param request HTTP请求对象
* @return 开票结果
@ -168,9 +569,6 @@ public class AppleInvoiceController extends BaseController {
@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);
@ -184,65 +582,109 @@ public class AppleInvoiceController extends BaseController {
return AppletControllerUtil.appletdengluWarning("");
}
// 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);
// 3. 获取订单ID数组
Object orderIdsObj = params.get("orderIds");
if (orderIdsObj == null) {
return AppletControllerUtil.appletWarning("订单ID列表不能为空");
}
List<String> orderIds;
if (orderIdsObj instanceof List) {
orderIds = (List<String>) orderIdsObj;
} else if (orderIdsObj instanceof String) {
String orderIdsStr = orderIdsObj.toString();
orderIds = objectMapper.readValue(orderIdsStr, new TypeReference<List<String>>() {});
} else {
return AppletControllerUtil.appletWarning("订单ID格式错误");
}
if (orderIds.isEmpty()) {
return AppletControllerUtil.appletWarning("订单ID列表不能为空");
}
// 4. 使用IPayMoneyLogService查询订单金额
List<Map<String, Object>> orderStats = payMoneyLogService.getOrderPriceStatistics(user.getId());
List<String> validOrderIds = new ArrayList<>();
BigDecimal totalAmount = BigDecimal.ZERO;
for (String orderId : orderIds) {
for (Map<String, Object> orderStat : orderStats) {
String statOrderId = (String) orderStat.get("orderId");
if (orderId.equals(statOrderId)) {
BigDecimal amount = (BigDecimal) orderStat.get("totalPrice");
if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
validOrderIds.add(orderId);
totalAmount = totalAmount.add(amount);
}
break;
}
}
} 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);
if (validOrderIds.isEmpty()) {
return AppletControllerUtil.appletWarning("没有找到有效的订单或金额为0无法开票");
}
// // 5. 直接创建发票记录不使用InvoiceUtil.createBatchInvoice
// // 这里需要调用发票服务直接创建发票
// for (String orderId : validOrderIds) {
// // 创建发票记录
// UsersInvoiceInfo invoiceInfo = new UsersInvoiceInfo();
// invoiceInfo.setUid(user.getId().intValue());
// invoiceInfo.setOrderid(orderId);
// invoiceInfo.setInvoiceTitle((String) params.get("invoiceTitle"));
// invoiceInfo.setType((Integer) params.get("type"));
// invoiceInfo.setCategory((Integer) params.get("category"));
// invoiceInfo.setTaxNumber((String) params.get("taxNumber"));
// invoiceInfo.setBankName((String) params.get("bankName"));
// invoiceInfo.setAddress((String) params.get("address"));
// invoiceInfo.setBankAccount((String) params.get("bankAccount"));
// invoiceInfo.setPhone((String) params.get("phone"));
// invoiceInfo.setEmail((String) params.get("email"));
// invoiceInfo.setWechat((String) params.get("wechat"));
// invoiceInfo.setStatus(1); // 已开票
// invoiceInfo.setInvoicemoney(totalAmount);
// invoiceInfo.setInvoicetext("批量开票");
//
// // 保存发票记录
// usersInvoiceInfoService.insertUsersInvoiceInfo(invoiceInfo);
// }
// 5. 直接创建发票记录不使用InvoiceUtil.createBatchInvoice
// 这里需要调用发票服务直接创建发票
// 只创建一张发票包含所有订单ID
UsersInvoiceInfo invoiceInfo = new UsersInvoiceInfo();
invoiceInfo.setUid(user.getId().intValue());
invoiceInfo.setOrderid(String.join(",", validOrderIds)); // 用逗号分隔所有订单ID
invoiceInfo.setInvoiceTitle((String) params.get("invoiceTitle"));
invoiceInfo.setType((Integer) params.get("type"));
invoiceInfo.setCategory((Integer) params.get("category"));
invoiceInfo.setTaxNumber((String) params.get("taxNumber"));
invoiceInfo.setBankName((String) params.get("bankName"));
invoiceInfo.setAddress((String) params.get("address"));
invoiceInfo.setBankAccount((String) params.get("bankAccount"));
invoiceInfo.setPhone((String) params.get("phone"));
invoiceInfo.setEmail((String) params.get("email"));
invoiceInfo.setWechat((String) params.get("wechat"));
invoiceInfo.setStatus(1); // 已开票
invoiceInfo.setInvoicemoney(totalAmount); // 总金额
invoiceInfo.setInvoicetext("批量开票");
// 保存发票记录
usersInvoiceInfoService.insertUsersInvoiceInfo(invoiceInfo);
Map<String, Object> result = new HashMap<>();
result.put("message", "发票开具成功");
result.put("orderIds", validOrderIds);
result.put("totalAmount", totalAmount);
return AppletControllerUtil.appletSuccess(result);
} catch (Exception e) {
return AppletControllerUtil.appletError("开具发票失败:" + e.getMessage());
}
}
/**
* 获取用户已保存的发票信息
*
@ -276,7 +718,7 @@ public class AppleInvoiceController extends BaseController {
}
/**
* 获取发票统计数据
* 获取发票统计数据基于支付记录数据源
*
* @param request HTTP请求对象
* @return 统计数据
@ -297,8 +739,11 @@ public class AppleInvoiceController extends BaseController {
return AppletControllerUtil.appletdengluWarning("");
}
// 3. 获取统计数据
Map<String, Object> statistics = InvoiceUtil.getInvoiceStatistics(user.getId());
// 3. 基于支付记录获取统计数据
List<Map<String, Object>> allOrderStats = payMoneyLogService.getOrderPriceStatistics(user.getId());
List<Map<String, Object>> completedInvoices = getCompletedInvoicesFromPayLogs(user.getId(), 1, 1000);
List<Map<String, Object>> pendingInvoices = getPendingInvoicesFromPayLogs(allOrderStats, completedInvoices, 1, 1000);
Map<String, Object> statistics = getInvoiceStatisticsFromPayLogs(pendingInvoices, completedInvoices);
return AppletControllerUtil.appletSuccess(statistics);
@ -502,4 +947,5 @@ public class AppleInvoiceController extends BaseController {
return AppletControllerUtil.appletError("获取发票详情失败:" + e.getMessage());
}
}
}

View File

@ -708,7 +708,7 @@ public class AppleOrderController extends BaseController {
HttpServletRequest request) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 1. 验证分页参数
Map<String, Object> pageValidation = PageUtil.validatePageParams(pageNum, pageSize);
if (!(Boolean) pageValidation.get("valid")) {
@ -6147,6 +6147,7 @@ public class AppleOrderController extends BaseController {
@PostMapping(value = "/api/coupon/add")
public AjaxResult apicouponadd(@RequestBody Map<String, Object> params, HttpServletRequest request) {
Long id = Long.parseLong(params.get("coupon_id").toString());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 获取token
String token = request.getHeader("token");
if (StringUtils.isEmpty(token)) {
@ -6166,6 +6167,11 @@ public class AppleOrderController extends BaseController {
if (coupon == null) {
AppletControllerUtil.appletWarning("优惠券不存在");
}
if (coupon.getStatus()==0){
AppletControllerUtil.appletWarning("优惠券已领用结束!");
}
CouponUser couponUser = new CouponUser();
couponUser.setUid(user.getId());
@ -6174,12 +6180,28 @@ public class AppleOrderController extends BaseController {
couponUser.setCouponPrice(coupon.getPrice().intValue());
couponUser.setMinPrice(coupon.getMinPrice().longValue());
couponUser.setAddTime(new Date().getTime()/1000);
couponUser.setLoseTime(String.valueOf(coupon.getEndTime()));
if (coupon.getIsPermanent()==null){
couponUser.setLoseTime("永久有效");
}else{
couponUser.setLoseTime(sdf.format(coupon.getEndTime()*1000));
}
couponUser.setCateId(coupon.getCateId());
couponUser.setProductId(coupon.getProductId());
couponUser.setReceiveType(String.valueOf(coupon.getReceiveType()));
couponUser.setStatus(1L);
couponUserService.insertCouponUser(couponUser);
int flg= couponUserService.insertCouponUser(couponUser);
if (flg>0){
if (coupon.getIsPermanent()!=1){
CouponUser coupondata=new CouponUser();
coupondata.setCouponId(coupon.getId());
List<CouponUser> couponUserList=couponUserService.selectCouponUserList(coupondata);
if (couponUserList.size()>=coupon.getCount()){
coupon.setStatus(0L);
couponsService.updateCoupons(coupon);
}
}
}
return AppletControllerUtil.appletSuccess("操作成功");
}

View File

@ -1181,12 +1181,15 @@ public class ApplePayController extends BaseController {
if (newpayBefor!=null){
// 创建订单
newpayBefor.setStatus(2L);
usersPayBeforService.updateUsersPayBefor(newpayBefor);
int upuser= usersPayBeforService.updateUsersPayBefor(newpayBefor);
if (upuser>0){
OrderUtil.prepayCallback(newpayBefor, user);
}
}
}
//BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
//回调方法用来处理订单相关数据
OrderUtil.prepayCallback(payBefor, user);
// OrderUtil.prepayCallback(payBefor, user);
payResult.put("istowx", 1);
return AppletControllerUtil.appletSuccess("支付成功");
}
@ -1218,12 +1221,16 @@ public class ApplePayController extends BaseController {
UsersPayBefor newpayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(orderNo);
if (newpayBefor!=null){
// 创建订单
payBefor.setPaytime(new Date());
newpayBefor.setStatus(2L);
usersPayBeforService.updateUsersPayBefor(newpayBefor);
int upuser= usersPayBeforService.updateUsersPayBefor(newpayBefor);
if (upuser>0){
OrderUtil.prepayCallback(newpayBefor, user);
}
}
}
//回调方法用来处理订单相关数据
OrderUtil.prepayCallback(payBefor, user);
// OrderUtil.prepayCallback(payBefor, user);
//IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
payResult.put("istowx", 2);
@ -1240,7 +1247,7 @@ public class ApplePayController extends BaseController {
// payBefor.setStatus(2L); // 已支付
// payBefor.setPaytime(new Date());
// usersPayBeforService.updateUsersPayBefor(payBefor);
OrderUtil.prepayCallback(payBefor, user);
//扣减消费金服务金
int flg= BenefitPointsUtil.creatServerOrderData(payBefor);
if (flg==0){
@ -1249,7 +1256,10 @@ public class ApplePayController extends BaseController {
// 创建订单
newpayBefor.setStatus(2L);
newpayBefor.setPaytime(new Date());
usersPayBeforService.updateUsersPayBefor(newpayBefor);
int updata=usersPayBeforService.updateUsersPayBefor(newpayBefor);
if (updata>0){
OrderUtil.prepayCallback(newpayBefor, user);
}
}
}
//BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
@ -1265,10 +1275,10 @@ public class ApplePayController extends BaseController {
// 组合支付
if (wxMoney.compareTo(BigDecimal.ZERO) <= 0 && yeMoney.compareTo(BigDecimal.ZERO) <= 0) {
// 两项都为0直接走后续逻辑
payBefor.setStatus(2L); // 已支付
payBefor.setPaytime(new Date());
usersPayBeforService.updateUsersPayBefor(payBefor);
OrderUtil.prepayCallback(payBefor, user);
// payBefor.setStatus(2L); // 已支付
// payBefor.setPaytime(new Date());
// usersPayBeforService.updateUsersPayBefor(payBefor);
//扣减消费金服务金
// BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
// IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
@ -1279,7 +1289,10 @@ public class ApplePayController extends BaseController {
// 创建订单
newpayBefor.setStatus(2L);
newpayBefor.setPaytime(new Date());
usersPayBeforService.updateUsersPayBefor(newpayBefor);
int updat= usersPayBeforService.updateUsersPayBefor(newpayBefor);
if (updat>0){
OrderUtil.prepayCallback(newpayBefor, user);
}
}
}
payResult.put("istowx", 1);
@ -1311,9 +1324,8 @@ public class ApplePayController extends BaseController {
payBefor.getOrderid()
);
if (balanceResult != null && Boolean.TRUE.equals(balanceResult.get("success"))) {
payBefor.setStatus(2L); // 已支付
usersPayBeforService.updateUsersPayBefor(payBefor);
OrderUtil.prepayCallback(payBefor, user);
// payBefor.setStatus(2L); // 已支付
// usersPayBeforService.updateUsersPayBefor(payBefor);
//扣减消费金服务金
int flg= BenefitPointsUtil.creatServerOrderData(payBefor);
if (flg==0){
@ -1322,7 +1334,10 @@ public class ApplePayController extends BaseController {
// 创建订单
newpayBefor.setStatus(2L);
newpayBefor.setPaytime(new Date());
usersPayBeforService.updateUsersPayBefor(newpayBefor);
int updata= usersPayBeforService.updateUsersPayBefor(newpayBefor);
if (updata>0){
OrderUtil.prepayCallback(newpayBefor, user);
}
}
}
//BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());

View File

@ -1580,15 +1580,16 @@ public class AppletController extends BaseController {
userInfo.put("tx_time", txTimeArr);
// 新增查询该用户可用优惠券数量
int couponNum = 0;
try {
com.ruoyi.system.domain.CouponUser queryCoupon = new com.ruoyi.system.domain.CouponUser();
queryCoupon.setUid(user.getId());
queryCoupon.setStatus(0L); // 0=可用
java.util.List<com.ruoyi.system.domain.CouponUser> couponList = couponUserService.selectCouponUserList(queryCoupon);
couponNum = couponList != null ? couponList.size() : 0;
} catch (Exception e) {
}
// int couponNum = CouponUtil.iscoupon(user.getId(), couponsService, couponUserService).size();
int couponNum = couponUserService.selectCountCouponsByUid(user.getId(), 1L);
// try {
// com.ruoyi.system.domain.CouponUser queryCoupon = new com.ruoyi.system.domain.CouponUser();
// queryCoupon.setUid(user.getId());
// queryCoupon.setStatus(0L); // 0=可用
// java.util.List<com.ruoyi.system.domain.CouponUser> couponList = couponUserService.selectCouponUserList(queryCoupon);
// couponNum = couponList != null ? couponList.size() : 0;
// } catch (Exception e) {
// }
userInfo.put("couponNum", couponNum);
return AppletControllerUtil.appletSuccess(userInfo);
@ -6137,7 +6138,6 @@ public class AppletController extends BaseController {
/**
* 报价获取服务项目
* GET /api/worker/quote/craft/{goodsId}
*/
@GetMapping("/api/worker/quote/craft/{goodsId}")
public Object getWorkerQuoteCraft(@PathVariable("goodsId") Long goodsId) {

View File

@ -2,24 +2,24 @@ package com.ruoyi.system.controller;
import java.math.BigDecimal;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.ControllerUtil.*;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.winnerlook.model.VoiceResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
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.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@ -37,6 +37,7 @@ import com.ruoyi.system.domain.ServiceGoods;
* @author ruoyi
* @date 2025-05-13
*/
@Api(tags = "订单管理接口")
@RestController
@RequestMapping("/system/Order")
public class OrderController extends BaseController {
@ -48,6 +49,19 @@ public class OrderController extends BaseController {
@Autowired
private IUsersPayBeforService usersPayBeforService;
@Autowired
private IQuoteTypeService quoteTypeService;
@Autowired
private IQuoteCraftService quoteCraftService;
@Autowired
private IQuoteMaterialTypeService quoteMaterialTypeService;
@Autowired
private IQuoteMaterialService quoteMaterialService;
@Autowired
IUsersService usersService;
@ -1051,4 +1065,556 @@ public class OrderController extends BaseController {
return error("项目报价失败:" + e.getMessage());
}
}
//---------------------------------------------------------------报价相关-----------------------------------------------------
// ... existing code ...
/**
* 获取基检项目和订单报价信息
* GET /api/worker/basic/project?id=订单id&goodid=服务id
*/
@GetMapping("/basic/project/{id}")
public AjaxResult getWorkerBasicProject(@PathVariable("id") Long id ) {
List<String> basicList = new ArrayList<>();
Map<String, Object> data = new HashMap<>();
Long goodid = null;
Object quoteJson = null;
// 1. 如果订单id不为空查订单和报价日志
if (id != null) {
Order order = orderService.selectOrderById(id);
if (order != null) {
// type=5.0 的订单日志
OrderLog logQuery = new OrderLog();
logQuery.setOid(order.getId());
logQuery.setType(new BigDecimal("5.0"));
List<OrderLog> logs = orderLogService.selectOrderLogList(logQuery);
if (logs != null && !logs.isEmpty()) {
String content = logs.getFirst().getContent();
try {
quoteJson = JSON.parse(content);
} catch (Exception e) {
quoteJson = content;
}
}
// 取服务id
if (order.getProductId() != null) {
goodid = order.getProductId();
}
}
}
// 2. 查服务信息
if (goodid != null) {
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodid);
if (serviceGoods != null) {
String basic = serviceGoods.getBasic();
if (basic != null && !basic.trim().isEmpty()) {
try {
JSONArray jsonArray = JSONArray.parse(basic);
for (int i = 0; i < jsonArray.size(); i++) {
String item = jsonArray.getString(i);
if (item != null && !item.trim().isEmpty()) {
basicList.add(item.trim());
}
}
} catch (Exception e) {
String[] arr = basic.split("[\n,]");
for (String s : arr) {
if (!s.trim().isEmpty()) basicList.add(s.trim());
}
}
}
}
}
//查询报价的支付信息
if (id != null) {
Order order = orderService.selectOrderById(id);
if (order != null) {
// type=5.0 的订单日志
OrderLog logQuery = new OrderLog();
logQuery.setOid(order.getId());
logQuery.setType(new BigDecimal("5.0"));
List<OrderLog> logs = orderLogService.selectOrderLogList(logQuery);
if (logs != null && !logs.isEmpty()) {
OrderLog logdata = logs.getFirst();
if (logdata != null) {
Map<String, Object> paydata = new HashMap<>();
paydata.put("weikuan", logdata.getPaid());
paydata.put("dingjin", logdata.getDepPaid());
data.put("payStatusdata", paydata);
}
}
}
}else{
Map<String, Object> paydata = new HashMap<>();
paydata.put("weikuan", "1");
paydata.put("dingjin", "1");
data.put("payStatusdata", paydata);
}
data.put("basic", basicList);
if (quoteJson != null) {
data.put("quote", quoteJson);
}
return AjaxResult.success(data);
}
// /**
// * 获取基检项目
// */
// @ApiOperation("获取基检项目")
// @GetMapping("/basic/project/{id}")
// public AjaxResult getWorkerBasicProject(@PathVariable("id") Long id) {
// Order order = orderService.selectOrderById(id);
// if (order == null) {
// return AjaxResult.error("订单不存在");
// }
// ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
// if (serviceGoods == null) {
// return AjaxResult.error("商品不存在");
// }
//
// String basic = serviceGoods.getBasic();
// List<String> basicList = new ArrayList<>();
// if (basic != null && !basic.trim().isEmpty()) {
// try {
// JSONArray jsonArray = JSONArray.parseArray(basic);
// for (int i = 0; i < jsonArray.size(); i++) {
// String item = jsonArray.getString(i);
// if (item != null && !item.trim().isEmpty()) {
// basicList.add(item.trim());
// }
// }
// } catch (Exception e) {
// String[] arr = basic.split("[\n,]");
// for (String s : arr) {
// if (!s.trim().isEmpty()) basicList.add(s.trim());
// }
// }
// }
// Map<String, Object> data = new HashMap<>();
// data.put("basic", basicList);
// return AjaxResult.success(data);
// }
/**
* 报价获取服务项目
*/
@ApiOperation("获取取服务项目")
@GetMapping("/quote/craft/{goodsId}")
public AjaxResult getWorkerQuoteCraft(@PathVariable("goodsId") Long goodsId) {
// 1. 查询商品基本信息
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodsId);
if (serviceGoods == null) {
return AjaxResult.error("商品不存在");
}
// 2. 查询服务分类IQuoteTypeService
QuoteType typeQuery = new QuoteType();
typeQuery.setGoodId("\"" + goodsId + "\"");
List<QuoteType> typeList = quoteTypeService.selectQuoteTypeList(typeQuery);
List<Object> dataArr = new ArrayList<>();
for (QuoteType type : typeList) {
Map<String, Object> typeMap = new HashMap<>();
typeMap.put("id", type.getId());
typeMap.put("title", type.getTitle());
// 3. 查询工艺IQuoteCraftService
QuoteCraft craftQuery = new QuoteCraft();
craftQuery.setTypeId("[\"" + type.getId() + "\"]");
List<QuoteCraft> craftList = quoteCraftService.selectQuoteCraftList(craftQuery);
List<Map<String, Object>> craftArr = new ArrayList<>();
for (QuoteCraft craft : craftList) {
Map<String, Object> craftMap = new HashMap<>();
craftMap.put("id", craft.getId());
craftMap.put("title", craft.getTitle());
craftMap.put("price", craft.getPrice() != null ? craft.getPrice().toString() : "0.00");
craftMap.put("unit", craft.getUnit());
// type_id为数组需解析
List<String> typeIdList = new ArrayList<>();
String typeIdStr = craft.getTypeId();
if (typeIdStr != null && typeIdStr.trim().startsWith("[") && typeIdStr.trim().endsWith("]")) {
try {
typeIdList = JSON.parseArray(typeIdStr, String.class);
} catch (Exception e) {
typeIdList.add(typeIdStr);
}
} else if (typeIdStr != null) {
typeIdList.add(typeIdStr);
}
craftMap.put("type_id", typeIdList);
craftArr.add(craftMap);
}
typeMap.put("craft", craftArr);
dataArr.add(typeMap);
}
return AjaxResult.success(dataArr);
}
/**
* 报价所需物料查询
* GET /api/worker/quote/material/{goodsId}
*/
@ApiOperation("获取所需物料")
@GetMapping("/quote/material/{goodsId}")
public AjaxResult getWorkerQuoteMaterial(@PathVariable("goodsId") Long goodsId) {
// 1. 查询商品基本信息
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodsId);
if (serviceGoods == null) {
return AjaxResult.error("商品不存在");
}
// 2. 查询物料分类IQuoteMaterialTypeService
QuoteMaterialType typeQuery = new QuoteMaterialType();
typeQuery.setGoodId("\"" + goodsId + "\"");
List<QuoteMaterialType> typeList = quoteMaterialTypeService.selectQuoteMaterialTypeList(typeQuery);
List<Object> dataArr = new ArrayList<>();
for (QuoteMaterialType type : typeList) {
Map<String, Object> typeMap = new HashMap<>();
typeMap.put("id", type.getId());
typeMap.put("title", type.getTitle());
// 3. 查询物料信息IQuoteMaterialService
QuoteMaterial materialQuery = new QuoteMaterial();
materialQuery.setTypeId("\"" + type.getId() + "\"");
List<QuoteMaterial> materialList = quoteMaterialService.selectQuoteMaterialList(materialQuery);
List<Map<String, Object>> materialArr = new ArrayList<>();
for (QuoteMaterial material : materialList) {
Map<String, Object> materialMap = new HashMap<>();
materialMap.put("id", material.getId());
materialMap.put("title", material.getTitle());
materialMap.put("image",AppletControllerUtil.buildImageUrl(material.getImage()));
materialMap.put("price", material.getPrice() != null ? material.getPrice().toString() : "0.00");
materialMap.put("unit", material.getUnit());
// 格式化manyimages为数组
if (material.getManyimages() != null && !material.getManyimages().trim().isEmpty()) {
materialMap.put("manyimages", JSONArray.parseArray(material.getManyimages()));
} else {
materialMap.put("manyimages", new JSONArray());
}
if (org.apache.commons.lang3.StringUtils.isNotBlank(material.getContent())&& org.apache.commons.lang3.StringUtils.isNotBlank(material.getManyimages())){
materialMap.put("showtype", 1);
}else{
materialMap.put("showtype", 2);
}
materialMap.put("content", material.getContent());
// type_id为数组需解析
List<String> typeIdList = new ArrayList<>();
String typeIdStr = material.getTypeId();
if (typeIdStr != null && typeIdStr.trim().startsWith("[") && typeIdStr.trim().endsWith("]")) {
try {
typeIdList = JSON.parseArray(typeIdStr, String.class);
} catch (Exception e) {
typeIdList.add(typeIdStr);
}
} else if (typeIdStr != null) {
typeIdList.add(typeIdStr);
}
materialMap.put("type_id", typeIdList);
materialArr.add(materialMap);
}
typeMap.put("material", materialArr);
dataArr.add(typeMap);
}
return AjaxResult.success(dataArr);
}
/**
* 师傅报价接口
* POST /api/worker/estimate
*/
@ApiOperation(value = "测试")
@PostMapping("/worker/estimate")
public AjaxResult workerEstimate(@RequestBody Map<String, Object> params, HttpServletRequest request) throws Exception {
if (params == null) {
return AjaxResult.error("参数错误");
}
PayBeforeUtil payBeforeUtil = new PayBeforeUtil();
// 1. 计算金额
BigDecimal GoodsAllPrice = BigDecimal.ZERO;
BigDecimal ServiceAllPrice = BigDecimal.ZERO;
BigDecimal totalPrice = BigDecimal.ZERO;
List<Map<String, Object>> craftList = (List<Map<String, Object>>) params.get("craft");
if (craftList != null) {
for (Map<String, Object> craft : craftList) {
Long craftId = null;
try {
craftId = Long.valueOf(craft.get("id").toString());
} catch (Exception ignore) {
}
if (craftId != null) {
QuoteCraft quoteCraft = quoteCraftService.selectQuoteCraftById(craftId);
if (quoteCraft != null) {
BigDecimal price = new BigDecimal(craft.get("price").toString());
Integer count = craft.get("count") == null ? 1 : Integer.parseInt(craft.get("count").toString());
totalPrice = totalPrice.add(price.multiply(BigDecimal.valueOf(count)));
ServiceAllPrice = ServiceAllPrice.add(price.multiply(BigDecimal.valueOf(count)));
}
}
}
}
List<Map<String, Object>> materialList = (List<Map<String, Object>>) params.get("material");
if (materialList != null) {
for (Map<String, Object> material : materialList) {
Long materialId = null;
try {
materialId = Long.valueOf(material.get("id").toString());
} catch (Exception ignore) {
}
if (materialId != null) {
QuoteMaterial quoteMaterial = quoteMaterialService.selectQuoteMaterialById(materialId);
if (quoteMaterial != null) {
BigDecimal price = new BigDecimal(material.get("price").toString());
Integer count = material.get("count") == null ? 1 : Integer.parseInt(material.get("count").toString());
totalPrice = totalPrice.add(price.multiply(BigDecimal.valueOf(count)));
GoodsAllPrice = GoodsAllPrice.add(price.multiply(BigDecimal.valueOf(count)));
}
}
}
}
BigDecimal reductionPrice = BigDecimal.ZERO;
String reduction = params.get("reduction").toString();
String reamk = null;
if (params.get("reamk") != null){
reamk =params.get("reamk").toString();
}
if (reduction != null && !reduction.trim().isEmpty()) {
reductionPrice = new BigDecimal(reduction);
// totalPrice = totalPrice.subtract(reductionPrice);
totalPrice = totalPrice;
}
// 2. 组装新json
Map<String, Object> resultJson = new LinkedHashMap<>();
// project
Map<String, Object> project = new LinkedHashMap<>();
project.put("name", "项目费用");
project.put("price", totalPrice);
resultJson.put("project", project);
Map<String, Object> reductionproject = new LinkedHashMap<>();
reductionproject.put("name", "优惠金额");
reductionproject.put("price", params.get("reduction"));
resultJson.put("reduction", reductionproject);
Map<String, Object> depositproject = new LinkedHashMap<>();
depositproject.put("name", "定金");
depositproject.put("price", params.get("price"));
resultJson.put("deposit", depositproject);
// basic
resultJson.put("basic", params.get("basic"));
if (StringUtils.isNotBlank(reamk)){
resultJson.put("reamk", reamk);
}
// craft
List<Map<String, Object>> craftListNew = new ArrayList<>();
if (craftList != null) {
for (Map<String, Object> craft : craftList) {
Map<String, Object> item = new LinkedHashMap<>();
item.put("name", craft.get("title") != null ? craft.get("title") : craft.get("name"));
item.put("price", craft.get("price"));
item.put("pid", craft.get("pid"));
item.put("id", craft.get("id"));
item.put("count", craft.get("count"));
craftListNew.add(item);
}
}
resultJson.put("craft", craftListNew);
// material
List<Map<String, Object>> materialListNew = new ArrayList<>();
if (materialList != null) {
for (Map<String, Object> material : materialList) {
Map<String, Object> item = new LinkedHashMap<>();
item.put("name", material.get("title") != null ? material.get("title") : material.get("name"));
item.put("price", material.get("price"));
item.put("id", material.get("id"));
item.put("pid", material.get("pid"));
item.put("count", material.get("count"));
materialListNew.add(item);
}
}
resultJson.put("material", materialListNew);
// 3. 转为字符串
String contentStr = com.alibaba.fastjson2.JSONObject.toJSONString(resultJson);
// 4. 订单相关处理
Long orderId = null;
if (params.get("id") != null) {
try {
orderId = Long.valueOf(params.get("id").toString());
} catch (Exception ignore) {
}
}
if (orderId == null) {
return AppletControllerUtil.appletError("订单ID格式错误");
}
Order order = orderService.selectOrderById(orderId);
if (order == null) {
return AppletControllerUtil.appletError("订单不存在");
}
// 查询最新订单日志
OrderLog neworderLogdata =new OrderLog();
neworderLogdata.setType(new BigDecimal(5.0));
neworderLogdata.setOid(order.getId());
List<OrderLog> orderLogslist = orderLogService.selectOrderLogList(neworderLogdata);
if(!orderLogslist.isEmpty()){
OrderLog neworderLog=orderLogslist.getFirst();
neworderLog.setContent(contentStr);
if (params.get("price") != null) {
//String DepLogId = GenerateCustomCode.generCreateOrder("LOG");
neworderLog.setDeposit(new BigDecimal(params.get("price").toString()));
neworderLog.setDepPaid(1);
// neworderLog.setDepLogId(DepLogId);
//给尾款添加预支
// BigDecimal totalAmount=neworderLog.getDeposit();
// PayBeforeUtil payBeforeUtil = new PayBeforeUtil();
// payBeforeUtil.createPayBefore(userinfo, totalAmount, DepLogId, neworderLog.getId(),
// null, 7L, null, null,
// null, null, null,1L,null);
//// payBeforeUtil.createPayBefore(user, totalPrice.add(reductionPrice), order.getOrderId(), order.getId(),);
}else {
neworderLog.setDeposit(BigDecimal.ZERO);
}
// neworderLog.setPrice(totalPrice.add(reductionPrice));
neworderLog.setPaid(1L);
if (params.get("reduction") != null) {
neworderLog.setReductionPrice(new BigDecimal(params.get("reduction").toString()));
} else {
neworderLog.setReductionPrice(BigDecimal.ZERO);
}
System.out.println("neworderLog.getPrice():totalPrice"+totalPrice);
System.out.println("neworderLog.getPrice():reductionPrice"+reductionPrice);
System.out.println("neworderLog.getPrice():neworderLog.getDeposit()"+neworderLog.getDeposit());
BigDecimal WK=totalPrice.subtract(reductionPrice).subtract(neworderLog.getDeposit());
System.out.println("neworderLog.getPrice():neworderLog.getDeposit()WKWKWK"+WK);
if(WK.compareTo(BigDecimal.ZERO)>0){
System.out.println("111neworderLog.getPrice():neworderLog.getDeposit()WKWKWK"+WK);
neworderLog.setPrice(WK);
}else{
neworderLog.setPrice(BigDecimal.ZERO);
}
// if (params.get("reduction") != null) {
// neworderLog.setReductionPrice(new BigDecimal(params.get("reduction").toString()));
// } else {
// neworderLog.setReductionPrice(BigDecimal.ZERO);
// }
neworderLog.setWorkerCost(BigDecimal.ZERO);
//log.set
neworderLog.setLogId(GenerateCustomCode.generCreateOrder("EST"));
//删除之前的预支付信息
UsersPayBefor payBefore = new UsersPayBefor();
payBefore.setOrderid(neworderLog.getDepLogId());
List<UsersPayBefor> payBeforeList = usersPayBeforService.selectUsersPayBeforList(payBefore);
if(!payBeforeList.isEmpty()){
for (UsersPayBefor payBefore1 : payBeforeList) {
usersPayBeforService.deleteUsersPayBeforById(payBefore1.getId());
}
}
//删除之前的预支付信息
UsersPayBefor payBefore3 = new UsersPayBefor();
payBefore3.setOrderid(neworderLog.getLogOrderId());
payBefore3.setType(9L);
List<UsersPayBefor> payBeforeList3 = usersPayBeforService.selectUsersPayBeforList(payBefore3);
if(!payBeforeList3.isEmpty()){
for (UsersPayBefor payBefore4 : payBeforeList3) {
usersPayBeforService.deleteUsersPayBeforById(payBefore4.getId());
}
}
Users userinfo = usersService.selectUsersById(order.getUid());
payBeforeUtil.handleQuotationPayBefore(userinfo, neworderLog, contentStr, order.getOrderId());
int flg= orderLogService.updateOrderLog(neworderLog);
if (flg > 0) {
order.setGoodPrice(GoodsAllPrice);
order.setServicePrice(ServiceAllPrice);
orderService.updateOrder(order);
}
//小程序推送报价成功
Users user = usersService.selectUsersById(order.getUid());
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
WXsendMsgUtil.sendWorkerADDmoney(user.getOpenid(), order, serviceGoods);
return AjaxResult.success("报价成功");
}else{
order.setJsonStatus(6);
com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
jsonObject.put("type", 5);
order.setLogJson(jsonObject.toJSONString());
// order.setTotalPrice(totalPrice);
// order.setUpdatedAt(new Date());
order.setGoodPrice(GoodsAllPrice);
order.setServicePrice(ServiceAllPrice);
int update = orderService.updateOrder(order);
if (update > 0) {
OrderLog log = new OrderLog();
log.setOid(order.getId());
log.setLogOrderId(GenerateCustomCode.generCreateOrder("DSB") );
log.setOrderId(order.getOrderId());
log.setType(new BigDecimal(5));
log.setContent(contentStr);
log.setTitle("已检查评估报价");
if (params.get("price") != null) {
log.setDeposit(new BigDecimal(params.get("price").toString()));
log.setDepPaid(1);
log.setDepLogId(GenerateCustomCode.generCreateOrder("RED"));
}else {
log.setDeposit(BigDecimal.ZERO);
}
BigDecimal WK=totalPrice.subtract(reductionPrice).subtract(log.getDeposit());
if(WK.compareTo(BigDecimal.ZERO)>0){
log.setPrice(WK);
}else{
log.setPrice(BigDecimal.ZERO);
}
// log.setPrice(totalPrice.add(reductionPrice));
log.setPaid(1L);
if (params.get("reduction") != null) {
log.setReductionPrice(new BigDecimal(params.get("reduction").toString()));
} else {
log.setReductionPrice(BigDecimal.ZERO);
}
//log.setPrice(ServiceAllPrice.subtract(reductionPrice));
//log.set
log.setLogId(GenerateCustomCode.generCreateOrder("EST"));
log.setWorkerLogId(order.getWorkerId());
log.setWorkerId(order.getWorkerId());
int flg=orderLogService.insertOrderLog(log);
if (flg > 0) {
order.setGoodPrice(GoodsAllPrice);
order.setServicePrice(ServiceAllPrice);
orderService.updateOrder(order);
}
Users user = usersService.selectUsersById(order.getUid());
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
//小程序推送用户报价成功
WXsendMsgUtil.sendWorkerADDmoney(user.getOpenid(), order, serviceGoods);
Users userinfo = usersService.selectUsersById(order.getUid());
payBeforeUtil.handleQuotationPayBefore(userinfo, log, contentStr, order.getOrderId());
return AjaxResult.success("报价成功");
} else {
return AjaxResult.success("报价失败");
}
}
}
}

View File

@ -88,6 +88,16 @@ public class PayMoneyLogController extends BaseController
return success(payMoneyLogService.getPayMoneyLogStatistics());
}
/**
* 获取订单价格统计按订单ID分组
*/
@PreAuthorize("@ss.hasPermi('system:PayMoneyLog:query')")
@GetMapping(value = "/getOrderPriceStatistics")
public AjaxResult getOrderPriceStatistics()
{
return success(payMoneyLogService.getOrderPriceStatistics(1l));
}
/**
* 导出支付记录列表
*/

View File

@ -518,13 +518,13 @@ public class PayNotifyController extends BaseController {
}
}
if (usersPayBefor != null) {
usersPayBefor.setStatus(2L);
usersPayBefor.setPaytime(new Date());
usersPayBefor.setPaycode(transactionId);
usersPayBeforService.updateUsersPayBefor(usersPayBefor);
}
// if (usersPayBefor != null) {
// usersPayBefor.setStatus(2L);
// usersPayBefor.setPaytime(new Date());
// usersPayBefor.setPaycode(transactionId);
// usersPayBeforService.updateUsersPayBefor(usersPayBefor);
//
// }
Users users = null;
if (usersPayBefor != null) {
users = usersService.selectUsersById(usersPayBefor.getUid());

View File

@ -97,7 +97,14 @@ public class ServiceCateController extends BaseController
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(serviceCateService.selectServiceCateById(id));
ServiceCate serviceCate= serviceCateService.selectServiceCateById(id);
if (serviceCate != null){
serviceCate.setIcon(AppletControllerUtil.buildImageUrl(serviceCate.getIcon()));
}
return success(serviceCate);
}
/**

View File

@ -1868,6 +1868,10 @@ public class AppletControllerUtil {
}
}
if (couponUser.getCateId() == null && couponUser.getProductId() == null){
suitTitle="通用券";
}
if (couponUser.getReceiveType().equals("1")){
if (totalPrice!=null){
if (totalPrice.compareTo(new BigDecimal(couponUser.getMinPrice()))>0){
@ -1896,7 +1900,7 @@ public class AppletControllerUtil {
break;
}
}
couponData.put("tag", tag);
couponData.put("tag","tag");
resultList.add(couponData);
}
@ -1916,7 +1920,7 @@ public class AppletControllerUtil {
for (Coupons coupons : couponsList) {
Map<String, Object> couponData = new HashMap<>();
couponData.put("id", coupons.getId());
couponData.put("title", coupons.getId());
couponData.put("title", coupons.getTitle());
couponData.put("price", coupons.getPrice());
couponData.put("min_price", coupons.getMinPrice());
couponData.put("start_time", coupons.getStartTime());
@ -5542,6 +5546,7 @@ public class AppletControllerUtil {
order.setProductId(serviceGoods.getId());
order.setBigtype(serviceGoods.getServicetype());
order.setProductName(serviceGoods.getTitle());
order.setReamk(reamk);
order.setSku(sku);
if (userAddress != null) {
@ -5580,6 +5585,14 @@ public class AppletControllerUtil {
order.setDeduction(new BigDecimal(0));
order.setFileData(attachments); // 设置附件数据
order.setType(1);
// 使用 Fastjson2 将实体安全序列化为JSON字符串避免直接使用 toString() 解析导致的异常
if (userAddress != null) {
try {
order.setAdressjson(JSON.toJSONString(userAddress));
} catch (Exception e) {
order.setAdressjson(null);
}
}
//order.setPayPrice(new BigDecimal(0));
int insertResult = orderService.insertOrder(order);
if (insertResult <= 0) {
@ -5716,6 +5729,13 @@ public class AppletControllerUtil {
order.setProductName(serviceGoods.getTitle());
order.setSku(sku);
order.setBigtype(serviceGoods.getServicetype());
if (userAddress != null) {
try {
order.setAdressjson(JSON.toJSONString(userAddress));
} catch (Exception e) {
order.setAdressjson(null);
}
}
if(StringUtils.isNotBlank(cikaid)){
order.setTotalPrice(serviceGoods.getFixedprice());
order.setCartid(cikaid);
@ -5923,7 +5943,13 @@ public class AppletControllerUtil {
}
}
}
if (userAddress != null) {
try {
order.setAdressjson(JSON.toJSONString(userAddress));
} catch (Exception e) {
order.setAdressjson(null);
}
}
order.setTotalPrice(itemPrice);
order.setGoodPrice(BigDecimal.ZERO);
order.setServicePrice(BigDecimal.ZERO);
@ -6007,6 +6033,13 @@ public class AppletControllerUtil {
order.setProductName(serviceGoods.getTitle());
order.setSku(sku);
order.setJsonStatus(0);
if (userAddress != null) {
try {
order.setAdressjson(JSON.toJSONString(userAddress));
} catch (Exception e) {
order.setAdressjson(null);
}
}
order.setType(1);
order.setNum(Long.valueOf(num));
if (userAddress != null) {

View File

@ -167,7 +167,7 @@ public class BenefitPointsUtil {
private static BenefitPointsResult processServiceOrder(Order order, Users user, BigDecimal money, Map<String, Object> config) {
try {
log.info("【服务订单处理】订单ID: {}, 用户ID: {}, 金额: {}", order.getId(), user.getId(), money);
Users userdata=usersService.selectUsersById(user.getId());
// 获取服务金转换为消费金的比例
BigDecimal servicefeeRatio = getConfigValue(config, SERVICEFEE_KEY, new BigDecimal("0"));
if (servicefeeRatio.compareTo(ZERO) <= 0) {
@ -179,21 +179,21 @@ public class BenefitPointsUtil {
BigDecimal consumptionIncrease = money.multiply(servicefeeRatio).divide(new BigDecimal("100"));
// 更新用户消费金余额
BigDecimal beforeConsumption = user.getConsumption() != null ? user.getConsumption() : ZERO;
BigDecimal beforeConsumption = userdata.getConsumption() != null ? userdata.getConsumption() : ZERO;
BigDecimal afterConsumption = beforeConsumption.add(consumptionIncrease);
user.setConsumption(afterConsumption);
userdata.setConsumption(afterConsumption);
// 更新用户信息
int updateResult = usersService.updateUsers(user);
int updateResult = usersService.updateUsers(userdata);
if (updateResult <= 0) {
log.error("【错误】用户消费金更新失败用户ID: {}", user.getId());
log.error("【错误】用户消费金更新失败用户ID: {}", userdata.getId());
return new BenefitPointsResult(false, "用户消费金更新失败", null);
}
// 记录日志
UserBenefitPoints benefitLog = createBenefitPointsLog(
order.getId(),
user.getId(),
userdata.getId(),
TYPE_CONSUMPTION,
ORDER_TYPE_INCOME,
money,
@ -205,12 +205,12 @@ public class BenefitPointsUtil {
int insertResult = userBenefitPointsService.insertUserBenefitPoints(benefitLog);
if (insertResult <= 0) {
log.error("【错误】消费金日志记录失败用户ID: {}", user.getId());
log.error("【错误】消费金日志记录失败用户ID: {}", userdata.getId());
return new BenefitPointsResult(false, "消费金日志记录失败", null);
}
log.info("【服务订单处理完成】用户ID: {}, 消费金增加: {}, 更新前: {}, 更新后: {}",
user.getId(), consumptionIncrease, beforeConsumption, afterConsumption);
userdata.getId(), consumptionIncrease, beforeConsumption, afterConsumption);
return new BenefitPointsResult(true, "服务订单消费金处理成功", benefitLog);
@ -225,7 +225,7 @@ public class BenefitPointsUtil {
private static BenefitPointsResult processCikaOrder(UserUseSecondaryCard order, Users user, BigDecimal money, Map<String, Object> config) {
try {
log.info("【服务订单处理】订单ID: {}, 用户ID: {}, 金额: {}", order.getId(), user.getId(), money);
Users userdata = usersService.selectUsersById(user.getId());
// 获取服务金转换为消费金的比例
BigDecimal servicefeeRatio = getConfigValue(config, SERVICEFEE_KEY, new BigDecimal("0"));
if (servicefeeRatio.compareTo(ZERO) <= 0) {
@ -237,21 +237,21 @@ public class BenefitPointsUtil {
BigDecimal consumptionIncrease = money.multiply(servicefeeRatio).divide(new BigDecimal("100"));
// 更新用户消费金余额
BigDecimal beforeConsumption = user.getConsumption() != null ? user.getConsumption() : ZERO;
BigDecimal beforeConsumption = userdata.getConsumption() != null ? userdata.getConsumption() : ZERO;
BigDecimal afterConsumption = beforeConsumption.add(consumptionIncrease);
user.setConsumption(afterConsumption);
userdata.setConsumption(afterConsumption);
// 更新用户信息
int updateResult = usersService.updateUsers(user);
int updateResult = usersService.updateUsers(userdata);
if (updateResult <= 0) {
log.error("【错误】用户消费金更新失败用户ID: {}", user.getId());
log.error("【错误】用户消费金更新失败用户ID: {}", userdata.getId());
return new BenefitPointsResult(false, "用户消费金更新失败", null);
}
// 记录日志
UserBenefitPoints benefitLog = createBenefitPointsLog(
order.getId(),
user.getId(),
userdata.getId(),
TYPE_CONSUMPTION,
ORDER_TYPE_INCOME,
money,
@ -263,7 +263,7 @@ public class BenefitPointsUtil {
int insertResult = userBenefitPointsService.insertUserBenefitPoints(benefitLog);
if (insertResult <= 0) {
log.error("【错误】消费金日志记录失败用户ID: {}", user.getId());
log.error("【错误】消费金日志记录失败用户ID: {}", userdata.getId());
return new BenefitPointsResult(false, "消费金日志记录失败", null);
}
@ -283,7 +283,7 @@ public class BenefitPointsUtil {
private static BenefitPointsResult processGoodsOrder(GoodsOrder order, Users user, BigDecimal money, Map<String, Object> config) {
try {
log.info("【商品订单处理】订单ID: {}, 用户ID: {}, 金额: {}", order.getId(), user.getId(), money);
user=usersService.selectUsersById(order.getUid());
Users userdata = usersService.selectUsersById(user.getId());
// 获取消费金转换为服务金的比例
BigDecimal consumptionRatio = getConfigValue(config, CONSUMPTION_KEY, new BigDecimal("0"));
if (consumptionRatio.compareTo(ZERO) <= 0) {
@ -295,21 +295,21 @@ public class BenefitPointsUtil {
BigDecimal servicefeeIncrease = money.multiply(consumptionRatio).divide(new BigDecimal("100"));
// 更新用户服务金余额
BigDecimal beforeServicefee = user.getServicefee() != null ? user.getServicefee() : ZERO;
BigDecimal beforeServicefee = userdata.getServicefee() != null ? userdata.getServicefee() : ZERO;
BigDecimal afterServicefee = beforeServicefee.add(servicefeeIncrease);
user.setServicefee(afterServicefee);
userdata.setServicefee(afterServicefee);
// 更新用户信息
int updateResult = usersService.updateUsers(user);
int updateResult = usersService.updateUsers(userdata);
if (updateResult <= 0) {
log.error("【错误】用户服务金更新失败用户ID: {}", user.getId());
log.error("【错误】用户服务金更新失败用户ID: {}", userdata.getId());
return new BenefitPointsResult(false, "用户服务金更新失败", null);
}
// 记录日志
UserBenefitPoints benefitLog = createBenefitPointsLog(
order.getId(),
user.getId(),
userdata.getId(),
TYPE_SERVICE_FEE,
ORDER_TYPE_INCOME,
money,
@ -321,12 +321,12 @@ public class BenefitPointsUtil {
int insertResult = userBenefitPointsService.insertUserBenefitPoints(benefitLog);
if (insertResult <= 0) {
log.error("【错误】服务金日志记录失败用户ID: {}", user.getId());
log.error("【错误】服务金日志记录失败用户ID: {}", userdata.getId());
return new BenefitPointsResult(false, "服务金日志记录失败", null);
}
log.info("【商品订单处理完成】用户ID: {}, 服务金增加: {}, 更新前: {}, 更新后: {}",
user.getId(), servicefeeIncrease, beforeServicefee, afterServicefee);
userdata.getId(), servicefeeIncrease, beforeServicefee, afterServicefee);
return new BenefitPointsResult(true, "商品订单服务金处理成功", benefitLog);
@ -1268,6 +1268,7 @@ public class BenefitPointsUtil {
}
//type 1增加(用户增加就是退款的时候用) 0减少
if(type==1){
user.setServicefee(user.getServicefee().add(amountService));
UserBenefitPoints benefitLog = new UserBenefitPoints();
benefitLog.setOrderid(usersPayBefor.getId());
@ -1292,7 +1293,13 @@ public class BenefitPointsUtil {
return remap;
}else{
user.setServicefee(user.getServicefee().subtract(amountService));
//如果计算下来小于0则修改值为0不能出现负数
if(user.getServicefee().subtract(amountService).compareTo(BigDecimal.ZERO)<0){
user.setServicefee(new BigDecimal("0"));
}else{
user.setServicefee(user.getServicefee().subtract(amountService));
}
UserBenefitPoints benefitLog = new UserBenefitPoints();
benefitLog.setOrderid(usersPayBefor.getId());
benefitLog.setUid(usersPayBefor.getUid());
@ -1420,7 +1427,13 @@ public class BenefitPointsUtil {
}else{
System.out.println("抵扣区间-------"+user.getConsumption().subtract(amountGoodsmoney));
user.setConsumption(user.getConsumption().subtract(amountGoodsmoney));
//如果计算下来小于0则修改值为0不能出现负数
if(user.getConsumption().subtract(amountGoodsmoney).compareTo(BigDecimal.ZERO)<0){
user.setConsumption(BigDecimal.ZERO);
}else{
user.setConsumption(user.getConsumption().subtract(amountGoodsmoney));
}
// user.setConsumption(user.getConsumption().subtract(amountGoodsmoney));
UserBenefitPoints benefitLog = new UserBenefitPoints();
benefitLog.setOrderid(usersPayBefor.getId());
benefitLog.setUid(usersPayBefor.getUid());

View File

@ -106,6 +106,7 @@ public class CartOrderUtil {
order.setBigtype(serviceGoods.getServicetype());
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
order.setCreatePhone(user.getPhone());
order.setAdressjson(JSONObject.parseObject(userAddress.toString()).toJSONString());
int insertResult = orderService.insertOrder(order);
if (insertResult <= 0) {
result.put("success", false);
@ -277,6 +278,7 @@ public class CartOrderUtil {
goodsOrder.setStatus(1L); // 待支付
goodsOrder.setPostage(serviceGoods.getPostage());
goodsOrder.setMainOrderId(maincorid);
// goodsOrder.setAdressjson(JSONObject.parseObject(userAddress.toString()).toJSONString());
//goodsOrder.setIsmany(1L);
int insertResult = goodsOrderService.insertGoodsOrder(goodsOrder);
if (insertResult <= 0) {

View File

@ -73,4 +73,60 @@ public class CouponUtil {
return canReceiveList;
}
/**
* 处理过期优惠券
* 规则查询当前有效status = 1的优惠券 end_time + coupon_time() 计算到期时间
* 如果已到期则将优惠券状态置为 0并将该优惠券下的领取记录coupon_user置为 3失效已使用的保留原状态
*
* @param couponsService 优惠券服务
* @param couponUserService 优惠券领取记录服务
* @return 结果统计expiredCoupons 过期的优惠券数量updatedCouponUsers 被置为失效的领取记录数量
*/
public static Map<String, Object> processExpiredCoupons(ICouponsService couponsService, ICouponUserService couponUserService) {
long now = System.currentTimeMillis() / 1000; //
// 查询当前有效的优惠券status = 1
Coupons query = new Coupons();
query.setStatus(1L);
List<Coupons> activeCoupons = couponsService.selectCouponsList(query);
int expiredCouponCount = 0;
int updatedCouponUserCount = 0;
for (Coupons coupon : activeCoupons) {
// 若未设置结束时间视为永久有效直接跳过
if (coupon.getEndTime() == null || coupon.getEndTime() == 0L) {
continue;
}
long endTime = coupon.getEndTime(); //
long extraSeconds = coupon.getCouponTime() != null ? coupon.getCouponTime() * 24 * 60 * 60 : 0L; // ->
long expireAt = endTime + extraSeconds;
if (expireAt > 0 && now >= expireAt) {
// 1) 更新优惠券状态为关闭
coupon.setStatus(0L);
couponsService.updateCoupons(coupon);
expiredCouponCount++;
// 2) 将该优惠券下未使用/未失效的领取记录置为失效status = 3
CouponUser cuQuery = new CouponUser();
cuQuery.setCouponId(coupon.getId());
List<CouponUser> couponUsers = couponUserService.selectCouponUserList(cuQuery);
for (CouponUser cu : couponUsers) {
// status: 1未使用 2已使用 3已失效 仅把非已使用的置为失效
if (cu.getStatus() == null || cu.getStatus() != 2L) {
cu.setStatus(3L);
updatedCouponUserCount += couponUserService.updateCouponUser(cu);
}
}
}
}
Map<String, Object> result = new HashMap<>();
result.put("expiredCoupons", expiredCouponCount);
result.put("updatedCouponUsers", updatedCouponUserCount);
return result;
}
}

View File

@ -90,8 +90,7 @@ public class IntegralAndBenefitUtil {
users.setIntegral(newIntegral);
users.setTotalIntegral(newTotalIntegral);
logger.error("更新用户积分失败用户ID: {}", users.getIntegral());
logger.error("更新用户积分失败用户ID: {}", users.getTotalIntegral());
System.out.println("开始计算增加积分,这里开始处理" + orderid + "----------------------------------------------------------");
// 更新用户信息
int updateResult = usersService.updateUsers(users);
if (updateResult > 0) {

View File

@ -287,13 +287,13 @@ public class InvoiceUtil {
failedOrders.add(orderId + "(订单不存在或不属于当前用户)");
continue;
}
// 检查是否已开票
if (isOrderInvoiced(orderId)) {
failedOrders.add(orderId + "(已开过发票)");
continue;
}
// 累计金额和开票内容
BigDecimal orderAmount = (BigDecimal) orderInfo.get("amount");
if (orderAmount != null) {
@ -301,12 +301,12 @@ public class InvoiceUtil {
}
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));

View File

@ -34,6 +34,7 @@ public class OrderUtil {
private static IQuoteMaterialService quoteMaterialService = SpringUtils.getBean(IQuoteMaterialService.class);
private static IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
private static IOrderCallService orderCallService = SpringUtils.getBean(IOrderCallService.class);
private static IUserUseSecondaryCardService userUseSecondaryCardService = SpringUtils.getBean(IUserUseSecondaryCardService.class);
private static OrderLogHandler orderLogHandler = SpringUtils.getBean(OrderLogHandler.class);
@ -886,10 +887,13 @@ public class OrderUtil {
jsonObject.put("name", "报价订单支付成功,待服务,师傅"+users.getName());
orderLog.setContent(jsonObject.toJSONString());
int logInsertResult = orderLogService.insertOrderLog(orderLog);
//开始派单
if (logInsertResult>0){
DispatchUtil.dispatchOrder(order.getId());
}
//绑定号码打电话通知
Map<String, Object> map= OrderBindWorkerUtil.getOrderBindWorker(order.getId());
YunXinPhoneUtilAPI.httpsAxbTransfer(order.getWorkerPhone(), order.getId());
// //开始派单
// if (logInsertResult>0){
// DispatchUtil.dispatchOrder(order.getId());
// }
System.out.println("订单日志插入结果: " + logInsertResult);
System.out.println("需求报价订单处理完成");
} else {
@ -1026,6 +1030,7 @@ public class OrderUtil {
order.setType(1); // 服务订单
order.setCreateType(1); // 用户自主下单
order.setUname(user.getName());
//20250809处理过的一个故障
order.setPayPrice(payBefor.getAllmoney());
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
@ -1051,6 +1056,7 @@ public class OrderUtil {
UserAddress userAddress = userAddressService.selectUserAddressById(payBefor.getAddressid());
System.out.println("查询到的地址信息: " + (userAddress != null ? userAddress.toString() : "null"));
if (userAddress != null) {
order.setAdressjson(com.alibaba.fastjson2.JSONObject.parseObject(userAddress.toString()).toJSONString());
order.setAddressId(userAddress.getId());
order.setName(userAddress.getName());
order.setPhone(userAddress.getPhone());
@ -1332,6 +1338,26 @@ public class OrderUtil {
System.out.println("师傅佣金处理完成师傅ID: " + order.getWorkerId());
}
}
System.out.println("开始计算增加积分" + orderid + "----------------------------------------------------------");
//次卡下的服务不用给客户添加购物金
if (com.ruoyi.common.utils.StringUtils.isBlank(order.getCartid())){
//增加购物金
BenefitPointsUtil.processBenefitPoints(order.getId(),order.getPayPrice(),"1");
}
if (com.ruoyi.common.utils.StringUtils.isNotBlank(order.getCartid())){
//次卡进行分佣操作次卡的分佣只有一次
UserUseSecondaryCard userUseSecondaryCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(order.getCartid());
if (userUseSecondaryCard.getUsenum().intValue() >= userUseSecondaryCard.getNum().intValue()){
//次卡在这个时候就需要进行积分和购物金以的处理
if (userUseSecondaryCard.getStatus()==1){
BenefitPointsUtil.processBenefitPoints(userUseSecondaryCard.getId(), userUseSecondaryCard.getPaymoney(),"3");
// JSONObject integralAndBenefitResult = IntegralAndBenefitUtil.processIntegralAndBenefit(totalAmount, orderId, user.getId());
userUseSecondaryCard.setStatus(2L);//设置不可用
}
userUseSecondaryCardService.updateUserUseSecondaryCard(userUseSecondaryCard);
}
}
// // 处理用户通知可选
// if (order.getUid() != null) {

View File

@ -5,9 +5,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.Order;
import com.ruoyi.system.domain.Users;
import com.ruoyi.system.service.IOrderService;
import com.ruoyi.system.service.IUsersService;
import com.ruoyi.system.service.IWorkerMoneyLogService;
import com.ruoyi.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
@ -62,6 +60,9 @@ public class ScheduledTaskUtil implements CommandLineRunner {
// 任务执行统计
private final Map<String, TaskStatistics> taskStats = new ConcurrentHashMap<>();
private static ICouponsService couponsService = SpringUtils.getBean(ICouponsService.class);
private static ICouponUserService couponUserService = SpringUtils.getBean(ICouponUserService.class);
/**
* 初始化方法在Bean创建后执行
*/
@ -221,6 +222,34 @@ public class ScheduledTaskUtil implements CommandLineRunner {
}
}
/**
* 订单状态超时检查任务
* 每10分钟执行一次检查各种状态的订单是否超时
*
* 使用说明
* - 检查服务中订单是否超过预期时间
* - 检查待支付订单是否超时
* - 处理异常状态订单
*/
@Scheduled(fixedRate = 60 * 60 * 1000) // 每60分钟执行一次
public void checkcouponsStatusTimeout() {
String taskName = "优惠券过期检查时检查";
long startTime = System.currentTimeMillis();
try {
log.info("开始执行{}任务", taskName);
Map<String, Object> stat = CouponUtil.processExpiredCoupons(couponsService, couponUserService);
} catch (Exception e) {
log.error("{}任务执行失败", taskName, e);
updateTaskStatistics(taskName, false, System.currentTimeMillis() - startTime);
}
}
/**
* 系统数据清理任务
* 每天凌晨2点执行清理过期数据

View File

@ -721,25 +721,25 @@ public class WorkerCommissionUtil {
// 15. 计算并更新订单总金额用于开票
updateOrderTotalPriceForInvoice(order, amountComposition);
//次卡下的服务不用给客户添加购物金
if (StringUtils.isBlank(order.getCartid())){
//增加购物金
BenefitPointsUtil.processBenefitPoints(order.getId(),getOrderTotalAmount(order),"1");
}
if (StringUtils.isNotBlank(order.getCartid())){
//次卡进行分佣操作次卡的分佣只有一次
UserUseSecondaryCard userUseSecondaryCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(order.getCartid());
if (userUseSecondaryCard.getUsenum().intValue() >= userUseSecondaryCard.getNum().intValue()){
//次卡在这个时候就需要进行积分和购物金以的处理
if (userUseSecondaryCard.getStatus()==1){
BenefitPointsUtil.processBenefitPoints(userUseSecondaryCard.getId(), userUseSecondaryCard.getPaymoney(),"3");
// JSONObject integralAndBenefitResult = IntegralAndBenefitUtil.processIntegralAndBenefit(totalAmount, orderId, user.getId());
userUseSecondaryCard.setStatus(2L);//设置不可用
}
userUseSecondaryCardService.updateUserUseSecondaryCard(userUseSecondaryCard);
}
}
// //次卡下的服务不用给客户添加购物金
// if (StringUtils.isBlank(order.getCartid())){
// //增加购物金
// BenefitPointsUtil.processBenefitPoints(order.getId(),order.getPayPrice(),"1");
// }
// if (StringUtils.isNotBlank(order.getCartid())){
// //次卡进行分佣操作次卡的分佣只有一次
// UserUseSecondaryCard userUseSecondaryCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(order.getCartid());
// if (userUseSecondaryCard.getUsenum().intValue() >= userUseSecondaryCard.getNum().intValue()){
// //次卡在这个时候就需要进行积分和购物金以的处理
// if (userUseSecondaryCard.getStatus()==1){
// BenefitPointsUtil.processBenefitPoints(userUseSecondaryCard.getId(), userUseSecondaryCard.getPaymoney(),"3");
// // JSONObject integralAndBenefitResult = IntegralAndBenefitUtil.processIntegralAndBenefit(totalAmount, orderId, user.getId());
// userUseSecondaryCard.setStatus(2L);//设置不可用
// }
//
// userUseSecondaryCardService.updateUserUseSecondaryCard(userUseSecondaryCard);
// }
// }
//修改库存及销量
OrderUtil.updateInventoryAndSales(order.getOrderId(), 1);

View File

@ -73,4 +73,11 @@ public interface PayMoneyLogMapper
* @return 支付记录集合
*/
public List<PayMoneyLog> selectPayMoneyLogListForExport(PayMoneyLog payMoneyLog);
/**
* 按照订单ID分组统计价格总和
*
* @return 订单价格统计列表
*/
public List<java.util.Map<String, Object>> selectOrderPriceStatistics(Long uid);
}

View File

@ -73,4 +73,11 @@ public interface IPayMoneyLogService
* @return 支付记录集合
*/
public List<PayMoneyLog> selectPayMoneyLogListForExport(PayMoneyLog payMoneyLog);
/**
* 按照订单ID分组统计支付价格总和
*
* @return 订单价格统计列表包含orderId和totalPrice
*/
public List<java.util.Map<String, Object>> getOrderPriceStatistics(Long uid);
}

View File

@ -113,4 +113,15 @@ public class PayMoneyLogServiceImpl implements IPayMoneyLogService
{
return payMoneyLogMapper.selectPayMoneyLogListForExport(payMoneyLog);
}
/**
* 按照订单ID分组统计支付价格总和
*
* @return 订单价格统计列表包含orderId和totalPrice
*/
@Override
public List<java.util.Map<String, Object>> getOrderPriceStatistics(Long uid)
{
return payMoneyLogMapper.selectOrderPriceStatistics(uid);
}
}

View File

@ -128,4 +128,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
order by pml.id desc
</select>
<!-- 按照订单ID分组统计价格总和 -->
<select id="selectOrderPriceStatistics" parameterType="Long" resultType="java.util.Map">
SELECT
order_id as orderId,
SUM(price) as totalPrice
FROM pay_money_log
WHERE order_id IS NOT NULL AND order_id != '' and uid = #{uid}
GROUP BY order_id
ORDER BY totalPrice DESC
</select>
</mapper>

View File

@ -106,8 +106,6 @@
<if test="cr != null">cr,</if>
<if test="mergin != null">mergin,</if>
<if test="doorPrice != null">door_price,</if>
<if test="createdAt != null">created_at,</if>
<if test="updatedAt != null">updated_at,</if>
<if test="status != null">status,</if>
<if test="statusType != null">status_type,</if>
<if test="beginlook != null">beginlook,</if>
@ -118,6 +116,8 @@
<if test="lookMoney != null">look_money,</if>
<if test="gongshi != null">gongshi,</if>
<if test="clmoney != null">clmoney,</if>
created_at,
updated_at
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="workerId != null">#{workerId},</if>
@ -130,8 +130,6 @@
<if test="cr != null">#{cr},</if>
<if test="mergin != null">#{mergin},</if>
<if test="doorPrice != null">#{doorPrice},</if>
<if test="createdAt != null">#{createdAt},</if>
<if test="updatedAt != null">#{updatedAt},</if>
<if test="status != null">#{status},</if>
<if test="statusType != null">#{statusType},</if>
<if test="beginlook != null">#{beginlook},</if>
@ -142,6 +140,8 @@
<if test="lookMoney != null">#{lookMoney},</if>
<if test="gongshi != null">#{gongshi},</if>
<if test="clmoney != null">#{clmoney},</if>
NOW(),
NOW()
</trim>
</insert>

View File

@ -5,4 +5,4 @@ VUE_APP_TITLE = 华府人家
ENV = 'production'
# 西安华府人家装饰工程有限公司/生产环境
VUE_APP_BASE_API = '/prod-api'
VUE_APP_BASE_API = '/api'

Binary file not shown.

Binary file not shown.

View File

@ -401,7 +401,7 @@
style="width: 200px;"
placeholder="请输入数量"
/>
<span style="margin-left: 8px; color: #909399; font-size: 12px;">领取后至少30天有效</span>
<!-- <span style="margin-left: 8px; color: #909399; font-size: 12px;">领取后至少30天有效</span>-->
</div>
</el-form-item>
@ -854,7 +854,7 @@ export default {
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
this.getDataUserListByCoupon(id);
//this.getDataUserListByCoupon(id);
getCoupons(id).then(response => {
this.form = response.data;
//

View File

@ -2,7 +2,7 @@
<el-dialog
title="项目报价"
:visible.sync="visibleInner"
width="420px"
width="50%"
top="6vh"
append-to-body
@close="handleClose"
@ -14,14 +14,14 @@
<div class="group-sub">请和用户确认基础现象</div>
<div class="chip-list">
<el-button
v-for="opt in inspectionOptions"
:key="opt.id"
:type="selectedInspectionIds.includes(opt.id) ? 'primary' : 'default'"
v-for="item in form.basic"
:key="item.name"
:type="item.select ? 'primary' : 'default'"
size="mini"
class="chip"
@click="toggleInspection(opt.id)"
@click="item.select = !item.select"
>
{{ opt.name }}
{{ item.name }}
</el-button>
</div>
</section>
@ -31,18 +31,22 @@
<div class="group-title">服务项目</div>
<div class="group-sub">请和用户确认基础项目</div>
<el-card class="slot-card" shadow="never">
<div v-if="form.craft.length > 0" class="list">
<div v-for="(item, idx) in form.craft" :key="idx" class="list-item">
<span class="name">{{ item.title }}</span>
<span class="price">{{ item.price }}</span>
<el-input-number v-model="item.count" :min="1"></el-input-number>
<el-button type="text" @click="form.craft.splice(idx, 1)"
>移除</el-button
>
</div>
</div>
<div class="slot-row">
<el-button type="text" @click="projectPickerVisible = true">
去添加服务项目
</el-button>
</div>
<div v-if="projectItems.length > 0" class="list">
<div v-for="(item, idx) in projectItems" :key="idx" class="list-item">
<span class="name">{{ item.name }}</span>
<span class="price">{{ toMoney(item.price) }}</span>
<el-button type="text" @click="removeProject(idx)">移除</el-button>
</div>
</div>
</el-card>
</section>
@ -51,19 +55,39 @@
<div class="group-title">所需物料</div>
<div class="group-sub">如需物料请添加并向用户一并报价</div>
<el-card class="slot-card" shadow="never">
<div v-if="form.material.length > 0" class="list">
<div
v-for="(item, idx) in form.material"
:key="idx"
class="list-item"
>
<span class="name">{{ item.title }}</span>
<span class="price">{{ item.price }}</span>
<el-input-number v-model="item.count" :min="1"></el-input-number>
<el-button type="text" @click="form.material.splice(idx, 1)"
>移除</el-button
>
</div>
</div>
<div class="slot-row">
<el-button type="text" @click="materialPickerVisible = true">
去添加所需物料
</el-button>
</div>
<div v-if="materialItems.length > 0" class="list">
<div v-for="(item, idx) in materialItems" :key="idx" class="list-item">
<span class="name">{{ item.name }}</span>
<span class="qty">x{{ item.quantity }}</span>
<span class="price">{{ toMoney(item.price * item.quantity) }}</span>
<el-button type="text" @click="removeMaterial(idx)">移除</el-button>
</div>
</div>
</el-card>
</section>
<!-- 所需物料 -->
<section class="group">
<div class="group-title">备注</div>
<div class="group-sub">如有特殊情况说明请填写备注信息</div>
<el-card class="slot-card" shadow="never">
<el-input
type="textarea"
:rows="2"
placeholder="请输入内容"
v-model="form.reamk"
>
</el-input>
</el-card>
</section>
@ -76,26 +100,22 @@
<el-radio v-model="payType" label="stage">定金 + 尾款</el-radio>
<el-radio v-model="payType" label="once">一次性付清</el-radio>
</div>
<el-form v-show="payType == 'stage'">
<el-form-item label="定金金额">
<el-input-number v-model="form.price" :min="0" />
</el-form-item>
</el-form>
</el-card>
</section>
<!-- 优惠 -->
<section class="group">
<el-button type="text" @click="discountVisible = !discountVisible">添加优惠</el-button>
<el-button type="text">添加优惠</el-button>
<transition name="el-fade-in">
<div v-show="discountVisible" class="discount-box">
<el-form :model="discount" label-width="80px" size="small">
<el-form-item label="优惠类型">
<el-select v-model="discount.type" placeholder="请选择">
<el-option label="立减" value="minus" />
<el-option label="折扣(%)" value="rate" />
</el-select>
</el-form-item>
<el-form-item v-if="discount.type === 'minus'" label="立减金额">
<el-input-number v-model="discount.amount" :min="0" :step="1" />
</el-form-item>
<el-form-item v-else label="折扣比例">
<el-input-number v-model="discount.rate" :min="0" :max="100" :step="1" />
<div class="discount-box">
<el-form label-width="80px" size="small">
<el-form-item label="立减金额">
<el-input-number v-model="form.reduction" :min="0" />
</el-form-item>
</el-form>
</div>
@ -103,11 +123,6 @@
</section>
<!-- 底部报价 -->
<div class="footer">
<el-button type="primary" class="btn-generate" @click="handleGenerate">
生成报价报价{{ toMoney(grandTotal) }}
</el-button>
</div>
<!-- 服务项目选择弹窗临时简化版后续替换为接口数据 -->
<el-dialog
@ -116,18 +131,35 @@
width="520px"
append-to-body
>
<el-form :model="tempProject" label-width="90px" size="small">
<el-form-item label="项目名称">
<el-input v-model="tempProject.name" placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="项目单价">
<el-input-number v-model="tempProject.price" :min="0" :step="1" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="projectPickerVisible = false">取消</el-button>
<el-button type="primary" @click="addProject">添加</el-button>
</div>
<el-tabs v-model="craid">
<el-tab-pane
:label="item.title"
:name="item.id"
v-for="item in craftlist"
>
<div class="wullistbox">
<div v-for="value in item.craft" class="li">
<div class="left">
<p>{{ value.title }}</p>
<span>{{ value.price }}{{ value.unit }}</span>
</div>
<div
class="right"
v-if="!form.craft.find((r) => r.id == value.id)"
>
<el-button
type="primary"
@click="craftselect(value, item.craft.id)"
>选择</el-button
>
</div>
<div class="right" v-else>
<el-button disabled>已选</el-button>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
<!-- 物料选择弹窗临时简化版后续替换为接口数据 -->
@ -137,21 +169,36 @@
width="520px"
append-to-body
>
<el-form :model="tempMaterial" label-width="90px" size="small">
<el-form-item label="物料名称">
<el-input v-model="tempMaterial.name" placeholder="请输入物料名称" />
</el-form-item>
<el-form-item label="物料单价">
<el-input-number v-model="tempMaterial.price" :min="0" :step="1" />
</el-form-item>
<el-form-item label="数量">
<el-input-number v-model="tempMaterial.quantity" :min="1" :step="1" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="materialPickerVisible = false">取消</el-button>
<el-button type="primary" @click="addMaterial">添加</el-button>
</div>
<el-tabs v-model="materialid">
<el-tab-pane
:label="item.title"
:name="item.id"
v-for="item in materiallist"
>
<div class="wulist">
<div v-for="value in item.material" class="li">
<div class="left">
<img :src="value.image" />
<div>
<p>{{ value.title }}</p>
<span>{{ value.price }}{{ value.unit }}</span>
</div>
</div>
<div
class="right"
v-if="!form.material.find((r) => r.id == value.id)"
>
<el-button
type="primary"
@click="materialselect(value, item.material.id)"
>选择</el-button
>
</div>
<div v-else><el-button disabled>已选</el-button></div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
@ -160,17 +207,22 @@
<el-button type="primary" @click="handleGenerate">生成报价</el-button>
</div>
</el-dialog>
</template>
</template>
<script>
import request from '@/utils/request'
import {
Orderbasicproject,
Orderquotecraft,
Orderquotematerial,
Orderworkerestimate
} from "@/api/system/Order";
export default {
name: 'ProjectQuoteDialog',
name: "ProjectQuoteDialog",
props: {
visible: { type: Boolean, default: false },
orderId: { type: String, default: '' },
workerId: { type: [String, Number], default: '' },
goodId: { type: [String, Number], default: '' }
orderId: { type: String, default: "" },
workerId: { type: [String, Number], default: "" },
goodId: { type: [String, Number], default: "" },
},
data() {
return {
@ -185,165 +237,346 @@ export default {
materialItems: [],
//
payType: 'stage', // stage: +, once:
payType: "stage", // stage: +, once:
//
discountVisible: false,
discount: {
type: 'minus', // minus | rate
type: "minus", // minus | rate
amount: 0,
rate: 0
rate: 0,
},
form: {
basic: [], //
craft: [], //
material: [], //
price: 0, //
reduction: 0, //
reamk: "",
},
craid: "",
materialid: "",
craftlist: [],
materiallist: [],
//
projectPickerVisible: false,
materialPickerVisible: false,
tempProject: { name: '', price: 0 },
tempMaterial: { name: '', price: 0, quantity: 1 }
}
tempProject: { name: "", price: 0 },
tempMaterial: { name: "", price: 0, quantity: 1 },
};
},
watch: {
visible: {
immediate: true,
handler(val) {
this.visibleInner = val
this.visibleInner = val;
if (val) {
this.$nextTick(() => {
this.loadInspectionOptions()
})
this.loadInspectionOptions();
});
}
}
},
},
workerId() {
if (this.visibleInner) this.loadInspectionOptions();
},
orderId() {
if (this.visibleInner) this.loadInspectionOptions();
},
goodId() {
if (this.visibleInner) this.loadInspectionOptions();
},
workerId() { if (this.visibleInner) this.loadInspectionOptions() },
orderId() { if (this.visibleInner) this.loadInspectionOptions() },
goodId() { if (this.visibleInner) this.loadInspectionOptions() }
},
computed: {
projectTotal() {
return this.projectItems.reduce((sum, it) => sum + (Number(it.price) || 0), 0)
return this.projectItems.reduce(
(sum, it) => sum + (Number(it.price) || 0),
0
);
},
materialTotal() {
return this.materialItems.reduce((sum, it) => sum + (Number(it.price) || 0) * (Number(it.quantity) || 0), 0)
return this.materialItems.reduce(
(sum, it) => sum + (Number(it.price) || 0) * (Number(it.quantity) || 0),
0
);
},
subtotal() {
return this.projectTotal + this.materialTotal
return this.projectTotal + this.materialTotal;
},
discountAmount() {
if (this.discount.type === 'minus') {
return Number(this.discount.amount) || 0
if (this.discount.type === "minus") {
return Number(this.discount.amount) || 0;
}
const rate = Number(this.discount.rate) || 0
return (this.subtotal * rate) / 100
const rate = Number(this.discount.rate) || 0;
return (this.subtotal * rate) / 100;
},
grandTotal() {
const val = this.subtotal - this.discountAmount
return val > 0 ? val : 0
}
const val = this.subtotal - this.discountAmount;
return val > 0 ? val : 0;
},
},
methods: {
async loadInspectionOptions() {
// goodId goodid
if (!this.goodId && !this.orderId) {
//
return
return;
}
try {
this.loadingInspections = true
const res = await request.get('/api/worker/basic/project', {
params: { id: this.orderId || undefined, goodid: this.goodId || undefined }
})
if (res && res.code === 200 && res.data && Array.isArray(res.data.basic)) {
this.inspectionOptions = res.data.basic.map((name, idx) => ({ id: idx + 1, name }))
this.selectedInspectionIds = []
} else {
this.inspectionOptions = []
this.loadingInspections = true;
const res = await Orderbasicproject(this.orderId);
if (!res.data.quote) {
res.data.basic = res.data.basic.map((r) => {
return {
name: r,
select: false,
};
});
}
//
if (res.data.quote) {
res.data.basic = res.data.basic.map((r) => {
return {
name: r,
select:
res.data.quote.basic.findIndex((rr) => rr.name == r) != -1
? true
: false,
};
});
//
this.form.reamk = res.data.quote.reamk;
//
this.form.craft = res.data.quote.craft.map((r) => {
r["title"] = r.name;
return r;
});
//
this.form.material = res.data.quote.material.map((r) => {
r["title"] = r.name;
return r;
});
//
if (res.data.quote.deposit.price) {
this.payType = 'stage';
this.form.price = res.data.quote.deposit.price;
//
// if(res.data.payStatusdata.dingjin==2){
// isset.value=false;
// }
}
//
if (res.data.quote.project.price) {
this.form.reduction= res.data.quote.reduction.price;
}
}
this.form = { ...this.form, ...res.data };
//
Orderquotecraft(this.goodId).then((r) => {
this.craftlist = r.data;
if (r.data.length) {
this.craid = r.data[0].id;
}
});
//
Orderquotematerial(this.goodId).then((r) => {
this.materiallist = r.data;
if (r.data.length) {
this.materialid = r.data[0].id;
}
});
} catch (e) {
console.error('获取基检现象失败:', e)
this.$message.error('获取基检现象失败')
this.inspectionOptions = []
console.error("获取基检现象失败:", e);
this.$message.error("获取基检现象失败");
this.inspectionOptions = [];
} finally {
this.loadingInspections = false
this.loadingInspections = false;
}
},
craftselect(item, pid) {
this.form.craft.push({
...item,
count: 1,
pid: pid,
});
this.projectPickerVisible = false;
},
materialselect(item, pid) {
this.form.material.push({
...item,
count: 1,
pid: pid,
});
this.materialPickerVisible = false;
},
toMoney(v) {
const num = Number(v) || 0
return num.toFixed(2)
const num = Number(v) || 0;
return num.toFixed(2);
},
toggleInspection(id) {
const idx = this.selectedInspectionIds.indexOf(id)
if (idx >= 0) this.selectedInspectionIds.splice(idx, 1)
else this.selectedInspectionIds.push(id)
const idx = this.selectedInspectionIds.indexOf(id);
if (idx >= 0) this.selectedInspectionIds.splice(idx, 1);
else this.selectedInspectionIds.push(id);
},
addProject() {
if (!this.tempProject.name) return this.$message.warning('请输入项目名称')
this.projectItems.push({ ...this.tempProject })
this.tempProject = { name: '', price: 0 }
this.projectPickerVisible = false
if (!this.tempProject.name)
return this.$message.warning("请输入项目名称");
this.projectItems.push({ ...this.tempProject });
this.tempProject = { name: "", price: 0 };
this.projectPickerVisible = false;
},
removeProject(index) {
this.projectItems.splice(index, 1)
this.projectItems.splice(index, 1);
},
addMaterial() {
if (!this.tempMaterial.name) return this.$message.warning('请输入物料名称')
this.materialItems.push({ ...this.tempMaterial })
this.tempMaterial = { name: '', price: 0, quantity: 1 }
this.materialPickerVisible = false
if (!this.tempMaterial.name)
return this.$message.warning("请输入物料名称");
this.materialItems.push({ ...this.tempMaterial });
this.tempMaterial = { name: "", price: 0, quantity: 1 };
this.materialPickerVisible = false;
},
removeMaterial(index) {
this.materialItems.splice(index, 1)
this.materialItems.splice(index, 1);
},
handleGenerate() {
async handleGenerate() {
const payload = {
orderId: this.orderId,
inspections: this.selectedInspectionIds,
projects: this.projectItems,
materials: this.materialItems,
payType: this.payType,
discount: { ...this.discount },
amount: this.grandTotal
}
this.$emit('submit', payload)
this.visibleInner = false
this.$emit('update:visible', false)
id: this.orderId,
basic: this.form.basic.filter((r) => r.select), //
craft: this.form.craft, //
material: this.form.material, //
price: this.payType == "stage" ? this.form.price : undefined, //
reduction: this.form.reduction, //
reamk: this.form.reamk,
};
await Orderworkerestimate(payload)
this.$message.success('报价已生成')
this.$emit("submit", payload);
this.visibleInner = false;
this.$emit("update:visible", false);
},
handleClose() {
this.visibleInner = false
this.$emit('update:visible', false)
}
}
}
this.visibleInner = false;
this.$emit("update:visible", false);
},
},
};
</script>
<style lang="scss" scoped>
.wullistbox,
.wulist {
max-height: 600px;
overflow: auto;
.li {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid #eee;
border-radius: 10px;
margin: 15px 0;
padding: 15px;
span {
color: red;
}
}
}
.wulist {
.left {
display: flex;
align-items: center;
img {
width: 50px;
height: 50px;
margin-right: 15px;
}
}
p {
margin: 0px 0px 15px 0;
}
}
.quote-wrapper {
.group { margin-bottom: 16px; }
.group-title { font-weight: 600; color: #2c3e50; margin-bottom: 4px; }
.group-sub { font-size: 12px; color: #909399; margin-bottom: 8px; }
.group {
margin-bottom: 16px;
}
.group-title {
font-weight: 600;
color: #2c3e50;
margin-bottom: 4px;
}
.group-sub {
font-size: 12px;
color: #909399;
margin-bottom: 8px;
}
.chip-list {
display: flex; flex-wrap: wrap; gap: 8px;
.chip { min-width: 84px; }
display: flex;
flex-wrap: wrap;
gap: 8px;
.chip {
min-width: 84px;
}
}
.slot-card {
background: #f7fbff;
.slot-row { padding: 6px 0; }
.list { margin-top: 8px; }
.slot-row {
padding: 6px 0;
text-align: center;
}
.list {
margin-top: 8px;
}
.list-item {
display: flex; align-items: center; justify-content: space-between;
padding: 6px 0; border-bottom: 1px dashed #ebeef5;
.name { color: #303133; }
.qty { color: #606266; margin: 0 6px; }
.price { color: #409EFF; font-weight: 600; }
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 0;
border-bottom: 1px dashed #ebeef5;
.name {
color: #303133;
width: 200px;
}
.qty {
color: #606266;
margin: 0 6px;
}
.price {
color: #409eff;
font-weight: 600;
}
}
}
.pay-row { display: flex; align-items: center; gap: 12px; }
.discount-box { background: #f8f9fb; border: 1px solid #ebeef5; padding: 10px; border-radius: 6px; }
.footer { display: flex; justify-content: center; margin-top: 12px; }
.btn-generate { width: 100%; }
.pay-row {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 15px;
}
.discount-box {
background: #f8f9fb;
border: 1px solid #ebeef5;
padding: 20px 10px;
border-radius: 6px;
}
.footer {
display: flex;
justify-content: center;
margin-top: 12px;
}
.btn-generate {
width: 100%;
}
}
</style>

View File

@ -5346,7 +5346,7 @@ export default {
try {
//
// await request.post('/system/Order/project-quote', payload)
this.$message.success('报价已生成(待接入接口)')
//
this.refreshOrderDetail()
this.getList()
@ -5383,6 +5383,7 @@ export default {
cancelReason: row.cancelReason,
mark: row.mark,
fileData: row.fileData,
productId:row.productId,
servicePhotos: row.servicePhotos || [],
//
userName: row.uname || row.name,