2025008071805
This commit is contained in:
parent
cf3eb835b4
commit
263c5869c8
|
|
@ -0,0 +1,156 @@
|
||||||
|
# ISTOPAYSIZE方法修改说明
|
||||||
|
|
||||||
|
## 方法概述
|
||||||
|
|
||||||
|
`ISTOPAYSIZE`方法是用户付款后回调中修改订单状态的辅助方法,用于判断订单是否可以标记为已完成状态。
|
||||||
|
|
||||||
|
## 修改后的核心逻辑
|
||||||
|
|
||||||
|
### 1. 查询剩余可付款数量
|
||||||
|
```java
|
||||||
|
int paynum = usersPayBeforService.countByLastOrderIdAndStatus(orderid);
|
||||||
|
```
|
||||||
|
- 查询该订单还有多少可付款的数据
|
||||||
|
- `paynum = 0` 表示没有剩余可付款的数据
|
||||||
|
|
||||||
|
### 2. 查询订单最新日志状态
|
||||||
|
```java
|
||||||
|
OrderLog orderLog = orderLogService.selectDataTheFirstNew(order.getId());
|
||||||
|
BigDecimal latestLogType = orderLog.getType();
|
||||||
|
boolean isWorkerCompleted = latestLogType != null && latestLogType.compareTo(new BigDecimal("6")) >= 0;
|
||||||
|
```
|
||||||
|
- 获取订单最新的日志记录
|
||||||
|
- 判断师傅是否已完成工作(日志类型 >= 6)
|
||||||
|
|
||||||
|
### 3. 完成条件判断
|
||||||
|
```java
|
||||||
|
if (paynum <= 0 && isWorkerCompleted) {
|
||||||
|
// 修改订单为已完成状态
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**完成条件**:
|
||||||
|
- `paynum <= 0`:没有剩余可付款的数据
|
||||||
|
- `isWorkerCompleted`:师傅已完成工作(日志类型 >= 6)
|
||||||
|
|
||||||
|
## 订单状态更新
|
||||||
|
|
||||||
|
### 满足完成条件时
|
||||||
|
```java
|
||||||
|
order.setStatus(4L); // 4:已完成
|
||||||
|
order.setReceiveType(3L); // 3:完成类型
|
||||||
|
order.setJsonStatus(9); // 9:已完成
|
||||||
|
order.setLogJson("{\"type\":8}"); // 8:完成状态
|
||||||
|
```
|
||||||
|
|
||||||
|
### 不满足完成条件时
|
||||||
|
```java
|
||||||
|
if (paynum > 0 && isWorkerCompleted) {
|
||||||
|
order.setStatus(6L); // 6:待付款
|
||||||
|
order.setJsonStatus(9); // 9:已完成
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 业务处理
|
||||||
|
|
||||||
|
### 1. 师傅佣金处理
|
||||||
|
```java
|
||||||
|
if (order.getWorkerId() != null) {
|
||||||
|
Users worker = usersService.selectUsersById(order.getWorkerId());
|
||||||
|
if (worker != null) {
|
||||||
|
WorkerCommissionUtil.processWorkerCommission(order, worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 用户通知处理(可选)
|
||||||
|
```java
|
||||||
|
if (order.getUid() != null) {
|
||||||
|
Users user = usersService.selectUsersById(order.getUid());
|
||||||
|
if (user != null) {
|
||||||
|
// 可以添加微信通知等逻辑
|
||||||
|
// WXsendMsgUtil.sendWorkerFinishOrder(user.getOpenid(), order, serviceGoods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 日志类型说明
|
||||||
|
|
||||||
|
| 日志类型 | 说明 |
|
||||||
|
|----------|------|
|
||||||
|
| 1 | 生成订单 |
|
||||||
|
| 2 | 接单 |
|
||||||
|
| 3 | 上门 |
|
||||||
|
| 4 | 到达 |
|
||||||
|
| 5 | 评估报价 |
|
||||||
|
| 6 | 服务(开始服务) |
|
||||||
|
| 7 | 服务完成 |
|
||||||
|
| 8 | 评价 |
|
||||||
|
| 9 | 取消 |
|
||||||
|
|
||||||
|
## 订单状态说明
|
||||||
|
|
||||||
|
| 状态值 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 1 | 待接单 |
|
||||||
|
| 2 | 待服务 |
|
||||||
|
| 3 | 服务中 |
|
||||||
|
| 4 | 已完成 |
|
||||||
|
| 5 | 已取消 |
|
||||||
|
| 6 | 待付款 |
|
||||||
|
| 7 | 未服务提前结束 |
|
||||||
|
|
||||||
|
## 使用场景
|
||||||
|
|
||||||
|
### 场景1:正常完成流程
|
||||||
|
1. 用户下单
|
||||||
|
2. 师傅接单
|
||||||
|
3. 师傅上门服务
|
||||||
|
4. 师傅完成服务(日志类型 >= 6)
|
||||||
|
5. 用户付款完成(paynum = 0)
|
||||||
|
6. 订单状态自动更新为已完成
|
||||||
|
|
||||||
|
### 场景2:分阶段付款
|
||||||
|
1. 用户支付定金
|
||||||
|
2. 师傅完成服务(日志类型 >= 6)
|
||||||
|
3. 用户支付尾款(paynum = 0)
|
||||||
|
4. 订单状态更新为已完成
|
||||||
|
|
||||||
|
### 场景3:师傅完成但用户未付款
|
||||||
|
1. 师傅完成服务(日志类型 >= 6)
|
||||||
|
2. 用户还有未付款项(paynum > 0)
|
||||||
|
3. 订单状态更新为待付款
|
||||||
|
|
||||||
|
## 异常处理
|
||||||
|
|
||||||
|
```java
|
||||||
|
try {
|
||||||
|
// 业务逻辑
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("ISTOPAYSIZE方法执行异常,orderid: " + orderid + ", 错误: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 返回值
|
||||||
|
|
||||||
|
- **返回值**:剩余可付款数量(int)
|
||||||
|
- **异常情况**:返回0
|
||||||
|
|
||||||
|
## 调用示例
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 在用户付款回调中使用
|
||||||
|
public void handlePaymentCallback(String orderId) {
|
||||||
|
int remainingPayments = OrderUtil.ISTOPAYSIZE(orderId);
|
||||||
|
System.out.println("订单 " + orderId + " 剩余付款数量: " + remainingPayments);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **数据完整性**:确保订单和日志数据存在
|
||||||
|
2. **状态一致性**:确保订单状态和日志状态的一致性
|
||||||
|
3. **并发处理**:考虑多线程环境下的数据一致性
|
||||||
|
4. **异常恢复**:提供完善的异常处理机制
|
||||||
|
5. **日志记录**:详细记录处理过程,便于问题排查
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
# PayBeforeUtil 整合 BenefitPointsUtil 示例
|
||||||
|
|
||||||
|
## 整合说明
|
||||||
|
|
||||||
|
本文档展示如何在 `PayBeforeUtil.createPayBefore` 方法中整合 `BenefitPointsUtil` 的抵扣计算功能,简化原有的复杂逻辑。
|
||||||
|
|
||||||
|
## 原有代码分析
|
||||||
|
|
||||||
|
### 原有 PayBeforeUtil.createPayBefore 中的抵扣逻辑
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 原有代码片段
|
||||||
|
try {
|
||||||
|
SiteConfig configQuery = new SiteConfig();
|
||||||
|
configQuery.setName("config_one");
|
||||||
|
List<SiteConfig> configList = siteConfigService.selectSiteConfigList(configQuery);
|
||||||
|
if (configList != null && !configList.isEmpty()) {
|
||||||
|
String configValue = configList.get(0).getValue();
|
||||||
|
if (configValue != null && !configValue.trim().isEmpty()) {
|
||||||
|
com.alibaba.fastjson2.JSONObject configJson = com.alibaba.fastjson2.JSONObject.parseObject(configValue);
|
||||||
|
|
||||||
|
// 服务金抵扣
|
||||||
|
if (servicetype != null && servicetype == 1) {
|
||||||
|
Integer serviceFee = configJson.getInteger("servicefee");
|
||||||
|
if (serviceFee != null && serviceFee > 0) {
|
||||||
|
Users userDb = usersService.selectUsersById(user.getId());
|
||||||
|
if (userDb != null && userDb.getServicefee() != null && userDb.getServicefee().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
BigDecimal serviceRate = BigDecimal.valueOf(serviceFee).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP);
|
||||||
|
serviceMoney = userDb.getServicefee().multiply(serviceRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 购物金抵扣
|
||||||
|
if (servicetype != null && servicetype == 2) {
|
||||||
|
Integer consumption = configJson.getInteger("consumption");
|
||||||
|
if (consumption != null && consumption > 0) {
|
||||||
|
Users userDb = usersService.selectUsersById(user.getId());
|
||||||
|
if (userDb != null && userDb.getConsumption() != null && userDb.getConsumption().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
BigDecimal consumptionRate = BigDecimal.valueOf(consumption).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP);
|
||||||
|
shopMoney = userDb.getConsumption().multiply(consumptionRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 异常处理
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 整合后的代码
|
||||||
|
|
||||||
|
### 使用 BenefitPointsUtil 简化后的代码
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 整合后的代码
|
||||||
|
try {
|
||||||
|
// 使用 BenefitPointsUtil 进行抵扣计算
|
||||||
|
BenefitPointsUtil.BenefitDeductionResult deductionResult =
|
||||||
|
BenefitPointsUtil.getBenefitDeduction(user, amount, servicetype);
|
||||||
|
|
||||||
|
if (deductionResult.isSuccess()) {
|
||||||
|
serviceMoney = deductionResult.getServiceMoney(); // 服务金抵扣金额
|
||||||
|
shopMoney = deductionResult.getShopMoney(); // 消费金抵扣金额
|
||||||
|
BigDecimal finalAmount = deductionResult.getFinalAmount(); // 最终支付金额
|
||||||
|
|
||||||
|
log.info("【抵扣计算】用户ID: {}, 原金额: {}, 服务金抵扣: {}, 消费金抵扣: {}, 最终金额: {}",
|
||||||
|
user.getId(), amount, serviceMoney, shopMoney, finalAmount);
|
||||||
|
} else {
|
||||||
|
log.warn("【抵扣计算失败】用户ID: {}, 错误: {}", user.getId(), deductionResult.getMessage());
|
||||||
|
serviceMoney = BigDecimal.ZERO;
|
||||||
|
shopMoney = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("【抵扣计算异常】用户ID: {}, 异常: {}", user.getId(), e.getMessage(), e);
|
||||||
|
serviceMoney = BigDecimal.ZERO;
|
||||||
|
shopMoney = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 完整的 PayBeforeUtil 整合示例
|
||||||
|
|
||||||
|
```java
|
||||||
|
package com.ruoyi.system.ControllerUtil;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import com.ruoyi.system.domain.SiteConfig;
|
||||||
|
import com.ruoyi.system.domain.Users;
|
||||||
|
import com.ruoyi.system.domain.UsersPayBefor;
|
||||||
|
import com.ruoyi.system.service.IUsersPayBeforService;
|
||||||
|
import com.ruoyi.system.service.ISiteConfigService;
|
||||||
|
import com.ruoyi.system.service.IUsersService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.system.domain.OrderLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预支付工具类(整合版本)
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-07-17
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class PayBeforeUtil {
|
||||||
|
|
||||||
|
private static final IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class);
|
||||||
|
private static final ISiteConfigService siteConfigService = SpringUtils.getBean(ISiteConfigService.class);
|
||||||
|
private static final IUsersService usersService = SpringUtils.getBean(IUsersService.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预支付记录(整合版本)
|
||||||
|
*
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param amount 支付金额
|
||||||
|
* @param orderId 订单号
|
||||||
|
* @param oid 订单ID
|
||||||
|
* @param serviceId 服务ID
|
||||||
|
* @param orderType 订单类型
|
||||||
|
* @param sku SKU规格信息
|
||||||
|
* @param grouporderid 拼团订单ID
|
||||||
|
* @param addressid 地址ID
|
||||||
|
* @param maketime 预约时间
|
||||||
|
* @param attachments 附件信息
|
||||||
|
* @param servicetype 服务类型:1=服务金抵扣,2=消费金抵扣
|
||||||
|
* @param baojiaid 报价ID
|
||||||
|
* @param lastorderid 上一个订单ID
|
||||||
|
* @return 预支付记录ID,失败返回null
|
||||||
|
*/
|
||||||
|
public String createPayBefore(Users user, BigDecimal amount, String orderId, Long oid,
|
||||||
|
Long serviceId, Long orderType, String sku, String grouporderid,
|
||||||
|
Long addressid, String maketime, String attachments, Long servicetype,
|
||||||
|
Long baojiaid, String lastorderid) {
|
||||||
|
try {
|
||||||
|
// 计算会员优惠和服务金抵扣
|
||||||
|
BigDecimal memberMoney = BigDecimal.ZERO;
|
||||||
|
BigDecimal serviceMoney = BigDecimal.ZERO;
|
||||||
|
BigDecimal shopMoney = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
// 使用 BenefitPointsUtil 进行抵扣计算
|
||||||
|
try {
|
||||||
|
BenefitPointsUtil.BenefitDeductionResult deductionResult =
|
||||||
|
BenefitPointsUtil.getBenefitDeduction(user, amount, servicetype);
|
||||||
|
|
||||||
|
if (deductionResult.isSuccess()) {
|
||||||
|
serviceMoney = deductionResult.getServiceMoney(); // 服务金抵扣金额
|
||||||
|
shopMoney = deductionResult.getShopMoney(); // 消费金抵扣金额
|
||||||
|
|
||||||
|
System.out.println("【抵扣计算成功】用户ID: " + user.getId() +
|
||||||
|
", 服务金抵扣: " + serviceMoney +
|
||||||
|
", 消费金抵扣: " + shopMoney);
|
||||||
|
} else {
|
||||||
|
System.out.println("【抵扣计算失败】用户ID: " + user.getId() +
|
||||||
|
", 错误: " + deductionResult.getMessage());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("【抵扣计算异常】用户ID: " + user.getId() + ", 异常: " + e.getMessage());
|
||||||
|
serviceMoney = BigDecimal.ZERO;
|
||||||
|
shopMoney = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会员优惠计算(保持原有逻辑)
|
||||||
|
try {
|
||||||
|
SiteConfig configQuery = new SiteConfig();
|
||||||
|
configQuery.setName("config_one");
|
||||||
|
List<SiteConfig> configList = siteConfigService.selectSiteConfigList(configQuery);
|
||||||
|
if (configList != null && !configList.isEmpty()) {
|
||||||
|
String configValue = configList.get(0).getValue();
|
||||||
|
if (configValue != null && !configValue.trim().isEmpty()) {
|
||||||
|
JSONObject configJson = JSONObject.parseObject(configValue);
|
||||||
|
|
||||||
|
// 会员优惠
|
||||||
|
if (user.getIsmember() != null && user.getIsmember() == 1) {
|
||||||
|
Integer memberDiscount = configJson.getInteger("member_discount");
|
||||||
|
if (memberDiscount != null && memberDiscount > 0) {
|
||||||
|
BigDecimal discountRate = BigDecimal.valueOf(memberDiscount)
|
||||||
|
.divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP);
|
||||||
|
memberMoney = amount.multiply(discountRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
memberMoney = BigDecimal.ZERO;
|
||||||
|
System.out.println("【会员优惠计算异常】用户ID: " + user.getId() + ", 异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算最终支付金额
|
||||||
|
BigDecimal finalAmount = amount.subtract(memberMoney).subtract(serviceMoney).subtract(shopMoney);
|
||||||
|
if (finalAmount.compareTo(BigDecimal.ZERO) < 0) {
|
||||||
|
finalAmount = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("【最终计算】用户ID: " + user.getId() +
|
||||||
|
", 原金额: " + amount +
|
||||||
|
", 会员优惠: " + memberMoney +
|
||||||
|
", 服务金抵扣: " + serviceMoney +
|
||||||
|
", 消费金抵扣: " + shopMoney +
|
||||||
|
", 最终金额: " + finalAmount);
|
||||||
|
|
||||||
|
// 创建预支付记录
|
||||||
|
UsersPayBefor payBefore = new UsersPayBefor();
|
||||||
|
payBefore.setUid(user.getId());
|
||||||
|
payBefore.setAmount(finalAmount);
|
||||||
|
payBefore.setOrderId(orderId);
|
||||||
|
payBefore.setOid(oid);
|
||||||
|
payBefore.setServiceId(serviceId);
|
||||||
|
payBefore.setOrderType(orderType);
|
||||||
|
payBefore.setSku(sku);
|
||||||
|
payBefore.setGrouporderid(grouporderid);
|
||||||
|
payBefore.setAddressid(addressid);
|
||||||
|
payBefore.setMaketime(maketime);
|
||||||
|
payBefore.setAttachments(attachments);
|
||||||
|
payBefore.setServicetype(servicetype);
|
||||||
|
payBefore.setBaojiaid(baojiaid);
|
||||||
|
payBefore.setLastorderid(lastorderid);
|
||||||
|
payBefore.setStatus(1L); // 待支付状态
|
||||||
|
payBefore.setCreatedAt(new Date());
|
||||||
|
payBefore.setUpdatedAt(new Date());
|
||||||
|
|
||||||
|
int insertResult = usersPayBeforService.insertUsersPayBefor(payBefore);
|
||||||
|
if (insertResult > 0) {
|
||||||
|
System.out.println("【预支付创建成功】用户ID: " + user.getId() + ", 预支付ID: " + payBefore.getId());
|
||||||
|
return payBefore.getId().toString();
|
||||||
|
} else {
|
||||||
|
System.out.println("【预支付创建失败】用户ID: " + user.getId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("【预支付创建异常】用户ID: " + user.getId() + ", 异常: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他方法保持不变...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 整合优势
|
||||||
|
|
||||||
|
### 1. 代码简化
|
||||||
|
- **原有代码**:约 50 行复杂的配置解析和抵扣计算逻辑
|
||||||
|
- **整合后代码**:约 10 行简洁的调用逻辑
|
||||||
|
|
||||||
|
### 2. 功能增强
|
||||||
|
- **统一配置管理**:所有抵扣相关配置统一在 `BenefitPointsUtil` 中处理
|
||||||
|
- **错误处理完善**:提供详细的错误信息和日志记录
|
||||||
|
- **类型安全**:使用 `BigDecimal` 确保金额计算精度
|
||||||
|
|
||||||
|
### 3. 维护性提升
|
||||||
|
- **逻辑集中**:抵扣计算逻辑集中在 `BenefitPointsUtil` 中
|
||||||
|
- **易于测试**:提供专门的测试接口
|
||||||
|
- **易于扩展**:可以轻松添加新的抵扣类型
|
||||||
|
|
||||||
|
### 4. 性能优化
|
||||||
|
- **减少重复查询**:避免重复查询用户信息和配置信息
|
||||||
|
- **缓存友好**:为后续添加配置缓存奠定基础
|
||||||
|
|
||||||
|
## 使用建议
|
||||||
|
|
||||||
|
1. **逐步迁移**:建议先在测试环境中验证整合效果
|
||||||
|
2. **保留原有逻辑**:在完全验证前,可以保留原有逻辑作为备选
|
||||||
|
3. **监控日志**:密切关注抵扣计算的日志输出
|
||||||
|
4. **性能监控**:对比整合前后的性能表现
|
||||||
|
|
||||||
|
## 测试验证
|
||||||
|
|
||||||
|
可以使用以下测试接口验证整合效果:
|
||||||
|
|
||||||
|
```http
|
||||||
|
# 测试抵扣计算
|
||||||
|
POST /system/benefit/test/deduction
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
userId=123&amount=100.00&serviceType=1
|
||||||
|
|
||||||
|
# 测试余额查询
|
||||||
|
GET /system/benefit/test/balance/123
|
||||||
|
```
|
||||||
|
|
||||||
|
通过这种整合方式,可以大大简化 `PayBeforeUtil` 中的抵扣计算逻辑,提高代码的可维护性和可读性。
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
package com.ruoyi.system.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单配置类
|
||||||
|
* 用于管理派单系统的各种参数和权重
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "dispatch")
|
||||||
|
public class DispatchConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 距离权重
|
||||||
|
*/
|
||||||
|
private double weightDistance = 0.25;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 技能匹配权重
|
||||||
|
*/
|
||||||
|
private double weightSkillMatch = 0.20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经验权重
|
||||||
|
*/
|
||||||
|
private double weightExperience = 0.15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评分权重
|
||||||
|
*/
|
||||||
|
private double weightRating = 0.15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可用性权重
|
||||||
|
*/
|
||||||
|
private double weightAvailability = 0.15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新师傅奖励权重
|
||||||
|
*/
|
||||||
|
private double weightNewWorkerBonus = 0.10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大距离(公里)
|
||||||
|
*/
|
||||||
|
private double maxDistance = 50.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首选距离(公里)
|
||||||
|
*/
|
||||||
|
private double preferredDistance = 20.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新师傅订单数量阈值
|
||||||
|
*/
|
||||||
|
private int newWorkerOrderThreshold = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用新师傅奖励
|
||||||
|
*/
|
||||||
|
private boolean enableNewWorkerBonus = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用距离限制
|
||||||
|
*/
|
||||||
|
private boolean enableDistanceLimit = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用技能匹配
|
||||||
|
*/
|
||||||
|
private boolean enableSkillMatch = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用经验评分
|
||||||
|
*/
|
||||||
|
private boolean enableExperienceScore = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用评分系统
|
||||||
|
*/
|
||||||
|
private boolean enableRatingScore = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用可用性评分
|
||||||
|
*/
|
||||||
|
private boolean enableAvailabilityScore = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动派单超时时间(秒)
|
||||||
|
*/
|
||||||
|
private int autoDispatchTimeout = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大重试次数
|
||||||
|
*/
|
||||||
|
private int maxRetryCount = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用日志记录
|
||||||
|
*/
|
||||||
|
private boolean enableLogging = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用性能监控
|
||||||
|
*/
|
||||||
|
private boolean enablePerformanceMonitoring = true;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public double getWeightDistance() {
|
||||||
|
return weightDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightDistance(double weightDistance) {
|
||||||
|
this.weightDistance = weightDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWeightSkillMatch() {
|
||||||
|
return weightSkillMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightSkillMatch(double weightSkillMatch) {
|
||||||
|
this.weightSkillMatch = weightSkillMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWeightExperience() {
|
||||||
|
return weightExperience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightExperience(double weightExperience) {
|
||||||
|
this.weightExperience = weightExperience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWeightRating() {
|
||||||
|
return weightRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightRating(double weightRating) {
|
||||||
|
this.weightRating = weightRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWeightAvailability() {
|
||||||
|
return weightAvailability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightAvailability(double weightAvailability) {
|
||||||
|
this.weightAvailability = weightAvailability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWeightNewWorkerBonus() {
|
||||||
|
return weightNewWorkerBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightNewWorkerBonus(double weightNewWorkerBonus) {
|
||||||
|
this.weightNewWorkerBonus = weightNewWorkerBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxDistance() {
|
||||||
|
return maxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxDistance(double maxDistance) {
|
||||||
|
this.maxDistance = maxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPreferredDistance() {
|
||||||
|
return preferredDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreferredDistance(double preferredDistance) {
|
||||||
|
this.preferredDistance = preferredDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNewWorkerOrderThreshold() {
|
||||||
|
return newWorkerOrderThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewWorkerOrderThreshold(int newWorkerOrderThreshold) {
|
||||||
|
this.newWorkerOrderThreshold = newWorkerOrderThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableNewWorkerBonus() {
|
||||||
|
return enableNewWorkerBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableNewWorkerBonus(boolean enableNewWorkerBonus) {
|
||||||
|
this.enableNewWorkerBonus = enableNewWorkerBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableDistanceLimit() {
|
||||||
|
return enableDistanceLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableDistanceLimit(boolean enableDistanceLimit) {
|
||||||
|
this.enableDistanceLimit = enableDistanceLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableSkillMatch() {
|
||||||
|
return enableSkillMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableSkillMatch(boolean enableSkillMatch) {
|
||||||
|
this.enableSkillMatch = enableSkillMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableExperienceScore() {
|
||||||
|
return enableExperienceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableExperienceScore(boolean enableExperienceScore) {
|
||||||
|
this.enableExperienceScore = enableExperienceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableRatingScore() {
|
||||||
|
return enableRatingScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableRatingScore(boolean enableRatingScore) {
|
||||||
|
this.enableRatingScore = enableRatingScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableAvailabilityScore() {
|
||||||
|
return enableAvailabilityScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableAvailabilityScore(boolean enableAvailabilityScore) {
|
||||||
|
this.enableAvailabilityScore = enableAvailabilityScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAutoDispatchTimeout() {
|
||||||
|
return autoDispatchTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoDispatchTimeout(int autoDispatchTimeout) {
|
||||||
|
this.autoDispatchTimeout = autoDispatchTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxRetryCount() {
|
||||||
|
return maxRetryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxRetryCount(int maxRetryCount) {
|
||||||
|
this.maxRetryCount = maxRetryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnableLogging() {
|
||||||
|
return enableLogging;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableLogging(boolean enableLogging) {
|
||||||
|
this.enableLogging = enableLogging;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnablePerformanceMonitoring() {
|
||||||
|
return enablePerformanceMonitoring;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnablePerformanceMonitoring(boolean enablePerformanceMonitoring) {
|
||||||
|
this.enablePerformanceMonitoring = enablePerformanceMonitoring;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证权重配置是否有效
|
||||||
|
*/
|
||||||
|
public boolean validateWeights() {
|
||||||
|
double totalWeight = weightDistance + weightSkillMatch + weightExperience +
|
||||||
|
weightRating + weightAvailability + weightNewWorkerBonus;
|
||||||
|
return Math.abs(totalWeight - 1.0) < 0.001;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取配置摘要
|
||||||
|
*/
|
||||||
|
public String getConfigSummary() {
|
||||||
|
return String.format(
|
||||||
|
"DispatchConfig{weightDistance=%.2f, weightSkillMatch=%.2f, weightExperience=%.2f, " +
|
||||||
|
"weightRating=%.2f, weightAvailability=%.2f, weightNewWorkerBonus=%.2f, " +
|
||||||
|
"maxDistance=%.1f, preferredDistance=%.1f, newWorkerOrderThreshold=%d}",
|
||||||
|
weightDistance, weightSkillMatch, weightExperience, weightRating,
|
||||||
|
weightAvailability, weightNewWorkerBonus, maxDistance, preferredDistance, newWorkerOrderThreshold
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1158,6 +1158,8 @@ public class ApplePayController extends BaseController {
|
||||||
return AppletControllerUtil.appletWarning("该订单已支付或已失效");
|
return AppletControllerUtil.appletWarning("该订单已支付或已失效");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 4. 获取支付方式和金额
|
// 4. 获取支付方式和金额
|
||||||
Integer paytype = payBefor.getPaytype() != null ? payBefor.getPaytype().intValue() : 1;
|
Integer paytype = payBefor.getPaytype() != null ? payBefor.getPaytype().intValue() : 1;
|
||||||
BigDecimal wxMoney = payBefor.getWxmoney() != null ? payBefor.getWxmoney() : BigDecimal.ZERO;
|
BigDecimal wxMoney = payBefor.getWxmoney() != null ? payBefor.getWxmoney() : BigDecimal.ZERO;
|
||||||
|
|
@ -1173,6 +1175,9 @@ public class ApplePayController extends BaseController {
|
||||||
payBefor.setStatus(2L); // 已支付
|
payBefor.setStatus(2L); // 已支付
|
||||||
payBefor.setPaytime(new Date());
|
payBefor.setPaytime(new Date());
|
||||||
usersPayBeforService.updateUsersPayBefor(payBefor);
|
usersPayBeforService.updateUsersPayBefor(payBefor);
|
||||||
|
//扣减消费金服务金
|
||||||
|
BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
|
||||||
|
//回调方法用来处理订单相关数据
|
||||||
OrderUtil.prepayCallback(payBefor, user);
|
OrderUtil.prepayCallback(payBefor, user);
|
||||||
payResult.put("istowx", 1);
|
payResult.put("istowx", 1);
|
||||||
return AppletControllerUtil.appletSuccess("支付成功");
|
return AppletControllerUtil.appletSuccess("支付成功");
|
||||||
|
|
@ -1198,8 +1203,12 @@ public class ApplePayController extends BaseController {
|
||||||
payBefor.setStatus(2L); // 已支付
|
payBefor.setStatus(2L); // 已支付
|
||||||
payBefor.setPaytime(new Date());
|
payBefor.setPaytime(new Date());
|
||||||
usersPayBeforService.updateUsersPayBefor(payBefor);
|
usersPayBeforService.updateUsersPayBefor(payBefor);
|
||||||
|
//扣减消费金服务金
|
||||||
|
BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
|
||||||
|
//回调方法用来处理订单相关数据
|
||||||
OrderUtil.prepayCallback(payBefor, user);
|
OrderUtil.prepayCallback(payBefor, user);
|
||||||
IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
|
||||||
|
//IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
||||||
payResult.put("istowx", 2);
|
payResult.put("istowx", 2);
|
||||||
return AppletControllerUtil.appletSuccess("支付成功");
|
return AppletControllerUtil.appletSuccess("支付成功");
|
||||||
}
|
}
|
||||||
|
|
@ -1215,8 +1224,10 @@ public class ApplePayController extends BaseController {
|
||||||
payBefor.setPaytime(new Date());
|
payBefor.setPaytime(new Date());
|
||||||
usersPayBeforService.updateUsersPayBefor(payBefor);
|
usersPayBeforService.updateUsersPayBefor(payBefor);
|
||||||
OrderUtil.prepayCallback(payBefor, user);
|
OrderUtil.prepayCallback(payBefor, user);
|
||||||
IntegralAndBenefitUtil.processIntegralAndBenefit(payBefor.getAllmoney(), payBefor.getOrderid(), user.getId(), payBefor.getId());
|
//扣减消费金服务金
|
||||||
IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
|
||||||
|
//IntegralAndBenefitUtil.processIntegralAndBenefit(payBefor.getAllmoney(), payBefor.getOrderid(), user.getId(), payBefor.getId());
|
||||||
|
// IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
||||||
payResult.put("istowx", 2);
|
payResult.put("istowx", 2);
|
||||||
return AppletControllerUtil.appletSuccess(payResult);
|
return AppletControllerUtil.appletSuccess(payResult);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1231,24 +1242,14 @@ public class ApplePayController extends BaseController {
|
||||||
payBefor.setPaytime(new Date());
|
payBefor.setPaytime(new Date());
|
||||||
usersPayBeforService.updateUsersPayBefor(payBefor);
|
usersPayBeforService.updateUsersPayBefor(payBefor);
|
||||||
OrderUtil.prepayCallback(payBefor, user);
|
OrderUtil.prepayCallback(payBefor, user);
|
||||||
IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
//扣减消费金服务金
|
||||||
|
BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
|
||||||
|
// IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
||||||
payResult.put("istowx", 1);
|
payResult.put("istowx", 1);
|
||||||
return AppletControllerUtil.appletSuccess("支付成功");
|
return AppletControllerUtil.appletSuccess("支付成功");
|
||||||
}
|
}
|
||||||
if (wxMoney.compareTo(BigDecimal.ZERO) > 0 && yeMoney.compareTo(BigDecimal.ZERO) > 0) {
|
if (wxMoney.compareTo(BigDecimal.ZERO) > 0 && yeMoney.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
// // 先扣余额
|
//先微信支付,微信支付成功之后再回调中把剩余的进行余额支付
|
||||||
// Map<String, Object> balanceResult = BalancePayUtil.processBalancePayment(
|
|
||||||
// user.getId(),
|
|
||||||
// yeMoney,
|
|
||||||
// "订单组合支付-余额部分"+payBefor.getYemoney()+"元",
|
|
||||||
// payBefor.getOrderid()
|
|
||||||
// );
|
|
||||||
// if (balanceResult == null || !Boolean.TRUE.equals(balanceResult.get("success"))) {
|
|
||||||
// String errorMsg = balanceResult != null ? (String) balanceResult.get("message") : "余额支付失败";
|
|
||||||
// return AppletControllerUtil.appletWarning(errorMsg);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 再微信支付
|
|
||||||
payResult = wechatPayUtil.createBatchOrderAndPay(
|
payResult = wechatPayUtil.createBatchOrderAndPay(
|
||||||
user.getOpenid(),
|
user.getOpenid(),
|
||||||
payBefor.getPaycode(),
|
payBefor.getPaycode(),
|
||||||
|
|
@ -1275,8 +1276,10 @@ public class ApplePayController extends BaseController {
|
||||||
payBefor.setStatus(2L); // 已支付
|
payBefor.setStatus(2L); // 已支付
|
||||||
usersPayBeforService.updateUsersPayBefor(payBefor);
|
usersPayBeforService.updateUsersPayBefor(payBefor);
|
||||||
OrderUtil.prepayCallback(payBefor, user);
|
OrderUtil.prepayCallback(payBefor, user);
|
||||||
IntegralAndBenefitUtil.processIntegralAndBenefit(payBefor.getAllmoney(), payBefor.getOrderid(), user.getId(), payBefor.getId());
|
//扣减消费金服务金
|
||||||
IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
BenefitPointsUtil.deductServiceAndConsumption(payBefor.getOid(), user, payBefor.getServicemoney(), payBefor.getShopmoney());
|
||||||
|
// IntegralAndBenefitUtil.processIntegralAndBenefit(payBefor.getAllmoney(), payBefor.getOrderid(), user.getId(), payBefor.getId());
|
||||||
|
// IntegralAndBenefitUtil.paymentPostProcess(payBefor, user.getId());
|
||||||
payResult.put("istowx", 2);
|
payResult.put("istowx", 2);
|
||||||
return AppletControllerUtil.appletSuccess("余额支付成功");
|
return AppletControllerUtil.appletSuccess("余额支付成功");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1514,8 +1517,8 @@ public class ApplePayController extends BaseController {
|
||||||
return AppletControllerUtil.appletWarning("该次卡已申请退款,请勿重复操作");
|
return AppletControllerUtil.appletWarning("该次卡已申请退款,请勿重复操作");
|
||||||
}
|
}
|
||||||
// 7. 调用微信退款接口
|
// 7. 调用微信退款接口
|
||||||
Map<String, Object> refundResult = wechatPayV3Util.refund(useCard.getOrderid(),
|
Map<String, Object> refundResult = wechatPayV3Util.refund(String.valueOf(useCard.getId()),
|
||||||
"cika000001",
|
useCard.getOrderid(),
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
"次卡退款",
|
"次卡退款",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,290 @@
|
||||||
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.system.ControllerUtil.BenefitPointsUtil;
|
||||||
|
import com.ruoyi.system.ControllerUtil.BenefitPointsUtil.BenefitPointsResult;
|
||||||
|
import com.ruoyi.system.domain.Order;
|
||||||
|
import com.ruoyi.system.domain.Users;
|
||||||
|
import com.ruoyi.system.service.IOrderService;
|
||||||
|
import com.ruoyi.system.service.IUsersService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物金服务金测试控制器
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-01-27
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/benefit/test")
|
||||||
|
public class BenefitPointsTestController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderService orderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IUsersService usersService;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 测试购物金服务金处理
|
||||||
|
// */
|
||||||
|
// @PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
// @Log(title = "购物金服务金测试", businessType = BusinessType.OTHER)
|
||||||
|
// @PostMapping("/process")
|
||||||
|
// public AjaxResult testBenefitPointsProcess(
|
||||||
|
// @RequestParam("orderId") Long orderId,
|
||||||
|
// @RequestParam("money") BigDecimal money) {
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// BenefitPointsResult result = BenefitPointsUtil.processBenefitPoints(orderId, money);
|
||||||
|
//
|
||||||
|
// Map<String, Object> data = new HashMap<>();
|
||||||
|
// data.put("success", result.isSuccess());
|
||||||
|
// data.put("message", result.getMessage());
|
||||||
|
//
|
||||||
|
// if (result.getLog() != null) {
|
||||||
|
// Map<String, Object> logData = new HashMap<>();
|
||||||
|
// logData.put("id", result.getLog().getId());
|
||||||
|
// logData.put("orderId", result.getLog().getOrderid());
|
||||||
|
// logData.put("userId", result.getLog().getUid());
|
||||||
|
// logData.put("type", result.getLog().getType());
|
||||||
|
// logData.put("orderType", result.getLog().getOrdertype());
|
||||||
|
// logData.put("orderMoney", result.getLog().getOrdermoney());
|
||||||
|
// logData.put("money", result.getLog().getMoney());
|
||||||
|
// logData.put("beforeMoney", result.getLog().getBeformoney());
|
||||||
|
// logData.put("afterMoney", result.getLog().getAftremoney());
|
||||||
|
// logData.put("remark", result.getLog().getReamk());
|
||||||
|
// logData.put("dotime", result.getLog().getDotime());
|
||||||
|
// data.put("log", logData);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return AjaxResult.success("测试完成", data);
|
||||||
|
//
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// return AjaxResult.error("测试异常: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取订单信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@GetMapping("/order/{orderId}")
|
||||||
|
public AjaxResult getOrderInfo(@PathVariable("orderId") Long orderId) {
|
||||||
|
try {
|
||||||
|
Order order = orderService.selectOrderById(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return AjaxResult.error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("id", order.getId());
|
||||||
|
data.put("type", order.getType());
|
||||||
|
data.put("uid", order.getUid());
|
||||||
|
data.put("totalPrice", order.getTotalPrice());
|
||||||
|
data.put("payPrice", order.getPayPrice());
|
||||||
|
data.put("status", order.getStatus());
|
||||||
|
|
||||||
|
return AjaxResult.success("获取订单信息成功", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("获取订单信息异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@GetMapping("/user/{userId}")
|
||||||
|
public AjaxResult getUserInfo(@PathVariable("userId") Long userId) {
|
||||||
|
try {
|
||||||
|
Users user = usersService.selectUsersById(userId);
|
||||||
|
if (user == null) {
|
||||||
|
return AjaxResult.error("用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("id", user.getId());
|
||||||
|
data.put("name", user.getName());
|
||||||
|
data.put("phone", user.getPhone());
|
||||||
|
data.put("consumption", user.getConsumption());
|
||||||
|
data.put("servicefee", user.getServicefee());
|
||||||
|
|
||||||
|
return AjaxResult.success("获取用户信息成功", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("获取用户信息异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试系统配置获取
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@GetMapping("/config")
|
||||||
|
public AjaxResult testConfig() {
|
||||||
|
try {
|
||||||
|
// 这里可以添加配置测试逻辑
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("configName", "config_one");
|
||||||
|
data.put("expectedKeys", new String[]{"consumption", "servicefee", "consumption_deduction", "service_deduction"});
|
||||||
|
|
||||||
|
return AjaxResult.success("配置测试", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("配置测试异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试抵扣计算
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@PostMapping("/deduction")
|
||||||
|
public AjaxResult testDeduction(
|
||||||
|
@RequestParam("userId") Long userId,
|
||||||
|
@RequestParam("amount") BigDecimal amount,
|
||||||
|
@RequestParam("serviceType") Long serviceType) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Users user = usersService.selectUsersById(userId);
|
||||||
|
if (user == null) {
|
||||||
|
return AjaxResult.error("用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
BenefitPointsUtil.BenefitDeductionResult result = BenefitPointsUtil.getBenefitDeduction(user, amount, serviceType);
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("success", result.isSuccess());
|
||||||
|
data.put("message", result.getMessage());
|
||||||
|
data.put("serviceMoney", result.getServiceMoney());
|
||||||
|
data.put("shopMoney", result.getShopMoney());
|
||||||
|
data.put("finalAmount", result.getFinalAmount());
|
||||||
|
|
||||||
|
return AjaxResult.success("抵扣计算测试完成", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("抵扣计算测试异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试余额查询
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@GetMapping("/balance/{userId}")
|
||||||
|
public AjaxResult testBalance(@PathVariable("userId") Long userId) {
|
||||||
|
try {
|
||||||
|
BenefitPointsUtil.BenefitBalanceResult result = BenefitPointsUtil.getBenefitBalance(userId);
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("success", result.isSuccess());
|
||||||
|
data.put("message", result.getMessage());
|
||||||
|
data.put("servicefee", result.getServicefee());
|
||||||
|
data.put("consumption", result.getConsumption());
|
||||||
|
|
||||||
|
return AjaxResult.success("余额查询测试完成", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("余额查询测试异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试增加福利金
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@Log(title = "增加福利金测试", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/increase")
|
||||||
|
public AjaxResult testIncreaseBenefitPoints(
|
||||||
|
@RequestParam("money") BigDecimal money,
|
||||||
|
@RequestParam("type") Long type,
|
||||||
|
@RequestParam("orderId") Long orderId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
BenefitPointsResult result = BenefitPointsUtil.increaseBenefitPoints(money, type, orderId);
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("success", result.isSuccess());
|
||||||
|
data.put("message", result.getMessage());
|
||||||
|
|
||||||
|
if (result.getLog() != null) {
|
||||||
|
Map<String, Object> logData = new HashMap<>();
|
||||||
|
logData.put("id", result.getLog().getId());
|
||||||
|
logData.put("orderId", result.getLog().getOrderid());
|
||||||
|
logData.put("userId", result.getLog().getUid());
|
||||||
|
logData.put("type", result.getLog().getType());
|
||||||
|
logData.put("orderType", result.getLog().getOrdertype());
|
||||||
|
logData.put("orderMoney", result.getLog().getOrdermoney());
|
||||||
|
logData.put("money", result.getLog().getMoney());
|
||||||
|
logData.put("beforeMoney", result.getLog().getBeformoney());
|
||||||
|
logData.put("afterMoney", result.getLog().getAftremoney());
|
||||||
|
logData.put("remark", result.getLog().getReamk());
|
||||||
|
logData.put("dotime", result.getLog().getDotime());
|
||||||
|
data.put("log", logData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AjaxResult.success("增加福利金测试完成", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("增加福利金测试异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试抵扣福利金
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:benefit:test')")
|
||||||
|
@Log(title = "抵扣福利金测试", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/deduct")
|
||||||
|
public AjaxResult testDeductBenefitPoints(
|
||||||
|
@RequestParam("money") BigDecimal money,
|
||||||
|
@RequestParam("type") Long type,
|
||||||
|
@RequestParam("orderId") Long orderId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
BenefitPointsResult result = BenefitPointsUtil.deductBenefitPoints(money, type, orderId);
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("success", result.isSuccess());
|
||||||
|
data.put("message", result.getMessage());
|
||||||
|
|
||||||
|
if (result.getLog() != null) {
|
||||||
|
Map<String, Object> logData = new HashMap<>();
|
||||||
|
logData.put("id", result.getLog().getId());
|
||||||
|
logData.put("orderId", result.getLog().getOrderid());
|
||||||
|
logData.put("userId", result.getLog().getUid());
|
||||||
|
logData.put("type", result.getLog().getType());
|
||||||
|
logData.put("orderType", result.getLog().getOrdertype());
|
||||||
|
logData.put("orderMoney", result.getLog().getOrdermoney());
|
||||||
|
logData.put("money", result.getLog().getMoney());
|
||||||
|
logData.put("beforeMoney", result.getLog().getBeformoney());
|
||||||
|
logData.put("afterMoney", result.getLog().getAftremoney());
|
||||||
|
logData.put("remark", result.getLog().getReamk());
|
||||||
|
logData.put("dotime", result.getLog().getDotime());
|
||||||
|
data.put("log", logData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AjaxResult.success("抵扣福利金测试完成", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("抵扣福利金测试异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.system.ControllerUtil.AppletControllerUtil;
|
import com.ruoyi.system.ControllerUtil.AppletControllerUtil;
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
import com.ruoyi.system.ControllerUtil.WechatPayUtil;
|
import com.ruoyi.system.ControllerUtil.WechatPayUtil;
|
||||||
import com.ruoyi.system.ControllerUtil.WorkerCommissionUtil;
|
import com.ruoyi.system.ControllerUtil.WorkerCommissionUtil;
|
||||||
import com.ruoyi.system.domain.ServiceGoods;
|
import com.ruoyi.system.domain.ServiceGoods;
|
||||||
|
|
@ -132,7 +133,24 @@ public class CoursorUtil extends BaseController {
|
||||||
return AppletControllerUtil.appletError("查询游标信息失败:" + e.getMessage());
|
return AppletControllerUtil.appletError("查询游标信息失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取订单游标信息
|
||||||
|
*
|
||||||
|
* @param id 游标ID
|
||||||
|
* @param request HTTP请求对象
|
||||||
|
* @return 游标详细信息
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/api/DispatchUtil/{id}")
|
||||||
|
public AjaxResult getOrderDispatchUtil(@PathVariable("id") long id, HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
DispatchUtil dispatchUtil = new DispatchUtil();
|
||||||
|
|
||||||
|
return AppletControllerUtil.appletSuccess(DispatchUtil.dispatchOrder(id));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AppletControllerUtil.appletError("查询游标信息失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,288 @@
|
||||||
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
|
import com.ruoyi.system.domain.Order;
|
||||||
|
import com.ruoyi.system.domain.Users;
|
||||||
|
import com.ruoyi.system.service.IOrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单控制器
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/dispatch")
|
||||||
|
public class DispatchController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderService orderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动派单
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @return 派单结果
|
||||||
|
*/
|
||||||
|
@Log(title = "自动派单", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/auto/{orderId}")
|
||||||
|
public AjaxResult autoDispatch(@PathVariable("orderId") Long orderId) {
|
||||||
|
try {
|
||||||
|
// 检查订单是否存在
|
||||||
|
Order order = orderService.selectOrderById(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return AjaxResult.error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查订单状态
|
||||||
|
if (order.getStatus() != 0L) {
|
||||||
|
return AjaxResult.error("订单状态不正确,无法派单");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行派单
|
||||||
|
DispatchUtil.DispatchResult result = DispatchUtil.dispatchOrder(orderId);
|
||||||
|
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
Users worker = result.getWorker();
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("orderId", orderId);
|
||||||
|
data.put("workerId", worker.getId());
|
||||||
|
data.put("workerName", worker.getName());
|
||||||
|
data.put("workerPhone", worker.getPhone());
|
||||||
|
data.put("message", result.getMessage());
|
||||||
|
|
||||||
|
return AjaxResult.success("派单成功", data);
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error(result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("派单失败,订单ID: {}", orderId, e);
|
||||||
|
return AjaxResult.error("派单失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动派单
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @param workerId 师傅ID
|
||||||
|
* @return 派单结果
|
||||||
|
*/
|
||||||
|
@Log(title = "手动派单", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/manual")
|
||||||
|
public AjaxResult manualDispatch(@RequestParam("orderId") Long orderId,
|
||||||
|
@RequestParam("workerId") Long workerId) {
|
||||||
|
try {
|
||||||
|
// 检查订单是否存在
|
||||||
|
Order order = orderService.selectOrderById(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return AjaxResult.error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查订单状态
|
||||||
|
if (order.getStatus() != 0L) {
|
||||||
|
return AjaxResult.error("订单状态不正确,无法派单");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新订单师傅信息
|
||||||
|
order.setWorkerId(workerId);
|
||||||
|
orderService.updateOrder(order);
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("orderId", orderId);
|
||||||
|
data.put("workerId", workerId);
|
||||||
|
data.put("message", "手动派单成功");
|
||||||
|
|
||||||
|
return AjaxResult.success("手动派单成功", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("手动派单失败,订单ID: {}, 师傅ID: {}", orderId, workerId, e);
|
||||||
|
return AjaxResult.error("手动派单失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单详情
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @return 派单详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/detail/{orderId}")
|
||||||
|
public AjaxResult getDispatchDetail(@PathVariable("orderId") Long orderId) {
|
||||||
|
try {
|
||||||
|
// 检查订单是否存在
|
||||||
|
Order order = orderService.selectOrderById(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return AjaxResult.error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("orderId", orderId);
|
||||||
|
data.put("workerId", order.getWorkerId());
|
||||||
|
data.put("orderStatus", order.getStatus());
|
||||||
|
|
||||||
|
// 如果有师傅,获取师傅信息
|
||||||
|
if (order.getWorkerId() != null) {
|
||||||
|
// 这里应该查询师傅详细信息
|
||||||
|
data.put("hasWorker", true);
|
||||||
|
} else {
|
||||||
|
data.put("hasWorker", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AjaxResult.success(data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取派单详情失败,订单ID: {}", orderId, e);
|
||||||
|
return AjaxResult.error("获取派单详情失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消派单
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @return 取消结果
|
||||||
|
*/
|
||||||
|
@Log(title = "取消派单", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/cancel/{orderId}")
|
||||||
|
public AjaxResult cancelDispatch(@PathVariable("orderId") Long orderId) {
|
||||||
|
try {
|
||||||
|
// 检查订单是否存在
|
||||||
|
Order order = orderService.selectOrderById(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return AjaxResult.error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查订单状态
|
||||||
|
if (order.getStatus() != 1L) {
|
||||||
|
return AjaxResult.error("订单状态不正确,无法取消派单");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消派单(清空师傅ID)
|
||||||
|
order.setWorkerId(null);
|
||||||
|
orderService.updateOrder(order);
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("orderId", orderId);
|
||||||
|
data.put("message", "取消派单成功");
|
||||||
|
|
||||||
|
return AjaxResult.success("取消派单成功", data);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("取消派单失败,订单ID: {}", orderId, e);
|
||||||
|
return AjaxResult.error("取消派单失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新派单
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @return 重新派单结果
|
||||||
|
*/
|
||||||
|
@Log(title = "重新派单", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/redispatch/{orderId}")
|
||||||
|
public AjaxResult redispatch(@PathVariable("orderId") Long orderId) {
|
||||||
|
try {
|
||||||
|
// 检查订单是否存在
|
||||||
|
Order order = orderService.selectOrderById(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
return AjaxResult.error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查订单状态
|
||||||
|
if (order.getStatus() != 1L) {
|
||||||
|
return AjaxResult.error("订单状态不正确,无法重新派单");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先取消当前派单
|
||||||
|
order.setWorkerId(null);
|
||||||
|
orderService.updateOrder(order);
|
||||||
|
|
||||||
|
// 重新派单
|
||||||
|
DispatchUtil.DispatchResult result = DispatchUtil.dispatchOrder(orderId);
|
||||||
|
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
Users worker = result.getWorker();
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("orderId", orderId);
|
||||||
|
data.put("workerId", worker.getId());
|
||||||
|
data.put("workerName", worker.getName());
|
||||||
|
data.put("workerPhone", worker.getPhone());
|
||||||
|
data.put("message", result.getMessage());
|
||||||
|
|
||||||
|
return AjaxResult.success("重新派单成功", data);
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error(result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("重新派单失败,订单ID: {}", orderId, e);
|
||||||
|
return AjaxResult.error("重新派单失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 为所有师傅生成评分数据
|
||||||
|
// *
|
||||||
|
// * @param orderId 订单ID(可选,如果为null则使用模拟数据)
|
||||||
|
// * @return 处理结果
|
||||||
|
// */
|
||||||
|
// @Log(title = "生成所有师傅评分数据", businessType = BusinessType.INSERT)
|
||||||
|
// @PostMapping("/generate-scores")
|
||||||
|
// public AjaxResult generateAllWorkerScores(@RequestParam(value = "orderId", required = false) Long orderId) {
|
||||||
|
// try {
|
||||||
|
// logger.info("开始为所有师傅生成评分数据,订单ID: {}", orderId);
|
||||||
|
//
|
||||||
|
// // 调用DispatchUtil中的方法
|
||||||
|
// DispatchUtil.DispatchResult result = DispatchUtil.generateAllWorkerScores(orderId);
|
||||||
|
//
|
||||||
|
// if (result.isSuccess()) {
|
||||||
|
// Map<String, Object> data = new HashMap<>();
|
||||||
|
// data.put("message", result.getMessage());
|
||||||
|
// data.put("orderId", orderId);
|
||||||
|
//
|
||||||
|
// return AjaxResult.success("生成评分数据成功", data);
|
||||||
|
// } else {
|
||||||
|
// return AjaxResult.error(result.getMessage());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// logger.error("生成所有师傅评分数据失败,订单ID: {}", orderId, e);
|
||||||
|
// return AjaxResult.error("生成评分数据失败: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试派单逻辑
|
||||||
|
*
|
||||||
|
* @return 测试结果
|
||||||
|
*/
|
||||||
|
@Log(title = "测试派单逻辑", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/test")
|
||||||
|
public AjaxResult testDispatchLogic() {
|
||||||
|
try {
|
||||||
|
logger.info("开始测试派单逻辑");
|
||||||
|
|
||||||
|
// 调用测试方法
|
||||||
|
DispatchUtil.testDispatchLogic();
|
||||||
|
|
||||||
|
return AjaxResult.success("派单逻辑测试完成");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("派单逻辑测试失败", e);
|
||||||
|
return AjaxResult.error("派单逻辑测试失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
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 com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.system.domain.DispatchScoreRecord;
|
||||||
|
import com.ruoyi.system.service.IDispatchScoreRecordService;
|
||||||
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单评分记录Controller
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-08-04
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/DispatchScoreRecord")
|
||||||
|
public class DispatchScoreRecordController extends BaseController
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private IDispatchScoreRecordService dispatchScoreRecordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
startPage();
|
||||||
|
List<DispatchScoreRecord> list = dispatchScoreRecordService.selectDispatchScoreRecordList(dispatchScoreRecord);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出派单评分记录列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:export')")
|
||||||
|
@Log(title = "派单评分记录", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(HttpServletResponse response, DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
List<DispatchScoreRecord> list = dispatchScoreRecordService.selectDispatchScoreRecordList(dispatchScoreRecord);
|
||||||
|
ExcelUtil<DispatchScoreRecord> util = new ExcelUtil<DispatchScoreRecord>(DispatchScoreRecord.class);
|
||||||
|
util.exportExcel(response, list, "派单评分记录数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单评分记录详细信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:query')")
|
||||||
|
@GetMapping(value = "/{id}")
|
||||||
|
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||||
|
{
|
||||||
|
return success(dispatchScoreRecordService.selectDispatchScoreRecordById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单评分记录
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:add')")
|
||||||
|
@Log(title = "派单评分记录", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@RequestBody DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
return toAjax(dispatchScoreRecordService.insertDispatchScoreRecord(dispatchScoreRecord));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单评分记录
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:edit')")
|
||||||
|
@Log(title = "派单评分记录", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@RequestBody DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
return toAjax(dispatchScoreRecordService.updateDispatchScoreRecord(dispatchScoreRecord));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单评分记录
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:remove')")
|
||||||
|
@Log(title = "派单评分记录", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public AjaxResult remove(@PathVariable Long[] ids)
|
||||||
|
{
|
||||||
|
return toAjax(dispatchScoreRecordService.deleteDispatchScoreRecordByIds(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新派单评分数据
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:DispatchScoreRecord:refresh')")
|
||||||
|
@Log(title = "刷新派单评分数据", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/refresh")
|
||||||
|
public AjaxResult refresh()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 调用DispatchUtil生成所有师傅的评分数据
|
||||||
|
DispatchUtil.DispatchResult result = DispatchUtil.generateAllWorkerScores(null);
|
||||||
|
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
return success("刷新评分数据成功:" + result.getMessage());
|
||||||
|
} else {
|
||||||
|
return error("刷新评分数据失败:" + result.getMessage());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return error("刷新评分数据时发生异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单系统测试控制器
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/dispatch/test")
|
||||||
|
public class DispatchTestController extends BaseController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证经验评分机制
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:dispatch:test')")
|
||||||
|
@Log(title = "验证经验评分机制", businessType = BusinessType.OTHER)
|
||||||
|
@GetMapping("/validateExperience")
|
||||||
|
public AjaxResult validateExperiencePriority() {
|
||||||
|
try {
|
||||||
|
DispatchUtil.validateExperiencePriority();
|
||||||
|
return AjaxResult.success("经验评分机制验证完成,请查看控制台日志");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("验证失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印详细评分信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:dispatch:test')")
|
||||||
|
@Log(title = "打印详细评分", businessType = BusinessType.OTHER)
|
||||||
|
@GetMapping("/printScores/{orderId}")
|
||||||
|
public AjaxResult printDetailedScores(@PathVariable("orderId") Long orderId) {
|
||||||
|
try {
|
||||||
|
DispatchUtil.printDetailedScores(orderId);
|
||||||
|
return AjaxResult.success("详细评分信息已打印到控制台");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("打印评分失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行综合测试
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:dispatch:test')")
|
||||||
|
@Log(title = "运行综合测试", businessType = BusinessType.OTHER)
|
||||||
|
@GetMapping("/comprehensiveTest")
|
||||||
|
public AjaxResult runComprehensiveTest() {
|
||||||
|
try {
|
||||||
|
DispatchUtil.DispatchTestResult result = DispatchUtil.comprehensiveTest();
|
||||||
|
return AjaxResult.success("综合测试完成", result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("综合测试失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单统计信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:dispatch:test')")
|
||||||
|
@Log(title = "获取派单统计", businessType = BusinessType.OTHER)
|
||||||
|
@GetMapping("/statistics")
|
||||||
|
public AjaxResult getDispatchStatistics() {
|
||||||
|
try {
|
||||||
|
return AjaxResult.success(DispatchUtil.getDispatchStatistics());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("获取统计信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置派单统计信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:dispatch:test')")
|
||||||
|
@Log(title = "重置派单统计", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/resetStatistics")
|
||||||
|
public AjaxResult resetDispatchStatistics() {
|
||||||
|
try {
|
||||||
|
DispatchUtil.resetDispatchStatistics();
|
||||||
|
return AjaxResult.success("统计信息已重置");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("重置统计信息失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试派单时间限制
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:dispatch:test')")
|
||||||
|
@Log(title = "测试派单时间限制", businessType = BusinessType.OTHER)
|
||||||
|
@GetMapping("/testTimeLimit")
|
||||||
|
public AjaxResult testTimeLimit() {
|
||||||
|
try {
|
||||||
|
boolean isAllowed = DispatchUtil.checkDispatchTimeLimit();
|
||||||
|
return AjaxResult.success("时间限制检查完成",
|
||||||
|
Map.of("isAllowed", isAllowed,
|
||||||
|
"message", isAllowed ? "当前时间允许派单" : "当前时间不允许派单"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("时间限制检查失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.system.controller;
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -179,9 +180,9 @@ public class GoodsOrderController extends BaseController
|
||||||
if (goodsOrder == null) {
|
if (goodsOrder == null) {
|
||||||
return error("订单不存在");
|
return error("订单不存在");
|
||||||
}
|
}
|
||||||
String reamk=params.get("reamk").toString() ;
|
String reamk = params.getString("rejectReason");
|
||||||
if (reamk == null) {
|
if (reamk == null) {
|
||||||
reamk="测试数据";
|
reamk = "无";
|
||||||
}
|
}
|
||||||
// 检查当前状态是否为申请状态或平台收货状态
|
// 检查当前状态是否为申请状态或平台收货状态
|
||||||
if (goodsOrder.getReturnstatus() == null ||
|
if (goodsOrder.getReturnstatus() == null ||
|
||||||
|
|
@ -252,10 +253,40 @@ public class GoodsOrderController extends BaseController
|
||||||
if (goodsOrder.getReturnstatus() != 4) {
|
if (goodsOrder.getReturnstatus() != 4) {
|
||||||
return error("当前状态不允许此操作");
|
return error("当前状态不允许此操作");
|
||||||
}
|
}
|
||||||
newStatus = 5L;
|
|
||||||
logMessage = "同意退款";
|
// 获取退款金额和备注
|
||||||
returnJsonObject2.put("title","退款成功");
|
String refundAmountStr = params.getString("returnrealmoney");
|
||||||
returnJsonObject2.put("content","平台以退款"+reamk);
|
String refundRemark = params.getString("refundRemark");
|
||||||
|
|
||||||
|
if (refundAmountStr == null || refundAmountStr.trim().isEmpty()) {
|
||||||
|
return error("退款金额不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
BigDecimal refundAmount = new BigDecimal(refundAmountStr);
|
||||||
|
BigDecimal orderAmount = goodsOrder.getPayPrice();
|
||||||
|
|
||||||
|
if (refundAmount.compareTo(orderAmount) > 0) {
|
||||||
|
return error("退款金额不能超过订单金额");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置退款金额
|
||||||
|
goodsOrder.setReturnmoney(refundAmount);
|
||||||
|
|
||||||
|
// 构建退款内容
|
||||||
|
String refundContent = "退款金额:¥" + refundAmount;
|
||||||
|
if (refundRemark != null && !refundRemark.trim().isEmpty()) {
|
||||||
|
refundContent += ",备注:" + refundRemark;
|
||||||
|
}
|
||||||
|
|
||||||
|
newStatus = 5L;
|
||||||
|
logMessage = "同意退款";
|
||||||
|
returnJsonObject2.put("title","退款成功");
|
||||||
|
returnJsonObject2.put("content", refundContent);
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return error("退款金额格式错误");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return error("操作类型错误");
|
return error("操作类型错误");
|
||||||
}
|
}
|
||||||
|
|
@ -293,4 +324,78 @@ public class GoodsOrderController extends BaseController
|
||||||
return error("操作失败:" + e.getMessage());
|
return error("操作失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单发货处理
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('system:GoodsOrder:edit')")
|
||||||
|
@Log(title = "订单发货", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/shipOrder")
|
||||||
|
public AjaxResult shipOrder(@RequestBody GoodsOrder goodsOrder)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 验证订单是否存在
|
||||||
|
GoodsOrder existingOrder = goodsOrderService.selectGoodsOrderById(goodsOrder.getId());
|
||||||
|
if (existingOrder == null) {
|
||||||
|
return error("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证订单状态是否为已支付待发货
|
||||||
|
if (existingOrder.getStatus() != 2L) {
|
||||||
|
return error("只有已支付待发货的订单才能发货");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证必填字段
|
||||||
|
if (goodsOrder.getDeliveryId() == null) {
|
||||||
|
return error("请选择快递公司");
|
||||||
|
}
|
||||||
|
if (goodsOrder.getDeliveryNum() == null || goodsOrder.getDeliveryNum().trim().isEmpty()) {
|
||||||
|
return error("请输入快递单号");
|
||||||
|
}
|
||||||
|
if (goodsOrder.getSendTime() == null) {
|
||||||
|
return error("请选择发货时间");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取快递公司信息
|
||||||
|
SiteDelivery siteDelivery = siteDeliveryService.selectSiteDeliveryById(goodsOrder.getDeliveryId());
|
||||||
|
if (siteDelivery == null) {
|
||||||
|
return error("快递公司不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新订单信息
|
||||||
|
existingOrder.setDeliveryId(goodsOrder.getDeliveryId());
|
||||||
|
existingOrder.setDeliveryNum(goodsOrder.getDeliveryNum());
|
||||||
|
existingOrder.setSendTime(goodsOrder.getSendTime());
|
||||||
|
existingOrder.setStatus(3L); // 设置为已发货状态
|
||||||
|
if (goodsOrder.getMark() != null && !goodsOrder.getMark().trim().isEmpty()) {
|
||||||
|
existingOrder.setMark(goodsOrder.getMark());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新订单
|
||||||
|
int result = goodsOrderService.updateGoodsOrder(existingOrder);
|
||||||
|
|
||||||
|
if (result > 0) {
|
||||||
|
// 添加发货日志
|
||||||
|
JSONObject logData = new JSONObject();
|
||||||
|
logData.put("wlgs", siteDelivery.getTitle());
|
||||||
|
logData.put("wldh", goodsOrder.getDeliveryNum());
|
||||||
|
OrderUtil.addgoodsorderlog(
|
||||||
|
existingOrder.getId(),
|
||||||
|
existingOrder.getOrderId(),
|
||||||
|
"订单已发货",
|
||||||
|
"2",
|
||||||
|
logData,
|
||||||
|
2L
|
||||||
|
);
|
||||||
|
|
||||||
|
return success("发货成功");
|
||||||
|
} else {
|
||||||
|
return error("发货失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("订单发货失败", e);
|
||||||
|
return error("发货失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.system.ControllerUtil.BalancePayUtil;
|
import com.ruoyi.system.ControllerUtil.*;
|
||||||
import com.ruoyi.system.ControllerUtil.GenerateCustomCode;
|
|
||||||
import com.ruoyi.system.ControllerUtil.OrderUtil;
|
|
||||||
import com.ruoyi.system.ControllerUtil.WXsendMsgUtil;
|
|
||||||
import com.ruoyi.system.ControllerUtil.WechatPayUtil;
|
|
||||||
import com.ruoyi.system.ControllerUtil.WechatPayV3Util;
|
|
||||||
import com.ruoyi.system.domain.*;
|
import com.ruoyi.system.domain.*;
|
||||||
import com.ruoyi.system.service.*;
|
import com.ruoyi.system.service.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -318,8 +313,12 @@ public class PayNotifyController extends BaseController {
|
||||||
if (usersPayBefor != null) {
|
if (usersPayBefor != null) {
|
||||||
users = usersService.selectUsersById(usersPayBefor.getUid());
|
users = usersService.selectUsersById(usersPayBefor.getUid());
|
||||||
}
|
}
|
||||||
//订单回调处理,拼团创建订单,其他订单修改状态
|
//扣减消费金服务金
|
||||||
|
BenefitPointsUtil.deductServiceAndConsumption(usersPayBefor.getOid(), users, usersPayBefor.getServicemoney(), usersPayBefor.getShopmoney());
|
||||||
|
//回调方法用来处理订单相关数据
|
||||||
OrderUtil.prepayCallback(usersPayBefor, users);
|
OrderUtil.prepayCallback(usersPayBefor, users);
|
||||||
|
// //订单回调处理,拼团创建订单,其他订单修改状态
|
||||||
|
// OrderUtil.prepayCallback(usersPayBefor, users);
|
||||||
|
|
||||||
// //最后无论如何平台流水需要添加,让平台看到流水和账目
|
// //最后无论如何平台流水需要添加,让平台看到流水和账目
|
||||||
PayMoneyLog payMoneyLog = new PayMoneyLog();
|
PayMoneyLog payMoneyLog = new PayMoneyLog();
|
||||||
|
|
@ -465,6 +464,9 @@ public class PayNotifyController extends BaseController {
|
||||||
usersPayBefor.getOrderid()
|
usersPayBefor.getOrderid()
|
||||||
);
|
);
|
||||||
if (balanceResult == null || !Boolean.TRUE.equals(balanceResult.get("success"))) {
|
if (balanceResult == null || !Boolean.TRUE.equals(balanceResult.get("success"))) {
|
||||||
|
//扣减消费金服务金
|
||||||
|
BenefitPointsUtil.deductServiceAndConsumption(usersPayBefor.getOid(), user, usersPayBefor.getServicemoney(), usersPayBefor.getShopmoney());
|
||||||
|
//回调方法用来处理订单相关数据
|
||||||
OrderUtil.prepayCallback(usersPayBefor, user);
|
OrderUtil.prepayCallback(usersPayBefor, user);
|
||||||
String errorMsg = balanceResult != null ? (String) balanceResult.get("message") : "余额支付失败";
|
String errorMsg = balanceResult != null ? (String) balanceResult.get("message") : "余额支付失败";
|
||||||
logger.error("组合支付余额部分扣款失败:{}", errorMsg);
|
logger.error("组合支付余额部分扣款失败:{}", errorMsg);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.util.List;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.system.ControllerUtil.AppletControllerUtil;
|
import com.ruoyi.system.ControllerUtil.AppletControllerUtil;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -46,6 +47,10 @@ public class ServiceCateController extends BaseController
|
||||||
{
|
{
|
||||||
// 如果pageSize大于1000,说明是要获取所有数据,不分页
|
// 如果pageSize大于1000,说明是要获取所有数据,不分页
|
||||||
String pageSizeStr = request.getParameter("pageSize");
|
String pageSizeStr = request.getParameter("pageSize");
|
||||||
|
String type = request.getParameter("type");
|
||||||
|
if(StringUtils.isNotBlank(type)){
|
||||||
|
serviceCate.setType(Long.parseLong(type));
|
||||||
|
}
|
||||||
if (pageSizeStr != null && Integer.parseInt(pageSizeStr) > 1000) {
|
if (pageSizeStr != null && Integer.parseInt(pageSizeStr) > 1000) {
|
||||||
// 不分页查询
|
// 不分页查询
|
||||||
List<ServiceCate> list = serviceCateService.selectServiceCateList(serviceCate);
|
List<ServiceCate> list = serviceCateService.selectServiceCateList(serviceCate);
|
||||||
|
|
@ -68,6 +73,10 @@ public class ServiceCateController extends BaseController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出服务分类列表
|
* 导出服务分类列表
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,16 @@ public class ServiceGoodsController extends BaseController {
|
||||||
* 获取服务内容详细信息
|
* 获取服务内容详细信息
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:ServiceGoods:query')")
|
@PreAuthorize("@ss.hasPermi('system:ServiceGoods:query')")
|
||||||
@GetMapping(value = "/selectServiceCateList")
|
@GetMapping(value = "/selectServiceCateList/{type}")
|
||||||
public AjaxResult selectServiceCateList() {
|
public AjaxResult selectServiceCateList(@PathVariable("type") Integer type) {
|
||||||
return success(serviceCateService.selectServiceCateList(new ServiceCate()));
|
|
||||||
|
ServiceCate serviceGoods = new ServiceCate();
|
||||||
|
if (type != null){
|
||||||
|
serviceGoods.setType(Long.valueOf(type));
|
||||||
|
}
|
||||||
|
return success(serviceCateService.selectServiceCateList(serviceGoods));
|
||||||
|
|
||||||
|
// return success(serviceCateService.selectServiceCateList(new ServiceCate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,4 +101,14 @@ public class UsersPayBeforController extends BaseController
|
||||||
{
|
{
|
||||||
return toAjax(usersPayBeforService.deleteUsersPayBeforByIds(ids));
|
return toAjax(usersPayBeforService.deleteUsersPayBeforByIds(ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单ID查询预支付数据
|
||||||
|
*/
|
||||||
|
@GetMapping("/getByOrderId/{orderId}")
|
||||||
|
public AjaxResult getByOrderId(@PathVariable("orderId") String orderId)
|
||||||
|
{
|
||||||
|
UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(orderId);
|
||||||
|
return success(usersPayBefor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.ruoyi.system.utils.FFmpegUtilsSimple;
|
import com.ruoyi.system.utils.FFmpegUtilsSimple;
|
||||||
import com.ruoyi.system.utils.QiniuUploadUtil;
|
import com.ruoyi.system.utils.QiniuUploadUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
@ -50,6 +51,8 @@ public class AppletControllerUtil {
|
||||||
private static final IOrderCommentService orderCommentService = SpringUtils.getBean(IOrderCommentService.class);
|
private static final IOrderCommentService orderCommentService = SpringUtils.getBean(IOrderCommentService.class);
|
||||||
private static final IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class);
|
private static final IOrderLogService orderLogService = SpringUtils.getBean(IOrderLogService.class);
|
||||||
private static final IOrderSoundLogService orderSoundLogService = SpringUtils.getBean(IOrderSoundLogService.class);
|
private static final IOrderSoundLogService orderSoundLogService = SpringUtils.getBean(IOrderSoundLogService.class);
|
||||||
|
private static final IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
||||||
|
private static final IUserGroupBuyingService userGroupBuyingService = SpringUtils.getBean(IUserGroupBuyingService.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2910,57 +2913,57 @@ public class AppletControllerUtil {
|
||||||
return timeSlotList;
|
return timeSlotList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 订单生成给师傅派单
|
// * 订单生成给师傅派单
|
||||||
*
|
// *
|
||||||
* @param order 订单主键
|
// * @param order 订单主键
|
||||||
* @return 是否可用
|
// * @return 是否可用
|
||||||
*/
|
// */
|
||||||
public static Users creatWorkerForOrder(Order order,Users worker) {
|
// public static Users creatWorkerForOrder(Order order,Users worker) {
|
||||||
|
//
|
||||||
order.setWorkerId(worker.getId());
|
// order.setWorkerId(worker.getId());
|
||||||
order.setStatus(1L);
|
// order.setStatus(1L);
|
||||||
order.setIsPause(1);
|
// order.setIsPause(1);
|
||||||
order.setReceiveTime(new Date());
|
// order.setReceiveTime(new Date());
|
||||||
order.setWorkerPhone(worker.getPhone());
|
// order.setWorkerPhone(worker.getPhone());
|
||||||
UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId());
|
|
||||||
if (userAddress != null){
|
|
||||||
order.setUserPhone(userAddress.getPhone());
|
|
||||||
}
|
|
||||||
order.setMiddlePhone("18339212639");
|
|
||||||
order.setReceiveType(3l);
|
|
||||||
order.setLogStatus(9);
|
|
||||||
JSONObject jSONObject = new JSONObject();
|
|
||||||
jSONObject.put("type", 9);
|
|
||||||
order.setLogJson(jSONObject.toJSONString());
|
|
||||||
orderService.updateOrder(order);
|
|
||||||
|
|
||||||
|
|
||||||
OrderLog orderLognew = new OrderLog();
|
|
||||||
orderLognew.setOid(order.getId());
|
|
||||||
orderLognew.setOrderId(order.getOrderId());
|
|
||||||
orderLognew.setTitle("系统派单");
|
|
||||||
orderLognew.setType(new BigDecimal(1.1));
|
|
||||||
JSONObject jSONObject1 = new JSONObject();
|
|
||||||
jSONObject1.put("name", "师傅收到派单信息");
|
|
||||||
orderLognew.setContent(jSONObject1.toJSONString());
|
|
||||||
orderLognew.setWorkerId(worker.getId());
|
|
||||||
orderLognew.setWorkerLogId(worker.getId());
|
|
||||||
orderLogService.insertOrderLog(orderLognew);
|
|
||||||
|
|
||||||
// GaoDeMapUtil gaoDeMapUtil = new GaoDeMapUtil();
|
|
||||||
// UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId());
|
// UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId());
|
||||||
//// if (userAddress != null){
|
// if (userAddress != null){
|
||||||
//// String city = gaoDeMapUtil.getCityByLocation(userAddress.getLongitude(), userAddress.getLatitude());
|
// order.setUserPhone(userAddress.getPhone());
|
||||||
//// if (city != null){
|
// }
|
||||||
////
|
// order.setMiddlePhone("18339212639");
|
||||||
//// }else{
|
// order.setReceiveType(3l);
|
||||||
////
|
// order.setLogStatus(9);
|
||||||
//// }
|
// JSONObject jSONObject = new JSONObject();
|
||||||
//// }
|
// jSONObject.put("type", 9);
|
||||||
// // Users worker = usersService.selectUsersById(2l);
|
// order.setLogJson(jSONObject.toJSONString());
|
||||||
return worker;
|
// orderService.updateOrder(order);
|
||||||
}
|
//
|
||||||
|
//
|
||||||
|
// OrderLog orderLognew = new OrderLog();
|
||||||
|
// orderLognew.setOid(order.getId());
|
||||||
|
// orderLognew.setOrderId(order.getOrderId());
|
||||||
|
// orderLognew.setTitle("系统派单");
|
||||||
|
// orderLognew.setType(new BigDecimal(1.1));
|
||||||
|
// JSONObject jSONObject1 = new JSONObject();
|
||||||
|
// jSONObject1.put("name", "师傅收到派单信息");
|
||||||
|
// orderLognew.setContent(jSONObject1.toJSONString());
|
||||||
|
// orderLognew.setWorkerId(worker.getId());
|
||||||
|
// orderLognew.setWorkerLogId(worker.getId());
|
||||||
|
// orderLogService.insertOrderLog(orderLognew);
|
||||||
|
//
|
||||||
|
//// GaoDeMapUtil gaoDeMapUtil = new GaoDeMapUtil();
|
||||||
|
//// UserAddress userAddress = userAddressService.selectUserAddressById(order.getAddressId());
|
||||||
|
////// if (userAddress != null){
|
||||||
|
////// String city = gaoDeMapUtil.getCityByLocation(userAddress.getLongitude(), userAddress.getLatitude());
|
||||||
|
////// if (city != null){
|
||||||
|
//////
|
||||||
|
////// }else{
|
||||||
|
//////
|
||||||
|
////// }
|
||||||
|
////// }
|
||||||
|
//// // Users worker = usersService.selectUsersById(2l);
|
||||||
|
// return worker;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3927,6 +3930,16 @@ public class AppletControllerUtil {
|
||||||
if (params.get("name") != null) {
|
if (params.get("name") != null) {
|
||||||
updateUser.setName(params.get("name").toString().trim());
|
updateUser.setName(params.get("name").toString().trim());
|
||||||
}
|
}
|
||||||
|
if (params.get("workerLongitude") != null) {
|
||||||
|
updateUser.setWorkerLongitude(params.get("workerLongitude").toString().trim());
|
||||||
|
}
|
||||||
|
if (params.get("workerLatitude") != null) {
|
||||||
|
updateUser.setWorkerLatitude(params.get("workerLatitude").toString().trim());
|
||||||
|
}
|
||||||
|
if (params.get("workerAdress") != null) {
|
||||||
|
updateUser.setWorkerAdress(params.get("workerAdress").toString().trim());
|
||||||
|
updateUser.setLastLocationTime(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
if (params.get("nickname") != null && !params.get("nickname").toString().trim().isEmpty()) {
|
if (params.get("nickname") != null && !params.get("nickname").toString().trim().isEmpty()) {
|
||||||
updateUser.setNickname(params.get("nickname").toString().trim());
|
updateUser.setNickname(params.get("nickname").toString().trim());
|
||||||
|
|
@ -5457,6 +5470,630 @@ public class AppletControllerUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单类型创建相应的订单
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> createOrderByType(Integer ordertype, Users user, Long productId,
|
||||||
|
UserAddress userAddress, String sku, Integer num, String makeTime,
|
||||||
|
String fileData, String grouporderid, String reamk, String cikaid, BigDecimal totalAmount, String ptcode) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (ordertype) {
|
||||||
|
case 0: // 普通预约
|
||||||
|
return createNormalOrder(user, productId, userAddress, sku, num, makeTime,fileData,reamk);
|
||||||
|
case 1: // 拼团
|
||||||
|
return createGroupBuyingOrder(user, productId,fileData,grouporderid,ptcode,reamk);
|
||||||
|
case 2: // 一口价
|
||||||
|
return createCardOrder(user, productId, userAddress, sku, num, makeTime, fileData,cikaid,totalAmount,reamk);
|
||||||
|
case 3: // 秒杀
|
||||||
|
return createSeckillOrder(user, productId, userAddress, sku, num, makeTime,fileData,totalAmount,reamk);
|
||||||
|
case 4: // 报价
|
||||||
|
return createQuoteOrder(user, productId, userAddress, sku, num, makeTime,fileData,reamk);
|
||||||
|
default:
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "不支持的订单类型");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.error("创建订单失败:", e);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建订单失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建普通预约订单
|
||||||
|
* 1预约 2报价 3一口价 4拼团 5普通订单
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> createNormalOrder(Users user, Long productId, UserAddress userAddress,
|
||||||
|
String sku, Integer num, String makeTime,
|
||||||
|
String attachments, String reamk) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
//派单模式
|
||||||
|
Integer dispatchtype=serviceGoods.getDispatchtype();
|
||||||
|
if (dispatchtype==null){
|
||||||
|
dispatchtype=1;
|
||||||
|
}
|
||||||
|
// 计算订单金额
|
||||||
|
BigDecimal itemPrice = serviceGoods.getPrice().multiply(BigDecimal.valueOf(num));
|
||||||
|
|
||||||
|
// 生成订单号
|
||||||
|
String orderId = GenerateCustomCode.generCreateOrder("YY");
|
||||||
|
String mainorderId = GenerateCustomCode.generCreateOrder("MYY");
|
||||||
|
|
||||||
|
// 创建普通预约订单(统一使用服务订单表)
|
||||||
|
Order order = new Order();
|
||||||
|
order.setNum(Long.valueOf(num));
|
||||||
|
order.setType(1); // 普通预约订单
|
||||||
|
order.setMainOrderId(mainorderId);
|
||||||
|
order.setCreateType(1); // 用户自主下单
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
order.setUid(user.getId());
|
||||||
|
order.setUname(user.getName());
|
||||||
|
order.setProductId(serviceGoods.getId());
|
||||||
|
order.setBigtype(serviceGoods.getServicetype());
|
||||||
|
order.setProductName(serviceGoods.getTitle());
|
||||||
|
order.setReamk(reamk);
|
||||||
|
order.setSku(sku);
|
||||||
|
if (userAddress != null) {
|
||||||
|
order.setAddressId(userAddress.getId());
|
||||||
|
order.setName(userAddress.getName());
|
||||||
|
order.setPhone(userAddress.getPhone());
|
||||||
|
order.setAddress(userAddress.getAddressInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理预约时间
|
||||||
|
if (makeTime != null && !makeTime.isEmpty()) {
|
||||||
|
String[] makeTimeArr = makeTime.split(" ");
|
||||||
|
if (makeTimeArr.length == 2) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
Date date = sdf.parse(makeTimeArr[0]);
|
||||||
|
order.setMakeTime(date.getTime() / 1000);
|
||||||
|
order.setMakeHour(makeTimeArr[1]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.warn("预约时间格式错误: " + makeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
order.setTotalPrice(BigDecimal.ZERO);
|
||||||
|
order.setGoodPrice(BigDecimal.ZERO);
|
||||||
|
order.setServicePrice(BigDecimal.ZERO);
|
||||||
|
order.setPayPrice(BigDecimal.ZERO);
|
||||||
|
order.setStatus(1L); // 待支付
|
||||||
|
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
|
||||||
|
order.setIsAccept(0);
|
||||||
|
order.setIsComment(0);
|
||||||
|
order.setIsPause(1);
|
||||||
|
order.setJsonStatus(0);
|
||||||
|
order.setOdertype(0);
|
||||||
|
order.setDeduction(new BigDecimal(0));
|
||||||
|
order.setFileData(attachments); // 设置附件数据
|
||||||
|
order.setType(1);
|
||||||
|
int insertResult = orderService.insertOrder(order);
|
||||||
|
if (insertResult <= 0) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "普通预约订单创建失败");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加订单日志
|
||||||
|
OrderLog orderLog = new OrderLog();
|
||||||
|
orderLog.setOid(order.getId());
|
||||||
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
orderLog.setTitle("订单生成");
|
||||||
|
orderLog.setType(BigDecimal.valueOf(1.0));
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("name", "订单创建成功");
|
||||||
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
|
int flg= orderLogService.insertOrderLog(orderLog);
|
||||||
|
if (flg>0){
|
||||||
|
//开始派单
|
||||||
|
DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
}
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("orderId", orderId);
|
||||||
|
result.put("oid", order.getId());
|
||||||
|
result.put("totalAmount", itemPrice);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.error("创建普通预约订单失败:", e);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建普通预约订单失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建拼团订单user, productId,fileData,grouporderid
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> createGroupBuyingOrder(Users user, Long productId, String fileData,
|
||||||
|
String grouporderid, String ptcode, String reamk) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
try {
|
||||||
|
// 验证拼团价格
|
||||||
|
if (serviceGoods.getGroupprice() == null) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "该商品不支持拼团");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// 计算订单金额
|
||||||
|
BigDecimal itemPrice = serviceGoods.getGroupprice().multiply(BigDecimal.valueOf(1));
|
||||||
|
|
||||||
|
// // 处理拼团单号
|
||||||
|
// String finalPtcode = ptcode;
|
||||||
|
// if (finalPtcode == null || finalPtcode.trim().isEmpty()) {
|
||||||
|
// // 如果没有提供拼团单号,生成新的拼团单号
|
||||||
|
// finalPtcode = GenerateCustomCode.generCreateOrder("PT");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 创建拼团订单(预支付状态)
|
||||||
|
UserGroupBuying userGroupBuying = new UserGroupBuying();
|
||||||
|
userGroupBuying.setOrderid(grouporderid); // 使用拼团单号作为订单号
|
||||||
|
userGroupBuying.setPtorderid(ptcode);
|
||||||
|
userGroupBuying.setUid(user.getId());
|
||||||
|
userGroupBuying.setImage(user.getAvatar());
|
||||||
|
userGroupBuying.setUname(user.getName());
|
||||||
|
userGroupBuying.setProductId(serviceGoods.getId());
|
||||||
|
userGroupBuying.setMoney(itemPrice);
|
||||||
|
userGroupBuying.setStatus(4L); // 待支付
|
||||||
|
userGroupBuying.setPaystatus(2L); // 待支付
|
||||||
|
userGroupBuying.setPaytype(1L); // 默认微信支付
|
||||||
|
userGroupBuying.setDeduction(new BigDecimal(0));
|
||||||
|
int insertResult = userGroupBuyingService.insertUserGroupBuying(userGroupBuying);
|
||||||
|
if (insertResult <= 0) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "拼团订单创建失败");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预支付接口不需要检查拼团人数,只需要记录预支付信息
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("orderId", ptcode);
|
||||||
|
result.put("oid", userGroupBuying.getId());
|
||||||
|
result.put("totalAmount", itemPrice);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.error("创建拼团订单失败:", e);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建拼团订单失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一口价次卡
|
||||||
|
* 1预约 2报价 3一口价 4拼团 5普通订单
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> createCardOrder(Users user, Long productId, UserAddress userAddress,
|
||||||
|
String sku, Integer num, String makeTime,
|
||||||
|
String attachments, String cikaid, BigDecimal totalAmount, String reamk) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
//派单模式
|
||||||
|
Integer dispatchtype=serviceGoods.getDispatchtype();
|
||||||
|
if (dispatchtype==null){
|
||||||
|
dispatchtype=1;
|
||||||
|
}
|
||||||
|
// 计算订单金额
|
||||||
|
BigDecimal itemPrice = totalAmount;
|
||||||
|
// 生成订单号
|
||||||
|
String orderId = GenerateCustomCode.generCreateOrder("N");
|
||||||
|
String mainorderId = GenerateCustomCode.generCreateOrder("MYKJ");
|
||||||
|
// 创建普通预约订单(统一使用服务订单表)
|
||||||
|
Order order = new Order();
|
||||||
|
order.setNum(Long.valueOf(num));
|
||||||
|
order.setType(1); // 普通预约订单
|
||||||
|
order.setCreateType(1); // 用户自主下单
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
order.setMainOrderId(mainorderId);
|
||||||
|
order.setUid(user.getId());
|
||||||
|
order.setReamk(reamk);
|
||||||
|
order.setUname(user.getName());
|
||||||
|
order.setProductId(serviceGoods.getId());
|
||||||
|
order.setProductName(serviceGoods.getTitle());
|
||||||
|
order.setSku(sku);
|
||||||
|
order.setBigtype(serviceGoods.getServicetype());
|
||||||
|
if(StringUtils.isNotBlank(cikaid)){
|
||||||
|
order.setTotalPrice(serviceGoods.getFixedprice());
|
||||||
|
order.setCartid(cikaid);
|
||||||
|
|
||||||
|
}
|
||||||
|
// order.setc
|
||||||
|
if (userAddress != null) {
|
||||||
|
order.setAddressId(userAddress.getId());
|
||||||
|
order.setName(userAddress.getName());
|
||||||
|
order.setPhone(userAddress.getPhone());
|
||||||
|
order.setAddress(userAddress.getAddressInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理预约时间
|
||||||
|
if (makeTime != null && !makeTime.isEmpty()) {
|
||||||
|
String[] makeTimeArr = makeTime.split(" ");
|
||||||
|
if (makeTimeArr.length == 2) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
Date date = sdf.parse(makeTimeArr[0]);
|
||||||
|
order.setMakeTime(date.getTime() / 1000);
|
||||||
|
order.setMakeHour(makeTimeArr[1]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.warn("预约时间格式错误: " + makeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
order.setTotalPrice(itemPrice);
|
||||||
|
order.setGoodPrice(BigDecimal.ZERO);
|
||||||
|
order.setServicePrice(BigDecimal.ZERO);
|
||||||
|
order.setPayPrice(itemPrice);
|
||||||
|
//有次卡直接形成订单
|
||||||
|
if (StringUtils.isNotBlank(cikaid)){
|
||||||
|
order.setStatus(1L); // 待接单
|
||||||
|
}else{
|
||||||
|
order.setStatus(11L); // 待支付
|
||||||
|
}
|
||||||
|
|
||||||
|
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
|
||||||
|
order.setIsAccept(0);
|
||||||
|
order.setIsComment(0);
|
||||||
|
order.setIsPause(1);
|
||||||
|
order.setOdertype(2);
|
||||||
|
order.setJsonStatus(0);
|
||||||
|
order.setDeduction(new BigDecimal(0));
|
||||||
|
order.setFileData(attachments); // 设置附件数据
|
||||||
|
order.setType(1);
|
||||||
|
order.setTotalPrice(itemPrice);
|
||||||
|
int insertResult = orderService.insertOrder(order);
|
||||||
|
if (insertResult <= 0) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "普通预约订单创建失败");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加订单日志
|
||||||
|
OrderLog orderLog = new OrderLog();
|
||||||
|
if (StringUtils.isNotBlank(cikaid)){
|
||||||
|
orderLog.setOid(order.getId());
|
||||||
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
orderLog.setTitle("订单生成");
|
||||||
|
orderLog.setType(BigDecimal.valueOf(1.0));
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("name", "订单创建成功,待派单");
|
||||||
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
|
|
||||||
|
}else{
|
||||||
|
orderLog.setOid(order.getId());
|
||||||
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
orderLog.setTitle("订单生成");
|
||||||
|
orderLog.setType(BigDecimal.valueOf(1.0));
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("name", "订单创建成功,待支付");
|
||||||
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
orderLogService.insertOrderLog(orderLog);
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("orderId", orderId);
|
||||||
|
result.put("oid", order.getId());
|
||||||
|
result.put("totalAmount", itemPrice);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.error("创建普通预约订单失败:", e);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建普通预约订单失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 创建次卡订单
|
||||||
|
// */
|
||||||
|
// private Map<String, Object> createCardOrder(Users user, Long productId, UserAddress userAddress,
|
||||||
|
// String sku, Integer num, String makeTime, CouponUser couponUser,
|
||||||
|
// BigDecimal couponDiscount, BigDecimal memberMoney, String mtcode, String attachments,String goodsids) {
|
||||||
|
// Map<String, Object> result = new HashMap<>();
|
||||||
|
// try {
|
||||||
|
//
|
||||||
|
// UserSecondaryCard userSecondaryCard = userSecondaryCardService.selectUserSecondaryCardById(productId);
|
||||||
|
//
|
||||||
|
// // 计算订单金额
|
||||||
|
// BigDecimal itemPrice = userSecondaryCard.getRealMoney();
|
||||||
|
// // 生成订单号
|
||||||
|
// String orderId = GenerateCustomCode.generCreateOrder("C");
|
||||||
|
// // 创建次卡使用记录
|
||||||
|
// UserUseSecondaryCard card = new UserUseSecondaryCard();
|
||||||
|
// card.setUid(user.getId());
|
||||||
|
// card.setCarid(String.valueOf(userSecondaryCard.getId())); // 假设商品ID即为次卡ID
|
||||||
|
// card.setGoodsids(goodsids); // 如有多个服务ID可调整
|
||||||
|
// card.setNum(Long.valueOf(num));
|
||||||
|
// card.setUsenum(0L);
|
||||||
|
// card.setOrderid(orderId);
|
||||||
|
// card.setTransactionId("");
|
||||||
|
// card.setPaymoney(itemPrice);
|
||||||
|
// card.setStatus(4L); // 1可用 2已用完 3已退款 4未支付
|
||||||
|
// card.setRemark(attachments); // 附件信息存remark
|
||||||
|
// int insertResult = userUseSecondaryCardService.insertUserUseSecondaryCard(card);
|
||||||
|
// if (insertResult <= 0) {
|
||||||
|
// result.put("success", false);
|
||||||
|
// result.put("message", "次卡订单创建失败");
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// result.put("success", true);
|
||||||
|
// result.put("orderId", orderId);
|
||||||
|
// result.put("oid", card.getId());
|
||||||
|
// result.put("totalAmount", itemPrice);
|
||||||
|
// return result;
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// logger.error("创建次卡订单失败:", e);
|
||||||
|
// result.put("success", false);
|
||||||
|
// result.put("message", "创建次卡订单失败:" + e.getMessage());
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建秒杀订单
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> createSeckillOrder(Users user, Long productId, UserAddress userAddress,
|
||||||
|
String sku, Integer num, String makeTime,
|
||||||
|
String attachments, BigDecimal totalAmount, String reamk) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
//派单模式
|
||||||
|
Integer dispatchtype=serviceGoods.getDispatchtype();
|
||||||
|
if (dispatchtype==null){
|
||||||
|
dispatchtype=1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 验证秒杀价格
|
||||||
|
if (serviceGoods.getFixedprice() == null) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "该商品不支持秒杀");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算订单金额
|
||||||
|
BigDecimal itemPrice = serviceGoods.getFixedprice().multiply(BigDecimal.valueOf(num));
|
||||||
|
|
||||||
|
// 生成订单号
|
||||||
|
String orderId = GenerateCustomCode.generCreateOrder("S");
|
||||||
|
String mainorderId = GenerateCustomCode.generCreateOrder("MS");
|
||||||
|
// 创建秒杀订单(使用服务订单表)
|
||||||
|
Order order = new Order();
|
||||||
|
order.setType(1); // 秒杀类型
|
||||||
|
order.setCreateType(1); // 用户自主下单
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
order.setMainOrderId(mainorderId);
|
||||||
|
order.setReamk(reamk);
|
||||||
|
order.setUid(user.getId());
|
||||||
|
order.setUname(user.getName());
|
||||||
|
order.setProductId(serviceGoods.getId());
|
||||||
|
order.setProductName(serviceGoods.getTitle());
|
||||||
|
order.setBigtype(serviceGoods.getServicetype());
|
||||||
|
order.setSku(sku);
|
||||||
|
order.setNum(Long.valueOf(num));
|
||||||
|
if (userAddress != null) {
|
||||||
|
order.setAddressId(userAddress.getId());
|
||||||
|
order.setName(userAddress.getName());
|
||||||
|
order.setPhone(userAddress.getPhone());
|
||||||
|
order.setAddress(userAddress.getAddressInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理预约时间
|
||||||
|
if (makeTime != null && !makeTime.isEmpty()) {
|
||||||
|
String[] makeTimeArr = makeTime.split(" ");
|
||||||
|
if (makeTimeArr.length == 2) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
Date date = sdf.parse(makeTimeArr[0]);
|
||||||
|
order.setMakeTime(date.getTime() / 1000);
|
||||||
|
order.setMakeHour(makeTimeArr[1]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.warn("预约时间格式错误: " + makeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
order.setTotalPrice(itemPrice);
|
||||||
|
order.setGoodPrice(BigDecimal.ZERO);
|
||||||
|
order.setServicePrice(BigDecimal.ZERO);
|
||||||
|
order.setPayPrice(itemPrice);
|
||||||
|
order.setStatus(11L); // 待待接单
|
||||||
|
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
|
||||||
|
order.setIsAccept(0);
|
||||||
|
order.setIsComment(0);
|
||||||
|
order.setOdertype(3);
|
||||||
|
order.setIsPause(1);
|
||||||
|
order.setJsonStatus(0);
|
||||||
|
order.setDeduction(new BigDecimal(0));
|
||||||
|
order.setFileData(attachments); // 设置附件数据
|
||||||
|
order.setTotalPrice(totalAmount);
|
||||||
|
int insertResult = orderService.insertOrder(order);
|
||||||
|
if (insertResult <= 0) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "秒杀订单创建失败");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加订单日志
|
||||||
|
OrderLog orderLog = new OrderLog();
|
||||||
|
orderLog.setOid(order.getId());
|
||||||
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
orderLog.setType(BigDecimal.valueOf(1));
|
||||||
|
orderLog.setTitle("订单生成");
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("name", "用户创建秒杀订单,待支付");
|
||||||
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
|
orderLogService.insertOrderLog(orderLog);
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("orderId", orderId);
|
||||||
|
result.put("oid", order.getId());
|
||||||
|
result.put("totalAmount", itemPrice);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.error("创建秒杀订单失败:", e);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建秒杀订单失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建报价订单
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> createQuoteOrder(Users user, Long productId, UserAddress userAddress,
|
||||||
|
String sku, Integer num, String makeTime,
|
||||||
|
String attachments, String reamk) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
|
||||||
|
Integer dispatchtype=serviceGoods.getDispatchtype();
|
||||||
|
if (dispatchtype==null){
|
||||||
|
dispatchtype=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 计算订单金额
|
||||||
|
BigDecimal itemPrice = serviceGoods.getPrice().multiply(BigDecimal.valueOf(num));
|
||||||
|
|
||||||
|
// 生成订单号
|
||||||
|
String orderId = GenerateCustomCode.generCreateOrder("Q");
|
||||||
|
String mainorderId = GenerateCustomCode.generCreateOrder("XQ");
|
||||||
|
|
||||||
|
// 创建报价订单(使用服务订单表)
|
||||||
|
Order order = new Order();
|
||||||
|
|
||||||
|
order.setCreateType(1); // 用户自主下单
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
order.setUid(user.getId());
|
||||||
|
order.setUname(user.getName());
|
||||||
|
order.setMainOrderId(mainorderId);
|
||||||
|
order.setProductId(serviceGoods.getId());
|
||||||
|
order.setReamk(reamk);
|
||||||
|
order.setProductName(serviceGoods.getTitle());
|
||||||
|
order.setSku(sku);
|
||||||
|
order.setJsonStatus(0);
|
||||||
|
order.setType(1);
|
||||||
|
order.setNum(Long.valueOf(num));
|
||||||
|
if (userAddress != null) {
|
||||||
|
order.setAddressId(userAddress.getId());
|
||||||
|
order.setName(userAddress.getName());
|
||||||
|
order.setPhone(userAddress.getPhone());
|
||||||
|
order.setAddress(userAddress.getAddressInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理预约时间
|
||||||
|
if (makeTime != null && !makeTime.isEmpty()) {
|
||||||
|
String[] makeTimeArr = makeTime.split(" ");
|
||||||
|
if (makeTimeArr.length == 2) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
Date date = sdf.parse(makeTimeArr[0]);
|
||||||
|
order.setMakeTime(date.getTime() / 1000);
|
||||||
|
order.setMakeHour(makeTimeArr[1]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.warn("预约时间格式错误: " + makeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//order.setNum(num);
|
||||||
|
order.setTotalPrice(itemPrice);
|
||||||
|
order.setGoodPrice(BigDecimal.ZERO);
|
||||||
|
order.setServicePrice(BigDecimal.ZERO);
|
||||||
|
order.setPayPrice(itemPrice);
|
||||||
|
order.setStatus(8L); // 待待报价
|
||||||
|
order.setBigtype(serviceGoods.getServicetype());
|
||||||
|
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
|
||||||
|
order.setIsAccept(0);
|
||||||
|
order.setIsComment(0);
|
||||||
|
order.setIsPause(1);
|
||||||
|
order.setOdertype(4);
|
||||||
|
order.setType(1); // 报价订单
|
||||||
|
order.setDeduction(new BigDecimal(0));
|
||||||
|
order.setFileData(attachments); // 设置附件数据
|
||||||
|
|
||||||
|
int insertResult = orderService.insertOrder(order);
|
||||||
|
if (insertResult <= 0) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "报价订单创建失败");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加订单日志
|
||||||
|
OrderLog orderLog = new OrderLog();
|
||||||
|
orderLog.setOid(order.getId());
|
||||||
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
orderLog.setType(BigDecimal.valueOf(1));
|
||||||
|
orderLog.setTitle("订单生成");
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("name", "用户创建报价订单,待报价");
|
||||||
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
|
|
||||||
|
orderLogService.insertOrderLog(orderLog);
|
||||||
|
|
||||||
|
// // 添加订单日志
|
||||||
|
// OrderLog orderLog1 = new OrderLog();
|
||||||
|
// orderLog1.setOid(order.getId());
|
||||||
|
// orderLog1.setOrderId(order.getOrderId());
|
||||||
|
// orderLog1.setType(BigDecimal.valueOf(1));
|
||||||
|
// orderLog1.setTitle("师傅报价");
|
||||||
|
// JSONObject jsonObject1 = new JSONObject();
|
||||||
|
// jsonObject1.put("name", "等待师傅报价中");
|
||||||
|
// orderLog.setContent(jsonObject1.toJSONString());
|
||||||
|
//
|
||||||
|
// orderLogService.insertOrderLog(orderLog1);
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("orderId", orderId);
|
||||||
|
result.put("oid", order.getId());
|
||||||
|
result.put("totalAmount", itemPrice);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
//logger.error("创建报价订单失败:", e);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "创建报价订单失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println(formatStringToJson("{\"image\":\"['https:img.huafurenjia.cn/images/2024-10-13/dKriAtS3HHsM0JAm6DdQEPQvAFnnuPcnOxau6SSy.jpg']\",\"num\":1,\"text\":\"你很好我爱你\" ,\"labels\":[\"技术专业\",\"作业规范\",\"价格合理\"] }"));
|
System.out.println(formatStringToJson("{\"image\":\"['https:img.huafurenjia.cn/images/2024-10-13/dKriAtS3HHsM0JAm6DdQEPQvAFnnuPcnOxau6SSy.jpg']\",\"num\":1,\"text\":\"你很好我爱你\" ,\"labels\":[\"技术专业\",\"作业规范\",\"价格合理\"] }"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -31,6 +31,11 @@ public class CartOrderUtil {
|
||||||
public static Map<String, Object> createServiceOrderFromCart(Users user, GoodsCart cart, ServiceGoods serviceGoods, UserAddress userAddress, String makeTime, IOrderService orderService, com.ruoyi.system.service.IOrderLogService orderLogService,String maincorid) {
|
public static Map<String, Object> createServiceOrderFromCart(Users user, GoodsCart cart, ServiceGoods serviceGoods, UserAddress userAddress, String makeTime, IOrderService orderService, com.ruoyi.system.service.IOrderLogService orderLogService,String maincorid) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
|
//派单模式
|
||||||
|
Integer dispatchtype=serviceGoods.getDispatchtype();
|
||||||
|
if (dispatchtype==null){
|
||||||
|
dispatchtype=1;
|
||||||
|
}
|
||||||
BigDecimal itemPrice=BigDecimal.ZERO;
|
BigDecimal itemPrice=BigDecimal.ZERO;
|
||||||
// 判断ordertype=2时的特殊价格逻辑
|
// 判断ordertype=2时的特殊价格逻辑
|
||||||
if (cart.getOrdertype() != null && cart.getOrdertype() == 2) {
|
if (cart.getOrdertype() != null && cart.getOrdertype() == 2) {
|
||||||
|
|
@ -99,6 +104,7 @@ public class CartOrderUtil {
|
||||||
order.setMainOrderId(maincorid);
|
order.setMainOrderId(maincorid);
|
||||||
order.setDeduction(BigDecimal.ZERO);
|
order.setDeduction(BigDecimal.ZERO);
|
||||||
order.setBigtype(serviceGoods.getServicetype());
|
order.setBigtype(serviceGoods.getServicetype());
|
||||||
|
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
|
||||||
int insertResult = orderService.insertOrder(order);
|
int insertResult = orderService.insertOrder(order);
|
||||||
if (insertResult <= 0) {
|
if (insertResult <= 0) {
|
||||||
result.put("success", false);
|
result.put("success", false);
|
||||||
|
|
@ -124,6 +130,8 @@ public class CartOrderUtil {
|
||||||
|
|
||||||
if (order.getTotalPrice().compareTo(BigDecimal.ZERO)>0){
|
if (order.getTotalPrice().compareTo(BigDecimal.ZERO)>0){
|
||||||
String payBeforeId = payBeforeUtil.createPayBefore(user, itemPrice, order.getOrderId(), null, order.getProductId(), cart.getOrdertype(), order.getSku(), null, null, null, null,1L, null, null);
|
String payBeforeId = payBeforeUtil.createPayBefore(user, itemPrice, order.getOrderId(), null, order.getProductId(), cart.getOrdertype(), order.getSku(), null, null, null, null,1L, null, null);
|
||||||
|
}else{
|
||||||
|
DispatchUtil.dispatchOrder(order.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -37,18 +37,26 @@ public class IntegralAndBenefitUtil {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 积分及购物消费金处理
|
* 积分处理
|
||||||
*
|
*
|
||||||
* @param money 订单金额
|
* @param money 订单金额
|
||||||
* @param orderid 订单ID
|
* @param orderid 订单ID
|
||||||
|
* @param uid 用户ID
|
||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
*/
|
*/
|
||||||
public static JSONObject processIntegralAndBenefit(BigDecimal money, String orderid, Long uid,Long befoid) {
|
public static JSONObject processIntegralAndBenefit(BigDecimal money, String orderid, Long uid) {
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforById(befoid);
|
// 获取用户信息
|
||||||
Users users = usersService.selectUsersById(uid);
|
Users users = usersService.selectUsersById(uid);
|
||||||
|
if (users == null) {
|
||||||
|
logger.error("未找到用户信息,用户ID: {}", uid);
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "用户信息不存在");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. 查询配置信息
|
// 1. 查询配置信息
|
||||||
SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
|
SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
|
||||||
if (config == null || config.getValue() == null) {
|
if (config == null || config.getValue() == null) {
|
||||||
|
|
@ -57,71 +65,37 @@ public class IntegralAndBenefitUtil {
|
||||||
result.put("message", "系统配置信息缺失");
|
result.put("message", "系统配置信息缺失");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析配置信息
|
// 解析配置信息
|
||||||
JSONObject configJson = JSONObject.parseObject(config.getValue());
|
JSONObject configJson = JSONObject.parseObject(config.getValue());
|
||||||
BigDecimal orderScore = configJson.getBigDecimal("orderScore");
|
BigDecimal orderScore = configJson.getBigDecimal("orderScore");
|
||||||
BigDecimal servicefee = configJson.getBigDecimal("servicefee");
|
|
||||||
BigDecimal consumption = configJson.getBigDecimal("consumption");
|
if (orderScore == null || orderScore.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
logger.error("配置信息不完整或无效,orderScore: {}", orderScore);
|
||||||
if (orderScore == null || servicefee == null || consumption == null) {
|
|
||||||
logger.error("配置信息不完整,orderScore: {}, servicefee: {}, consumption: {}",
|
|
||||||
orderScore, servicefee, consumption);
|
|
||||||
result.put("success", false);
|
result.put("success", false);
|
||||||
result.put("message", "系统配置信息不完整");
|
result.put("message", "系统配置信息不完整");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 处理用户积分
|
// 2. 计算积分:money / orderScore,向下取整
|
||||||
Long integralPoints = processUserIntegral(money, orderScore, orderid, users);
|
|
||||||
|
|
||||||
// 3. 处理消费金和服务金
|
|
||||||
boolean benefitResult = processUserBenefit(money, Math.toIntExact(usersPayBefor.getServicetype()), servicefee, consumption, orderid, users);
|
|
||||||
|
|
||||||
if (integralPoints > 0 && benefitResult) {
|
|
||||||
result.put("success", true);
|
|
||||||
result.put("message", "积分和消费金处理成功");
|
|
||||||
result.put("integralPoints", integralPoints);
|
|
||||||
} else {
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", "积分或消费金处理失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("积分及购物消费金处理异常", e);
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", "处理过程中发生异常:" + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理用户积分
|
|
||||||
*
|
|
||||||
* @param money 订单金额
|
|
||||||
* @param orderScore 积分兑换比例
|
|
||||||
* @param orderid 订单ID
|
|
||||||
* @param users 用户对象
|
|
||||||
* @return 获得的积分数量
|
|
||||||
*/
|
|
||||||
private static Long processUserIntegral(BigDecimal money, BigDecimal orderScore, String orderid, Users users) {
|
|
||||||
try {
|
|
||||||
// 计算积分:money / orderScore,向下取整
|
|
||||||
BigDecimal integralDecimal = money.divide(orderScore, 0, RoundingMode.DOWN);
|
BigDecimal integralDecimal = money.divide(orderScore, 0, RoundingMode.DOWN);
|
||||||
Long integralPoints = integralDecimal.longValue();
|
Long integralPoints = integralDecimal.longValue();
|
||||||
|
|
||||||
if (integralPoints > 0) {
|
if (integralPoints > 0) {
|
||||||
// 更新用户积分
|
// 3. 更新用户积分和累计积分
|
||||||
Long currentIntegral = users.getIntegral() != null ? users.getIntegral() : 0L;
|
Long currentIntegral = users.getIntegral() != null ? users.getIntegral() : 0L;
|
||||||
Long currentTotalIntegral = users.getTotalIntegral() != null ? users.getTotalIntegral() : 0L;
|
Long currentTotalIntegral = users.getTotalIntegral() != null ? users.getTotalIntegral() : 0L;
|
||||||
|
Long newIntegral = currentIntegral + integralPoints;
|
||||||
|
Long newTotalIntegral = currentTotalIntegral + integralPoints;
|
||||||
|
|
||||||
users.setIntegral(currentIntegral + integralPoints);
|
users.setIntegral(newIntegral);
|
||||||
users.setTotalIntegral(currentTotalIntegral + integralPoints);
|
users.setTotalIntegral(newTotalIntegral);
|
||||||
|
logger.error("更新用户积分失败,用户ID: {}", users.getIntegral());
|
||||||
|
logger.error("更新用户积分失败,用户ID: {}", users.getTotalIntegral());
|
||||||
// 更新用户信息
|
// 更新用户信息
|
||||||
int updateResult = usersService.updateUsers(users);
|
int updateResult = usersService.updateUsers(users);
|
||||||
if (updateResult > 0) {
|
if (updateResult > 0) {
|
||||||
// 添加积分日志
|
// 4. 添加积分日志
|
||||||
IntegralLog integralLog = new IntegralLog();
|
IntegralLog integralLog = new IntegralLog();
|
||||||
integralLog.setOrderId(orderid);
|
integralLog.setOrderId(orderid);
|
||||||
integralLog.setTitle("订单消费获得积分");
|
integralLog.setTitle("订单消费获得积分");
|
||||||
|
|
@ -135,24 +109,36 @@ public class IntegralAndBenefitUtil {
|
||||||
|
|
||||||
integralLogService.insertIntegralLog(integralLog);
|
integralLogService.insertIntegralLog(integralLog);
|
||||||
|
|
||||||
logger.info("用户{}积分处理成功,获得积分{}点", users.getId(), integralPoints);
|
logger.info("【积分处理成功】用户ID: {}, 订单金额: {}, 积分兑换比例: {}, 获得积分: {}点, 更新前积分: {}, 更新后积分: {}, 更新前累计积分: {}, 更新后累计积分: {}",
|
||||||
return integralPoints;
|
users.getId(), money, orderScore, integralPoints, currentIntegral, newIntegral, currentTotalIntegral, newTotalIntegral);
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("message", "积分处理成功");
|
||||||
|
result.put("integralPoints", integralPoints);
|
||||||
} else {
|
} else {
|
||||||
logger.error("更新用户积分失败,用户ID: {}", users.getId());
|
logger.error("【错误】更新用户积分失败,用户ID: {}", users.getId());
|
||||||
return 0L;
|
result.put("success", false);
|
||||||
|
result.put("message", "积分更新失败");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.info("订单金额{}元,积分兑换比例{},计算积分{}点,不进行积分处理",
|
logger.info("【积分处理跳过】订单金额{}元,积分兑换比例{},计算积分{}点,不进行积分处理",
|
||||||
money, orderScore, integralPoints);
|
money, orderScore, integralPoints);
|
||||||
return 0L;
|
result.put("success", true);
|
||||||
|
result.put("message", "积分计算为0,无需处理");
|
||||||
|
result.put("integralPoints", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("处理用户积分异常", e);
|
logger.error("积分处理异常", e);
|
||||||
return 0L;
|
result.put("success", false);
|
||||||
|
result.put("message", "处理过程中发生异常:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理用户消费金和服务金
|
* 处理用户消费金和服务金
|
||||||
*
|
*
|
||||||
|
|
@ -464,217 +450,217 @@ public class IntegralAndBenefitUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 支付后期处理
|
// * 支付后期处理
|
||||||
*
|
// *
|
||||||
* @param usersPayBefor 支付前对象
|
// * @param usersPayBefor 支付前对象
|
||||||
* @param uid 用户ID
|
// * @param uid 用户ID
|
||||||
* @return 处理结果
|
// * @return 处理结果
|
||||||
*/
|
// */
|
||||||
public static JSONObject paymentPostProcess(UsersPayBefor usersPayBefor, Long uid) {
|
// public static JSONObject paymentPostProcess(UsersPayBefor usersPayBefor, Long uid) {
|
||||||
JSONObject result = new JSONObject();
|
// JSONObject result = new JSONObject();
|
||||||
|
//
|
||||||
try {
|
// try {
|
||||||
Users users = usersService.selectUsersById(uid);
|
// Users users = usersService.selectUsersById(uid);
|
||||||
if (users == null) {
|
// if (users == null) {
|
||||||
logger.error("未找到用户信息,用户ID: {}", uid);
|
// logger.error("未找到用户信息,用户ID: {}", uid);
|
||||||
result.put("success", false);
|
// result.put("success", false);
|
||||||
result.put("message", "用户信息不存在");
|
// result.put("message", "用户信息不存在");
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 1. 查询配置信息
|
// // 1. 查询配置信息
|
||||||
SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
|
// SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
|
||||||
if (config == null || config.getValue() == null) {
|
// if (config == null || config.getValue() == null) {
|
||||||
logger.error("未找到config_one配置信息");
|
// logger.error("未找到config_one配置信息");
|
||||||
result.put("success", false);
|
// result.put("success", false);
|
||||||
result.put("message", "系统配置信息缺失");
|
// result.put("message", "系统配置信息缺失");
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 解析配置信息
|
// // 解析配置信息
|
||||||
JSONObject configJson = JSONObject.parseObject(config.getValue());
|
// JSONObject configJson = JSONObject.parseObject(config.getValue());
|
||||||
BigDecimal servicefee = configJson.getBigDecimal("servicefee");
|
// BigDecimal servicefee = configJson.getBigDecimal("servicefee");
|
||||||
BigDecimal consumption = configJson.getBigDecimal("consumption");
|
// BigDecimal consumption = configJson.getBigDecimal("consumption");
|
||||||
|
//
|
||||||
if (servicefee == null || consumption == null) {
|
// if (servicefee == null || consumption == null) {
|
||||||
logger.error("配置信息不完整,servicefee: {}, consumption: {}", servicefee, consumption);
|
// logger.error("配置信息不完整,servicefee: {}, consumption: {}", servicefee, consumption);
|
||||||
result.put("success", false);
|
// result.put("success", false);
|
||||||
result.put("message", "系统配置信息不完整");
|
// result.put("message", "系统配置信息不完整");
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
boolean shopResult = false;
|
// boolean shopResult = false;
|
||||||
boolean serviceResult = false;
|
// boolean serviceResult = false;
|
||||||
|
//
|
||||||
// 2. 处理购物金扣除(如果shopmoney有值)
|
// // 2. 处理购物金扣除(如果shopmoney有值)
|
||||||
BigDecimal shopmoney = usersPayBefor.getShopmoney();
|
// BigDecimal shopmoney = usersPayBefor.getShopmoney();
|
||||||
if (shopmoney != null && shopmoney.compareTo(BigDecimal.ZERO) > 0) {
|
// if (shopmoney != null && shopmoney.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
try {
|
// try {
|
||||||
shopResult = processShopMoneyDeduction(shopmoney, users, consumption);
|
// shopResult = processShopMoneyDeduction(shopmoney, users, consumption);
|
||||||
logger.info("购物金扣除处理完成,结果:{}", shopResult);
|
// logger.info("购物金扣除处理完成,结果:{}", shopResult);
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
logger.error("购物金扣除处理异常", e);
|
// logger.error("购物金扣除处理异常", e);
|
||||||
shopResult = false;
|
// shopResult = false;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
logger.info("用户{}购物金为空或为0,不进行处理", users.getId());
|
// logger.info("用户{}购物金为空或为0,不进行处理", users.getId());
|
||||||
shopResult = true;
|
// shopResult = true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 3. 处理服务金扣除(如果servicemoney有值)
|
// // 3. 处理服务金扣除(如果servicemoney有值)
|
||||||
BigDecimal servicemoney = usersPayBefor.getServicemoney();
|
// BigDecimal servicemoney = usersPayBefor.getServicemoney();
|
||||||
if (servicemoney != null && servicemoney.compareTo(BigDecimal.ZERO) > 0) {
|
// if (servicemoney != null && servicemoney.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
try {
|
// try {
|
||||||
serviceResult = processServiceMoneyDeduction(servicemoney, users, servicefee);
|
// serviceResult = processServiceMoneyDeduction(servicemoney, users, servicefee);
|
||||||
logger.info("服务金扣除处理完成,结果:{}", serviceResult);
|
// logger.info("服务金扣除处理完成,结果:{}", serviceResult);
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
logger.error("服务金扣除处理异常", e);
|
// logger.error("服务金扣除处理异常", e);
|
||||||
serviceResult = false;
|
// serviceResult = false;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
logger.info("用户{}服务金为空或为0,不进行处理", users.getId());
|
// logger.info("用户{}服务金为空或为0,不进行处理", users.getId());
|
||||||
serviceResult = true;
|
// serviceResult = true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 4. 返回处理结果
|
// // 4. 返回处理结果
|
||||||
result.put("success", true);
|
// result.put("success", true);
|
||||||
result.put("message", "支付后期处理完成");
|
// result.put("message", "支付后期处理完成");
|
||||||
result.put("shopResult", shopResult);
|
// result.put("shopResult", shopResult);
|
||||||
result.put("serviceResult", serviceResult);
|
// result.put("serviceResult", serviceResult);
|
||||||
|
//
|
||||||
logger.info("支付后期处理全部完成,购物金处理:{},服务金处理:{}", shopResult, serviceResult);
|
// logger.info("支付后期处理全部完成,购物金处理:{},服务金处理:{}", shopResult, serviceResult);
|
||||||
|
//
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
logger.error("支付后期处理异常", e);
|
// logger.error("支付后期处理异常", e);
|
||||||
result.put("success", false);
|
// result.put("success", false);
|
||||||
result.put("message", "处理过程中发生异常:" + e.getMessage());
|
// result.put("message", "处理过程中发生异常:" + e.getMessage());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* 处理服务金扣除
|
// * 处理服务金扣除
|
||||||
*
|
// *
|
||||||
* @param servicemoney 服务金金额
|
// * @param servicemoney 服务金金额
|
||||||
* @param users 用户对象
|
// * @param users 用户对象
|
||||||
* @param servicefee 服务金比例
|
// * @param servicefee 服务金比例
|
||||||
* @return 处理结果
|
// * @return 处理结果
|
||||||
*/
|
// */
|
||||||
private static boolean processServiceMoneyDeduction(BigDecimal servicemoney, Users users, BigDecimal servicefee) {
|
// private static boolean processServiceMoneyDeduction(BigDecimal servicemoney, Users users, BigDecimal servicefee) {
|
||||||
try {
|
// try {
|
||||||
// 计算扣除金额:servicemoney / servicefee%
|
// // 计算扣除金额:servicemoney / servicefee%
|
||||||
// 例如:servicefee=5,表示5%,计算方式:servicemoney / (5/100)
|
// // 例如:servicefee=5,表示5%,计算方式:servicemoney / (5/100)
|
||||||
BigDecimal servicefeeDecimal = servicefee.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
|
// BigDecimal servicefeeDecimal = servicefee.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
|
||||||
BigDecimal deductionAmount = servicemoney.divide(servicefeeDecimal, 2, RoundingMode.HALF_UP);
|
// BigDecimal deductionAmount = servicemoney.divide(servicefeeDecimal, 2, RoundingMode.HALF_UP);
|
||||||
|
//
|
||||||
// 获取当前消费金余额
|
// // 获取当前消费金余额
|
||||||
BigDecimal currentConsumption = users.getServicefee() != null ? users.getServicefee() : BigDecimal.ZERO;
|
// BigDecimal currentConsumption = users.getServicefee() != null ? users.getServicefee() : BigDecimal.ZERO;
|
||||||
BigDecimal actualDeductionAmount = deductionAmount;
|
// BigDecimal actualDeductionAmount = deductionAmount;
|
||||||
|
//
|
||||||
// 如果余额不足,设置为0,记录实际扣除金额
|
// // 如果余额不足,设置为0,记录实际扣除金额
|
||||||
if (currentConsumption.compareTo(deductionAmount) < 0) {
|
// if (currentConsumption.compareTo(deductionAmount) < 0) {
|
||||||
logger.warn("用户{}消费金不足,当前{}元,需要扣除{}元,将设置为0",
|
// logger.warn("用户{}消费金不足,当前{}元,需要扣除{}元,将设置为0",
|
||||||
users.getId(), currentConsumption, deductionAmount);
|
// users.getId(), currentConsumption, deductionAmount);
|
||||||
actualDeductionAmount = currentConsumption;
|
// actualDeductionAmount = currentConsumption;
|
||||||
users.setServicefee(BigDecimal.ZERO);
|
// users.setServicefee(BigDecimal.ZERO);
|
||||||
} else {
|
// } else {
|
||||||
// 余额充足,正常扣除
|
// // 余额充足,正常扣除
|
||||||
users.setServicefee(currentConsumption.subtract(deductionAmount));
|
// users.setServicefee(currentConsumption.subtract(deductionAmount));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 更新用户信息
|
// // 更新用户信息
|
||||||
int updateResult = usersService.updateUsers(users);
|
// int updateResult = usersService.updateUsers(users);
|
||||||
if (updateResult > 0) {
|
// if (updateResult > 0) {
|
||||||
// 添加福利金扣除日志
|
// // 添加福利金扣除日志
|
||||||
UserBenefitPoints benefitPoints = new UserBenefitPoints();
|
// UserBenefitPoints benefitPoints = new UserBenefitPoints();
|
||||||
benefitPoints.setType(1L); // 消费金
|
// benefitPoints.setType(1L); // 消费金
|
||||||
benefitPoints.setDotime(new Date());
|
// benefitPoints.setDotime(new Date());
|
||||||
benefitPoints.setOrdermoney(servicemoney);
|
// benefitPoints.setOrdermoney(servicemoney);
|
||||||
benefitPoints.setMoney(actualDeductionAmount.negate()); // 负数
|
// benefitPoints.setMoney(actualDeductionAmount.negate()); // 负数
|
||||||
benefitPoints.setOrdertype(2L); // 支出
|
// benefitPoints.setOrdertype(2L); // 支出
|
||||||
benefitPoints.setUid(users.getId());
|
// benefitPoints.setUid(users.getId());
|
||||||
benefitPoints.setBeformoney(currentConsumption);
|
// benefitPoints.setBeformoney(currentConsumption);
|
||||||
benefitPoints.setAftremoney(users.getServicefee());
|
// benefitPoints.setAftremoney(users.getServicefee());
|
||||||
benefitPoints.setCreatedAt(new Date());
|
// benefitPoints.setCreatedAt(new Date());
|
||||||
benefitPoints.setUpdatedAt(new Date());
|
// benefitPoints.setUpdatedAt(new Date());
|
||||||
benefitPoints.setReamk("支付后期处理扣除消费金,服务金金额:" + servicemoney + "元,服务金比例:" + servicefee + "%,实际扣除:" + actualDeductionAmount + "积分");
|
// benefitPoints.setReamk("支付后期处理扣除消费金,服务金金额:" + servicemoney + "元,服务金比例:" + servicefee + "%,实际扣除:" + actualDeductionAmount + "积分");
|
||||||
|
//
|
||||||
userBenefitPointsService.insertUserBenefitPoints(benefitPoints);
|
// userBenefitPointsService.insertUserBenefitPoints(benefitPoints);
|
||||||
|
//
|
||||||
logger.info("用户{}服务金扣除完成,服务金{}元,服务金比例{}%,扣除消费金{}元,实际扣除{}元",
|
// logger.info("用户{}服务金扣除完成,服务金{}元,服务金比例{}%,扣除消费金{}元,实际扣除{}元",
|
||||||
users.getId(), servicemoney, servicefee, deductionAmount, actualDeductionAmount);
|
// users.getId(), servicemoney, servicefee, deductionAmount, actualDeductionAmount);
|
||||||
return true;
|
// return true;
|
||||||
} else {
|
// } else {
|
||||||
logger.error("更新用户消费金失败,用户ID: {}", users.getId());
|
// logger.error("更新用户消费金失败,用户ID: {}", users.getId());
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
logger.error("处理服务金扣除异常", e);
|
// logger.error("处理服务金扣除异常", e);
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* 处理购物金扣除
|
// * 处理购物金扣除
|
||||||
*
|
// *
|
||||||
* @param shopmoney 购物金金额
|
// * @param shopmoney 购物金金额
|
||||||
* @param users 用户对象
|
// * @param users 用户对象
|
||||||
* @param consumption 消费金比例
|
// * @param consumption 消费金比例
|
||||||
* @return 处理结果
|
// * @return 处理结果
|
||||||
*/
|
// */
|
||||||
private static boolean processShopMoneyDeduction(BigDecimal shopmoney, Users users, BigDecimal consumption) {
|
// private static boolean processShopMoneyDeduction(BigDecimal shopmoney, Users users, BigDecimal consumption) {
|
||||||
try {
|
// try {
|
||||||
// 计算扣除金额:shopmoney / consumption%
|
// // 计算扣除金额:shopmoney / consumption%
|
||||||
// 例如:consumption=10,表示10%,计算方式:shopmoney / (10/100)
|
// // 例如:consumption=10,表示10%,计算方式:shopmoney / (10/100)
|
||||||
BigDecimal consumptionDecimal = consumption.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
|
// BigDecimal consumptionDecimal = consumption.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
|
||||||
BigDecimal deductionAmount = shopmoney.divide(consumptionDecimal, 2, RoundingMode.HALF_UP);
|
// BigDecimal deductionAmount = shopmoney.divide(consumptionDecimal, 2, RoundingMode.HALF_UP);
|
||||||
|
//
|
||||||
// 获取当前服务金余额
|
// // 获取当前服务金余额
|
||||||
BigDecimal currentServicefee = users.getConsumption() != null ? users.getConsumption() : BigDecimal.ZERO;
|
// BigDecimal currentServicefee = users.getConsumption() != null ? users.getConsumption() : BigDecimal.ZERO;
|
||||||
BigDecimal actualDeductionAmount = deductionAmount;
|
// BigDecimal actualDeductionAmount = deductionAmount;
|
||||||
|
//
|
||||||
// 如果余额不足,设置为0,记录实际扣除金额
|
// // 如果余额不足,设置为0,记录实际扣除金额
|
||||||
if (currentServicefee.compareTo(deductionAmount) < 0) {
|
// if (currentServicefee.compareTo(deductionAmount) < 0) {
|
||||||
logger.warn("用户{}服务金不足,当前{}元,需要扣除{}元,将设置为0",
|
// logger.warn("用户{}服务金不足,当前{}元,需要扣除{}元,将设置为0",
|
||||||
users.getId(), currentServicefee, deductionAmount);
|
// users.getId(), currentServicefee, deductionAmount);
|
||||||
actualDeductionAmount = currentServicefee;
|
// actualDeductionAmount = currentServicefee;
|
||||||
users.setConsumption(BigDecimal.ZERO);
|
// users.setConsumption(BigDecimal.ZERO);
|
||||||
} else {
|
// } else {
|
||||||
// 余额充足,正常扣除
|
// // 余额充足,正常扣除
|
||||||
users.setConsumption(currentServicefee.subtract(deductionAmount));
|
// users.setConsumption(currentServicefee.subtract(deductionAmount));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 更新用户信息
|
// // 更新用户信息
|
||||||
int updateResult = usersService.updateUsers(users);
|
// int updateResult = usersService.updateUsers(users);
|
||||||
if (updateResult > 0) {
|
// if (updateResult > 0) {
|
||||||
// 添加福利金扣除日志
|
// // 添加福利金扣除日志
|
||||||
UserBenefitPoints benefitPoints = new UserBenefitPoints();
|
// UserBenefitPoints benefitPoints = new UserBenefitPoints();
|
||||||
benefitPoints.setType(2L); // 服务金
|
// benefitPoints.setType(2L); // 服务金
|
||||||
benefitPoints.setDotime(new Date());
|
// benefitPoints.setDotime(new Date());
|
||||||
benefitPoints.setOrdermoney(shopmoney);
|
// benefitPoints.setOrdermoney(shopmoney);
|
||||||
benefitPoints.setMoney(actualDeductionAmount.negate()); // 负数
|
// benefitPoints.setMoney(actualDeductionAmount.negate()); // 负数
|
||||||
benefitPoints.setOrdertype(2L); // 支出
|
// benefitPoints.setOrdertype(2L); // 支出
|
||||||
benefitPoints.setUid(users.getId());
|
// benefitPoints.setUid(users.getId());
|
||||||
benefitPoints.setBeformoney(currentServicefee);
|
// benefitPoints.setBeformoney(currentServicefee);
|
||||||
benefitPoints.setAftremoney(users.getConsumption());
|
// benefitPoints.setAftremoney(users.getConsumption());
|
||||||
benefitPoints.setReamk("支付后期处理扣除服务金,购物金金额:" + shopmoney + "元,消费金比例:" + consumption + "%,实际扣除:" + actualDeductionAmount + "积分");
|
// benefitPoints.setReamk("支付后期处理扣除服务金,购物金金额:" + shopmoney + "元,消费金比例:" + consumption + "%,实际扣除:" + actualDeductionAmount + "积分");
|
||||||
|
//
|
||||||
userBenefitPointsService.insertUserBenefitPoints(benefitPoints);
|
// userBenefitPointsService.insertUserBenefitPoints(benefitPoints);
|
||||||
|
//
|
||||||
logger.info("用户{}购物金扣除完成,购物金{}元,消费金比例{}%,扣除服务金{}元,实际扣除{}元",
|
// logger.info("用户{}购物金扣除完成,购物金{}元,消费金比例{}%,扣除服务金{}元,实际扣除{}元",
|
||||||
users.getId(), shopmoney, consumption, deductionAmount, actualDeductionAmount);
|
// users.getId(), shopmoney, consumption, deductionAmount, actualDeductionAmount);
|
||||||
return true;
|
// return true;
|
||||||
} else {
|
// } else {
|
||||||
logger.error("更新用户服务金失败,用户ID: {}", users.getId());
|
// logger.error("更新用户服务金失败,用户ID: {}", users.getId());
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
logger.error("处理购物金扣除异常", e);
|
// logger.error("处理购物金扣除异常", e);
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
@ -14,6 +14,9 @@ import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,6 +31,7 @@ public class OrderUtil {
|
||||||
private static IUserDemandQuotationService userDemandQuotationService = SpringUtils.getBean(IUserDemandQuotationService.class);
|
private static IUserDemandQuotationService userDemandQuotationService = SpringUtils.getBean(IUserDemandQuotationService.class);
|
||||||
private static IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class);
|
private static IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class);
|
||||||
private static IQuoteMaterialService quoteMaterialService = SpringUtils.getBean(IQuoteMaterialService.class);
|
private static IQuoteMaterialService quoteMaterialService = SpringUtils.getBean(IQuoteMaterialService.class);
|
||||||
|
private static IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
||||||
|
|
||||||
private static OrderLogHandler orderLogHandler = SpringUtils.getBean(OrderLogHandler.class);
|
private static OrderLogHandler orderLogHandler = SpringUtils.getBean(OrderLogHandler.class);
|
||||||
|
|
||||||
|
|
@ -649,9 +653,12 @@ public class OrderUtil {
|
||||||
for (GoodsOrder g: gorders){
|
for (GoodsOrder g: gorders){
|
||||||
g.setStatus(2L);
|
g.setStatus(2L);
|
||||||
goodsOrderService.updateGoodsOrder(g);
|
goodsOrderService.updateGoodsOrder(g);
|
||||||
|
// BenefitPointsUtil.processBenefitPoints(g.getId(),g.getTotalPrice(),"2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateInventoryAndSales(gorder.getOrderId(), 2);
|
// updateInventoryAndSales(gorder.getOrderId(), 2);
|
||||||
|
//处理服务金
|
||||||
|
|
||||||
return payBefor.getOrderid();
|
return payBefor.getOrderid();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -669,6 +676,7 @@ public class OrderUtil {
|
||||||
goodsOrder.setStatus(2L);
|
goodsOrder.setStatus(2L);
|
||||||
goodsOrder.setTransactionId(payBefor.getPaycode());
|
goodsOrder.setTransactionId(payBefor.getPaycode());
|
||||||
int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder);
|
int updateResult = goodsOrderService.updateGoodsOrder(goodsOrder);
|
||||||
|
|
||||||
System.out.println("商品订单更新结果: " + updateResult);
|
System.out.println("商品订单更新结果: " + updateResult);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -684,6 +692,7 @@ public class OrderUtil {
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
order.setStatus(2L);
|
order.setStatus(2L);
|
||||||
order.setTransactionId(payBefor.getPaycode());
|
order.setTransactionId(payBefor.getPaycode());
|
||||||
|
//BenefitPointsUtil.processBenefitPoints(order.getId(),order.getTotalPrice(),"2");
|
||||||
int updateResult = goodsOrderService.updateGoodsOrder(order);
|
int updateResult = goodsOrderService.updateGoodsOrder(order);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -727,7 +736,7 @@ public class OrderUtil {
|
||||||
}
|
}
|
||||||
if (type == 9) {
|
if (type == 9) {
|
||||||
// 4. 查询对应的服务订单
|
// 4. 查询对应的服务订单
|
||||||
Order order = orderService.selectOrderByOrderId(payBefor.getOrderid());
|
Order order = orderService.selectOrderByOrderId(payBefor.getLastorderid());
|
||||||
|
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
//更新最新的一条日志信息
|
//更新最新的一条日志信息
|
||||||
|
|
@ -796,7 +805,7 @@ public class OrderUtil {
|
||||||
order.setStatus(2L);
|
order.setStatus(2L);
|
||||||
order.setJsonStatus(2);
|
order.setJsonStatus(2);
|
||||||
order.setFirstWorkerId(users.getId());
|
order.setFirstWorkerId(users.getId());
|
||||||
// order.setIsAccept(1);
|
order.setIsAccept(1);
|
||||||
order.setWorkerPhone(users.getPhone());
|
order.setWorkerPhone(users.getPhone());
|
||||||
order.setTotalPrice(userDemandQuotation.getMoney());
|
order.setTotalPrice(userDemandQuotation.getMoney());
|
||||||
order.setWorkerId(users.getId());
|
order.setWorkerId(users.getId());
|
||||||
|
|
@ -814,6 +823,10 @@ public class OrderUtil {
|
||||||
jsonObject.put("name", "报价订单支付成功,待服务,师傅"+users.getName());
|
jsonObject.put("name", "报价订单支付成功,待服务,师傅"+users.getName());
|
||||||
orderLog.setContent(jsonObject.toJSONString());
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
int logInsertResult = orderLogService.insertOrderLog(orderLog);
|
int logInsertResult = orderLogService.insertOrderLog(orderLog);
|
||||||
|
//开始派单
|
||||||
|
if (logInsertResult>0){
|
||||||
|
DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
}
|
||||||
System.out.println("订单日志插入结果: " + logInsertResult);
|
System.out.println("订单日志插入结果: " + logInsertResult);
|
||||||
System.out.println("需求报价订单处理完成");
|
System.out.println("需求报价订单处理完成");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -823,7 +836,7 @@ public class OrderUtil {
|
||||||
System.out.println("未找到报价记录,处理失败");
|
System.out.println("未找到报价记录,处理失败");
|
||||||
}
|
}
|
||||||
System.out.println("需求报价订单处理完成,返回order: " + (order != null ? order.getOrderId() : "null"));
|
System.out.println("需求报价订单处理完成,返回order: " + (order != null ? order.getOrderId() : "null"));
|
||||||
updateInventoryAndSales(order.getOrderId(), 1);
|
// updateInventoryAndSales(order.getOrderId(), 1);
|
||||||
//dispatchOrderCheck(order);
|
//dispatchOrderCheck(order);
|
||||||
return order;
|
return order;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -871,9 +884,26 @@ public class OrderUtil {
|
||||||
System.out.println("普通订单处理完成,返回order: " + order.getOrderId());
|
System.out.println("普通订单处理完成,返回order: " + order.getOrderId());
|
||||||
|
|
||||||
//派单效验
|
//派单效验
|
||||||
dispatchOrderCheck(order);
|
// dispatchOrderCheck(order);
|
||||||
//库存及销量变更
|
//库存及销量变更
|
||||||
updateInventoryAndSales(order.getOrderId(), 1);
|
// updateInventoryAndSales(order.getOrderId(), 1);
|
||||||
|
//开始派单 派单模式 1:系统派单 2:后台手动派单 3:指定工人
|
||||||
|
if (logInsertResult>0){
|
||||||
|
DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
}
|
||||||
|
// if (logInsertResult>0){
|
||||||
|
// if (order.getReceiveType()==1){
|
||||||
|
// DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
// }else{
|
||||||
|
// if (order.getReceiveType()==3){
|
||||||
|
// ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(order.getProductId());
|
||||||
|
// if (serviceGoods!=null){
|
||||||
|
// Users newworker = usersService.selectUsersById(order.getWorkerId());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
return order;
|
return order;
|
||||||
} else {
|
} else {
|
||||||
System.out.println("未找到订单");
|
System.out.println("未找到订单");
|
||||||
|
|
@ -901,7 +931,11 @@ public class OrderUtil {
|
||||||
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
||||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(payBefor.getServiceid());
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(payBefor.getServiceid());
|
||||||
System.out.println("查询到的商品信息: " + (serviceGoods != null ? serviceGoods.toString() : "null"));
|
System.out.println("查询到的商品信息: " + (serviceGoods != null ? serviceGoods.toString() : "null"));
|
||||||
|
//派单模式
|
||||||
|
Integer dispatchtype=serviceGoods.getDispatchtype();
|
||||||
|
if (dispatchtype==null){
|
||||||
|
dispatchtype=1;
|
||||||
|
}
|
||||||
// 商品名、图片、类型、价格等
|
// 商品名、图片、类型、价格等
|
||||||
String productName = "";
|
String productName = "";
|
||||||
|
|
||||||
|
|
@ -919,7 +953,7 @@ public class OrderUtil {
|
||||||
order.setCreateType(1); // 用户自主下单
|
order.setCreateType(1); // 用户自主下单
|
||||||
order.setUname(user.getName());
|
order.setUname(user.getName());
|
||||||
System.out.println("订单基本信息设置完成");
|
System.out.println("订单基本信息设置完成");
|
||||||
|
order.setReceiveType(Long.valueOf(dispatchtype)); // 自由抢单
|
||||||
// 预约时间
|
// 预约时间
|
||||||
System.out.println("预约时间: " + payBefor.getMaketime());
|
System.out.println("预约时间: " + payBefor.getMaketime());
|
||||||
if (payBefor.getMaketime() != null && !payBefor.getMaketime().isEmpty()) {
|
if (payBefor.getMaketime() != null && !payBefor.getMaketime().isEmpty()) {
|
||||||
|
|
@ -1018,7 +1052,7 @@ public class OrderUtil {
|
||||||
//派单效验
|
//派单效验
|
||||||
dispatchOrderCheck(order);
|
dispatchOrderCheck(order);
|
||||||
//库存及销量变更
|
//库存及销量变更
|
||||||
updateInventoryAndSales(ptorderid, 1);
|
// updateInventoryAndSales(ptorderid, 1);
|
||||||
return order;
|
return order;
|
||||||
} else { // 其他类型
|
} else { // 其他类型
|
||||||
System.out.println("=== 处理其他类型订单 ===");
|
System.out.println("=== 处理其他类型订单 ===");
|
||||||
|
|
@ -1048,6 +1082,9 @@ public class OrderUtil {
|
||||||
jsonObject.put("name", "一口价订单支付成功,待派单");
|
jsonObject.put("name", "一口价订单支付成功,待派单");
|
||||||
orderLog.setContent(jsonObject.toJSONString());
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
int logInsertResult = orderLogService.insertOrderLog(orderLog);
|
int logInsertResult = orderLogService.insertOrderLog(orderLog);
|
||||||
|
if (logInsertResult>0){
|
||||||
|
DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
}
|
||||||
order.setStatus(1L); // 1=待预约
|
order.setStatus(1L); // 1=待预约
|
||||||
int orderUpdateResult = orderService.updateOrder(order);
|
int orderUpdateResult = orderService.updateOrder(order);
|
||||||
dispatchOrderCheck(order);
|
dispatchOrderCheck(order);
|
||||||
|
|
@ -1071,6 +1108,9 @@ public class OrderUtil {
|
||||||
jsonObject.put("name", "订单支付成功,待派单");
|
jsonObject.put("name", "订单支付成功,待派单");
|
||||||
orderLog.setContent(jsonObject.toJSONString());
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
int logInsertResult = orderLogService.insertOrderLog(orderLog);
|
int logInsertResult = orderLogService.insertOrderLog(orderLog);
|
||||||
|
if (logInsertResult>0){
|
||||||
|
DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
}
|
||||||
System.out.println("订单日志插入结果: " + logInsertResult);
|
System.out.println("订单日志插入结果: " + logInsertResult);
|
||||||
|
|
||||||
System.out.println("更新订单状态为待派单");
|
System.out.println("更新订单状态为待派单");
|
||||||
|
|
@ -1309,9 +1349,52 @@ public class OrderUtil {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 其他派单类型可扩展
|
|
||||||
result.put("success", true);
|
// 智能派单 - 调用DispatchUtil进行智能派单
|
||||||
result.put("msg", "无需指定工人派单");
|
try {
|
||||||
|
System.out.println("【OrderUtil】开始智能派单,订单ID: " + order.getId());
|
||||||
|
DispatchUtil.DispatchResult dispatchResult = DispatchUtil.dispatchOrder(order.getId());
|
||||||
|
|
||||||
|
if (dispatchResult.isSuccess()) {
|
||||||
|
Users selectedWorker = dispatchResult.getWorker();
|
||||||
|
System.out.println("【OrderUtil】智能派单成功,选中师傅: " + selectedWorker.getName());
|
||||||
|
|
||||||
|
// 更新订单状态和师傅信息
|
||||||
|
order.setStatus(1L); // 待服务
|
||||||
|
order.setWorkerId(selectedWorker.getId());
|
||||||
|
order.setWorkerPhone(selectedWorker.getPhone());
|
||||||
|
orderService.updateOrder(order);
|
||||||
|
|
||||||
|
// 添加订单日志
|
||||||
|
OrderLog orderLog = new OrderLog();
|
||||||
|
orderLog.setOid(order.getId());
|
||||||
|
orderLog.setOrderId(order.getOrderId());
|
||||||
|
orderLog.setTitle("智能派单成功");
|
||||||
|
orderLog.setType(new BigDecimal("1.0"));
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("name", "智能派单成功,师傅: " + selectedWorker.getName());
|
||||||
|
orderLog.setContent(jsonObject.toJSONString());
|
||||||
|
orderLogService.insertOrderLog(orderLog);
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("msg", "智能派单成功,师傅: " + selectedWorker.getName());
|
||||||
|
result.put("workerId", selectedWorker.getId());
|
||||||
|
result.put("workerName", selectedWorker.getName());
|
||||||
|
result.put("workerPhone", selectedWorker.getPhone());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("【OrderUtil】智能派单失败: " + dispatchResult.getMessage());
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("msg", "智能派单失败: " + dispatchResult.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("【OrderUtil】智能派单异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("msg", "智能派单异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1398,8 +1481,27 @@ public class OrderUtil {
|
||||||
* @param type 商品类型 1=服务类商品 2=商城类商品
|
* @param type 商品类型 1=服务类商品 2=商城类商品
|
||||||
* @return 处理结果,成功返回true,失败返回false
|
* @return 处理结果,成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* 库存及销量变更方法
|
||||||
|
* 根据订单ID更新商品/服务的销量和库存
|
||||||
|
*
|
||||||
|
* @param orderid 订单ID
|
||||||
|
* @param type 商品类型:1-服务类商品,2-商城类商品
|
||||||
|
* @return 处理结果,成功返回true,失败返回false
|
||||||
|
*/
|
||||||
public static boolean updateInventoryAndSales(String orderid, Integer type) {
|
public static boolean updateInventoryAndSales(String orderid, Integer type) {
|
||||||
try {
|
try {
|
||||||
|
// 参数验证
|
||||||
|
if (orderid == null || orderid.trim().isEmpty()) {
|
||||||
|
System.err.println("订单ID不能为空");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == null || (type != 1 && type != 2)) {
|
||||||
|
System.err.println("无效的商品类型,type: " + type + ", orderid: " + orderid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. 根据type查询订单数据
|
// 1. 根据type查询订单数据
|
||||||
Object order = null;
|
Object order = null;
|
||||||
if (type == 1) {
|
if (type == 1) {
|
||||||
|
|
@ -1410,9 +1512,6 @@ public class OrderUtil {
|
||||||
// 商城类商品,调用IGoodsOrderService查询订单数据
|
// 商城类商品,调用IGoodsOrderService查询订单数据
|
||||||
IGoodsOrderService goodsOrderService = SpringUtils.getBean(IGoodsOrderService.class);
|
IGoodsOrderService goodsOrderService = SpringUtils.getBean(IGoodsOrderService.class);
|
||||||
order = goodsOrderService.selectGoodsOrderByorderId(orderid);
|
order = goodsOrderService.selectGoodsOrderByorderId(orderid);
|
||||||
} else {
|
|
||||||
System.err.println("无效的商品类型,type: " + type + ", orderid: " + orderid);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
|
|
@ -1420,7 +1519,7 @@ public class OrderUtil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 查询商品/服务数据
|
// 2. 提取订单信息
|
||||||
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
||||||
Long productId = null;
|
Long productId = null;
|
||||||
Long orderNum = null;
|
Long orderNum = null;
|
||||||
|
|
@ -1440,6 +1539,13 @@ public class OrderUtil {
|
||||||
orderSku = goodsOrder.getSku();
|
orderSku = goodsOrder.getSku();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证商品ID
|
||||||
|
if (productId == null) {
|
||||||
|
System.err.println("订单商品ID为空,orderid: " + orderid + ", type: " + type);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询商品/服务数据
|
||||||
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(productId);
|
||||||
|
|
||||||
if (serviceGoods == null) {
|
if (serviceGoods == null) {
|
||||||
|
|
@ -1447,14 +1553,18 @@ public class OrderUtil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 增加销量
|
// 4. 增加销量(无论是否有SKU都要增加销量)
|
||||||
Long currentSales = serviceGoods.getSales() != null ? serviceGoods.getSales() : 0L;
|
Long currentSales = serviceGoods.getSales() != null ? serviceGoods.getSales() : 0L;
|
||||||
serviceGoods.setSales(currentSales + orderNum);
|
serviceGoods.setSales(currentSales + orderNum);
|
||||||
|
|
||||||
// 4. 更新库存
|
System.out.println("销量更新:商品ID: " + serviceGoods.getId() +
|
||||||
updateStock(serviceGoods, orderSku, orderNum);
|
", 原销量: " + currentSales + ", 增加销量: " + orderNum +
|
||||||
|
", 新销量: " + serviceGoods.getSales());
|
||||||
|
|
||||||
// 5. 保存更新后的商品/服务数据
|
// 5. 更新库存
|
||||||
|
updateStock(serviceGoods, orderSku, orderNum, type);
|
||||||
|
|
||||||
|
// 6. 保存更新后的商品/服务数据
|
||||||
int updateResult = serviceGoodsService.updateServiceGoods(serviceGoods);
|
int updateResult = serviceGoodsService.updateServiceGoods(serviceGoods);
|
||||||
|
|
||||||
if (updateResult > 0) {
|
if (updateResult > 0) {
|
||||||
|
|
@ -1480,9 +1590,9 @@ public class OrderUtil {
|
||||||
* @param orderid 订单ID
|
* @param orderid 订单ID
|
||||||
* @return 处理结果,成功返回true,失败返回false
|
* @return 处理结果,成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
public static boolean updateInventoryAndSales(String orderid) {
|
// public static boolean updateInventoryAndSales(String orderid) {
|
||||||
return updateInventoryAndSales(orderid, 1); // 默认为服务类商品
|
//// return updateInventoryAndSales(orderid, 1); // 默认为服务类商品
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新库存逻辑
|
* 更新库存逻辑
|
||||||
|
|
@ -1490,17 +1600,45 @@ public class OrderUtil {
|
||||||
* @param serviceGoods 商品/服务对象
|
* @param serviceGoods 商品/服务对象
|
||||||
* @param orderSku 订单SKU
|
* @param orderSku 订单SKU
|
||||||
* @param orderNum 订单数量
|
* @param orderNum 订单数量
|
||||||
|
* @param type 商品类型:1-服务类商品,2-商城类商品
|
||||||
*/
|
*/
|
||||||
private static void updateStock(ServiceGoods serviceGoods, String orderSku, Long orderNum) {
|
private static void updateStock(ServiceGoods serviceGoods, String orderSku, Long orderNum, Integer type) {
|
||||||
// 如果订单的sku为空或null,直接扣减ServiceGoods的库存
|
try {
|
||||||
if (orderSku == null || orderSku.trim().isEmpty()) {
|
// 参数验证
|
||||||
Long currentStock = serviceGoods.getStock() != null ? serviceGoods.getStock() : 0L;
|
if (serviceGoods == null) {
|
||||||
serviceGoods.setStock(Math.max(0, currentStock - orderNum)); // 确保库存不为负数
|
System.err.println("商品对象为空,无法更新库存");
|
||||||
System.out.println("直接扣减库存,商品ID: " + serviceGoods.getId() +
|
return;
|
||||||
", 扣减数量: " + orderNum + ", 剩余库存: " + serviceGoods.getStock());
|
}
|
||||||
} else {
|
|
||||||
// 如果订单的sku有值,在ServiceGoods的sku中查找对应的sku并扣减库存
|
if (orderNum == null || orderNum <= 0) {
|
||||||
updateSkuStock(serviceGoods, orderSku, orderNum);
|
System.err.println("订单数量无效,orderNum: " + orderNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果订单的sku为空或null,直接扣减ServiceGoods的库存
|
||||||
|
if (orderSku == null || orderSku.trim().isEmpty()) {
|
||||||
|
Long currentStock = serviceGoods.getStock() != null ? serviceGoods.getStock() : 0L;
|
||||||
|
Long newStock = Math.max(0, currentStock - orderNum); // 确保库存不为负数
|
||||||
|
serviceGoods.setStock(newStock);
|
||||||
|
|
||||||
|
System.out.println("直接扣减库存,商品ID: " + serviceGoods.getId() +
|
||||||
|
", 原库存: " + currentStock + ", 扣减数量: " + orderNum +
|
||||||
|
", 剩余库存: " + newStock);
|
||||||
|
} else {
|
||||||
|
// 根据商品类型选择不同的SKU更新方法
|
||||||
|
if (type == 1) {
|
||||||
|
// 服务类商品,使用原有的SKU更新逻辑
|
||||||
|
updateSkuStock(serviceGoods, orderSku, orderNum);
|
||||||
|
} else if (type == 2) {
|
||||||
|
// 商城类商品,使用新的SKU更新逻辑
|
||||||
|
updateGoodsSkuStock(serviceGoods, orderSku, orderNum);
|
||||||
|
} else {
|
||||||
|
System.err.println("无效的商品类型,type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("更新库存异常,商品ID: " + (serviceGoods != null ? serviceGoods.getId() : "null") +
|
||||||
|
", 错误: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1513,6 +1651,17 @@ public class OrderUtil {
|
||||||
*/
|
*/
|
||||||
private static void updateSkuStock(ServiceGoods serviceGoods, String orderSku, Long orderNum) {
|
private static void updateSkuStock(ServiceGoods serviceGoods, String orderSku, Long orderNum) {
|
||||||
try {
|
try {
|
||||||
|
// 参数验证
|
||||||
|
if (serviceGoods == null) {
|
||||||
|
System.err.println("商品对象为空,无法更新SKU库存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderSku == null || orderSku.trim().isEmpty()) {
|
||||||
|
System.err.println("订单SKU为空,无法更新SKU库存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String serviceSku = serviceGoods.getSku();
|
String serviceSku = serviceGoods.getSku();
|
||||||
if (serviceSku == null || serviceSku.trim().isEmpty()) {
|
if (serviceSku == null || serviceSku.trim().isEmpty()) {
|
||||||
System.err.println("商品SKU为空,无法更新SKU库存,商品ID: " + serviceGoods.getId());
|
System.err.println("商品SKU为空,无法更新SKU库存,商品ID: " + serviceGoods.getId());
|
||||||
|
|
@ -1520,7 +1669,13 @@ public class OrderUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析ServiceGoods的SKU JSON(复杂多规格格式)
|
// 解析ServiceGoods的SKU JSON(复杂多规格格式)
|
||||||
JSONObject skuJson = JSONObject.parseObject(serviceSku);
|
JSONObject skuJson;
|
||||||
|
try {
|
||||||
|
skuJson = JSONObject.parseObject(serviceSku);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("商品SKU JSON格式错误,商品ID: " + serviceGoods.getId() + ", SKU: " + serviceSku);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否是复杂多规格格式
|
// 检查是否是复杂多规格格式
|
||||||
if (!skuJson.containsKey("sku") || !skuJson.containsKey("type")) {
|
if (!skuJson.containsKey("sku") || !skuJson.containsKey("type")) {
|
||||||
|
|
@ -1536,7 +1691,13 @@ public class OrderUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析订单SKU(具体规格选择)
|
// 解析订单SKU(具体规格选择)
|
||||||
JSONObject orderSkuJson = JSONObject.parseObject(orderSku);
|
JSONObject orderSkuJson;
|
||||||
|
try {
|
||||||
|
orderSkuJson = JSONObject.parseObject(orderSku);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("订单SKU JSON格式错误,订单SKU: " + orderSku);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 在sku数组中查找匹配的规格
|
// 在sku数组中查找匹配的规格
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
@ -1558,8 +1719,8 @@ public class OrderUtil {
|
||||||
serviceGoods.setSku(skuJson.toJSONString());
|
serviceGoods.setSku(skuJson.toJSONString());
|
||||||
|
|
||||||
System.out.println("SKU库存更新成功,商品ID: " + serviceGoods.getId() +
|
System.out.println("SKU库存更新成功,商品ID: " + serviceGoods.getId() +
|
||||||
", 订单SKU: " + orderSku + ", 扣减数量: " + orderNum +
|
", 订单SKU: " + orderSku + ", 原库存: " + currentStock +
|
||||||
", 剩余库存: " + newStock);
|
", 扣减数量: " + orderNum + ", 剩余库存: " + newStock);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
|
@ -1574,15 +1735,153 @@ public class OrderUtil {
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
System.err.println("未找到匹配的SKU,商品ID: " + serviceGoods.getId() +
|
System.err.println("未找到匹配的SKU,商品ID: " + serviceGoods.getId() +
|
||||||
", 订单SKU: " + orderSku);
|
", 订单SKU: " + orderSku + ", 商品SKU数组大小: " + skuArray.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("更新SKU库存异常,商品ID: " + serviceGoods.getId() +
|
System.err.println("更新SKU库存异常,商品ID: " + (serviceGoods != null ? serviceGoods.getId() : "null") +
|
||||||
", 订单SKU: " + orderSku + ", 错误: " + e.getMessage());
|
", 订单SKU: " + orderSku + ", 错误: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新商城商品SKU库存
|
||||||
|
*
|
||||||
|
* @param serviceGoods 商品/服务对象
|
||||||
|
* @param orderSku 订单SKU(具体规格选择)
|
||||||
|
* @param orderNum 订单数量
|
||||||
|
*/
|
||||||
|
private static void updateGoodsSkuStock(ServiceGoods serviceGoods, String orderSku, Long orderNum) {
|
||||||
|
try {
|
||||||
|
// 参数验证
|
||||||
|
if (serviceGoods == null) {
|
||||||
|
System.err.println("商品对象为空,无法更新SKU库存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderSku == null || orderSku.trim().isEmpty()) {
|
||||||
|
System.err.println("订单SKU为空,无法更新SKU库存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String serviceSku = serviceGoods.getSku();
|
||||||
|
if (serviceSku == null || serviceSku.trim().isEmpty()) {
|
||||||
|
System.err.println("商品SKU为空,无法更新SKU库存,商品ID: " + serviceGoods.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析ServiceGoods的SKU JSON(商城商品格式)
|
||||||
|
JSONObject skuJson;
|
||||||
|
try {
|
||||||
|
skuJson = JSONObject.parseObject(serviceSku);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("商品SKU JSON格式错误,商品ID: " + serviceGoods.getId() + ", SKU: " + serviceSku);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否是商城商品格式
|
||||||
|
if (!skuJson.containsKey("sku") || !skuJson.containsKey("type")) {
|
||||||
|
System.err.println("商品SKU格式不是商城商品格式,商品ID: " + serviceGoods.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取sku数组
|
||||||
|
JSONArray skuArray = skuJson.getJSONArray("sku");
|
||||||
|
if (skuArray == null || skuArray.isEmpty()) {
|
||||||
|
System.err.println("商品SKU数组为空,商品ID: " + serviceGoods.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析订单SKU(具体规格选择)
|
||||||
|
JSONObject orderSkuJson;
|
||||||
|
try {
|
||||||
|
orderSkuJson = JSONObject.parseObject(orderSku);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("订单SKU JSON格式错误,订单SKU: " + orderSku);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在sku数组中查找匹配的规格
|
||||||
|
boolean found = false;
|
||||||
|
for (int i = 0; i < skuArray.size(); i++) {
|
||||||
|
JSONObject skuItem = skuArray.getJSONObject(i);
|
||||||
|
|
||||||
|
// 检查是否匹配订单SKU的"价格"属性
|
||||||
|
if (isGoodsSkuMatch(skuItem, orderSkuJson)) {
|
||||||
|
// 找到匹配的SKU,更新库存
|
||||||
|
String stockStr = skuItem.getString("stock");
|
||||||
|
|
||||||
|
if (stockStr != null && !stockStr.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
Long currentStock = Long.parseLong(stockStr);
|
||||||
|
Long newStock = Math.max(0, currentStock - orderNum); // 确保库存不为负数
|
||||||
|
skuItem.put("stock", newStock.toString());
|
||||||
|
|
||||||
|
// 更新ServiceGoods的sku字段
|
||||||
|
serviceGoods.setSku(skuJson.toJSONString());
|
||||||
|
|
||||||
|
System.out.println("商城商品SKU库存更新成功,商品ID: " + serviceGoods.getId() +
|
||||||
|
", 订单SKU: " + orderSku + ", 原库存: " + currentStock +
|
||||||
|
", 扣减数量: " + orderNum + ", 剩余库存: " + newStock);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.err.println("SKU库存格式错误,商品ID: " + serviceGoods.getId() +
|
||||||
|
", SKU: " + orderSku + ", 库存值: " + stockStr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.err.println("SKU库存为空,商品ID: " + serviceGoods.getId() + ", SKU: " + orderSku);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
System.err.println("未找到匹配的SKU,商品ID: " + serviceGoods.getId() +
|
||||||
|
", 订单SKU: " + orderSku + ", 商品SKU数组大小: " + skuArray.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("更新商城商品SKU库存异常,商品ID: " + (serviceGoods != null ? serviceGoods.getId() : "null") +
|
||||||
|
", 订单SKU: " + orderSku + ", 错误: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查商城商品SKU是否匹配
|
||||||
|
*
|
||||||
|
* @param skuItem 商品SKU项
|
||||||
|
* @param orderSkuJson 订单SKU JSON
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
private static boolean isGoodsSkuMatch(JSONObject skuItem, JSONObject orderSkuJson) {
|
||||||
|
try {
|
||||||
|
// 参数验证
|
||||||
|
if (skuItem == null || orderSkuJson == null) {
|
||||||
|
System.err.println("商城商品SKU匹配检查参数为空");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商城商品主要根据"价格"属性进行匹配
|
||||||
|
String orderPrice = orderSkuJson.getString("价格");
|
||||||
|
String skuPrice = skuItem.getString("价格");
|
||||||
|
|
||||||
|
if (orderPrice == null || skuPrice == null) {
|
||||||
|
System.err.println("商城商品SKU价格属性为空,订单价格: " + orderPrice + ", 商品价格: " + skuPrice);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果价格属性匹配,返回true
|
||||||
|
if (orderPrice.equals(skuPrice)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("商城商品SKU匹配检查异常: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查SKU是否匹配
|
* 检查SKU是否匹配
|
||||||
*
|
*
|
||||||
|
|
@ -1592,23 +1891,41 @@ public class OrderUtil {
|
||||||
*/
|
*/
|
||||||
private static boolean isSkuMatch(JSONObject skuItem, JSONObject orderSkuJson) {
|
private static boolean isSkuMatch(JSONObject skuItem, JSONObject orderSkuJson) {
|
||||||
try {
|
try {
|
||||||
|
// 参数验证
|
||||||
|
if (skuItem == null || orderSkuJson == null) {
|
||||||
|
System.err.println("SKU匹配检查参数为空");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义需要跳过的非属性字段
|
||||||
|
Set<String> skipFields = new HashSet<>(Arrays.asList(
|
||||||
|
"price", "groupprice", "seckillprice", "stock", "pic", "image"
|
||||||
|
));
|
||||||
|
|
||||||
// 遍历订单SKU的所有属性,检查是否与商品SKU项匹配
|
// 遍历订单SKU的所有属性,检查是否与商品SKU项匹配
|
||||||
for (String key : orderSkuJson.keySet()) {
|
for (String key : orderSkuJson.keySet()) {
|
||||||
// 跳过非属性字段(如price、stock等)
|
// 跳过非属性字段
|
||||||
if ("price".equals(key) || "groupprice".equals(key) ||
|
if (skipFields.contains(key)) {
|
||||||
"seckillprice".equals(key) || "stock".equals(key) ||
|
|
||||||
"pic".equals(key)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String orderValue = orderSkuJson.getString(key);
|
String orderValue = orderSkuJson.getString(key);
|
||||||
String skuValue = skuItem.getString(key);
|
String skuValue = skuItem.getString(key);
|
||||||
|
|
||||||
|
// 如果订单SKU中的属性在商品SKU中不存在,返回false
|
||||||
|
if (skuValue == null) {
|
||||||
|
System.err.println("商品SKU中缺少属性: " + key + ", 订单SKU值: " + orderValue);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 如果属性值不匹配,返回false
|
// 如果属性值不匹配,返回false
|
||||||
if (!orderValue.equals(skuValue)) {
|
if (!orderValue.equals(skuValue)) {
|
||||||
|
System.err.println("SKU属性不匹配,属性: " + key +
|
||||||
|
", 订单值: " + orderValue + ", 商品值: " + skuValue);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("SKU匹配检查异常: " + e.getMessage());
|
System.err.println("SKU匹配检查异常: " + e.getMessage());
|
||||||
|
|
@ -1616,45 +1933,50 @@ public class OrderUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// 构造一个测试用的json字符串
|
|
||||||
String testJson = "{\"project\":{\"name\":\"项目费用\",\"price\":1132.00},\"reduction\":{\"name\":\"优惠金额\",\"price\":\"1\"},\"deposit\":{\"name\":\"定金\",\"price\":\"10\"},\"basic\":[{\"name\":\"测试基建2\",\"select\":true},{\"name\":\"测试基建5\",\"select\":true},{\"name\":\"测试基建8\",\"select\":true}],\"craft\":[{\"name\":\"三挂一方柜\",\"price\":\"336.00\",\"pid\":192,\"id\":1889,\"count\":3}],\"material\":[{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1241,\"pid\":93,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1240,\"pid\":93,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1196,\"pid\":93,\"count\":1},{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1197,\"pid\":93,\"count\":1},{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1197,\"pid\":92,\"count\":1},{\"name\":\"111\",\"price\":\"10.00\",\"id\":1250,\"pid\":92,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1196,\"pid\":92,\"count\":2}]}";
|
|
||||||
OrderUtil util = new OrderUtil();
|
|
||||||
JSONObject result = util.getbaojiajson(testJson);
|
|
||||||
System.out.println("处理后的结果: " + result.toJSONString());
|
// public static void main(String[] args) {
|
||||||
|
// // 构造一个测试用的json字符串
|
||||||
// 测试库存及销量变更方法
|
// String testJson = "{\"project\":{\"name\":\"项目费用\",\"price\":1132.00},\"reduction\":{\"name\":\"优惠金额\",\"price\":\"1\"},\"deposit\":{\"name\":\"定金\",\"price\":\"10\"},\"basic\":[{\"name\":\"测试基建2\",\"select\":true},{\"name\":\"测试基建5\",\"select\":true},{\"name\":\"测试基建8\",\"select\":true}],\"craft\":[{\"name\":\"三挂一方柜\",\"price\":\"336.00\",\"pid\":192,\"id\":1889,\"count\":3}],\"material\":[{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1241,\"pid\":93,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1240,\"pid\":93,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1196,\"pid\":93,\"count\":1},{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1197,\"pid\":93,\"count\":1},{\"name\":\"其他辅料面议项\",\"price\":\"1.00\",\"id\":1197,\"pid\":92,\"count\":1},{\"name\":\"111\",\"price\":\"10.00\",\"id\":1250,\"pid\":92,\"count\":1},{\"name\":\"除味剂\",\"price\":\"28.00\",\"id\":1196,\"pid\":92,\"count\":2}]}";
|
||||||
System.out.println("=== 测试库存及销量变更方法 ===");
|
// OrderUtil util = new OrderUtil();
|
||||||
|
// JSONObject result = util.getbaojiajson(testJson);
|
||||||
// 测试服务类商品(type=1)
|
// System.out.println("处理后的结果: " + result.toJSONString());
|
||||||
String serviceOrderId = "TEST_SERVICE_ORDER_001";
|
//
|
||||||
boolean serviceResult = updateInventoryAndSales(serviceOrderId, 1);
|
// // 测试库存及销量变更方法
|
||||||
System.out.println("服务类商品库存及销量变更测试结果: " + serviceResult);
|
// System.out.println("=== 测试库存及销量变更方法 ===");
|
||||||
|
//
|
||||||
// 测试商城类商品(type=2)
|
// // 测试服务类商品(type=1)
|
||||||
String goodsOrderId = "TEST_GOODS_ORDER_001";
|
// String serviceOrderId = "TEST_SERVICE_ORDER_001";
|
||||||
boolean goodsResult = updateInventoryAndSales(goodsOrderId, 2);
|
// boolean serviceResult = updateInventoryAndSales(serviceOrderId, 1);
|
||||||
System.out.println("商城类商品库存及销量变更测试结果: " + goodsResult);
|
// System.out.println("服务类商品库存及销量变更测试结果: " + serviceResult);
|
||||||
|
//
|
||||||
// 测试兼容旧版本(默认为服务类商品)
|
// // 测试商城类商品(type=2)
|
||||||
String orderId = "TEST_ORDER_001";
|
// String goodsOrderId = "TEST_GOODS_ORDER_001";
|
||||||
boolean result2 = updateInventoryAndSales(orderId);
|
// boolean goodsResult = updateInventoryAndSales(goodsOrderId, 2);
|
||||||
System.out.println("兼容旧版本库存及销量变更测试结果: " + result2);
|
// System.out.println("商城类商品库存及销量变更测试结果: " + goodsResult);
|
||||||
|
//
|
||||||
// 测试SKU匹配逻辑
|
// // 测试兼容旧版本(默认为服务类商品)
|
||||||
System.out.println("=== 测试SKU匹配逻辑 ===");
|
// String orderId = "TEST_ORDER_001";
|
||||||
String testOrderSku = "{\"颜色\":\"黑\",\"大小\":\"小\",\"尺寸\":\"300*300\",\"pic\":[\"https://img.huafurenjia.cn/images/2025-07-15/c638e39be08941aaaa47ee926a1ac5e5.png\"],\"price\":\"100\",\"groupprice\":\"100\",\"seckillprice\":\"99\",\"stock\":\"100\"}";
|
// boolean result2 = updateInventoryAndSales(orderId);
|
||||||
JSONObject orderSkuJson = JSONObject.parseObject(testOrderSku);
|
// System.out.println("兼容旧版本库存及销量变更测试结果: " + result2);
|
||||||
|
//
|
||||||
// 模拟一个SKU项进行匹配测试
|
// // 测试SKU匹配逻辑
|
||||||
JSONObject testSkuItem = new JSONObject();
|
// System.out.println("=== 测试SKU匹配逻辑 ===");
|
||||||
testSkuItem.put("颜色", "黑");
|
// String testOrderSku = "{\"颜色\":\"黑\",\"大小\":\"小\",\"尺寸\":\"300*300\",\"pic\":[\"https://img.huafurenjia.cn/images/2025-07-15/c638e39be08941aaaa47ee926a1ac5e5.png\"],\"price\":\"100\",\"groupprice\":\"100\",\"seckillprice\":\"99\",\"stock\":\"100\"}";
|
||||||
testSkuItem.put("大小", "小");
|
// JSONObject orderSkuJson = JSONObject.parseObject(testOrderSku);
|
||||||
testSkuItem.put("尺寸", "300*300");
|
//
|
||||||
testSkuItem.put("price", "100");
|
// // 模拟一个SKU项进行匹配测试
|
||||||
testSkuItem.put("stock", "100");
|
// JSONObject testSkuItem = new JSONObject();
|
||||||
|
// testSkuItem.put("颜色", "黑");
|
||||||
boolean matchResult = isSkuMatch(testSkuItem, orderSkuJson);
|
// testSkuItem.put("大小", "小");
|
||||||
System.out.println("SKU匹配测试结果: " + matchResult);
|
// testSkuItem.put("尺寸", "300*300");
|
||||||
}
|
// testSkuItem.put("price", "100");
|
||||||
|
// testSkuItem.put("stock", "100");
|
||||||
|
//
|
||||||
|
// boolean matchResult = isSkuMatch(testSkuItem, orderSkuJson);
|
||||||
|
// System.out.println("SKU匹配测试结果: " + matchResult);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ public class PageUtil {
|
||||||
pageData.put("last_page", lastPage);
|
pageData.put("last_page", lastPage);
|
||||||
pageData.put("next_page_url", nextPageUrl);
|
pageData.put("next_page_url", nextPageUrl);
|
||||||
pageData.put("per_page", String.valueOf(perPage));
|
pageData.put("per_page", String.valueOf(perPage));
|
||||||
//pageData.put("prev_page_url", prevPageUrl);
|
pageData.put("prev_page_url", prevPageUrl);
|
||||||
//pageData.put("to", to);
|
pageData.put("to", to);
|
||||||
pageData.put("total", total);
|
pageData.put("total", total);
|
||||||
|
|
||||||
return pageData;
|
return pageData;
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,8 @@ public class PayBeforeUtil {
|
||||||
Long serviceId, Long orderType, String sku, String grouporderid,
|
Long serviceId, Long orderType, String sku, String grouporderid,
|
||||||
Long addressid, String maketime, String attachments,Long servicetype,Long baojiaid,String lastorderid) {
|
Long addressid, String maketime, String attachments,Long servicetype,Long baojiaid,String lastorderid) {
|
||||||
try {
|
try {
|
||||||
// 计算会员优惠和服务金抵扣
|
// 计算会员优惠
|
||||||
BigDecimal memberMoney = BigDecimal.ZERO;
|
BigDecimal memberMoney = BigDecimal.ZERO;
|
||||||
BigDecimal serviceMoney = BigDecimal.ZERO;
|
|
||||||
BigDecimal shopMoney = BigDecimal.ZERO;
|
|
||||||
try {
|
try {
|
||||||
SiteConfig configQuery = new SiteConfig();
|
SiteConfig configQuery = new SiteConfig();
|
||||||
configQuery.setName("config_one");
|
configQuery.setName("config_one");
|
||||||
|
|
@ -72,34 +70,21 @@ public class PayBeforeUtil {
|
||||||
memberMoney = amount.multiply(discountRate);
|
memberMoney = amount.multiply(discountRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 服务金抵扣
|
|
||||||
if (servicetype != null && servicetype == 1) {
|
|
||||||
Integer serviceFee = configJson.getInteger("servicefee");
|
|
||||||
if (serviceFee != null && serviceFee > 0) {
|
|
||||||
Users userDb = usersService.selectUsersById(user.getId());
|
|
||||||
if (userDb != null && userDb.getServicefee() != null && userDb.getServicefee().compareTo(BigDecimal.ZERO) > 0) {
|
|
||||||
BigDecimal serviceRate = BigDecimal.valueOf(serviceFee).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP);
|
|
||||||
serviceMoney = userDb.getServicefee().multiply(serviceRate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 购物金抵扣(当servicetype=2时)
|
|
||||||
if (servicetype != null && servicetype == 2) {
|
|
||||||
Integer consumption = configJson.getInteger("consumption");
|
|
||||||
if (consumption != null && consumption > 0) {
|
|
||||||
Users userDb = usersService.selectUsersById(user.getId());
|
|
||||||
if (userDb != null && userDb.getConsumption() != null && userDb.getConsumption().compareTo(BigDecimal.ZERO) > 0) {
|
|
||||||
BigDecimal consumptionRate = BigDecimal.valueOf(consumption).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP);
|
|
||||||
shopMoney = userDb.getConsumption().multiply(consumptionRate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
memberMoney = BigDecimal.ZERO;
|
memberMoney = BigDecimal.ZERO;
|
||||||
serviceMoney = BigDecimal.ZERO;
|
}
|
||||||
shopMoney = BigDecimal.ZERO;
|
|
||||||
|
// 使用BenefitPointsUtil计算服务金和购物金抵扣
|
||||||
|
BigDecimal serviceMoney = BigDecimal.ZERO;
|
||||||
|
BigDecimal shopMoney = BigDecimal.ZERO;
|
||||||
|
if (servicetype != null) {
|
||||||
|
BenefitPointsUtil.BenefitDeductionResult deductionResult = BenefitPointsUtil.getBenefitDeduction(user, amount, servicetype);
|
||||||
|
if (deductionResult.isSuccess()) {
|
||||||
|
serviceMoney = deductionResult.getServiceMoney();
|
||||||
|
shopMoney = deductionResult.getShopMoney();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UsersPayBefor payBefore = new UsersPayBefor();
|
UsersPayBefor payBefore = new UsersPayBefor();
|
||||||
payBefore.setUid(user.getId());
|
payBefore.setUid(user.getId());
|
||||||
|
|
@ -475,7 +460,7 @@ public class PayBeforeUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算尾款金额:总金额 - 定金 - 优惠金额
|
// 计算尾款金额:总金额 - 定金 - 优惠金额
|
||||||
BigDecimal finalPaymentAmount = totalAmount.subtract(depositPrice).subtract(reductionPrice);
|
BigDecimal finalPaymentAmount = orderLog.getPrice();
|
||||||
|
|
||||||
// 查询预支付表中是否已有尾款数据
|
// 查询预支付表中是否已有尾款数据
|
||||||
UsersPayBefor existingFinalPayment = queryPayBeforeByOrderidAndType(orderLog.getOrderId(), 9L);
|
UsersPayBefor existingFinalPayment = queryPayBeforeByOrderidAndType(orderLog.getOrderId(), 9L);
|
||||||
|
|
|
||||||
|
|
@ -100,12 +100,12 @@ public class RefundUtil {
|
||||||
System.out.println("步骤3: 退款成功,开始处理积分和服务金消费金...");
|
System.out.println("步骤3: 退款成功,开始处理积分和服务金消费金...");
|
||||||
try {
|
try {
|
||||||
// 处理积分扣除
|
// 处理积分扣除
|
||||||
System.out.println(" 3.1: 处理积分扣除...");
|
// System.out.println(" 3.1: 处理积分扣除...");
|
||||||
processIntegralDeduction(payBefor);
|
// processIntegralDeduction(payBefor);
|
||||||
|
|
||||||
// 处理服务金和消费金扣除
|
// // 处理服务金和消费金扣除
|
||||||
System.out.println(" 3.2: 处理服务金和消费金增加...");
|
// System.out.println(" 3.2: 处理服务金和消费金增加...");
|
||||||
processBenefitDeduction(payBefor);
|
// processBenefitDeduction(payBefor);
|
||||||
|
|
||||||
// 修改状态为3
|
// 修改状态为3
|
||||||
System.out.println(" 3.3: 更新订单状态为已退款...");
|
System.out.println(" 3.3: 更新订单状态为已退款...");
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ public class WechatPayUtil {
|
||||||
private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款
|
private static final String WECHAT_TRANSFER_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款
|
||||||
|
|
||||||
|
|
||||||
public static final String PAY_FH = "https://12cb4ff9.r3.cpolar.top/";
|
public static final String PAY_FH = "https://73bb8889.r3.cpolar.top/";
|
||||||
/**
|
/**
|
||||||
* 其他配置常量
|
* 其他配置常量
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,10 @@
|
||||||
package com.ruoyi.system.ControllerUtil;
|
package com.ruoyi.system.ControllerUtil;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
import com.ruoyi.system.domain.Order;
|
import com.ruoyi.system.domain.*;
|
||||||
import com.ruoyi.system.domain.Users;
|
import com.ruoyi.system.service.*;
|
||||||
import com.ruoyi.system.domain.WorkerLevel;
|
|
||||||
import com.ruoyi.system.domain.WorkerMarginLog;
|
|
||||||
import com.ruoyi.system.domain.UsersPayBefor;
|
|
||||||
import com.ruoyi.system.domain.WorkerMoneyLog;
|
|
||||||
import com.ruoyi.system.domain.OrderLog;
|
|
||||||
import com.ruoyi.system.domain.ServiceGoods;
|
|
||||||
import com.ruoyi.system.service.IUsersService;
|
|
||||||
import com.ruoyi.system.service.IWorkerLevelService;
|
|
||||||
import com.ruoyi.system.service.IWorkerMarginLogService;
|
|
||||||
import com.ruoyi.system.service.IUsersPayBeforService;
|
|
||||||
import com.ruoyi.system.service.IWorkerMoneyLogService;
|
|
||||||
import com.ruoyi.system.service.IOrderLogService;
|
|
||||||
import com.ruoyi.system.service.IOrderService;
|
|
||||||
import com.ruoyi.system.service.IServiceGoodsService;
|
|
||||||
import com.ruoyi.system.service.ISiteConfigService;
|
|
||||||
import com.ruoyi.system.domain.SiteConfig;
|
|
||||||
import com.ruoyi.system.service.IQuoteMaterialService;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@ -30,7 +14,6 @@ import java.math.RoundingMode;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.ruoyi.system.domain.QuoteMaterial;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 师傅分佣处理工具类
|
* 师傅分佣处理工具类
|
||||||
|
|
@ -54,7 +37,56 @@ public class WorkerCommissionUtil {
|
||||||
private static final IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
private static final IServiceGoodsService serviceGoodsService = SpringUtils.getBean(IServiceGoodsService.class);
|
||||||
private static final ISiteConfigService siteConfigService = SpringUtils.getBean(ISiteConfigService.class);
|
private static final ISiteConfigService siteConfigService = SpringUtils.getBean(ISiteConfigService.class);
|
||||||
private static final IQuoteMaterialService quoteMaterialService = SpringUtils.getBean(IQuoteMaterialService.class);
|
private static final IQuoteMaterialService quoteMaterialService = SpringUtils.getBean(IQuoteMaterialService.class);
|
||||||
|
private static final IUserUseSecondaryCardService userUseSecondaryCardService = SpringUtils.getBean(IUserUseSecondaryCardService.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取订单总金额
|
||||||
|
* 计算订单的总金额:totalPrice + doorFee + deposit + finalPayment + priceDifference + discountAmount
|
||||||
|
*
|
||||||
|
* @param order 订单对象
|
||||||
|
* @return 订单总金额
|
||||||
|
*/
|
||||||
|
public static BigDecimal getOrderTotalAmount(Order order) {
|
||||||
|
logger.info("=== 开始获取订单总金额 ===");
|
||||||
|
logger.info("订单ID: {}, 订单号: {}", order.getId(), order.getOrderId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 订单总金额 (Order.total_price)
|
||||||
|
BigDecimal totalPrice = order.getTotalPrice();
|
||||||
|
if (totalPrice == null) {
|
||||||
|
totalPrice = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 上门费 (type=7)
|
||||||
|
BigDecimal doorFee = getPaymentAmount(order.getOrderId(), 7L);
|
||||||
|
|
||||||
|
// 3. 定金 (type=8)
|
||||||
|
BigDecimal deposit = getPaymentAmount(order.getOrderId(), 8L);
|
||||||
|
|
||||||
|
// 4. 尾款 (type=9)
|
||||||
|
BigDecimal finalPayment = getPaymentAmount(order.getOrderId(), 9L);
|
||||||
|
|
||||||
|
// 5. 差价 (type=10)
|
||||||
|
BigDecimal priceDifference = getPaymentAmount(order.getOrderId(), 10L);
|
||||||
|
|
||||||
|
// 6. 优惠金额 (从type=5的日志中解析)
|
||||||
|
BigDecimal discountAmount = getDiscountAmount(order.getId());
|
||||||
|
|
||||||
|
// 7. 计算总金额
|
||||||
|
BigDecimal totalAmount = totalPrice.add(doorFee).add(deposit).add(finalPayment).add(priceDifference).subtract(discountAmount);
|
||||||
|
|
||||||
|
logger.info("订单总金额计算完成: {}元", totalAmount);
|
||||||
|
logger.info("计算明细 - 订单总金额: {}, 上门费: {}, 定金: {}, 尾款: {}, 差价: {}, 优惠: {}",
|
||||||
|
totalPrice, doorFee, deposit, finalPayment, priceDifference, discountAmount);
|
||||||
|
|
||||||
|
return totalAmount;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取订单总金额异常", e);
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取订单金额组成
|
* 获取订单金额组成
|
||||||
* 详细分析订单总金额的各个组成部分
|
* 详细分析订单总金额的各个组成部分
|
||||||
|
|
@ -195,44 +227,48 @@ public class WorkerCommissionUtil {
|
||||||
BigDecimal totalDiscount = BigDecimal.ZERO;
|
BigDecimal totalDiscount = BigDecimal.ZERO;
|
||||||
|
|
||||||
if (logList != null && !logList.isEmpty()) {
|
if (logList != null && !logList.isEmpty()) {
|
||||||
for (OrderLog log : logList) {
|
if (logList.getFirst().getReductionPrice()!=null){
|
||||||
String content = log.getContent();
|
totalDiscount=logList.getFirst().getReductionPrice();
|
||||||
if (content != null && !content.trim().isEmpty()) {
|
|
||||||
try {
|
|
||||||
// 解析content中的JSON数据
|
|
||||||
JSONObject contentJson = JSONObject.parseObject(content);
|
|
||||||
|
|
||||||
// 查找reduction字段
|
|
||||||
if (contentJson.containsKey("reduction")) {
|
|
||||||
Object reductionObj = contentJson.get("reduction");
|
|
||||||
|
|
||||||
if (reductionObj instanceof JSONObject) {
|
|
||||||
JSONObject reductionJson = (JSONObject) reductionObj;
|
|
||||||
String priceStr = reductionJson.getString("price");
|
|
||||||
if (priceStr != null && !priceStr.trim().isEmpty()) {
|
|
||||||
BigDecimal discount = new BigDecimal(priceStr);
|
|
||||||
totalDiscount = totalDiscount.add(discount);
|
|
||||||
logger.debug("从日志中解析到优惠金额: {}元", discount);
|
|
||||||
}
|
|
||||||
} else if (reductionObj instanceof String) {
|
|
||||||
// 如果reduction是字符串,尝试解析
|
|
||||||
String reductionStr = (String) reductionObj;
|
|
||||||
if (reductionStr.contains("price")) {
|
|
||||||
JSONObject reductionJson = JSONObject.parseObject(reductionStr);
|
|
||||||
String priceStr = reductionJson.getString("price");
|
|
||||||
if (priceStr != null && !priceStr.trim().isEmpty()) {
|
|
||||||
BigDecimal discount = new BigDecimal(priceStr);
|
|
||||||
totalDiscount = totalDiscount.add(discount);
|
|
||||||
logger.debug("从字符串中解析到优惠金额: {}元", discount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("解析订单日志优惠金额失败,日志ID: {}, 内容: {}", log.getId(), content, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for (OrderLog log : logList) {
|
||||||
|
// String content = log.getContent();
|
||||||
|
// if (content != null && !content.trim().isEmpty()) {
|
||||||
|
// try {
|
||||||
|
// // 解析content中的JSON数据
|
||||||
|
// JSONObject contentJson = JSONObject.parseObject(content);
|
||||||
|
//
|
||||||
|
// // 查找reduction字段
|
||||||
|
// if (contentJson.containsKey("reduction")) {
|
||||||
|
// Object reductionObj = contentJson.get("reduction");
|
||||||
|
//
|
||||||
|
// if (reductionObj instanceof JSONObject) {
|
||||||
|
// JSONObject reductionJson = (JSONObject) reductionObj;
|
||||||
|
// String priceStr = reductionJson.getString("price");
|
||||||
|
// if (priceStr != null && !priceStr.trim().isEmpty()) {
|
||||||
|
// BigDecimal discount = new BigDecimal(priceStr);
|
||||||
|
// totalDiscount = totalDiscount.add(discount);
|
||||||
|
// logger.debug("从日志中解析到优惠金额: {}元", discount);
|
||||||
|
// }
|
||||||
|
// } else if (reductionObj instanceof String) {
|
||||||
|
// // 如果reduction是字符串,尝试解析
|
||||||
|
// String reductionStr = (String) reductionObj;
|
||||||
|
// if (reductionStr.contains("price")) {
|
||||||
|
// JSONObject reductionJson = JSONObject.parseObject(reductionStr);
|
||||||
|
// String priceStr = reductionJson.getString("price");
|
||||||
|
// if (priceStr != null && !priceStr.trim().isEmpty()) {
|
||||||
|
// BigDecimal discount = new BigDecimal(priceStr);
|
||||||
|
// totalDiscount = totalDiscount.add(discount);
|
||||||
|
// logger.debug("从字符串中解析到优惠金额: {}元", discount);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// logger.warn("解析订单日志优惠金额失败,日志ID: {}, 内容: {}", log.getId(), content, e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("订单 {} 总优惠金额: {}元", orderId, totalDiscount);
|
logger.debug("订单 {} 总优惠金额: {}元", orderId, totalDiscount);
|
||||||
|
|
@ -593,6 +629,13 @@ public class WorkerCommissionUtil {
|
||||||
|
|
||||||
BigDecimal materialFee = (BigDecimal) amountComposition.get("materialFee");
|
BigDecimal materialFee = (BigDecimal) amountComposition.get("materialFee");
|
||||||
|
|
||||||
|
// 获取用户支付总金额 (allmoney)
|
||||||
|
BigDecimal allmoney = (BigDecimal) amountComposition.get("totalPaymentAmount");
|
||||||
|
if (allmoney == null) {
|
||||||
|
allmoney = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
logger.info("用户支付总金额 (allmoney): {}元", allmoney);
|
||||||
|
|
||||||
// 4. 获取分佣基数
|
// 4. 获取分佣基数
|
||||||
BigDecimal serviceCommissionBase = getCommissionBase(orderId);
|
BigDecimal serviceCommissionBase = getCommissionBase(orderId);
|
||||||
BigDecimal materialCommissionBase = getMaterialCommissionBase();
|
BigDecimal materialCommissionBase = getMaterialCommissionBase();
|
||||||
|
|
@ -654,7 +697,8 @@ public class WorkerCommissionUtil {
|
||||||
.fluentPut("priceDifference", priceDifference)
|
.fluentPut("priceDifference", priceDifference)
|
||||||
.fluentPut("discountAmount", discountAmount)
|
.fluentPut("discountAmount", discountAmount)
|
||||||
.fluentPut("doorFee", doorFee)
|
.fluentPut("doorFee", doorFee)
|
||||||
.fluentPut("materialFee", materialFee));
|
.fluentPut("materialFee", materialFee)
|
||||||
|
.fluentPut("allmoney", allmoney));
|
||||||
result.put("commissionBases", new JSONObject()
|
result.put("commissionBases", new JSONObject()
|
||||||
.fluentPut("serviceCommissionBase", serviceCommissionBase)
|
.fluentPut("serviceCommissionBase", serviceCommissionBase)
|
||||||
.fluentPut("serviceCommissionBasePercent", serviceCommissionBase.multiply(new BigDecimal("100")))
|
.fluentPut("serviceCommissionBasePercent", serviceCommissionBase.multiply(new BigDecimal("100")))
|
||||||
|
|
@ -672,6 +716,31 @@ public class WorkerCommissionUtil {
|
||||||
// 14. 分佣完成后的业务处理
|
// 14. 分佣完成后的业务处理
|
||||||
handleCommissionCompletion(order, finalCommissionWithDoorFee, warrantyAmount, commissionSummary,serviceCommissionBase);
|
handleCommissionCompletion(order, finalCommissionWithDoorFee, warrantyAmount, commissionSummary,serviceCommissionBase);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改库存及销量
|
||||||
|
OrderUtil.updateInventoryAndSales(order.getOrderId(), 1);
|
||||||
logger.info("=== 师傅分佣计算完成 ===");
|
logger.info("=== 师傅分佣计算完成 ===");
|
||||||
logger.info("订单号: {}", order.getOrderId());
|
logger.info("订单号: {}", order.getOrderId());
|
||||||
logger.info("师傅ID: {}", order.getWorkerId());
|
logger.info("师傅ID: {}", order.getWorkerId());
|
||||||
|
|
@ -771,15 +840,12 @@ public class WorkerCommissionUtil {
|
||||||
logger.error("师傅信息更新失败");
|
logger.error("师傅信息更新失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 5. 检查是否已存在质保金流水记录,避免重复插入
|
||||||
// 5. 检查是否已存在质保金流水记录,避免重复插入
|
|
||||||
WorkerMarginLog queryMarginLog = new WorkerMarginLog();
|
WorkerMarginLog queryMarginLog = new WorkerMarginLog();
|
||||||
queryMarginLog.setUid(order.getWorkerId());
|
queryMarginLog.setUid(order.getWorkerId());
|
||||||
queryMarginLog.setOid(order.getId());
|
queryMarginLog.setOid(order.getId());
|
||||||
queryMarginLog.setOrderId(order.getOrderId());
|
queryMarginLog.setOrderId(order.getOrderId());
|
||||||
|
|
||||||
List<WorkerMarginLog> existingMarginLogs = workerMarginLogService.selectWorkerMarginLogList(queryMarginLog);
|
List<WorkerMarginLog> existingMarginLogs = workerMarginLogService.selectWorkerMarginLogList(queryMarginLog);
|
||||||
|
|
||||||
if (existingMarginLogs != null && !existingMarginLogs.isEmpty()) {
|
if (existingMarginLogs != null && !existingMarginLogs.isEmpty()) {
|
||||||
logger.warn("订单 {} 的师傅 {} 质保金流水记录已存在,跳过插入", order.getOrderId(), order.getWorkerId());
|
logger.warn("订单 {} 的师傅 {} 质保金流水记录已存在,跳过插入", order.getOrderId(), order.getWorkerId());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -800,15 +866,12 @@ public class WorkerCommissionUtil {
|
||||||
logger.error("师傅质保金流水记录添加失败");
|
logger.error("师傅质保金流水记录添加失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 检查是否已存在佣金流水记录,避免重复插入
|
// 6. 检查是否已存在佣金流水记录,避免重复插入
|
||||||
WorkerMoneyLog queryMoneyLog = new WorkerMoneyLog();
|
WorkerMoneyLog queryMoneyLog = new WorkerMoneyLog();
|
||||||
queryMoneyLog.setWorkerId(order.getWorkerId());
|
queryMoneyLog.setWorkerId(order.getWorkerId());
|
||||||
queryMoneyLog.setOid(order.getId());
|
queryMoneyLog.setOid(order.getId());
|
||||||
queryMoneyLog.setOrderId(order.getOrderId());
|
queryMoneyLog.setOrderId(order.getOrderId());
|
||||||
|
|
||||||
List<WorkerMoneyLog> existingMoneyLogs = workerMoneyLogService.selectWorkerMoneyLogList(queryMoneyLog);
|
List<WorkerMoneyLog> existingMoneyLogs = workerMoneyLogService.selectWorkerMoneyLogList(queryMoneyLog);
|
||||||
|
|
||||||
if (existingMoneyLogs != null && !existingMoneyLogs.isEmpty()) {
|
if (existingMoneyLogs != null && !existingMoneyLogs.isEmpty()) {
|
||||||
logger.warn("订单 {} 的师傅 {} 佣金流水记录已存在,跳过插入", order.getOrderId(), order.getWorkerId());
|
logger.warn("订单 {} 的师傅 {} 佣金流水记录已存在,跳过插入", order.getOrderId(), order.getWorkerId());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1501,6 +1564,75 @@ public class WorkerCommissionUtil {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算并更新订单总金额(用于开票)
|
||||||
|
* 公式:上门费 + 服务费用 + 材料费用 + 尾款 + 差价 + 定金 - 优惠费用
|
||||||
|
*
|
||||||
|
* @param order 订单对象
|
||||||
|
* @param amountComposition 订单金额组成
|
||||||
|
*/
|
||||||
|
private static void updateOrderTotalPriceForInvoice(Order order, JSONObject amountComposition) {
|
||||||
|
logger.info("=== 开始计算并更新订单总金额(用于开票) ===");
|
||||||
|
logger.info("订单ID: {}, 订单号: {}", order.getId(), order.getOrderId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 获取各项金额
|
||||||
|
BigDecimal doorFee = (BigDecimal) amountComposition.get("doorFee");
|
||||||
|
//订单初始费用
|
||||||
|
BigDecimal totalPrice = (BigDecimal) amountComposition.get("totalPrice");
|
||||||
|
BigDecimal serviceFee = (BigDecimal) amountComposition.get("serviceFee");
|
||||||
|
BigDecimal materialFee = (BigDecimal) amountComposition.get("materialFee");
|
||||||
|
BigDecimal finalPayment = (BigDecimal) amountComposition.get("finalPayment");
|
||||||
|
BigDecimal priceDifference = (BigDecimal) amountComposition.get("priceDifference");
|
||||||
|
BigDecimal deposit = (BigDecimal) amountComposition.get("deposit");
|
||||||
|
BigDecimal discountAmount = (BigDecimal) amountComposition.get("discountAmount");
|
||||||
|
|
||||||
|
// 2. 确保金额不为null
|
||||||
|
if (totalPrice == null) totalPrice = BigDecimal.ZERO;
|
||||||
|
if (doorFee == null) doorFee = BigDecimal.ZERO;
|
||||||
|
if (serviceFee == null) serviceFee = BigDecimal.ZERO;
|
||||||
|
if (materialFee == null) materialFee = BigDecimal.ZERO;
|
||||||
|
if (finalPayment == null) finalPayment = BigDecimal.ZERO;
|
||||||
|
if (priceDifference == null) priceDifference = BigDecimal.ZERO;
|
||||||
|
if (deposit == null) deposit = BigDecimal.ZERO;
|
||||||
|
if (discountAmount == null) discountAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
// 3. 计算订单总金额(用于开票)
|
||||||
|
// 公式:上门费 + 服务费用 + 材料费用 + 尾款 + 差价 + 定金 - 优惠费用
|
||||||
|
BigDecimal invoiceTotalPrice = doorFee.add(serviceFee).add(materialFee).add(totalPrice)
|
||||||
|
.add(finalPayment).add(priceDifference).add(deposit).subtract(discountAmount);
|
||||||
|
|
||||||
|
logger.info("=== 订单总金额计算明细(用于开票) ===");
|
||||||
|
logger.info("上门费: {}元", doorFee);
|
||||||
|
logger.info("服务费用: {}元", serviceFee);
|
||||||
|
logger.info("材料费用: {}元", materialFee);
|
||||||
|
logger.info("尾款: {}元", finalPayment);
|
||||||
|
logger.info("差价: {}元", priceDifference);
|
||||||
|
logger.info("定金: {}元", deposit);
|
||||||
|
logger.info("优惠费用: {}元", discountAmount);
|
||||||
|
logger.info("计算公式: {} + {} + {} + {} + {} + {} - {} = {}元",
|
||||||
|
doorFee, serviceFee, materialFee, finalPayment, priceDifference, deposit, discountAmount, invoiceTotalPrice);
|
||||||
|
|
||||||
|
// 4. 更新订单的total_price字段
|
||||||
|
order.setTotalPrice(invoiceTotalPrice);
|
||||||
|
|
||||||
|
// 5. 保存更新后的订单信息
|
||||||
|
int updateResult = orderService.updateOrder(order);
|
||||||
|
if (updateResult > 0) {
|
||||||
|
logger.info("订单总金额更新成功 - 订单ID: {}, 新总金额: {}元", order.getId(), invoiceTotalPrice);
|
||||||
|
} else {
|
||||||
|
logger.error("订单总金额更新失败 - 订单ID: {}", order.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("=== 订单总金额更新完成(用于开票) ===");
|
||||||
|
logger.info("订单号: {}", order.getOrderId());
|
||||||
|
logger.info("更新后总金额: {}元", invoiceTotalPrice);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("计算并更新订单总金额异常,订单ID: {}", order.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试完整分佣计算方法
|
* 测试完整分佣计算方法
|
||||||
* 用于验证完整的分佣计算功能,包含详细的步骤打印
|
* 用于验证完整的分佣计算功能,包含详细的步骤打印
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ public class YunXinPhoneUtilAPI {
|
||||||
setAxbCallbackUrl("http://your-callback-url.com/axb");
|
setAxbCallbackUrl("http://your-callback-url.com/axb");
|
||||||
setNotifyCallbackUrl("http://your-callback-url.com/notify");
|
setNotifyCallbackUrl("http://your-callback-url.com/notify");
|
||||||
// 示例:解绑操作
|
// 示例:解绑操作
|
||||||
VoiceResponseResult res = httpsPrivacyUnbind("18339212639", "15270824290", "15695650664");
|
VoiceResponseResult res = httpsPrivacyUnbind("15270824290", "18339212639", "13279237164");
|
||||||
System.out.println("解绑结果:" + JSON.toJSONString(res));
|
System.out.println("解绑结果:" + JSON.toJSONString(res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,689 @@
|
||||||
|
package com.ruoyi.system.domain;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单评分记录对象 dispatch_score_record
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-08-04
|
||||||
|
*/
|
||||||
|
public class DispatchScoreRecord extends BaseEntity
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 师傅ID */
|
||||||
|
@Excel(name = "师傅ID")
|
||||||
|
private Long workerId;
|
||||||
|
|
||||||
|
/** 师傅姓名 */
|
||||||
|
@Excel(name = "师傅姓名")
|
||||||
|
private String workerName;
|
||||||
|
|
||||||
|
/** 师傅电话 */
|
||||||
|
@Excel(name = "师傅电话")
|
||||||
|
private String workerPhone;
|
||||||
|
|
||||||
|
/** 订单ID(如果是在派单过程中记录) */
|
||||||
|
@Excel(name = "订单ID", readConverterExp = "如=果是在派单过程中记录")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/** 服务ID */
|
||||||
|
@Excel(name = "服务ID")
|
||||||
|
private Long serviceId;
|
||||||
|
|
||||||
|
/** 用户地址ID */
|
||||||
|
@Excel(name = "用户地址ID")
|
||||||
|
private Long userAddressId;
|
||||||
|
|
||||||
|
/** 距离评分 */
|
||||||
|
@Excel(name = "距离评分")
|
||||||
|
private BigDecimal distanceScore;
|
||||||
|
|
||||||
|
/** 技能匹配评分 */
|
||||||
|
@Excel(name = "技能匹配评分")
|
||||||
|
private BigDecimal skillMatchScore;
|
||||||
|
|
||||||
|
/** 经验评分 */
|
||||||
|
@Excel(name = "经验评分")
|
||||||
|
private BigDecimal experienceScore;
|
||||||
|
|
||||||
|
/** 评分权重 */
|
||||||
|
@Excel(name = "评分权重")
|
||||||
|
private BigDecimal ratingScore;
|
||||||
|
|
||||||
|
/** 可用性评分 */
|
||||||
|
@Excel(name = "可用性评分")
|
||||||
|
private BigDecimal availabilityScore;
|
||||||
|
|
||||||
|
/** 新师傅奖励评分 */
|
||||||
|
@Excel(name = "新师傅奖励评分")
|
||||||
|
private BigDecimal newWorkerBonusScore;
|
||||||
|
|
||||||
|
/** 综合评分 */
|
||||||
|
@Excel(name = "综合评分")
|
||||||
|
private BigDecimal totalScore;
|
||||||
|
|
||||||
|
/** 距离权重 */
|
||||||
|
@Excel(name = "距离权重")
|
||||||
|
private BigDecimal weightDistance;
|
||||||
|
|
||||||
|
/** 技能匹配权重 */
|
||||||
|
@Excel(name = "技能匹配权重")
|
||||||
|
private BigDecimal weightSkillMatch;
|
||||||
|
|
||||||
|
/** 经验权重 */
|
||||||
|
@Excel(name = "经验权重")
|
||||||
|
private BigDecimal weightExperience;
|
||||||
|
|
||||||
|
/** 评分权重 */
|
||||||
|
@Excel(name = "评分权重")
|
||||||
|
private BigDecimal weightRating;
|
||||||
|
|
||||||
|
/** 可用性权重 */
|
||||||
|
@Excel(name = "可用性权重")
|
||||||
|
private BigDecimal weightAvailability;
|
||||||
|
|
||||||
|
/** 新师傅奖励权重 */
|
||||||
|
@Excel(name = "新师傅奖励权重")
|
||||||
|
private BigDecimal weightNewWorkerBonus;
|
||||||
|
|
||||||
|
/** 实际距离(公里) */
|
||||||
|
@Excel(name = "实际距离", readConverterExp = "公=里")
|
||||||
|
private BigDecimal distanceKm;
|
||||||
|
|
||||||
|
/** 匹配技能数量 */
|
||||||
|
@Excel(name = "匹配技能数量")
|
||||||
|
private Long skillMatchCount;
|
||||||
|
|
||||||
|
/** 总技能数量 */
|
||||||
|
@Excel(name = "总技能数量")
|
||||||
|
private Long totalSkillsCount;
|
||||||
|
|
||||||
|
/** 已完成订单数量 */
|
||||||
|
@Excel(name = "已完成订单数量")
|
||||||
|
private Long completedOrdersCount;
|
||||||
|
|
||||||
|
/** 当前进行中订单数量 */
|
||||||
|
@Excel(name = "当前进行中订单数量")
|
||||||
|
private Long currentOrdersCount;
|
||||||
|
|
||||||
|
/** 是否新师傅(1是,0否) */
|
||||||
|
@Excel(name = "是否新师傅", readConverterExp = "1=是,0否")
|
||||||
|
private Integer isNewWorker;
|
||||||
|
|
||||||
|
/** 注册天数 */
|
||||||
|
@Excel(name = "注册天数")
|
||||||
|
private Long registrationDays;
|
||||||
|
|
||||||
|
/** 师傅纬度 */
|
||||||
|
@Excel(name = "师傅纬度")
|
||||||
|
private String workerLatitude;
|
||||||
|
|
||||||
|
/** 师傅经度 */
|
||||||
|
@Excel(name = "师傅经度")
|
||||||
|
private String workerLongitude;
|
||||||
|
|
||||||
|
/** 用户纬度 */
|
||||||
|
@Excel(name = "用户纬度")
|
||||||
|
private String userLatitude;
|
||||||
|
|
||||||
|
/** 用户经度 */
|
||||||
|
@Excel(name = "用户经度")
|
||||||
|
private String userLongitude;
|
||||||
|
|
||||||
|
/** 城市编码 */
|
||||||
|
@Excel(name = "城市编码")
|
||||||
|
private String cityCode;
|
||||||
|
|
||||||
|
/** 区县编码 */
|
||||||
|
@Excel(name = "区县编码")
|
||||||
|
private String districtCode;
|
||||||
|
|
||||||
|
/** 师傅状态(1启用,0禁用) */
|
||||||
|
@Excel(name = "师傅状态", readConverterExp = "1=启用,0禁用")
|
||||||
|
private Long workerStatus;
|
||||||
|
|
||||||
|
/** 是否工作(1是,0否) */
|
||||||
|
@Excel(name = "是否工作", readConverterExp = "1=是,0否")
|
||||||
|
private Long isWork;
|
||||||
|
|
||||||
|
/** 是否停止(1是,0否) */
|
||||||
|
@Excel(name = "是否停止", readConverterExp = "1=是,0否")
|
||||||
|
private Long isStop;
|
||||||
|
|
||||||
|
/** 是否有未完成订单(1是,0否) */
|
||||||
|
@Excel(name = "是否有未完成订单", readConverterExp = "1=是,0否")
|
||||||
|
private Integer hasUnfinishedOrders;
|
||||||
|
|
||||||
|
/** 是否可用(1是,0否) */
|
||||||
|
@Excel(name = "是否可用", readConverterExp = "1=是,0否")
|
||||||
|
private Integer isAvailable;
|
||||||
|
|
||||||
|
/** 排名位置 */
|
||||||
|
@Excel(name = "排名位置")
|
||||||
|
private Long rankPosition;
|
||||||
|
|
||||||
|
/** 总候选人数 */
|
||||||
|
@Excel(name = "总候选人数")
|
||||||
|
private Long totalCandidates;
|
||||||
|
|
||||||
|
/** 是否被选中(1是,0否) */
|
||||||
|
@Excel(name = "是否被选中", readConverterExp = "1=是,0否")
|
||||||
|
private Integer isSelected;
|
||||||
|
|
||||||
|
/** 选中原因 */
|
||||||
|
@Excel(name = "选中原因")
|
||||||
|
private String selectionReason;
|
||||||
|
|
||||||
|
/** 评分计算时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Excel(name = "评分计算时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
|
private Date scoreCalculationTime;
|
||||||
|
|
||||||
|
/** 最后更新时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Excel(name = "最后更新时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
|
private Date lastUpdateTime;
|
||||||
|
|
||||||
|
public void setId(Long id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerId(Long workerId)
|
||||||
|
{
|
||||||
|
this.workerId = workerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getWorkerId()
|
||||||
|
{
|
||||||
|
return workerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerName(String workerName)
|
||||||
|
{
|
||||||
|
this.workerName = workerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerName()
|
||||||
|
{
|
||||||
|
return workerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerPhone(String workerPhone)
|
||||||
|
{
|
||||||
|
this.workerPhone = workerPhone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerPhone()
|
||||||
|
{
|
||||||
|
return workerPhone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderId(Long orderId)
|
||||||
|
{
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getOrderId()
|
||||||
|
{
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceId(Long serviceId)
|
||||||
|
{
|
||||||
|
this.serviceId = serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getServiceId()
|
||||||
|
{
|
||||||
|
return serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserAddressId(Long userAddressId)
|
||||||
|
{
|
||||||
|
this.userAddressId = userAddressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUserAddressId()
|
||||||
|
{
|
||||||
|
return userAddressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistanceScore(BigDecimal distanceScore)
|
||||||
|
{
|
||||||
|
this.distanceScore = distanceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getDistanceScore()
|
||||||
|
{
|
||||||
|
return distanceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkillMatchScore(BigDecimal skillMatchScore)
|
||||||
|
{
|
||||||
|
this.skillMatchScore = skillMatchScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getSkillMatchScore()
|
||||||
|
{
|
||||||
|
return skillMatchScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExperienceScore(BigDecimal experienceScore)
|
||||||
|
{
|
||||||
|
this.experienceScore = experienceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getExperienceScore()
|
||||||
|
{
|
||||||
|
return experienceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRatingScore(BigDecimal ratingScore)
|
||||||
|
{
|
||||||
|
this.ratingScore = ratingScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getRatingScore()
|
||||||
|
{
|
||||||
|
return ratingScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailabilityScore(BigDecimal availabilityScore)
|
||||||
|
{
|
||||||
|
this.availabilityScore = availabilityScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAvailabilityScore()
|
||||||
|
{
|
||||||
|
return availabilityScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewWorkerBonusScore(BigDecimal newWorkerBonusScore)
|
||||||
|
{
|
||||||
|
this.newWorkerBonusScore = newWorkerBonusScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getNewWorkerBonusScore()
|
||||||
|
{
|
||||||
|
return newWorkerBonusScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalScore(BigDecimal totalScore)
|
||||||
|
{
|
||||||
|
this.totalScore = totalScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getTotalScore()
|
||||||
|
{
|
||||||
|
return totalScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightDistance(BigDecimal weightDistance)
|
||||||
|
{
|
||||||
|
this.weightDistance = weightDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWeightDistance()
|
||||||
|
{
|
||||||
|
return weightDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightSkillMatch(BigDecimal weightSkillMatch)
|
||||||
|
{
|
||||||
|
this.weightSkillMatch = weightSkillMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWeightSkillMatch()
|
||||||
|
{
|
||||||
|
return weightSkillMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightExperience(BigDecimal weightExperience)
|
||||||
|
{
|
||||||
|
this.weightExperience = weightExperience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWeightExperience()
|
||||||
|
{
|
||||||
|
return weightExperience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightRating(BigDecimal weightRating)
|
||||||
|
{
|
||||||
|
this.weightRating = weightRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWeightRating()
|
||||||
|
{
|
||||||
|
return weightRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightAvailability(BigDecimal weightAvailability)
|
||||||
|
{
|
||||||
|
this.weightAvailability = weightAvailability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWeightAvailability()
|
||||||
|
{
|
||||||
|
return weightAvailability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeightNewWorkerBonus(BigDecimal weightNewWorkerBonus)
|
||||||
|
{
|
||||||
|
this.weightNewWorkerBonus = weightNewWorkerBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWeightNewWorkerBonus()
|
||||||
|
{
|
||||||
|
return weightNewWorkerBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistanceKm(BigDecimal distanceKm)
|
||||||
|
{
|
||||||
|
this.distanceKm = distanceKm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getDistanceKm()
|
||||||
|
{
|
||||||
|
return distanceKm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkillMatchCount(Long skillMatchCount)
|
||||||
|
{
|
||||||
|
this.skillMatchCount = skillMatchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSkillMatchCount()
|
||||||
|
{
|
||||||
|
return skillMatchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalSkillsCount(Long totalSkillsCount)
|
||||||
|
{
|
||||||
|
this.totalSkillsCount = totalSkillsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTotalSkillsCount()
|
||||||
|
{
|
||||||
|
return totalSkillsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompletedOrdersCount(Long completedOrdersCount)
|
||||||
|
{
|
||||||
|
this.completedOrdersCount = completedOrdersCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCompletedOrdersCount()
|
||||||
|
{
|
||||||
|
return completedOrdersCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentOrdersCount(Long currentOrdersCount)
|
||||||
|
{
|
||||||
|
this.currentOrdersCount = currentOrdersCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCurrentOrdersCount()
|
||||||
|
{
|
||||||
|
return currentOrdersCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsNewWorker(Integer isNewWorker)
|
||||||
|
{
|
||||||
|
this.isNewWorker = isNewWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getIsNewWorker()
|
||||||
|
{
|
||||||
|
return isNewWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegistrationDays(Long registrationDays)
|
||||||
|
{
|
||||||
|
this.registrationDays = registrationDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getRegistrationDays()
|
||||||
|
{
|
||||||
|
return registrationDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerLatitude(String workerLatitude)
|
||||||
|
{
|
||||||
|
this.workerLatitude = workerLatitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerLatitude()
|
||||||
|
{
|
||||||
|
return workerLatitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerLongitude(String workerLongitude)
|
||||||
|
{
|
||||||
|
this.workerLongitude = workerLongitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerLongitude()
|
||||||
|
{
|
||||||
|
return workerLongitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserLatitude(String userLatitude)
|
||||||
|
{
|
||||||
|
this.userLatitude = userLatitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserLatitude()
|
||||||
|
{
|
||||||
|
return userLatitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserLongitude(String userLongitude)
|
||||||
|
{
|
||||||
|
this.userLongitude = userLongitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserLongitude()
|
||||||
|
{
|
||||||
|
return userLongitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCityCode(String cityCode)
|
||||||
|
{
|
||||||
|
this.cityCode = cityCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCityCode()
|
||||||
|
{
|
||||||
|
return cityCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistrictCode(String districtCode)
|
||||||
|
{
|
||||||
|
this.districtCode = districtCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDistrictCode()
|
||||||
|
{
|
||||||
|
return districtCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerStatus(Long workerStatus)
|
||||||
|
{
|
||||||
|
this.workerStatus = workerStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getWorkerStatus()
|
||||||
|
{
|
||||||
|
return workerStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsWork(Long isWork)
|
||||||
|
{
|
||||||
|
this.isWork = isWork;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getIsWork()
|
||||||
|
{
|
||||||
|
return isWork;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsStop(Long isStop)
|
||||||
|
{
|
||||||
|
this.isStop = isStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getIsStop()
|
||||||
|
{
|
||||||
|
return isStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasUnfinishedOrders(Integer hasUnfinishedOrders)
|
||||||
|
{
|
||||||
|
this.hasUnfinishedOrders = hasUnfinishedOrders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getHasUnfinishedOrders()
|
||||||
|
{
|
||||||
|
return hasUnfinishedOrders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsAvailable(Integer isAvailable)
|
||||||
|
{
|
||||||
|
this.isAvailable = isAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getIsAvailable()
|
||||||
|
{
|
||||||
|
return isAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRankPosition(Long rankPosition)
|
||||||
|
{
|
||||||
|
this.rankPosition = rankPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getRankPosition()
|
||||||
|
{
|
||||||
|
return rankPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalCandidates(Long totalCandidates)
|
||||||
|
{
|
||||||
|
this.totalCandidates = totalCandidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTotalCandidates()
|
||||||
|
{
|
||||||
|
return totalCandidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsSelected(Integer isSelected)
|
||||||
|
{
|
||||||
|
this.isSelected = isSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getIsSelected()
|
||||||
|
{
|
||||||
|
return isSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectionReason(String selectionReason)
|
||||||
|
{
|
||||||
|
this.selectionReason = selectionReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSelectionReason()
|
||||||
|
{
|
||||||
|
return selectionReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScoreCalculationTime(Date scoreCalculationTime)
|
||||||
|
{
|
||||||
|
this.scoreCalculationTime = scoreCalculationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getScoreCalculationTime()
|
||||||
|
{
|
||||||
|
return scoreCalculationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastUpdateTime(Date lastUpdateTime)
|
||||||
|
{
|
||||||
|
this.lastUpdateTime = lastUpdateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastUpdateTime()
|
||||||
|
{
|
||||||
|
return lastUpdateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("id", getId())
|
||||||
|
.append("workerId", getWorkerId())
|
||||||
|
.append("workerName", getWorkerName())
|
||||||
|
.append("workerPhone", getWorkerPhone())
|
||||||
|
.append("orderId", getOrderId())
|
||||||
|
.append("serviceId", getServiceId())
|
||||||
|
.append("userAddressId", getUserAddressId())
|
||||||
|
.append("distanceScore", getDistanceScore())
|
||||||
|
.append("skillMatchScore", getSkillMatchScore())
|
||||||
|
.append("experienceScore", getExperienceScore())
|
||||||
|
.append("ratingScore", getRatingScore())
|
||||||
|
.append("availabilityScore", getAvailabilityScore())
|
||||||
|
.append("newWorkerBonusScore", getNewWorkerBonusScore())
|
||||||
|
.append("totalScore", getTotalScore())
|
||||||
|
.append("weightDistance", getWeightDistance())
|
||||||
|
.append("weightSkillMatch", getWeightSkillMatch())
|
||||||
|
.append("weightExperience", getWeightExperience())
|
||||||
|
.append("weightRating", getWeightRating())
|
||||||
|
.append("weightAvailability", getWeightAvailability())
|
||||||
|
.append("weightNewWorkerBonus", getWeightNewWorkerBonus())
|
||||||
|
.append("distanceKm", getDistanceKm())
|
||||||
|
.append("skillMatchCount", getSkillMatchCount())
|
||||||
|
.append("totalSkillsCount", getTotalSkillsCount())
|
||||||
|
.append("completedOrdersCount", getCompletedOrdersCount())
|
||||||
|
.append("currentOrdersCount", getCurrentOrdersCount())
|
||||||
|
.append("isNewWorker", getIsNewWorker())
|
||||||
|
.append("registrationDays", getRegistrationDays())
|
||||||
|
.append("workerLatitude", getWorkerLatitude())
|
||||||
|
.append("workerLongitude", getWorkerLongitude())
|
||||||
|
.append("userLatitude", getUserLatitude())
|
||||||
|
.append("userLongitude", getUserLongitude())
|
||||||
|
.append("cityCode", getCityCode())
|
||||||
|
.append("districtCode", getDistrictCode())
|
||||||
|
.append("workerStatus", getWorkerStatus())
|
||||||
|
.append("isWork", getIsWork())
|
||||||
|
.append("isStop", getIsStop())
|
||||||
|
.append("hasUnfinishedOrders", getHasUnfinishedOrders())
|
||||||
|
.append("isAvailable", getIsAvailable())
|
||||||
|
.append("rankPosition", getRankPosition())
|
||||||
|
.append("totalCandidates", getTotalCandidates())
|
||||||
|
.append("isSelected", getIsSelected())
|
||||||
|
.append("selectionReason", getSelectionReason())
|
||||||
|
.append("scoreCalculationTime", getScoreCalculationTime())
|
||||||
|
.append("lastUpdateTime", getLastUpdateTime())
|
||||||
|
.append("createTime", getCreateTime())
|
||||||
|
.append("remark", getRemark())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,367 @@
|
||||||
|
package com.ruoyi.system.domain;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单统计对象 dispatch_statistics
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
public class DispatchStatistics extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 订单ID */
|
||||||
|
@Excel(name = "订单ID")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/** 师傅ID */
|
||||||
|
@Excel(name = "师傅ID")
|
||||||
|
private Long workerId;
|
||||||
|
|
||||||
|
/** 师傅姓名 */
|
||||||
|
@Excel(name = "师傅姓名")
|
||||||
|
private String workerName;
|
||||||
|
|
||||||
|
/** 服务ID */
|
||||||
|
@Excel(name = "服务ID")
|
||||||
|
private Long serviceId;
|
||||||
|
|
||||||
|
/** 服务名称 */
|
||||||
|
@Excel(name = "服务名称")
|
||||||
|
private String serviceName;
|
||||||
|
|
||||||
|
/** 用户地址ID */
|
||||||
|
@Excel(name = "用户地址ID")
|
||||||
|
private Long addressId;
|
||||||
|
|
||||||
|
/** 用户地址 */
|
||||||
|
@Excel(name = "用户地址")
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
/** 城市编码 */
|
||||||
|
@Excel(name = "城市编码")
|
||||||
|
private String cityCode;
|
||||||
|
|
||||||
|
/** 城市名称 */
|
||||||
|
@Excel(name = "城市名称")
|
||||||
|
private String cityName;
|
||||||
|
|
||||||
|
/** 派单类型 1:自动派单 2:手动派单 */
|
||||||
|
@Excel(name = "派单类型")
|
||||||
|
private Integer dispatchType;
|
||||||
|
|
||||||
|
/** 派单结果 1:成功 0:失败 */
|
||||||
|
@Excel(name = "派单结果")
|
||||||
|
private Integer dispatchResult;
|
||||||
|
|
||||||
|
/** 派单耗时(毫秒) */
|
||||||
|
@Excel(name = "派单耗时")
|
||||||
|
private Long dispatchTime;
|
||||||
|
|
||||||
|
/** 距离评分 */
|
||||||
|
@Excel(name = "距离评分")
|
||||||
|
private Double distanceScore;
|
||||||
|
|
||||||
|
/** 技能匹配评分 */
|
||||||
|
@Excel(name = "技能匹配评分")
|
||||||
|
private Double skillMatchScore;
|
||||||
|
|
||||||
|
/** 经验评分 */
|
||||||
|
@Excel(name = "经验评分")
|
||||||
|
private Double experienceScore;
|
||||||
|
|
||||||
|
/** 评分 */
|
||||||
|
@Excel(name = "评分")
|
||||||
|
private Double ratingScore;
|
||||||
|
|
||||||
|
/** 可用性评分 */
|
||||||
|
@Excel(name = "可用性评分")
|
||||||
|
private Double availabilityScore;
|
||||||
|
|
||||||
|
/** 新师傅奖励评分 */
|
||||||
|
@Excel(name = "新师傅奖励评分")
|
||||||
|
private Double newWorkerBonusScore;
|
||||||
|
|
||||||
|
/** 综合评分 */
|
||||||
|
@Excel(name = "综合评分")
|
||||||
|
private Double totalScore;
|
||||||
|
|
||||||
|
/** 候选师傅数量 */
|
||||||
|
@Excel(name = "候选师傅数量")
|
||||||
|
private Integer candidateCount;
|
||||||
|
|
||||||
|
/** 重试次数 */
|
||||||
|
@Excel(name = "重试次数")
|
||||||
|
private Integer retryCount;
|
||||||
|
|
||||||
|
/** 失败原因 */
|
||||||
|
@Excel(name = "失败原因")
|
||||||
|
private String failureReason;
|
||||||
|
|
||||||
|
/** 派单时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "派单时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date dispatchDate;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createdAt;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date updatedAt;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderId(Long orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getWorkerId() {
|
||||||
|
return workerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerId(Long workerId) {
|
||||||
|
this.workerId = workerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerName() {
|
||||||
|
return workerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerName(String workerName) {
|
||||||
|
this.workerName = workerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getServiceId() {
|
||||||
|
return serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceId(Long serviceId) {
|
||||||
|
this.serviceId = serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServiceName() {
|
||||||
|
return serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceName(String serviceName) {
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAddressId() {
|
||||||
|
return addressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddressId(Long addressId) {
|
||||||
|
this.addressId = addressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCityCode() {
|
||||||
|
return cityCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCityCode(String cityCode) {
|
||||||
|
this.cityCode = cityCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCityName() {
|
||||||
|
return cityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCityName(String cityName) {
|
||||||
|
this.cityName = cityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDispatchType() {
|
||||||
|
return dispatchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDispatchType(Integer dispatchType) {
|
||||||
|
this.dispatchType = dispatchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDispatchResult() {
|
||||||
|
return dispatchResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDispatchResult(Integer dispatchResult) {
|
||||||
|
this.dispatchResult = dispatchResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getDispatchTime() {
|
||||||
|
return dispatchTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDispatchTime(Long dispatchTime) {
|
||||||
|
this.dispatchTime = dispatchTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getDistanceScore() {
|
||||||
|
return distanceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistanceScore(Double distanceScore) {
|
||||||
|
this.distanceScore = distanceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getSkillMatchScore() {
|
||||||
|
return skillMatchScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkillMatchScore(Double skillMatchScore) {
|
||||||
|
this.skillMatchScore = skillMatchScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getExperienceScore() {
|
||||||
|
return experienceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExperienceScore(Double experienceScore) {
|
||||||
|
this.experienceScore = experienceScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getRatingScore() {
|
||||||
|
return ratingScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRatingScore(Double ratingScore) {
|
||||||
|
this.ratingScore = ratingScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAvailabilityScore() {
|
||||||
|
return availabilityScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailabilityScore(Double availabilityScore) {
|
||||||
|
this.availabilityScore = availabilityScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getNewWorkerBonusScore() {
|
||||||
|
return newWorkerBonusScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewWorkerBonusScore(Double newWorkerBonusScore) {
|
||||||
|
this.newWorkerBonusScore = newWorkerBonusScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTotalScore() {
|
||||||
|
return totalScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalScore(Double totalScore) {
|
||||||
|
this.totalScore = totalScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCandidateCount() {
|
||||||
|
return candidateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCandidateCount(Integer candidateCount) {
|
||||||
|
this.candidateCount = candidateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRetryCount() {
|
||||||
|
return retryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRetryCount(Integer retryCount) {
|
||||||
|
this.retryCount = retryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFailureReason() {
|
||||||
|
return failureReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailureReason(String failureReason) {
|
||||||
|
this.failureReason = failureReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDispatchDate() {
|
||||||
|
return dispatchDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDispatchDate(Date dispatchDate) {
|
||||||
|
this.dispatchDate = dispatchDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(Date createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpdatedAt() {
|
||||||
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdatedAt(Date updatedAt) {
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
.append("id", getId())
|
||||||
|
.append("orderId", getOrderId())
|
||||||
|
.append("workerId", getWorkerId())
|
||||||
|
.append("workerName", getWorkerName())
|
||||||
|
.append("serviceId", getServiceId())
|
||||||
|
.append("serviceName", getServiceName())
|
||||||
|
.append("addressId", getAddressId())
|
||||||
|
.append("address", getAddress())
|
||||||
|
.append("cityCode", getCityCode())
|
||||||
|
.append("cityName", getCityName())
|
||||||
|
.append("dispatchType", getDispatchType())
|
||||||
|
.append("dispatchResult", getDispatchResult())
|
||||||
|
.append("dispatchTime", getDispatchTime())
|
||||||
|
.append("distanceScore", getDistanceScore())
|
||||||
|
.append("skillMatchScore", getSkillMatchScore())
|
||||||
|
.append("experienceScore", getExperienceScore())
|
||||||
|
.append("ratingScore", getRatingScore())
|
||||||
|
.append("availabilityScore", getAvailabilityScore())
|
||||||
|
.append("newWorkerBonusScore", getNewWorkerBonusScore())
|
||||||
|
.append("totalScore", getTotalScore())
|
||||||
|
.append("candidateCount", getCandidateCount())
|
||||||
|
.append("retryCount", getRetryCount())
|
||||||
|
.append("failureReason", getFailureReason())
|
||||||
|
.append("dispatchDate", getDispatchDate())
|
||||||
|
.append("createdAt", getCreatedAt())
|
||||||
|
.append("updatedAt", getUpdatedAt())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -152,6 +152,8 @@ public class GoodsOrder extends BaseEntity
|
||||||
|
|
||||||
private BigDecimal payPriceMin;
|
private BigDecimal payPriceMin;
|
||||||
private BigDecimal payPriceMax;
|
private BigDecimal payPriceMax;
|
||||||
|
private BigDecimal returnrealmoney;
|
||||||
|
|
||||||
private String startdate;
|
private String startdate;
|
||||||
private String enddate;
|
private String enddate;
|
||||||
private String paystartdate;
|
private String paystartdate;
|
||||||
|
|
@ -658,6 +660,14 @@ public class GoodsOrder extends BaseEntity
|
||||||
this.returnshow = returnshow;
|
this.returnshow = returnshow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getReturnrealmoney() {
|
||||||
|
return returnrealmoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReturnrealmoney(BigDecimal returnrealmoney) {
|
||||||
|
this.returnrealmoney = returnrealmoney;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ public class Order extends BaseEntity
|
||||||
private Integer isComment;
|
private Integer isComment;
|
||||||
|
|
||||||
/** 1:自由抢单 ,2:系统派单 ,3:平台派单 */
|
/** 1:自由抢单 ,2:系统派单 ,3:平台派单 */
|
||||||
@Excel(name = "1:自由抢单 ,2:系统派单 ,3:平台派单")
|
@Excel(name = "1:系统派单 2:后台手动派单 3:指定工人")
|
||||||
private Long receiveType;
|
private Long receiveType;
|
||||||
|
|
||||||
/** 1:已经接单 */
|
/** 1:已经接单 */
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,23 @@ public class Users extends BaseEntity
|
||||||
@Excel(name = "生日", width = 30, dateFormat = "yyyy-MM-dd")
|
@Excel(name = "生日", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
private Date birthday;
|
private Date birthday;
|
||||||
|
|
||||||
|
/** 师傅当前位置纬度 */
|
||||||
|
@Excel(name = "师傅当前位置纬度")
|
||||||
|
private String workerLatitude;
|
||||||
|
|
||||||
|
/** 师傅当前位置经度 */
|
||||||
|
@Excel(name = "师傅当前位置经度")
|
||||||
|
private String workerLongitude;
|
||||||
|
|
||||||
|
/** 师傅当前位置纬度 */
|
||||||
|
@Excel(name = "师傅常工作地")
|
||||||
|
private String workerAdress;
|
||||||
|
|
||||||
|
/** 最后位置更新时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "最后位置更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date lastLocationTime;
|
||||||
|
|
||||||
/** $column.columnComment */
|
/** $column.columnComment */
|
||||||
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
|
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
|
||||||
private Date createdAt;
|
private Date createdAt;
|
||||||
|
|
@ -653,6 +670,38 @@ public class Users extends BaseEntity
|
||||||
this.birthday = birthday;
|
this.birthday = birthday;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getWorkerLatitude() {
|
||||||
|
return workerLatitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerLatitude(String workerLatitude) {
|
||||||
|
this.workerLatitude = workerLatitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerLongitude() {
|
||||||
|
return workerLongitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerLongitude(String workerLongitude) {
|
||||||
|
this.workerLongitude = workerLongitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastLocationTime() {
|
||||||
|
return lastLocationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastLocationTime(Date lastLocationTime) {
|
||||||
|
this.lastLocationTime = lastLocationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorkerAdress() {
|
||||||
|
return workerAdress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorkerAdress(String workerAdress) {
|
||||||
|
this.workerAdress = workerAdress;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getAreaList() { return areaList; }
|
public List<String> getAreaList() { return areaList; }
|
||||||
public void setAreaList(List<String> areaList) { this.areaList = areaList; }
|
public void setAreaList(List<String> areaList) { this.areaList = areaList; }
|
||||||
public String getSkill() { return skill; }
|
public String getSkill() { return skill; }
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ public class UsersPayBefor extends BaseEntity
|
||||||
private String maketime;
|
private String maketime;
|
||||||
private String attachments;
|
private String attachments;
|
||||||
private String grouporderid;
|
private String grouporderid;
|
||||||
|
private BigDecimal returnmoney;
|
||||||
|
|
||||||
|
|
||||||
/** 支付订单号 */
|
/** 支付订单号 */
|
||||||
|
|
@ -389,6 +390,14 @@ public class UsersPayBefor extends BaseEntity
|
||||||
this.num = num;
|
this.num = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getReturnmoney() {
|
||||||
|
return returnmoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReturnmoney(BigDecimal returnmoney) {
|
||||||
|
this.returnmoney = returnmoney;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.ruoyi.system.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.system.domain.DispatchScoreRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单评分记录Mapper接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
public interface DispatchScoreRecordMapper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录
|
||||||
|
*
|
||||||
|
* @param id 派单评分记录主键
|
||||||
|
* @return 派单评分记录
|
||||||
|
*/
|
||||||
|
public DispatchScoreRecord selectDispatchScoreRecordById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录列表
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 派单评分记录集合
|
||||||
|
*/
|
||||||
|
public List<DispatchScoreRecord> selectDispatchScoreRecordList(DispatchScoreRecord dispatchScoreRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单评分记录
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertDispatchScoreRecord(DispatchScoreRecord dispatchScoreRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单评分记录
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateDispatchScoreRecord(DispatchScoreRecord dispatchScoreRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单评分记录
|
||||||
|
*
|
||||||
|
* @param id 派单评分记录主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteDispatchScoreRecordById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除派单评分记录
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的数据主键集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteDispatchScoreRecordByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据师傅ID查询最新的评分记录
|
||||||
|
*
|
||||||
|
* @param workerId 师傅ID
|
||||||
|
* @return 派单评分记录
|
||||||
|
*/
|
||||||
|
public DispatchScoreRecord selectLatestByWorkerId(Long workerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询排名前N的师傅
|
||||||
|
*
|
||||||
|
* @param limit 限制数量
|
||||||
|
* @return 派单评分记录集合
|
||||||
|
*/
|
||||||
|
public List<DispatchScoreRecord> selectTopRankedWorkers(int limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询被选中的师傅记录
|
||||||
|
*
|
||||||
|
* @return 派单评分记录集合
|
||||||
|
*/
|
||||||
|
public List<DispatchScoreRecord> selectSelectedWorkers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理过期的评分记录(保留最近30天)
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int cleanExpiredRecords();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量插入评分记录
|
||||||
|
*
|
||||||
|
* @param records 评分记录列表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int batchInsertDispatchScoreRecord(List<DispatchScoreRecord> records);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
package com.ruoyi.system.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.ruoyi.system.domain.DispatchStatistics;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单统计Mapper接口
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
public interface DispatchStatisticsMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单统计
|
||||||
|
*
|
||||||
|
* @param id 派单统计主键
|
||||||
|
* @return 派单统计
|
||||||
|
*/
|
||||||
|
public DispatchStatistics selectDispatchStatisticsById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单统计列表
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计
|
||||||
|
* @return 派单统计集合
|
||||||
|
*/
|
||||||
|
public List<DispatchStatistics> selectDispatchStatisticsList(DispatchStatistics dispatchStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单统计
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertDispatchStatistics(DispatchStatistics dispatchStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单统计
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateDispatchStatistics(DispatchStatistics dispatchStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单统计
|
||||||
|
*
|
||||||
|
* @param id 派单统计主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteDispatchStatisticsById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除派单统计
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的数据主键集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteDispatchStatisticsByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单成功率统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 成功率统计
|
||||||
|
*/
|
||||||
|
public Map<String, Object> selectDispatchSuccessRate(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取师傅接单统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 师傅接单统计
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> selectWorkerOrderStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取地区派单统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 地区派单统计
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> selectAreaDispatchStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取服务类型派单统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 服务类型派单统计
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> selectServiceTypeDispatchStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单响应时间统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 响应时间统计
|
||||||
|
*/
|
||||||
|
public Map<String, Object> selectDispatchResponseTimeStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取新师傅派单统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 新师傅派单统计
|
||||||
|
*/
|
||||||
|
public Map<String, Object> selectNewWorkerDispatchStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单质量评分统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 质量评分统计
|
||||||
|
*/
|
||||||
|
public Map<String, Object> selectDispatchQualityStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单效率统计
|
||||||
|
*
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 效率统计
|
||||||
|
*/
|
||||||
|
public Map<String, Object> selectDispatchEfficiencyStatistics(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实时派单状态
|
||||||
|
*
|
||||||
|
* @return 实时状态
|
||||||
|
*/
|
||||||
|
public Map<String, Object> selectRealTimeDispatchStatus();
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ public interface OrderLogMapper
|
||||||
public OrderLog selectDataTheFirstNew(Long oid);
|
public OrderLog selectDataTheFirstNew(Long oid);
|
||||||
public int selectCountOrderLogByOrderId(String orderId);
|
public int selectCountOrderLogByOrderId(String orderId);
|
||||||
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog);
|
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog);
|
||||||
|
public int updateOrderLogEnd(Long id);
|
||||||
|
|
||||||
public List<OrderLog> selectOrderLogByOrderId(String orderId);
|
public List<OrderLog> selectOrderLogByOrderId(String orderId);
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,10 @@ public interface OrderMapper
|
||||||
|
|
||||||
public int selectCountOrderByUid(@Param("uid") Long uid,@Param("status") Long status);
|
public int selectCountOrderByUid(@Param("uid") Long uid,@Param("status") Long status);
|
||||||
|
|
||||||
|
public int updateOrderPhone(Long id);
|
||||||
|
|
||||||
|
public int updateOrderCika(Long id);
|
||||||
|
|
||||||
|
|
||||||
public int selectAllCountOrderByUid(Long uid);
|
public int selectAllCountOrderByUid(Long uid);
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.system.mapper;
|
package com.ruoyi.system.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import com.ruoyi.system.domain.Users;
|
import com.ruoyi.system.domain.Users;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -94,4 +95,24 @@ public interface UsersMapper
|
||||||
* @return 用户对象列表
|
* @return 用户对象列表
|
||||||
*/
|
*/
|
||||||
public List<Users> selectUsersByIds(List<Long> ids);
|
public List<Users> selectUsersByIds(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单专用查询 - 基础条件:type=2, status=1, is_stop=0, worker_time为当天
|
||||||
|
* @param params 查询参数,包含分页信息
|
||||||
|
* @return 符合条件的师傅列表
|
||||||
|
*/
|
||||||
|
public List<Users> selectDispatchWorkers(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单备用查询 - 不限制地区,获取更多师傅
|
||||||
|
* @param params 查询参数,包含数量限制
|
||||||
|
* @return 符合条件的师傅列表
|
||||||
|
*/
|
||||||
|
public List<Users> selectBackupDispatchWorkers(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试用派单查询 - 用于验证基础条件
|
||||||
|
* @return 符合条件的师傅列表(限制10条)
|
||||||
|
*/
|
||||||
|
public List<Users> selectTestDispatchWorkers();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.ruoyi.system.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.system.domain.DispatchScoreRecord;
|
||||||
|
import com.ruoyi.system.domain.Order;
|
||||||
|
import com.ruoyi.system.domain.ServiceGoods;
|
||||||
|
import com.ruoyi.system.domain.UserAddress;
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单评分记录Service接口
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-08-04
|
||||||
|
*/
|
||||||
|
public interface IDispatchScoreRecordService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录
|
||||||
|
*
|
||||||
|
* @param id 派单评分记录主键
|
||||||
|
* @return 派单评分记录
|
||||||
|
*/
|
||||||
|
public DispatchScoreRecord selectDispatchScoreRecordById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录列表
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 派单评分记录集合
|
||||||
|
*/
|
||||||
|
public List<DispatchScoreRecord> selectDispatchScoreRecordList(DispatchScoreRecord dispatchScoreRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单评分记录
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertDispatchScoreRecord(DispatchScoreRecord dispatchScoreRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单评分记录
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateDispatchScoreRecord(DispatchScoreRecord dispatchScoreRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除派单评分记录
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的派单评分记录主键集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteDispatchScoreRecordByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单评分记录信息
|
||||||
|
*
|
||||||
|
* @param id 派单评分记录主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteDispatchScoreRecordById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录派单评分过程
|
||||||
|
*
|
||||||
|
* @param workerScores 师傅评分列表
|
||||||
|
* @param order 订单信息
|
||||||
|
* @param serviceGoods 服务信息
|
||||||
|
* @param userAddress 用户地址信息
|
||||||
|
* @param selectedWorker 选中的师傅(可选)
|
||||||
|
* @return 保存的记录数量
|
||||||
|
*/
|
||||||
|
public int recordDispatchScoreProcess(List<DispatchUtil.WorkerScore> workerScores,
|
||||||
|
Order order, ServiceGoods serviceGoods,
|
||||||
|
UserAddress userAddress, Object selectedWorker);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
package com.ruoyi.system.service;
|
||||||
|
|
||||||
|
import com.ruoyi.system.domain.DispatchStatistics;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单统计服务接口
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
public interface IDispatchStatisticsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单统计列表
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 查询条件
|
||||||
|
* @return 派单统计列表
|
||||||
|
*/
|
||||||
|
List<DispatchStatistics> selectDispatchStatisticsList(DispatchStatistics dispatchStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询派单统计
|
||||||
|
*
|
||||||
|
* @param id 统计ID
|
||||||
|
* @return 派单统计信息
|
||||||
|
*/
|
||||||
|
DispatchStatistics selectDispatchStatisticsById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单统计
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int insertDispatchStatistics(DispatchStatistics dispatchStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单统计
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int updateDispatchStatistics(DispatchStatistics dispatchStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除派单统计
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的统计ID数组
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int deleteDispatchStatisticsByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单统计
|
||||||
|
*
|
||||||
|
* @param id 派单统计主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int deleteDispatchStatisticsById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单成功率统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 成功率统计
|
||||||
|
*/
|
||||||
|
Map<String, Object> getDispatchSuccessRate(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取师傅接单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 师傅接单统计
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> getWorkerOrderStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取地区派单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 地区派单统计
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> getAreaDispatchStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取服务类型派单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 服务类型派单统计
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> getServiceTypeDispatchStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单响应时间统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 响应时间统计
|
||||||
|
*/
|
||||||
|
Map<String, Object> getDispatchResponseTimeStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取新师傅派单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 新师傅派单统计
|
||||||
|
*/
|
||||||
|
Map<String, Object> getNewWorkerDispatchStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单质量评分统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 质量评分统计
|
||||||
|
*/
|
||||||
|
Map<String, Object> getDispatchQualityStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单效率统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 效率统计
|
||||||
|
*/
|
||||||
|
Map<String, Object> getDispatchEfficiencyStatistics(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取综合派单报告
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 综合报告
|
||||||
|
*/
|
||||||
|
Map<String, Object> getComprehensiveDispatchReport(String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录派单统计
|
||||||
|
*
|
||||||
|
* @param statistics 统计信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int recordDispatchStatistics(DispatchStatistics statistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实时派单状态
|
||||||
|
*
|
||||||
|
* @return 实时状态
|
||||||
|
*/
|
||||||
|
Map<String, Object> getRealTimeDispatchStatus();
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ public interface IOrderLogService
|
||||||
*/
|
*/
|
||||||
public OrderLog selectOrderLogById(Long id);
|
public OrderLog selectOrderLogById(Long id);
|
||||||
|
|
||||||
|
public int updateOrderLogEnd(Long id);
|
||||||
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog);
|
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog);
|
||||||
/**
|
/**
|
||||||
* 查询最新一条日志记录
|
* 查询最新一条日志记录
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ public interface IOrderService
|
||||||
*/
|
*/
|
||||||
public List<OrderApple> selectOrderAppleList(OrderApple orderApple);
|
public List<OrderApple> selectOrderAppleList(OrderApple orderApple);
|
||||||
|
|
||||||
|
public int updateOrderPhone(Long id);
|
||||||
|
|
||||||
|
public int updateOrderCika(Long id);
|
||||||
|
|
||||||
public Order selectOrderByOrderId(String orderId);
|
public Order selectOrderByOrderId(String orderId);
|
||||||
/**
|
/**
|
||||||
* 查询服务订单列表
|
* 查询服务订单列表
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.system.service;
|
package com.ruoyi.system.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import com.ruoyi.system.domain.Users;
|
import com.ruoyi.system.domain.Users;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -94,4 +95,24 @@ public interface IUsersService
|
||||||
* @return 用户对象列表
|
* @return 用户对象列表
|
||||||
*/
|
*/
|
||||||
public List<Users> selectUsersByIds(List<Long> ids);
|
public List<Users> selectUsersByIds(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单专用查询 - 基础条件:type=2, status=1, is_stop=0, worker_time为当天
|
||||||
|
* @param params 查询参数,包含分页信息
|
||||||
|
* @return 符合条件的师傅列表
|
||||||
|
*/
|
||||||
|
public List<Users> selectDispatchWorkers(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单备用查询 - 不限制地区,获取更多师傅
|
||||||
|
* @param params 查询参数,包含数量限制
|
||||||
|
* @return 符合条件的师傅列表
|
||||||
|
*/
|
||||||
|
public List<Users> selectBackupDispatchWorkers(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试用派单查询 - 用于验证基础条件
|
||||||
|
* @return 符合条件的师傅列表(限制10条)
|
||||||
|
*/
|
||||||
|
public List<Users> selectTestDispatchWorkers();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,206 @@
|
||||||
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import com.ruoyi.system.mapper.DispatchScoreRecordMapper;
|
||||||
|
import com.ruoyi.system.domain.DispatchScoreRecord;
|
||||||
|
import com.ruoyi.system.service.IDispatchScoreRecordService;
|
||||||
|
import com.ruoyi.system.service.IOrderService;
|
||||||
|
import com.ruoyi.system.domain.Order;
|
||||||
|
import com.ruoyi.system.domain.ServiceGoods;
|
||||||
|
import com.ruoyi.system.domain.UserAddress;
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单评分记录Service业务层处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-08-04
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class DispatchScoreRecordServiceImpl implements IDispatchScoreRecordService
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private DispatchScoreRecordMapper dispatchScoreRecordMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录
|
||||||
|
*
|
||||||
|
* @param id 派单评分记录主键
|
||||||
|
* @return 派单评分记录
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DispatchScoreRecord selectDispatchScoreRecordById(Long id)
|
||||||
|
{
|
||||||
|
return dispatchScoreRecordMapper.selectDispatchScoreRecordById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单评分记录列表
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 派单评分记录
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<DispatchScoreRecord> selectDispatchScoreRecordList(DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
return dispatchScoreRecordMapper.selectDispatchScoreRecordList(dispatchScoreRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单评分记录
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int insertDispatchScoreRecord(DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
dispatchScoreRecord.setCreateTime(DateUtils.getNowDate());
|
||||||
|
return dispatchScoreRecordMapper.insertDispatchScoreRecord(dispatchScoreRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单评分记录
|
||||||
|
*
|
||||||
|
* @param dispatchScoreRecord 派单评分记录
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int updateDispatchScoreRecord(DispatchScoreRecord dispatchScoreRecord)
|
||||||
|
{
|
||||||
|
return dispatchScoreRecordMapper.updateDispatchScoreRecord(dispatchScoreRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除派单评分记录
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的派单评分记录主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int deleteDispatchScoreRecordByIds(Long[] ids)
|
||||||
|
{
|
||||||
|
return dispatchScoreRecordMapper.deleteDispatchScoreRecordByIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单评分记录信息
|
||||||
|
*
|
||||||
|
* @param id 派单评分记录主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int deleteDispatchScoreRecordById(Long id)
|
||||||
|
{
|
||||||
|
return dispatchScoreRecordMapper.deleteDispatchScoreRecordById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录派单评分过程
|
||||||
|
*
|
||||||
|
* @param workerScores 师傅评分列表
|
||||||
|
* @param order 订单信息
|
||||||
|
* @param serviceGoods 服务信息
|
||||||
|
* @param userAddress 用户地址信息
|
||||||
|
* @param selectedWorker 选中的师傅(可选)
|
||||||
|
* @return 保存的记录数量
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int recordDispatchScoreProcess(List<DispatchUtil.WorkerScore> workerScores,
|
||||||
|
Order order, ServiceGoods serviceGoods,
|
||||||
|
UserAddress userAddress, Object selectedWorker)
|
||||||
|
{
|
||||||
|
int savedCount = 0;
|
||||||
|
Date now = new Date();
|
||||||
|
|
||||||
|
// 获取订单服务
|
||||||
|
IOrderService orderService = SpringUtils.getBean(IOrderService.class);
|
||||||
|
|
||||||
|
for (int i = 0; i < workerScores.size(); i++) {
|
||||||
|
DispatchUtil.WorkerScore workerScore = workerScores.get(i);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DispatchScoreRecord record = new DispatchScoreRecord();
|
||||||
|
|
||||||
|
// 设置基本信息
|
||||||
|
record.setWorkerId(workerScore.getWorkerId());
|
||||||
|
record.setWorkerName(workerScore.getWorkerName());
|
||||||
|
record.setWorkerPhone(workerScore.getWorker().getPhone());
|
||||||
|
|
||||||
|
// 设置订单和服务信息
|
||||||
|
if (order != null) {
|
||||||
|
record.setOrderId(order.getId());
|
||||||
|
}
|
||||||
|
if (serviceGoods != null) {
|
||||||
|
record.setServiceId(serviceGoods.getId());
|
||||||
|
}
|
||||||
|
if (userAddress != null) {
|
||||||
|
record.setUserAddressId(userAddress.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询师傅的已完成订单数量
|
||||||
|
Order queryOrder = new Order();
|
||||||
|
queryOrder.setWorkerId(workerScore.getWorkerId());
|
||||||
|
queryOrder.setStatus(4L); // 已完成状态
|
||||||
|
List<Order> completedOrders = orderService.selectOrderList(queryOrder);
|
||||||
|
record.setCompletedOrdersCount(Long.valueOf(completedOrders.size()));
|
||||||
|
|
||||||
|
// 查询师傅的当前进行中订单数量(状态为1、2、3的订单)
|
||||||
|
Order currentQueryOrder = new Order();
|
||||||
|
currentQueryOrder.setWorkerId(workerScore.getWorkerId());
|
||||||
|
currentQueryOrder.setStatus(1L); // 待派单
|
||||||
|
List<Order> pendingOrders = orderService.selectOrderList(currentQueryOrder);
|
||||||
|
currentQueryOrder.setStatus(2L); // 待服务
|
||||||
|
List<Order> waitingOrders = orderService.selectOrderList(currentQueryOrder);
|
||||||
|
currentQueryOrder.setStatus(3L); // 服务中
|
||||||
|
List<Order> servingOrders = orderService.selectOrderList(currentQueryOrder);
|
||||||
|
int currentOrdersCount = pendingOrders.size() + waitingOrders.size() + servingOrders.size();
|
||||||
|
record.setCurrentOrdersCount(Long.valueOf(currentOrdersCount));
|
||||||
|
|
||||||
|
// 设置评分信息
|
||||||
|
record.setDistanceScore(BigDecimal.valueOf(workerScore.getDistanceScore()));
|
||||||
|
record.setSkillMatchScore(BigDecimal.valueOf(workerScore.getSkillMatchScore()));
|
||||||
|
record.setExperienceScore(BigDecimal.valueOf(workerScore.getExperienceScore()));
|
||||||
|
record.setRatingScore(BigDecimal.valueOf(workerScore.getRatingScore()));
|
||||||
|
record.setAvailabilityScore(BigDecimal.valueOf(workerScore.getAvailabilityScore()));
|
||||||
|
record.setNewWorkerBonusScore(BigDecimal.valueOf(workerScore.getNewWorkerBonusScore()));
|
||||||
|
record.setTotalScore(BigDecimal.valueOf(workerScore.getTotalScore()));
|
||||||
|
|
||||||
|
// 设置排名信息
|
||||||
|
record.setRankPosition(Long.valueOf(i + 1));
|
||||||
|
record.setTotalCandidates(Long.valueOf(workerScores.size()));
|
||||||
|
|
||||||
|
// 设置是否被选中
|
||||||
|
if (selectedWorker != null && selectedWorker instanceof DispatchUtil.WorkerScore) {
|
||||||
|
DispatchUtil.WorkerScore selected = (DispatchUtil.WorkerScore) selectedWorker;
|
||||||
|
record.setIsSelected(workerScore.getWorkerId().equals(selected.getWorkerId()) ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
record.setIsSelected(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置评分计算时间
|
||||||
|
record.setScoreCalculationTime(now);
|
||||||
|
record.setLastUpdateTime(now);
|
||||||
|
record.setCreateTime(now);
|
||||||
|
|
||||||
|
// 保存记录
|
||||||
|
int result = dispatchScoreRecordMapper.insertDispatchScoreRecord(record);
|
||||||
|
if (result > 0) {
|
||||||
|
savedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 记录错误但继续处理其他记录
|
||||||
|
System.err.println("保存师傅评分记录失败,师傅ID: " + workerScore.getWorkerId() + ", 错误: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return savedCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,260 @@
|
||||||
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import com.ruoyi.system.mapper.DispatchStatisticsMapper;
|
||||||
|
import com.ruoyi.system.domain.DispatchStatistics;
|
||||||
|
import com.ruoyi.system.service.IDispatchStatisticsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单统计Service业务层处理
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class DispatchStatisticsServiceImpl implements IDispatchStatisticsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DispatchStatisticsMapper dispatchStatisticsMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单统计
|
||||||
|
*
|
||||||
|
* @param id 派单统计主键
|
||||||
|
* @return 派单统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DispatchStatistics selectDispatchStatisticsById(Long id) {
|
||||||
|
return dispatchStatisticsMapper.selectDispatchStatisticsById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询派单统计列表
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计
|
||||||
|
* @return 派单统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<DispatchStatistics> selectDispatchStatisticsList(DispatchStatistics dispatchStatistics) {
|
||||||
|
return dispatchStatisticsMapper.selectDispatchStatisticsList(dispatchStatistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增派单统计
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int insertDispatchStatistics(DispatchStatistics dispatchStatistics) {
|
||||||
|
dispatchStatistics.setCreatedAt(new Date());
|
||||||
|
dispatchStatistics.setUpdatedAt(new Date());
|
||||||
|
return dispatchStatisticsMapper.insertDispatchStatistics(dispatchStatistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改派单统计
|
||||||
|
*
|
||||||
|
* @param dispatchStatistics 派单统计
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int updateDispatchStatistics(DispatchStatistics dispatchStatistics) {
|
||||||
|
dispatchStatistics.setUpdatedAt(new Date());
|
||||||
|
return dispatchStatisticsMapper.updateDispatchStatistics(dispatchStatistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除派单统计
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的派单统计主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int deleteDispatchStatisticsByIds(Long[] ids) {
|
||||||
|
return dispatchStatisticsMapper.deleteDispatchStatisticsByIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除派单统计信息
|
||||||
|
*
|
||||||
|
* @param id 派单统计主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int deleteDispatchStatisticsById(Long id) {
|
||||||
|
return dispatchStatisticsMapper.deleteDispatchStatisticsById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单成功率统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 成功率统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getDispatchSuccessRate(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectDispatchSuccessRate(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取师傅接单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 师傅接单统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> getWorkerOrderStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectWorkerOrderStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取地区派单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 地区派单统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> getAreaDispatchStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectAreaDispatchStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取服务类型派单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 服务类型派单统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> getServiceTypeDispatchStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectServiceTypeDispatchStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单响应时间统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 响应时间统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getDispatchResponseTimeStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectDispatchResponseTimeStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取新师傅派单统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 新师傅派单统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getNewWorkerDispatchStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectNewWorkerDispatchStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单质量评分统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 质量评分统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getDispatchQualityStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectDispatchQualityStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取派单效率统计
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 效率统计
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getDispatchEfficiencyStatistics(String startDate, String endDate) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("startDate", startDate);
|
||||||
|
params.put("endDate", endDate);
|
||||||
|
return dispatchStatisticsMapper.selectDispatchEfficiencyStatistics(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取综合派单报告
|
||||||
|
*
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 综合报告
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getComprehensiveDispatchReport(String startDate, String endDate) {
|
||||||
|
Map<String, Object> report = new HashMap<>();
|
||||||
|
|
||||||
|
// 获取各项统计数据
|
||||||
|
report.put("successRate", getDispatchSuccessRate(startDate, endDate));
|
||||||
|
report.put("workerStatistics", getWorkerOrderStatistics(startDate, endDate));
|
||||||
|
report.put("areaStatistics", getAreaDispatchStatistics(startDate, endDate));
|
||||||
|
report.put("serviceTypeStatistics", getServiceTypeDispatchStatistics(startDate, endDate));
|
||||||
|
report.put("responseTimeStatistics", getDispatchResponseTimeStatistics(startDate, endDate));
|
||||||
|
report.put("newWorkerStatistics", getNewWorkerDispatchStatistics(startDate, endDate));
|
||||||
|
report.put("qualityStatistics", getDispatchQualityStatistics(startDate, endDate));
|
||||||
|
report.put("efficiencyStatistics", getDispatchEfficiencyStatistics(startDate, endDate));
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录派单统计
|
||||||
|
*
|
||||||
|
* @param statistics 统计信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int recordDispatchStatistics(DispatchStatistics statistics) {
|
||||||
|
return insertDispatchStatistics(statistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实时派单状态
|
||||||
|
*
|
||||||
|
* @return 实时状态
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getRealTimeDispatchStatus() {
|
||||||
|
return dispatchStatisticsMapper.selectRealTimeDispatchStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,7 +33,9 @@ public class OrderLogServiceImpl implements IOrderLogService
|
||||||
return orderLogMapper.selectOrderLogById(id);
|
return orderLogMapper.selectOrderLogById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int updateOrderLogEnd(Long id){
|
||||||
|
return orderLogMapper.updateOrderLogEnd(id);
|
||||||
|
}
|
||||||
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog){
|
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog){
|
||||||
return orderLogMapper.selectOneByOidTypeWorkerIdPaid(orderLog);
|
return orderLogMapper.selectOneByOidTypeWorkerIdPaid(orderLog);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,13 @@ public class OrderServiceImpl implements IOrderService
|
||||||
return orderMapper.selectOrderById(id);
|
return orderMapper.selectOrderById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int updateOrderPhone(Long id){
|
||||||
|
return orderMapper.updateOrderPhone(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int updateOrderCika(Long id){
|
||||||
|
return orderMapper.updateOrderCika(id);
|
||||||
|
}
|
||||||
public int selectCountOrderByUid(Long uid,Long status) {
|
public int selectCountOrderByUid(Long uid,Long status) {
|
||||||
return orderMapper.selectCountOrderByUid(uid,status);
|
return orderMapper.selectCountOrderByUid(uid,status);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.system.service.impl;
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ruoyi.system.mapper.UsersMapper;
|
import com.ruoyi.system.mapper.UsersMapper;
|
||||||
|
|
@ -134,4 +135,33 @@ public class UsersServiceImpl implements IUsersService
|
||||||
if (ids == null || ids.isEmpty()) return java.util.Collections.emptyList();
|
if (ids == null || ids.isEmpty()) return java.util.Collections.emptyList();
|
||||||
return usersMapper.selectUsersByIds(ids);
|
return usersMapper.selectUsersByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单专用查询 - 基础条件:type=2, status=1, is_stop=0, worker_time为当天
|
||||||
|
* @param params 查询参数,包含分页信息
|
||||||
|
* @return 符合条件的师傅列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Users> selectDispatchWorkers(Map<String, Object> params) {
|
||||||
|
return usersMapper.selectDispatchWorkers(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单备用查询 - 不限制地区,获取更多师傅
|
||||||
|
* @param params 查询参数,包含数量限制
|
||||||
|
* @return 符合条件的师傅列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Users> selectBackupDispatchWorkers(Map<String, Object> params) {
|
||||||
|
return usersMapper.selectBackupDispatchWorkers(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试用派单查询 - 用于验证基础条件
|
||||||
|
* @return 符合条件的师傅列表(限制10条)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Users> selectTestDispatchWorkers() {
|
||||||
|
return usersMapper.selectTestDispatchWorkers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.ruoyi.system.task;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import com.ruoyi.system.service.IDispatchScoreRecordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单评分更新定时任务
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
@Component("dispatchScoreUpdateTask")
|
||||||
|
public class DispatchScoreUpdateTask
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(DispatchScoreUpdateTask.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDispatchScoreRecordService dispatchScoreRecordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每天晚上12点更新所有师傅的评分记录
|
||||||
|
*/
|
||||||
|
public void updateAllWorkerScores()
|
||||||
|
{
|
||||||
|
log.info("========== 开始执行派单评分更新定时任务 ==========");
|
||||||
|
|
||||||
|
try {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// // 1. 清理过期的评分记录
|
||||||
|
// log.info("【步骤1】清理过期的评分记录");
|
||||||
|
// int cleanedCount = dispatchScoreRecordService.cleanExpiredRecords();
|
||||||
|
// log.info("【成功】清理了{}条过期记录", cleanedCount);
|
||||||
|
//
|
||||||
|
// // 2. 更新所有师傅的评分记录
|
||||||
|
// log.info("【步骤2】更新所有师傅的评分记录");
|
||||||
|
// int updatedCount = dispatchScoreRecordService.updateAllWorkerScores();
|
||||||
|
// log.info("【成功】更新了{}个师傅的评分记录", updatedCount);
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
log.info("【完成】派单评分更新定时任务执行完成,总耗时: {}ms", endTime - startTime);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("【错误】派单评分更新定时任务执行失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动触发评分更新(用于测试)
|
||||||
|
*/
|
||||||
|
public void manualUpdateScores()
|
||||||
|
{
|
||||||
|
log.info("========== 手动触发派单评分更新 ==========");
|
||||||
|
updateAllWorkerScores();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.ruoyi.system.test;
|
||||||
|
|
||||||
|
import com.ruoyi.system.ControllerUtil.DispatchUtil;
|
||||||
|
import com.ruoyi.system.domain.Users;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 派单功能测试类
|
||||||
|
*
|
||||||
|
* @author Mr. Zhang Pan
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DispatchTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试派单功能
|
||||||
|
*/
|
||||||
|
public void testDispatch() {
|
||||||
|
try {
|
||||||
|
// 测试订单ID
|
||||||
|
Long orderId = 1001L;
|
||||||
|
|
||||||
|
System.out.println("开始测试派单功能,订单ID: " + orderId);
|
||||||
|
|
||||||
|
// 执行派单
|
||||||
|
DispatchUtil.DispatchResult result = DispatchUtil.dispatchOrder(orderId);
|
||||||
|
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
Users worker = result.getWorker();
|
||||||
|
System.out.println("派单成功!");
|
||||||
|
System.out.println("选中的师傅信息:");
|
||||||
|
System.out.println(" 师傅ID: " + worker.getId());
|
||||||
|
System.out.println(" 师傅姓名: " + worker.getName());
|
||||||
|
System.out.println(" 师傅电话: " + worker.getPhone());
|
||||||
|
System.out.println(" 师傅类型: " + worker.getType());
|
||||||
|
System.out.println(" 师傅状态: " + worker.getStatus());
|
||||||
|
} else {
|
||||||
|
System.out.println("派单失败:" + result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("派单测试失败:" + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试配置参数
|
||||||
|
*/
|
||||||
|
public void testConfig() {
|
||||||
|
try {
|
||||||
|
System.out.println("测试派单配置参数...");
|
||||||
|
|
||||||
|
// 这里可以添加配置参数的测试逻辑
|
||||||
|
System.out.println("配置测试完成");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("配置测试失败:" + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行所有测试
|
||||||
|
*/
|
||||||
|
public void runAllTests() {
|
||||||
|
System.out.println("=== 开始派单系统测试 ===");
|
||||||
|
|
||||||
|
testConfig();
|
||||||
|
testDispatch();
|
||||||
|
|
||||||
|
System.out.println("=== 派单系统测试完成 ===");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
# FFmpeg集成说明
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
本项目已将FFmpeg集成到项目中,无需依赖系统安装的FFmpeg。
|
||||||
|
|
||||||
|
## 文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
ruoyi-system/src/main/resources/ffmpeg/
|
||||||
|
├── ffmpeg.exe # FFmpeg可执行文件
|
||||||
|
└── README.md # 说明文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
1. **自动检测**:优先使用项目内部的FFmpeg,如果不可用则回退到系统安装的FFmpeg
|
||||||
|
2. **跨平台支持**:支持Windows、Linux、macOS
|
||||||
|
3. **JAR包支持**:当项目打包为JAR时,会自动从JAR包中提取FFmpeg到临时目录
|
||||||
|
4. **错误处理**:完善的错误处理和日志记录
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 在代码中使用
|
||||||
|
|
||||||
|
```java
|
||||||
|
import com.ruoyi.system.utils.FFmpegUtils;
|
||||||
|
|
||||||
|
// 检查FFmpeg是否可用
|
||||||
|
boolean isAvailable = FFmpegUtils.isFFmpegAvailable();
|
||||||
|
|
||||||
|
// 获取FFmpeg版本
|
||||||
|
String version = FFmpegUtils.getFFmpegVersion();
|
||||||
|
|
||||||
|
// 合并音频文件
|
||||||
|
List<String> inputFiles = Arrays.asList("file1.mp3", "file2.mp3");
|
||||||
|
boolean success = FFmpegUtils.mergeAudioFiles(inputFiles, "output.mp3");
|
||||||
|
```
|
||||||
|
|
||||||
|
### API接口
|
||||||
|
|
||||||
|
- **录音上传**:`POST /api/worker/order/sound`
|
||||||
|
- **录音合并**:`POST /api/worker/order/sound/merge`
|
||||||
|
- **当前订单**:`GET /api/worker/sound/current/order`
|
||||||
|
|
||||||
|
## 技术实现
|
||||||
|
|
||||||
|
### 路径检测优先级
|
||||||
|
|
||||||
|
1. 项目内部FFmpeg (`/ffmpeg/ffmpeg.exe`)
|
||||||
|
2. 系统PATH中的FFmpeg
|
||||||
|
3. 常见安装路径:
|
||||||
|
- Windows: `C:\ffmpeg\bin\ffmpeg.exe`
|
||||||
|
- Linux: `/usr/bin/ffmpeg`
|
||||||
|
- macOS: `/usr/local/bin/ffmpeg`
|
||||||
|
|
||||||
|
### JAR包处理
|
||||||
|
|
||||||
|
当项目打包为JAR时,FFmpeg会被包含在JAR包中。运行时会自动提取到临时目录:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 自动提取FFmpeg到临时目录
|
||||||
|
String ffmpegPath = extractFFmpegFromJar();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **文件大小**:FFmpeg.exe文件较大(约100MB),会增加项目体积
|
||||||
|
2. **权限设置**:提取的FFmpeg会自动设置可执行权限
|
||||||
|
3. **临时文件**:从JAR包提取的FFmpeg会保存在临时目录中
|
||||||
|
4. **兼容性**:支持Windows、Linux、macOS等主流操作系统
|
||||||
|
|
||||||
|
## 故障排除
|
||||||
|
|
||||||
|
### 问题1:FFmpeg不可用
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 检查项目资源目录中是否存在`ffmpeg.exe`
|
||||||
|
2. 确认文件具有执行权限
|
||||||
|
3. 查看日志中的详细错误信息
|
||||||
|
|
||||||
|
### 问题2:合并失败
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 检查输入文件是否存在
|
||||||
|
2. 确认输出目录有写入权限
|
||||||
|
3. 查看FFmpeg执行日志
|
||||||
|
|
||||||
|
### 问题3:JAR包中FFmpeg无法提取
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 确认JAR包中包含FFmpeg资源
|
||||||
|
2. 检查临时目录权限
|
||||||
|
3. 查看提取过程的日志信息
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
- **v1.0.0**:初始版本,支持基本的音频合并功能
|
||||||
|
- **v1.1.0**:添加项目内部FFmpeg集成
|
||||||
|
- **v1.2.0**:支持JAR包中的FFmpeg提取
|
||||||
|
|
@ -0,0 +1,274 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.system.mapper.DispatchScoreRecordMapper">
|
||||||
|
|
||||||
|
<resultMap type="DispatchScoreRecord" id="DispatchScoreRecordResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="workerId" column="worker_id" />
|
||||||
|
<result property="workerName" column="worker_name" />
|
||||||
|
<result property="workerPhone" column="worker_phone" />
|
||||||
|
<result property="orderId" column="order_id" />
|
||||||
|
<result property="serviceId" column="service_id" />
|
||||||
|
<result property="userAddressId" column="user_address_id" />
|
||||||
|
<result property="distanceScore" column="distance_score" />
|
||||||
|
<result property="skillMatchScore" column="skill_match_score" />
|
||||||
|
<result property="experienceScore" column="experience_score" />
|
||||||
|
<result property="ratingScore" column="rating_score" />
|
||||||
|
<result property="availabilityScore" column="availability_score" />
|
||||||
|
<result property="newWorkerBonusScore" column="new_worker_bonus_score" />
|
||||||
|
<result property="totalScore" column="total_score" />
|
||||||
|
<result property="weightDistance" column="weight_distance" />
|
||||||
|
<result property="weightSkillMatch" column="weight_skill_match" />
|
||||||
|
<result property="weightExperience" column="weight_experience" />
|
||||||
|
<result property="weightRating" column="weight_rating" />
|
||||||
|
<result property="weightAvailability" column="weight_availability" />
|
||||||
|
<result property="weightNewWorkerBonus" column="weight_new_worker_bonus" />
|
||||||
|
<result property="distanceKm" column="distance_km" />
|
||||||
|
<result property="skillMatchCount" column="skill_match_count" />
|
||||||
|
<result property="totalSkillsCount" column="total_skills_count" />
|
||||||
|
<result property="completedOrdersCount" column="completed_orders_count" />
|
||||||
|
<result property="currentOrdersCount" column="current_orders_count" />
|
||||||
|
<result property="isNewWorker" column="is_new_worker" />
|
||||||
|
<result property="registrationDays" column="registration_days" />
|
||||||
|
<result property="workerLatitude" column="worker_latitude" />
|
||||||
|
<result property="workerLongitude" column="worker_longitude" />
|
||||||
|
<result property="userLatitude" column="user_latitude" />
|
||||||
|
<result property="userLongitude" column="user_longitude" />
|
||||||
|
<result property="cityCode" column="city_code" />
|
||||||
|
<result property="districtCode" column="district_code" />
|
||||||
|
<result property="workerStatus" column="worker_status" />
|
||||||
|
<result property="isWork" column="is_work" />
|
||||||
|
<result property="isStop" column="is_stop" />
|
||||||
|
<result property="hasUnfinishedOrders" column="has_unfinished_orders" />
|
||||||
|
<result property="isAvailable" column="is_available" />
|
||||||
|
<result property="rankPosition" column="rank_position" />
|
||||||
|
<result property="totalCandidates" column="total_candidates" />
|
||||||
|
<result property="isSelected" column="is_selected" />
|
||||||
|
<result property="selectionReason" column="selection_reason" />
|
||||||
|
<result property="scoreCalculationTime" column="score_calculation_time" />
|
||||||
|
<result property="lastUpdateTime" column="last_update_time" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="remark" column="remark" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectDispatchScoreRecordVo">
|
||||||
|
select id, worker_id, worker_name, worker_phone, order_id, service_id, user_address_id, distance_score, skill_match_score, experience_score, rating_score, availability_score, new_worker_bonus_score, total_score, weight_distance, weight_skill_match, weight_experience, weight_rating, weight_availability, weight_new_worker_bonus, distance_km, skill_match_count, total_skills_count, completed_orders_count, current_orders_count, is_new_worker, registration_days, worker_latitude, worker_longitude, user_latitude, user_longitude, city_code, district_code, worker_status, is_work, is_stop, has_unfinished_orders, is_available, rank_position, total_candidates, is_selected, selection_reason, score_calculation_time, last_update_time, create_time, remark from dispatch_score_record
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectDispatchScoreRecordList" parameterType="DispatchScoreRecord" resultMap="DispatchScoreRecordResult">
|
||||||
|
<include refid="selectDispatchScoreRecordVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="workerId != null "> and worker_id = #{workerId}</if>
|
||||||
|
<if test="workerName != null and workerName != ''"> and worker_name like concat('%', #{workerName}, '%')</if>
|
||||||
|
<if test="workerPhone != null and workerPhone != ''"> and worker_phone = #{workerPhone}</if>
|
||||||
|
<if test="orderId != null "> and order_id = #{orderId}</if>
|
||||||
|
<if test="serviceId != null "> and service_id = #{serviceId}</if>
|
||||||
|
<if test="userAddressId != null "> and user_address_id = #{userAddressId}</if>
|
||||||
|
<if test="distanceScore != null "> and distance_score = #{distanceScore}</if>
|
||||||
|
<if test="skillMatchScore != null "> and skill_match_score = #{skillMatchScore}</if>
|
||||||
|
<if test="experienceScore != null "> and experience_score = #{experienceScore}</if>
|
||||||
|
<if test="ratingScore != null "> and rating_score = #{ratingScore}</if>
|
||||||
|
<if test="availabilityScore != null "> and availability_score = #{availabilityScore}</if>
|
||||||
|
<if test="newWorkerBonusScore != null "> and new_worker_bonus_score = #{newWorkerBonusScore}</if>
|
||||||
|
<if test="totalScore != null "> and total_score = #{totalScore}</if>
|
||||||
|
<if test="weightDistance != null "> and weight_distance = #{weightDistance}</if>
|
||||||
|
<if test="weightSkillMatch != null "> and weight_skill_match = #{weightSkillMatch}</if>
|
||||||
|
<if test="weightExperience != null "> and weight_experience = #{weightExperience}</if>
|
||||||
|
<if test="weightRating != null "> and weight_rating = #{weightRating}</if>
|
||||||
|
<if test="weightAvailability != null "> and weight_availability = #{weightAvailability}</if>
|
||||||
|
<if test="weightNewWorkerBonus != null "> and weight_new_worker_bonus = #{weightNewWorkerBonus}</if>
|
||||||
|
<if test="distanceKm != null "> and distance_km = #{distanceKm}</if>
|
||||||
|
<if test="skillMatchCount != null "> and skill_match_count = #{skillMatchCount}</if>
|
||||||
|
<if test="totalSkillsCount != null "> and total_skills_count = #{totalSkillsCount}</if>
|
||||||
|
<if test="completedOrdersCount != null "> and completed_orders_count = #{completedOrdersCount}</if>
|
||||||
|
<if test="currentOrdersCount != null "> and current_orders_count = #{currentOrdersCount}</if>
|
||||||
|
<if test="isNewWorker != null "> and is_new_worker = #{isNewWorker}</if>
|
||||||
|
<if test="registrationDays != null "> and registration_days = #{registrationDays}</if>
|
||||||
|
<if test="workerLatitude != null and workerLatitude != ''"> and worker_latitude = #{workerLatitude}</if>
|
||||||
|
<if test="workerLongitude != null and workerLongitude != ''"> and worker_longitude = #{workerLongitude}</if>
|
||||||
|
<if test="userLatitude != null and userLatitude != ''"> and user_latitude = #{userLatitude}</if>
|
||||||
|
<if test="userLongitude != null and userLongitude != ''"> and user_longitude = #{userLongitude}</if>
|
||||||
|
<if test="cityCode != null and cityCode != ''"> and city_code = #{cityCode}</if>
|
||||||
|
<if test="districtCode != null and districtCode != ''"> and district_code = #{districtCode}</if>
|
||||||
|
<if test="workerStatus != null "> and worker_status = #{workerStatus}</if>
|
||||||
|
<if test="isWork != null "> and is_work = #{isWork}</if>
|
||||||
|
<if test="isStop != null "> and is_stop = #{isStop}</if>
|
||||||
|
<if test="hasUnfinishedOrders != null "> and has_unfinished_orders = #{hasUnfinishedOrders}</if>
|
||||||
|
<if test="isAvailable != null "> and is_available = #{isAvailable}</if>
|
||||||
|
<if test="rankPosition != null "> and rank_position = #{rankPosition}</if>
|
||||||
|
<if test="totalCandidates != null "> and total_candidates = #{totalCandidates}</if>
|
||||||
|
<if test="isSelected != null "> and is_selected = #{isSelected}</if>
|
||||||
|
<if test="selectionReason != null and selectionReason != ''"> and selection_reason = #{selectionReason}</if>
|
||||||
|
<if test="scoreCalculationTime != null "> and score_calculation_time = #{scoreCalculationTime}</if>
|
||||||
|
<if test="lastUpdateTime != null "> and last_update_time = #{lastUpdateTime}</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDispatchScoreRecordById" parameterType="Long" resultMap="DispatchScoreRecordResult">
|
||||||
|
<include refid="selectDispatchScoreRecordVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertDispatchScoreRecord" parameterType="DispatchScoreRecord" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into dispatch_score_record
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="workerId != null">worker_id,</if>
|
||||||
|
<if test="workerName != null and workerName != ''">worker_name,</if>
|
||||||
|
<if test="workerPhone != null">worker_phone,</if>
|
||||||
|
<if test="orderId != null">order_id,</if>
|
||||||
|
<if test="serviceId != null">service_id,</if>
|
||||||
|
<if test="userAddressId != null">user_address_id,</if>
|
||||||
|
<if test="distanceScore != null">distance_score,</if>
|
||||||
|
<if test="skillMatchScore != null">skill_match_score,</if>
|
||||||
|
<if test="experienceScore != null">experience_score,</if>
|
||||||
|
<if test="ratingScore != null">rating_score,</if>
|
||||||
|
<if test="availabilityScore != null">availability_score,</if>
|
||||||
|
<if test="newWorkerBonusScore != null">new_worker_bonus_score,</if>
|
||||||
|
<if test="totalScore != null">total_score,</if>
|
||||||
|
<if test="weightDistance != null">weight_distance,</if>
|
||||||
|
<if test="weightSkillMatch != null">weight_skill_match,</if>
|
||||||
|
<if test="weightExperience != null">weight_experience,</if>
|
||||||
|
<if test="weightRating != null">weight_rating,</if>
|
||||||
|
<if test="weightAvailability != null">weight_availability,</if>
|
||||||
|
<if test="weightNewWorkerBonus != null">weight_new_worker_bonus,</if>
|
||||||
|
<if test="distanceKm != null">distance_km,</if>
|
||||||
|
<if test="skillMatchCount != null">skill_match_count,</if>
|
||||||
|
<if test="totalSkillsCount != null">total_skills_count,</if>
|
||||||
|
<if test="completedOrdersCount != null">completed_orders_count,</if>
|
||||||
|
<if test="currentOrdersCount != null">current_orders_count,</if>
|
||||||
|
<if test="isNewWorker != null">is_new_worker,</if>
|
||||||
|
<if test="registrationDays != null">registration_days,</if>
|
||||||
|
<if test="workerLatitude != null">worker_latitude,</if>
|
||||||
|
<if test="workerLongitude != null">worker_longitude,</if>
|
||||||
|
<if test="userLatitude != null">user_latitude,</if>
|
||||||
|
<if test="userLongitude != null">user_longitude,</if>
|
||||||
|
<if test="cityCode != null">city_code,</if>
|
||||||
|
<if test="districtCode != null">district_code,</if>
|
||||||
|
<if test="workerStatus != null">worker_status,</if>
|
||||||
|
<if test="isWork != null">is_work,</if>
|
||||||
|
<if test="isStop != null">is_stop,</if>
|
||||||
|
<if test="hasUnfinishedOrders != null">has_unfinished_orders,</if>
|
||||||
|
<if test="isAvailable != null">is_available,</if>
|
||||||
|
<if test="rankPosition != null">rank_position,</if>
|
||||||
|
<if test="totalCandidates != null">total_candidates,</if>
|
||||||
|
<if test="isSelected != null">is_selected,</if>
|
||||||
|
<if test="selectionReason != null">selection_reason,</if>
|
||||||
|
<if test="scoreCalculationTime != null">score_calculation_time,</if>
|
||||||
|
<if test="lastUpdateTime != null">last_update_time,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="remark != null">remark,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="workerId != null">#{workerId},</if>
|
||||||
|
<if test="workerName != null and workerName != ''">#{workerName},</if>
|
||||||
|
<if test="workerPhone != null">#{workerPhone},</if>
|
||||||
|
<if test="orderId != null">#{orderId},</if>
|
||||||
|
<if test="serviceId != null">#{serviceId},</if>
|
||||||
|
<if test="userAddressId != null">#{userAddressId},</if>
|
||||||
|
<if test="distanceScore != null">#{distanceScore},</if>
|
||||||
|
<if test="skillMatchScore != null">#{skillMatchScore},</if>
|
||||||
|
<if test="experienceScore != null">#{experienceScore},</if>
|
||||||
|
<if test="ratingScore != null">#{ratingScore},</if>
|
||||||
|
<if test="availabilityScore != null">#{availabilityScore},</if>
|
||||||
|
<if test="newWorkerBonusScore != null">#{newWorkerBonusScore},</if>
|
||||||
|
<if test="totalScore != null">#{totalScore},</if>
|
||||||
|
<if test="weightDistance != null">#{weightDistance},</if>
|
||||||
|
<if test="weightSkillMatch != null">#{weightSkillMatch},</if>
|
||||||
|
<if test="weightExperience != null">#{weightExperience},</if>
|
||||||
|
<if test="weightRating != null">#{weightRating},</if>
|
||||||
|
<if test="weightAvailability != null">#{weightAvailability},</if>
|
||||||
|
<if test="weightNewWorkerBonus != null">#{weightNewWorkerBonus},</if>
|
||||||
|
<if test="distanceKm != null">#{distanceKm},</if>
|
||||||
|
<if test="skillMatchCount != null">#{skillMatchCount},</if>
|
||||||
|
<if test="totalSkillsCount != null">#{totalSkillsCount},</if>
|
||||||
|
<if test="completedOrdersCount != null">#{completedOrdersCount},</if>
|
||||||
|
<if test="currentOrdersCount != null">#{currentOrdersCount},</if>
|
||||||
|
<if test="isNewWorker != null">#{isNewWorker},</if>
|
||||||
|
<if test="registrationDays != null">#{registrationDays},</if>
|
||||||
|
<if test="workerLatitude != null">#{workerLatitude},</if>
|
||||||
|
<if test="workerLongitude != null">#{workerLongitude},</if>
|
||||||
|
<if test="userLatitude != null">#{userLatitude},</if>
|
||||||
|
<if test="userLongitude != null">#{userLongitude},</if>
|
||||||
|
<if test="cityCode != null">#{cityCode},</if>
|
||||||
|
<if test="districtCode != null">#{districtCode},</if>
|
||||||
|
<if test="workerStatus != null">#{workerStatus},</if>
|
||||||
|
<if test="isWork != null">#{isWork},</if>
|
||||||
|
<if test="isStop != null">#{isStop},</if>
|
||||||
|
<if test="hasUnfinishedOrders != null">#{hasUnfinishedOrders},</if>
|
||||||
|
<if test="isAvailable != null">#{isAvailable},</if>
|
||||||
|
<if test="rankPosition != null">#{rankPosition},</if>
|
||||||
|
<if test="totalCandidates != null">#{totalCandidates},</if>
|
||||||
|
<if test="isSelected != null">#{isSelected},</if>
|
||||||
|
<if test="selectionReason != null">#{selectionReason},</if>
|
||||||
|
<if test="scoreCalculationTime != null">#{scoreCalculationTime},</if>
|
||||||
|
<if test="lastUpdateTime != null">#{lastUpdateTime},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="remark != null">#{remark},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateDispatchScoreRecord" parameterType="DispatchScoreRecord">
|
||||||
|
update dispatch_score_record
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="workerId != null">worker_id = #{workerId},</if>
|
||||||
|
<if test="workerName != null and workerName != ''">worker_name = #{workerName},</if>
|
||||||
|
<if test="workerPhone != null">worker_phone = #{workerPhone},</if>
|
||||||
|
<if test="orderId != null">order_id = #{orderId},</if>
|
||||||
|
<if test="serviceId != null">service_id = #{serviceId},</if>
|
||||||
|
<if test="userAddressId != null">user_address_id = #{userAddressId},</if>
|
||||||
|
<if test="distanceScore != null">distance_score = #{distanceScore},</if>
|
||||||
|
<if test="skillMatchScore != null">skill_match_score = #{skillMatchScore},</if>
|
||||||
|
<if test="experienceScore != null">experience_score = #{experienceScore},</if>
|
||||||
|
<if test="ratingScore != null">rating_score = #{ratingScore},</if>
|
||||||
|
<if test="availabilityScore != null">availability_score = #{availabilityScore},</if>
|
||||||
|
<if test="newWorkerBonusScore != null">new_worker_bonus_score = #{newWorkerBonusScore},</if>
|
||||||
|
<if test="totalScore != null">total_score = #{totalScore},</if>
|
||||||
|
<if test="weightDistance != null">weight_distance = #{weightDistance},</if>
|
||||||
|
<if test="weightSkillMatch != null">weight_skill_match = #{weightSkillMatch},</if>
|
||||||
|
<if test="weightExperience != null">weight_experience = #{weightExperience},</if>
|
||||||
|
<if test="weightRating != null">weight_rating = #{weightRating},</if>
|
||||||
|
<if test="weightAvailability != null">weight_availability = #{weightAvailability},</if>
|
||||||
|
<if test="weightNewWorkerBonus != null">weight_new_worker_bonus = #{weightNewWorkerBonus},</if>
|
||||||
|
<if test="distanceKm != null">distance_km = #{distanceKm},</if>
|
||||||
|
<if test="skillMatchCount != null">skill_match_count = #{skillMatchCount},</if>
|
||||||
|
<if test="totalSkillsCount != null">total_skills_count = #{totalSkillsCount},</if>
|
||||||
|
<if test="completedOrdersCount != null">completed_orders_count = #{completedOrdersCount},</if>
|
||||||
|
<if test="currentOrdersCount != null">current_orders_count = #{currentOrdersCount},</if>
|
||||||
|
<if test="isNewWorker != null">is_new_worker = #{isNewWorker},</if>
|
||||||
|
<if test="registrationDays != null">registration_days = #{registrationDays},</if>
|
||||||
|
<if test="workerLatitude != null">worker_latitude = #{workerLatitude},</if>
|
||||||
|
<if test="workerLongitude != null">worker_longitude = #{workerLongitude},</if>
|
||||||
|
<if test="userLatitude != null">user_latitude = #{userLatitude},</if>
|
||||||
|
<if test="userLongitude != null">user_longitude = #{userLongitude},</if>
|
||||||
|
<if test="cityCode != null">city_code = #{cityCode},</if>
|
||||||
|
<if test="districtCode != null">district_code = #{districtCode},</if>
|
||||||
|
<if test="workerStatus != null">worker_status = #{workerStatus},</if>
|
||||||
|
<if test="isWork != null">is_work = #{isWork},</if>
|
||||||
|
<if test="isStop != null">is_stop = #{isStop},</if>
|
||||||
|
<if test="hasUnfinishedOrders != null">has_unfinished_orders = #{hasUnfinishedOrders},</if>
|
||||||
|
<if test="isAvailable != null">is_available = #{isAvailable},</if>
|
||||||
|
<if test="rankPosition != null">rank_position = #{rankPosition},</if>
|
||||||
|
<if test="totalCandidates != null">total_candidates = #{totalCandidates},</if>
|
||||||
|
<if test="isSelected != null">is_selected = #{isSelected},</if>
|
||||||
|
<if test="selectionReason != null">selection_reason = #{selectionReason},</if>
|
||||||
|
<if test="scoreCalculationTime != null">score_calculation_time = #{scoreCalculationTime},</if>
|
||||||
|
<if test="lastUpdateTime != null">last_update_time = #{lastUpdateTime},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteDispatchScoreRecordById" parameterType="Long">
|
||||||
|
delete from dispatch_score_record where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteDispatchScoreRecordByIds" parameterType="String">
|
||||||
|
delete from dispatch_score_record where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
|
|
@ -0,0 +1,280 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.system.mapper.DispatchStatisticsMapper">
|
||||||
|
|
||||||
|
<resultMap type="DispatchStatistics" id="DispatchStatisticsResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="orderId" column="order_id" />
|
||||||
|
<result property="workerId" column="worker_id" />
|
||||||
|
<result property="workerName" column="worker_name" />
|
||||||
|
<result property="serviceId" column="service_id" />
|
||||||
|
<result property="serviceName" column="service_name" />
|
||||||
|
<result property="addressId" column="address_id" />
|
||||||
|
<result property="address" column="address" />
|
||||||
|
<result property="cityCode" column="city_code" />
|
||||||
|
<result property="cityName" column="city_name" />
|
||||||
|
<result property="dispatchType" column="dispatch_type" />
|
||||||
|
<result property="dispatchResult" column="dispatch_result" />
|
||||||
|
<result property="dispatchTime" column="dispatch_time" />
|
||||||
|
<result property="distanceScore" column="distance_score" />
|
||||||
|
<result property="skillMatchScore" column="skill_match_score" />
|
||||||
|
<result property="experienceScore" column="experience_score" />
|
||||||
|
<result property="ratingScore" column="rating_score" />
|
||||||
|
<result property="availabilityScore" column="availability_score" />
|
||||||
|
<result property="newWorkerBonusScore" column="new_worker_bonus_score" />
|
||||||
|
<result property="totalScore" column="total_score" />
|
||||||
|
<result property="candidateCount" column="candidate_count" />
|
||||||
|
<result property="retryCount" column="retry_count" />
|
||||||
|
<result property="failureReason" column="failure_reason" />
|
||||||
|
<result property="dispatchDate" column="dispatch_date" />
|
||||||
|
<result property="createdAt" column="created_at" />
|
||||||
|
<result property="updatedAt" column="updated_at" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectDispatchStatisticsVo">
|
||||||
|
select id, order_id, worker_id, worker_name, service_id, service_name, address_id, address,
|
||||||
|
city_code, city_name, dispatch_type, dispatch_result, dispatch_time, distance_score,
|
||||||
|
skill_match_score, experience_score, rating_score, availability_score, new_worker_bonus_score,
|
||||||
|
total_score, candidate_count, retry_count, failure_reason, dispatch_date, created_at, updated_at
|
||||||
|
from dispatch_statistics
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectDispatchStatisticsList" parameterType="DispatchStatistics" resultMap="DispatchStatisticsResult">
|
||||||
|
<include refid="selectDispatchStatisticsVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="orderId != null "> and order_id = #{orderId}</if>
|
||||||
|
<if test="workerId != null "> and worker_id = #{workerId}</if>
|
||||||
|
<if test="workerName != null and workerName != ''"> and worker_name like concat('%', #{workerName}, '%')</if>
|
||||||
|
<if test="serviceId != null "> and service_id = #{serviceId}</if>
|
||||||
|
<if test="serviceName != null and serviceName != ''"> and service_name like concat('%', #{serviceName}, '%')</if>
|
||||||
|
<if test="cityCode != null and cityCode != ''"> and city_code = #{cityCode}</if>
|
||||||
|
<if test="cityName != null and cityName != ''"> and city_name like concat('%', #{cityName}, '%')</if>
|
||||||
|
<if test="dispatchType != null "> and dispatch_type = #{dispatchType}</if>
|
||||||
|
<if test="dispatchResult != null "> and dispatch_result = #{dispatchResult}</if>
|
||||||
|
<if test="dispatchDate != null "> and date_format(dispatch_date,'%y-%m-%d') = date_format(#{dispatchDate},'%y-%m-%d')</if>
|
||||||
|
</where>
|
||||||
|
order by created_at desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDispatchStatisticsById" parameterType="Long" resultMap="DispatchStatisticsResult">
|
||||||
|
<include refid="selectDispatchStatisticsVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertDispatchStatistics" parameterType="DispatchStatistics" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into dispatch_statistics
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="orderId != null">order_id,</if>
|
||||||
|
<if test="workerId != null">worker_id,</if>
|
||||||
|
<if test="workerName != null">worker_name,</if>
|
||||||
|
<if test="serviceId != null">service_id,</if>
|
||||||
|
<if test="serviceName != null">service_name,</if>
|
||||||
|
<if test="addressId != null">address_id,</if>
|
||||||
|
<if test="address != null">address,</if>
|
||||||
|
<if test="cityCode != null">city_code,</if>
|
||||||
|
<if test="cityName != null">city_name,</if>
|
||||||
|
<if test="dispatchType != null">dispatch_type,</if>
|
||||||
|
<if test="dispatchResult != null">dispatch_result,</if>
|
||||||
|
<if test="dispatchTime != null">dispatch_time,</if>
|
||||||
|
<if test="distanceScore != null">distance_score,</if>
|
||||||
|
<if test="skillMatchScore != null">skill_match_score,</if>
|
||||||
|
<if test="experienceScore != null">experience_score,</if>
|
||||||
|
<if test="ratingScore != null">rating_score,</if>
|
||||||
|
<if test="availabilityScore != null">availability_score,</if>
|
||||||
|
<if test="newWorkerBonusScore != null">new_worker_bonus_score,</if>
|
||||||
|
<if test="totalScore != null">total_score,</if>
|
||||||
|
<if test="candidateCount != null">candidate_count,</if>
|
||||||
|
<if test="retryCount != null">retry_count,</if>
|
||||||
|
<if test="failureReason != null">failure_reason,</if>
|
||||||
|
<if test="dispatchDate != null">dispatch_date,</if>
|
||||||
|
<if test="createdAt != null">created_at,</if>
|
||||||
|
<if test="updatedAt != null">updated_at,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="orderId != null">#{orderId},</if>
|
||||||
|
<if test="workerId != null">#{workerId},</if>
|
||||||
|
<if test="workerName != null">#{workerName},</if>
|
||||||
|
<if test="serviceId != null">#{serviceId},</if>
|
||||||
|
<if test="serviceName != null">#{serviceName},</if>
|
||||||
|
<if test="addressId != null">#{addressId},</if>
|
||||||
|
<if test="address != null">#{address},</if>
|
||||||
|
<if test="cityCode != null">#{cityCode},</if>
|
||||||
|
<if test="cityName != null">#{cityName},</if>
|
||||||
|
<if test="dispatchType != null">#{dispatchType},</if>
|
||||||
|
<if test="dispatchResult != null">#{dispatchResult},</if>
|
||||||
|
<if test="dispatchTime != null">#{dispatchTime},</if>
|
||||||
|
<if test="distanceScore != null">#{distanceScore},</if>
|
||||||
|
<if test="skillMatchScore != null">#{skillMatchScore},</if>
|
||||||
|
<if test="experienceScore != null">#{experienceScore},</if>
|
||||||
|
<if test="ratingScore != null">#{ratingScore},</if>
|
||||||
|
<if test="availabilityScore != null">#{availabilityScore},</if>
|
||||||
|
<if test="newWorkerBonusScore != null">#{newWorkerBonusScore},</if>
|
||||||
|
<if test="totalScore != null">#{totalScore},</if>
|
||||||
|
<if test="candidateCount != null">#{candidateCount},</if>
|
||||||
|
<if test="retryCount != null">#{retryCount},</if>
|
||||||
|
<if test="failureReason != null">#{failureReason},</if>
|
||||||
|
<if test="dispatchDate != null">#{dispatchDate},</if>
|
||||||
|
<if test="createdAt != null">#{createdAt},</if>
|
||||||
|
<if test="updatedAt != null">#{updatedAt},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateDispatchStatistics" parameterType="DispatchStatistics">
|
||||||
|
update dispatch_statistics
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="orderId != null">order_id = #{orderId},</if>
|
||||||
|
<if test="workerId != null">worker_id = #{workerId},</if>
|
||||||
|
<if test="workerName != null">worker_name = #{workerName},</if>
|
||||||
|
<if test="serviceId != null">service_id = #{serviceId},</if>
|
||||||
|
<if test="serviceName != null">service_name = #{serviceName},</if>
|
||||||
|
<if test="addressId != null">address_id = #{addressId},</if>
|
||||||
|
<if test="address != null">address = #{address},</if>
|
||||||
|
<if test="cityCode != null">city_code = #{cityCode},</if>
|
||||||
|
<if test="cityName != null">city_name = #{cityName},</if>
|
||||||
|
<if test="dispatchType != null">dispatch_type = #{dispatchType},</if>
|
||||||
|
<if test="dispatchResult != null">dispatch_result = #{dispatchResult},</if>
|
||||||
|
<if test="dispatchTime != null">dispatch_time = #{dispatchTime},</if>
|
||||||
|
<if test="distanceScore != null">distance_score = #{distanceScore},</if>
|
||||||
|
<if test="skillMatchScore != null">skill_match_score = #{skillMatchScore},</if>
|
||||||
|
<if test="experienceScore != null">experience_score = #{experienceScore},</if>
|
||||||
|
<if test="ratingScore != null">rating_score = #{ratingScore},</if>
|
||||||
|
<if test="availabilityScore != null">availability_score = #{availabilityScore},</if>
|
||||||
|
<if test="newWorkerBonusScore != null">new_worker_bonus_score = #{newWorkerBonusScore},</if>
|
||||||
|
<if test="totalScore != null">total_score = #{totalScore},</if>
|
||||||
|
<if test="candidateCount != null">candidate_count = #{candidateCount},</if>
|
||||||
|
<if test="retryCount != null">retry_count = #{retryCount},</if>
|
||||||
|
<if test="failureReason != null">failure_reason = #{failureReason},</if>
|
||||||
|
<if test="dispatchDate != null">dispatch_date = #{dispatchDate},</if>
|
||||||
|
<if test="createdAt != null">created_at = #{createdAt},</if>
|
||||||
|
<if test="updatedAt != null">updated_at = #{updatedAt},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteDispatchStatisticsById" parameterType="Long">
|
||||||
|
delete from dispatch_statistics where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteDispatchStatisticsByIds" parameterType="String">
|
||||||
|
delete from dispatch_statistics where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<!-- 获取派单成功率统计 -->
|
||||||
|
<select id="selectDispatchSuccessRate" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total_count,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as success_count,
|
||||||
|
SUM(CASE WHEN dispatch_result = 0 THEN 1 ELSE 0 END) as failure_count,
|
||||||
|
ROUND(SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as success_rate
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取师傅接单统计 -->
|
||||||
|
<select id="selectWorkerOrderStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
worker_id,
|
||||||
|
worker_name,
|
||||||
|
COUNT(*) as order_count,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as success_count,
|
||||||
|
ROUND(AVG(total_score), 2) as avg_score
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
GROUP BY worker_id, worker_name
|
||||||
|
ORDER BY order_count DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取地区派单统计 -->
|
||||||
|
<select id="selectAreaDispatchStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
city_code,
|
||||||
|
city_name,
|
||||||
|
COUNT(*) as order_count,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as success_count,
|
||||||
|
ROUND(AVG(dispatch_time), 2) as avg_dispatch_time
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
GROUP BY city_code, city_name
|
||||||
|
ORDER BY order_count DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取服务类型派单统计 -->
|
||||||
|
<select id="selectServiceTypeDispatchStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
service_id,
|
||||||
|
service_name,
|
||||||
|
COUNT(*) as order_count,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as success_count,
|
||||||
|
ROUND(AVG(total_score), 2) as avg_score
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
GROUP BY service_id, service_name
|
||||||
|
ORDER BY order_count DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取派单响应时间统计 -->
|
||||||
|
<select id="selectDispatchResponseTimeStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
ROUND(AVG(dispatch_time), 2) as avg_dispatch_time,
|
||||||
|
MIN(dispatch_time) as min_dispatch_time,
|
||||||
|
MAX(dispatch_time) as max_dispatch_time,
|
||||||
|
COUNT(*) as total_count
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
AND dispatch_result = 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取新师傅派单统计 -->
|
||||||
|
<select id="selectNewWorkerDispatchStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
COUNT(DISTINCT worker_id) as new_worker_count,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as success_count,
|
||||||
|
ROUND(AVG(new_worker_bonus_score), 2) as avg_bonus_score
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
AND new_worker_bonus_score > 0
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取派单质量评分统计 -->
|
||||||
|
<select id="selectDispatchQualityStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
ROUND(AVG(total_score), 2) as avg_total_score,
|
||||||
|
ROUND(AVG(distance_score), 2) as avg_distance_score,
|
||||||
|
ROUND(AVG(skill_match_score), 2) as avg_skill_match_score,
|
||||||
|
ROUND(AVG(experience_score), 2) as avg_experience_score,
|
||||||
|
ROUND(AVG(rating_score), 2) as avg_rating_score,
|
||||||
|
ROUND(AVG(availability_score), 2) as avg_availability_score
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
AND dispatch_result = 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取派单效率统计 -->
|
||||||
|
<select id="selectDispatchEfficiencyStatistics" parameterType="Map" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total_orders,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as successful_orders,
|
||||||
|
ROUND(AVG(dispatch_time), 2) as avg_dispatch_time,
|
||||||
|
ROUND(AVG(candidate_count), 2) as avg_candidate_count,
|
||||||
|
ROUND(AVG(retry_count), 2) as avg_retry_count
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE dispatch_date BETWEEN #{startDate} AND #{endDate}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取实时派单状态 -->
|
||||||
|
<select id="selectRealTimeDispatchStatus" resultType="Map">
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as today_total,
|
||||||
|
SUM(CASE WHEN dispatch_result = 1 THEN 1 ELSE 0 END) as today_success,
|
||||||
|
SUM(CASE WHEN dispatch_result = 0 THEN 1 ELSE 0 END) as today_failure,
|
||||||
|
ROUND(AVG(dispatch_time), 2) as avg_dispatch_time
|
||||||
|
FROM dispatch_statistics
|
||||||
|
WHERE DATE(dispatch_date) = CURDATE()
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
|
|
@ -16,6 +16,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<result property="isforservice" column="isforservice" />
|
<result property="isforservice" column="isforservice" />
|
||||||
<result property="forserviceid" column="forserviceid" />
|
<result property="forserviceid" column="forserviceid" />
|
||||||
<result property="name" column="name" />
|
<result property="name" column="name" />
|
||||||
|
<result property="returnrealmoney" column="returnrealmoney" />
|
||||||
|
|
||||||
<result property="phone" column="phone" />
|
<result property="phone" column="phone" />
|
||||||
<result property="address" column="address" />
|
<result property="address" column="address" />
|
||||||
<result property="num" column="num" />
|
<result property="num" column="num" />
|
||||||
|
|
@ -57,7 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectGoodsOrderVo">
|
<sql id="selectGoodsOrderVo">
|
||||||
select id, type, main_order_id,returnshow, returnstatus,order_id,returntime,returnmoney,returnfinshtime,returntype,returnreason,returnfiledata,returnlogistics,returnlogisticscode,returnjson, transaction_id,forserviceid,isforservice,isself,coupon_id,shopadresssid, uid, product_id, name, phone, address, num, total_price, good_price, service_price, pay_price, deduction, postage, pay_time, status, delivery_id, delivery_num, send_time, mark, address_id, sku, created_at, updated_at, deleted_at from goods_order
|
select id, type, main_order_id,returnshow,returnrealmoney, returnstatus,order_id,returntime,returnmoney,returnfinshtime,returntype,returnreason,returnfiledata,returnlogistics,returnlogisticscode,returnjson, transaction_id,forserviceid,isforservice,isself,coupon_id,shopadresssid, uid, product_id, name, phone, address, num, total_price, good_price, service_price, pay_price, deduction, postage, pay_time, status, delivery_id, delivery_num, send_time, mark, address_id, sku, created_at, updated_at, deleted_at from goods_order
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectGoodsOrderList" parameterType="GoodsOrder" resultMap="GoodsOrderResult">
|
<select id="selectGoodsOrderList" parameterType="GoodsOrder" resultMap="GoodsOrderResult">
|
||||||
|
|
@ -155,6 +157,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="returnfinshtime != null">returnfinshtime,</if>
|
<if test="returnfinshtime != null">returnfinshtime,</if>
|
||||||
<if test="returnstatus != null">returnstatus,</if>
|
<if test="returnstatus != null">returnstatus,</if>
|
||||||
<if test="returnshow != null">returnshow,</if>
|
<if test="returnshow != null">returnshow,</if>
|
||||||
|
<if test="returnrealmoney != null">returnrealmoney,</if>
|
||||||
|
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
|
|
@ -201,6 +204,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="returnfinshtime != null">#{returnfinshtime},</if>
|
<if test="returnfinshtime != null">#{returnfinshtime},</if>
|
||||||
<if test="returnstatus != null">#{returnstatus},</if>
|
<if test="returnstatus != null">#{returnstatus},</if>
|
||||||
<if test="returnshow != null">#{returnshow},</if>
|
<if test="returnshow != null">#{returnshow},</if>
|
||||||
|
<if test="returnrealmoney != null">#{returnrealmoney},</if>
|
||||||
|
|
||||||
NOW(),
|
NOW(),
|
||||||
NOW()
|
NOW()
|
||||||
|
|
||||||
|
|
@ -252,6 +257,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="returnfinshtime != null">returnfinshtime = #{returnfinshtime},</if>
|
<if test="returnfinshtime != null">returnfinshtime = #{returnfinshtime},</if>
|
||||||
<if test="returnstatus != null">returnstatus = #{returnstatus},</if>
|
<if test="returnstatus != null">returnstatus = #{returnstatus},</if>
|
||||||
<if test="returnshow != null">returnshow = #{returnshow},</if>
|
<if test="returnshow != null">returnshow = #{returnshow},</if>
|
||||||
|
<if test="returnrealmoney != null">returnrealmoney = #{returnrealmoney},</if>
|
||||||
|
|
||||||
updated_at=NOW()
|
updated_at=NOW()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
<update id="updateOrderLogEnd" parameterType="Long">
|
||||||
|
update order_log set
|
||||||
|
deposit = null,
|
||||||
|
dep_paid =null,
|
||||||
|
dep_log_id=null,
|
||||||
|
price = null,
|
||||||
|
log_id = null,
|
||||||
|
reduction_price = null,
|
||||||
|
paid = null
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
<update id="updateOrderLog" parameterType="OrderLog">
|
<update id="updateOrderLog" parameterType="OrderLog">
|
||||||
update order_log
|
update order_log
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
|
|
||||||
|
|
@ -578,6 +578,14 @@
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<update id="updateOrderPhone" parameterType="Long">
|
||||||
|
UPDATE order_data SET user_phone=null,worker_phone=null,middle_phone=null WHERE id=#{id}
|
||||||
|
</update>
|
||||||
|
<update id="updateOrderCika" parameterType="Long">
|
||||||
|
UPDATE order_data SET cartid=null WHERE id=#{id}
|
||||||
|
</update>
|
||||||
<update id="updateOrder" parameterType="Order">
|
<update id="updateOrder" parameterType="Order">
|
||||||
update order_data
|
update order_data
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,11 @@
|
||||||
<result property="openid" column="openid"/>
|
<result property="openid" column="openid"/>
|
||||||
<result property="avatar" column="avatar"/>
|
<result property="avatar" column="avatar"/>
|
||||||
<result property="type" column="type"/>
|
<result property="type" column="type"/>
|
||||||
|
<result property="workerAdress" column="worker_adress"/>
|
||||||
|
<result property="workerLatitude" column="worker_latitude"/>
|
||||||
|
<result property="workerLongitude" column="worker_longitude"/>
|
||||||
|
<result property="lastLocationTime" column="last_location_time"/>
|
||||||
|
|
||||||
<result property="workerTime" column="worker_time"/>
|
<result property="workerTime" column="worker_time"/>
|
||||||
<result property="integral" column="integral"/>
|
<result property="integral" column="integral"/>
|
||||||
<result property="totalIntegral" column="total_integral"/>
|
<result property="totalIntegral" column="total_integral"/>
|
||||||
|
|
@ -52,6 +57,10 @@
|
||||||
password,
|
password,
|
||||||
remember_token,
|
remember_token,
|
||||||
openid,
|
openid,
|
||||||
|
worker_adress,
|
||||||
|
worker_latitude,
|
||||||
|
worker_longitude,
|
||||||
|
last_location_time,
|
||||||
avatar,
|
avatar,
|
||||||
type,
|
type,
|
||||||
worker_time,
|
worker_time,
|
||||||
|
|
@ -355,6 +364,20 @@
|
||||||
birthday,
|
birthday,
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
|
|
||||||
|
<if test="workerAdress != null">
|
||||||
|
worker_adress,
|
||||||
|
</if>
|
||||||
|
<if test="workerLatitude != null">
|
||||||
|
worker_latitude,
|
||||||
|
</if>
|
||||||
|
<if test="workerLongitude != null">
|
||||||
|
worker_longitude,
|
||||||
|
</if>
|
||||||
|
<if test="lastLocationTime != null">
|
||||||
|
last_location_lime,
|
||||||
|
</if>
|
||||||
|
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
</trim>
|
</trim>
|
||||||
|
|
@ -464,7 +487,18 @@
|
||||||
<if test="birthday != null">
|
<if test="birthday != null">
|
||||||
#{birthday},
|
#{birthday},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="workerAdress != null">
|
||||||
|
#{workerAdress},
|
||||||
|
</if>
|
||||||
|
<if test="workerLatitude != null">
|
||||||
|
#{workerLatitude},
|
||||||
|
</if>
|
||||||
|
<if test="workerLongitude != null">
|
||||||
|
#{workerLongitude},
|
||||||
|
</if>
|
||||||
|
<if test="lastLocationTime != null">
|
||||||
|
#{lastLocationTime},
|
||||||
|
</if>
|
||||||
NOW(),
|
NOW(),
|
||||||
NOW()
|
NOW()
|
||||||
</trim>
|
</trim>
|
||||||
|
|
@ -579,6 +613,19 @@
|
||||||
birthday = #{birthday},
|
birthday = #{birthday},
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
|
<if test="workerAdress != null">
|
||||||
|
worker_adress = #{workerAdress},
|
||||||
|
</if>
|
||||||
|
<if test="workerLatitude != null">
|
||||||
|
worker_latitude = #{workerLatitude},
|
||||||
|
</if>
|
||||||
|
<if test="workerLongitude != null">
|
||||||
|
worker_longitude = #{workerLongitude},
|
||||||
|
</if>
|
||||||
|
<if test="lastLocationTime != null">
|
||||||
|
last_location_time = #{lastLocationTime},
|
||||||
|
</if>
|
||||||
|
|
||||||
updated_at = NOW()
|
updated_at = NOW()
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
|
|
@ -605,4 +652,44 @@
|
||||||
#{id}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 派单专用查询 - 基础条件:type=2, status=1, is_stop=0, worker_time为当天 -->
|
||||||
|
<select id="selectDispatchWorkers" parameterType="java.util.Map" resultMap="UsersResult">
|
||||||
|
<include refid="selectUsersVo"/>
|
||||||
|
<where>
|
||||||
|
<!-- 基础筛选条件 -->
|
||||||
|
type = '2'
|
||||||
|
AND status = 1
|
||||||
|
AND is_stop = 0
|
||||||
|
AND worker_time IS NOT NULL
|
||||||
|
AND DATE(worker_time) = CURDATE()
|
||||||
|
</where>
|
||||||
|
ORDER BY id DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 派单备用查询 - 不限制地区,获取更多师傅 -->
|
||||||
|
<select id="selectBackupDispatchWorkers" parameterType="java.util.Map" resultMap="UsersResult">
|
||||||
|
<include refid="selectUsersVo"/>
|
||||||
|
<where>
|
||||||
|
<!-- 基础筛选条件 -->
|
||||||
|
type = '2'
|
||||||
|
AND status = 1
|
||||||
|
AND is_stop = 0
|
||||||
|
AND worker_time IS NOT NULL
|
||||||
|
AND DATE(worker_time) = CURDATE()
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 测试用派单查询 - 用于验证基础条件 -->
|
||||||
|
<select id="selectTestDispatchWorkers" resultMap="UsersResult">
|
||||||
|
<include refid="selectUsersVo"/>
|
||||||
|
<where>
|
||||||
|
<!-- 基础筛选条件 -->
|
||||||
|
type = '2'
|
||||||
|
AND status = 1
|
||||||
|
AND is_stop = 0
|
||||||
|
AND worker_time IS NOT NULL
|
||||||
|
AND DATE(worker_time) = CURDATE()
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -22,6 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<result property="baojiaid" column="baojiaid" />
|
<result property="baojiaid" column="baojiaid" />
|
||||||
<result property="lastorderid" column="lastorderid" />
|
<result property="lastorderid" column="lastorderid" />
|
||||||
<result property="num" column="num" />
|
<result property="num" column="num" />
|
||||||
|
<result property="returnmoney" column="returnmoney" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -42,7 +43,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectUsersPayBeforVo">
|
<sql id="selectUsersPayBeforVo">
|
||||||
select id, uid, paytype,grouporderid,baojiaid,num, lastorderid,wxmoney,serviceid,servicetype,sku,addressid,maketime,attachments, yemoney, allmoney,membermoney, shopmoney, servicemoney, couponid, couponmoney, mtcode, mtmoney, type, orderid, oid, status, paytime, paycode from users_pay_befor
|
select id, uid, paytype,grouporderid,baojiaid,num,returnmoney, lastorderid,wxmoney,serviceid,servicetype,sku,addressid,maketime,attachments, yemoney, allmoney,membermoney, shopmoney, servicemoney, couponid, couponmoney, mtcode, mtmoney, type, orderid, oid, status, paytime, paycode from users_pay_befor
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectUsersPayBeforList" parameterType="UsersPayBefor" resultMap="UsersPayBeforResult">
|
<select id="selectUsersPayBeforList" parameterType="UsersPayBefor" resultMap="UsersPayBeforResult">
|
||||||
|
|
@ -120,6 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="baojiaid != null">baojiaid,</if>
|
<if test="baojiaid != null">baojiaid,</if>
|
||||||
<if test="lastorderid != null">lastorderid,</if>
|
<if test="lastorderid != null">lastorderid,</if>
|
||||||
<if test="num != null">num,</if>
|
<if test="num != null">num,</if>
|
||||||
|
<if test="returnmoney != null">returnmoney,</if>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -154,6 +156,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="baojiaid != null">#{baojiaid},</if>
|
<if test="baojiaid != null">#{baojiaid},</if>
|
||||||
<if test="lastorderid != null">#{lastorderid},</if>
|
<if test="lastorderid != null">#{lastorderid},</if>
|
||||||
<if test="num != null">#{num},</if>
|
<if test="num != null">#{num},</if>
|
||||||
|
<if test="returnmoney != null">#{returnmoney},</if>
|
||||||
|
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
@ -181,6 +184,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="allmoney != null">allmoney = #{allmoney},</if>
|
<if test="allmoney != null">allmoney = #{allmoney},</if>
|
||||||
<if test="serviceid != null">serviceid = #{serviceid},</if>
|
<if test="serviceid != null">serviceid = #{serviceid},</if>
|
||||||
<if test="baojiaid != null">baojiaid = #{baojiaid},</if>
|
<if test="baojiaid != null">baojiaid = #{baojiaid},</if>
|
||||||
|
<if test="returnmoney != null">returnmoney = #{returnmoney},</if>
|
||||||
|
|
||||||
<if test="sku != null">sku = #{sku},</if>
|
<if test="sku != null">sku = #{sku},</if>
|
||||||
<if test="addressid != null">addressid = #{addressid},</if>
|
<if test="addressid != null">addressid = #{addressid},</if>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询派单评分记录列表
|
||||||
|
export function listDispatchScoreRecord(query) {
|
||||||
|
return request({
|
||||||
|
url: '/system/DispatchScoreRecord/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询派单评分记录详细
|
||||||
|
export function getDispatchScoreRecord(id) {
|
||||||
|
return request({
|
||||||
|
url: '/system/DispatchScoreRecord/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增派单评分记录
|
||||||
|
export function addDispatchScoreRecord(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/DispatchScoreRecord',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改派单评分记录
|
||||||
|
export function updateDispatchScoreRecord(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/DispatchScoreRecord',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除派单评分记录
|
||||||
|
export function delDispatchScoreRecord(id) {
|
||||||
|
return request({
|
||||||
|
url: '/system/DispatchScoreRecord/' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新派单评分数据
|
||||||
|
export function refreshDispatchScoreData() {
|
||||||
|
return request({
|
||||||
|
url: '/system/DispatchScoreRecord/refresh',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -91,3 +91,20 @@ export function processAfterSale(data) {
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发货处理
|
||||||
|
export function shipOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/GoodsOrder/shipOrder',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据订单ID查询预支付数据
|
||||||
|
export function getPrePaymentByOrderId(orderId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/UsersPayBefor/getByOrderId/' + orderId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,12 @@ export function delServiceCate(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有分类列表(用于下拉选择,不分页)
|
// 获取所有分类列表(用于下拉选择,不分页)
|
||||||
export function getAllServiceCateList() {
|
export function getAllServiceCateList(type) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/ServiceCate/list',
|
url: '/system/ServiceCate/list',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: {
|
params: {
|
||||||
|
type:type,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10000 // 设置大于1000的值,后端会返回所有数据不分页
|
pageSize: 10000 // 设置大于1000的值,后端会返回所有数据不分页
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,9 @@ export function getselectTypeList(type) {
|
||||||
|
|
||||||
|
|
||||||
// 查询服务内容详细
|
// 查询服务内容详细
|
||||||
export function selectServiceCateList(id) {
|
export function selectServiceCateList(type) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/ServiceGoods/selectServiceCateList',
|
url: '/system/ServiceGoods/selectServiceCateList/' + type,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,15 @@ export function getSiteSkill(id) {
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取师傅技能配置列表用户下拉数据选择
|
||||||
|
export function getSiteSkillList() {
|
||||||
|
return request({
|
||||||
|
url: '/system/SiteSkill/getSiteSkillList',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 任务状态修改
|
// 任务状态修改
|
||||||
export function changefenleiStatus(id, status) {
|
export function changefenleiStatus(id, status) {
|
||||||
const data = {
|
const data = {
|
||||||
|
|
@ -28,6 +37,7 @@ export function changefenleiStatus(id, status) {
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增师傅技能配置
|
// 新增师傅技能配置
|
||||||
export function addSiteSkill(data) {
|
export function addSiteSkill(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ export function selectList() {
|
||||||
|
|
||||||
|
|
||||||
// 查询服务内容详细
|
// 查询服务内容详细
|
||||||
export function selectServiceCateList() {
|
export function selectServiceCateList(type) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/ServiceGoods/selectServiceCateList',
|
url: '/system/ServiceGoods/selectServiceCateList/' + type,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,161 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 自动派单
|
||||||
|
export function autoDispatch(orderId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/dispatch/auto/' + orderId,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动派单
|
||||||
|
export function manualDispatch(orderId, workerId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/dispatch/manual',
|
||||||
|
method: 'post',
|
||||||
|
params: {
|
||||||
|
orderId: orderId,
|
||||||
|
workerId: workerId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取派单详情
|
||||||
|
export function getDispatchDetail(orderId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/dispatch/detail/' + orderId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消派单
|
||||||
|
export function cancelDispatch(orderId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/dispatch/cancel/' + orderId,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新派单
|
||||||
|
export function redispatch(orderId) {
|
||||||
|
return request({
|
||||||
|
url: '/system/dispatch/redispatch/' + orderId,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取派单成功率统计
|
||||||
|
export function getDispatchSuccessRate(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/success-rate',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取师傅接单统计
|
||||||
|
export function getWorkerOrderStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/worker-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取地区派单统计
|
||||||
|
export function getAreaDispatchStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/area-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取服务类型派单统计
|
||||||
|
export function getServiceTypeDispatchStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/service-type-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取派单响应时间统计
|
||||||
|
export function getDispatchResponseTimeStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/response-time-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取新师傅派单统计
|
||||||
|
export function getNewWorkerDispatchStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/new-worker-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取派单质量评分统计
|
||||||
|
export function getDispatchQualityStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/quality-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取派单效率统计
|
||||||
|
export function getDispatchEfficiencyStatistics(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/efficiency-statistics',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取综合派单报告
|
||||||
|
export function getComprehensiveDispatchReport(startDate, endDate) {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/comprehensive-report',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实时派单状态
|
||||||
|
export function getRealTimeDispatchStatus() {
|
||||||
|
return request({
|
||||||
|
url: '/system/statistics/real-time-status',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -177,3 +177,32 @@ aside {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 修复对话框遮罩层问题 */
|
||||||
|
//.v-modal {
|
||||||
|
// z-index: 9998 !important;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//.el-dialog__wrapper {
|
||||||
|
// z-index: 9999 !important;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//.el-dialog {
|
||||||
|
// z-index: 10000 !important;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/* 防止多个遮罩层重叠 */
|
||||||
|
//.v-modal:not(:last-child) {
|
||||||
|
// display: none !important;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/* 确保对话框内容可交互 */
|
||||||
|
//.el-dialog__body {
|
||||||
|
// z-index: 10001 !important;
|
||||||
|
// position: relative;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/* 防止灰色遮罩区域 */
|
||||||
|
//.el-dialog__wrapper:not(:last-child) {
|
||||||
|
// display: none !important;
|
||||||
|
//}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="师傅姓名" prop="workerName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.workerName"
|
||||||
|
placeholder="请输入师傅姓名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="师傅电话" prop="workerPhone">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.workerPhone"
|
||||||
|
placeholder="请输入师傅电话"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
size="mini"
|
||||||
|
@click="handleRefresh"
|
||||||
|
v-hasPermi="['system:DispatchScoreRecord:refresh']"
|
||||||
|
>刷新评分数据</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
v-hasPermi="['system:DispatchScoreRecord:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['system:DispatchScoreRecord:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="DispatchScoreRecordList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="师傅姓名" align="center" prop="workerName" />
|
||||||
|
<el-table-column label="师傅电话" align="center" prop="workerPhone" />
|
||||||
|
<el-table-column label="订单ID" align="center" prop="orderId" />
|
||||||
|
<el-table-column label="已完成订单数" align="center" prop="completedOrdersCount" />
|
||||||
|
<el-table-column label="当前订单数" align="center" prop="currentOrdersCount" />
|
||||||
|
<el-table-column label="距离评分" align="center" prop="distanceScore" />
|
||||||
|
<el-table-column label="技能匹配评分" align="center" prop="skillMatchScore" />
|
||||||
|
<el-table-column label="经验评分" align="center" prop="experienceScore" />
|
||||||
|
<el-table-column label="评分权重" align="center" prop="ratingScore" />
|
||||||
|
<el-table-column label="可用性评分" align="center" prop="availabilityScore" />
|
||||||
|
<el-table-column label="新师傅奖励评分" align="center" prop="newWorkerBonusScore" />
|
||||||
|
<el-table-column label="综合评分" align="center" prop="totalScore" />
|
||||||
|
<el-table-column label="排名位置" align="center" prop="rankPosition" />
|
||||||
|
<el-table-column label="评分计算时间" align="center" prop="scoreCalculationTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.scoreCalculationTime, '{y}-{m}-{d}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['system:DispatchScoreRecord:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listDispatchScoreRecord, delDispatchScoreRecord, refreshDispatchScoreData } from "@/api/system/DispatchScoreRecord"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "DispatchScoreRecord",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 派单评分记录表格数据
|
||||||
|
DispatchScoreRecordList: [],
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
workerName: null,
|
||||||
|
workerPhone: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询派单评分记录列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true
|
||||||
|
listDispatchScoreRecord(this.queryParams).then(response => {
|
||||||
|
this.DispatchScoreRecordList = response.rows
|
||||||
|
this.total = response.total
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm")
|
||||||
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
// 多选框选中数据
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.id)
|
||||||
|
this.single = selection.length!==1
|
||||||
|
this.multiple = !selection.length
|
||||||
|
},
|
||||||
|
/** 刷新评分数据按钮操作 */
|
||||||
|
handleRefresh() {
|
||||||
|
this.$modal.confirm('是否确认刷新派单评分数据?这将重新计算并保存所有师傅的评分数据。').then(function() {
|
||||||
|
return refreshDispatchScoreData()
|
||||||
|
}).then(() => {
|
||||||
|
this.getList()
|
||||||
|
this.$modal.msgSuccess("刷新评分数据成功")
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const ids = row.id || this.ids
|
||||||
|
this.$modal.confirm('是否确认删除派单评分记录编号为"' + ids + '"的数据项?').then(function() {
|
||||||
|
return delDispatchScoreRecord(ids)
|
||||||
|
}).then(() => {
|
||||||
|
this.getList()
|
||||||
|
this.$modal.msgSuccess("删除成功")
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
handleExport() {
|
||||||
|
this.download('system/DispatchScoreRecord/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `DispatchScoreRecord_${new Date().getTime()}.xlsx`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -742,7 +742,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getserviceCateList(){
|
getserviceCateList(){
|
||||||
selectServiceCateList().then(response => {
|
selectServiceCateList(2).then(response => {
|
||||||
this.serviceCateList = response.data
|
this.serviceCateList = response.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1464,13 +1464,13 @@ export default {
|
||||||
},
|
},
|
||||||
getserviceCateList(){
|
getserviceCateList(){
|
||||||
// 获取所有分类数据
|
// 获取所有分类数据
|
||||||
getAllServiceCateList().then(response => {
|
getAllServiceCateList(1).then(response => {
|
||||||
this.serviceCateList = response.rows || []
|
this.serviceCateList = response.rows || []
|
||||||
this.processServiceCateList()
|
this.processServiceCateList()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error('获取分类列表失败:', error)
|
console.error('获取分类列表失败:', error)
|
||||||
// 降级处理:使用原有接口
|
// 降级处理:使用原有接口
|
||||||
selectServiceCateList().then(response => {
|
selectServiceCateList(1).then(response => {
|
||||||
this.serviceCateList = response.data || []
|
this.serviceCateList = response.data || []
|
||||||
this.processServiceCateList()
|
this.processServiceCateList()
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
getUserSecondaryCard () {
|
getUserSecondaryCard () {
|
||||||
getGoodsDataList(1).then(response => {
|
getGoodsDataList(3).then(response => {
|
||||||
this.ServiceGoodsList = response.data
|
this.ServiceGoodsList = response.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -476,14 +476,14 @@ export default {
|
||||||
|
|
||||||
|
|
||||||
getserviceCateList(){
|
getserviceCateList(){
|
||||||
selectServiceCateList().then(response => {
|
selectServiceCateList(1).then(response => {
|
||||||
this.serviceCateList = response.data
|
this.serviceCateList = response.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
parseImageArray(val) {
|
parseImageArray(val) {
|
||||||
if (!val) return [];
|
if (!val) return [];
|
||||||
|
|
||||||
if (Array.isArray(val)) {
|
if (Array.isArray(val)) {
|
||||||
return val.map(item => {
|
return val.map(item => {
|
||||||
if (typeof item === 'string') return item;
|
if (typeof item === 'string') return item;
|
||||||
|
|
@ -491,7 +491,7 @@ export default {
|
||||||
return '';
|
return '';
|
||||||
}).filter(Boolean);
|
}).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const arr = JSON.parse(val);
|
const arr = JSON.parse(val);
|
||||||
if (Array.isArray(arr)) {
|
if (Array.isArray(arr)) {
|
||||||
|
|
@ -507,7 +507,7 @@ export default {
|
||||||
return [val.trim()];
|
return [val.trim()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -516,7 +516,7 @@ export default {
|
||||||
const imgElement = event.target;
|
const imgElement = event.target;
|
||||||
imgElement.style.display = 'none';
|
imgElement.style.display = 'none';
|
||||||
imgElement.onerror = null; // 防止重复触发
|
imgElement.onerror = null; // 防止重复触发
|
||||||
|
|
||||||
// 在图片位置显示错误提示
|
// 在图片位置显示错误提示
|
||||||
const errorDiv = document.createElement('div');
|
const errorDiv = document.createElement('div');
|
||||||
errorDiv.className = 'image-error';
|
errorDiv.className = 'image-error';
|
||||||
|
|
@ -575,25 +575,6 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.form.carouselImage = []
|
this.form.carouselImage = []
|
||||||
}
|
}
|
||||||
// 展示图片处理为数组,兼容对象数组和字符串数组
|
|
||||||
if (this.form.showimage) {
|
|
||||||
try {
|
|
||||||
const arr = JSON.parse(this.form.showimage)
|
|
||||||
if (Array.isArray(arr)) {
|
|
||||||
this.form.showimage = arr.map(item => {
|
|
||||||
if (typeof item === 'string') return item;
|
|
||||||
if (item && item.url) return item.url;
|
|
||||||
return '';
|
|
||||||
}).filter(Boolean);
|
|
||||||
} else {
|
|
||||||
this.form.showimage = []
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.form.showimage = []
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.form.showimage = []
|
|
||||||
}
|
|
||||||
// 兼容后端返回goodsids为JSON字符串数组或逗号分隔字符串,全部转为字符串数组
|
// 兼容后端返回goodsids为JSON字符串数组或逗号分隔字符串,全部转为字符串数组
|
||||||
if (this.form.goodsids) {
|
if (this.form.goodsids) {
|
||||||
if (typeof this.form.goodsids === 'string') {
|
if (typeof this.form.goodsids === 'string') {
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { selectAreaList } from "@/api/system/WorkerApply"
|
import { selectAreaList } from "@/api/system/WorkerApply"
|
||||||
|
import { getSiteSkillList } from "@/api/system/SiteSkill"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "UserEditDialog",
|
name: "UserEditDialog",
|
||||||
|
|
@ -146,12 +147,7 @@ export default {
|
||||||
selectAreaShiDataList: [],
|
selectAreaShiDataList: [],
|
||||||
selectedAreas: [],
|
selectedAreas: [],
|
||||||
selectedSkills: [],
|
selectedSkills: [],
|
||||||
skillList: [
|
skillList: []
|
||||||
{ id: 1, title: '水电工' },
|
|
||||||
{ id: 2, title: '油工师傅' },
|
|
||||||
{ id: 3, title: '改造维修' },
|
|
||||||
{ id: 4, title: '工程施工' }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -166,23 +162,63 @@ export default {
|
||||||
user: {
|
user: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
|
console.log('UserEditDialog - 接收到用户数据:', val);
|
||||||
this.form = { ...val }
|
this.form = { ...val }
|
||||||
// 确保status是数字类型
|
// 确保status是数字类型
|
||||||
if (typeof this.form.status === 'string') {
|
if (typeof this.form.status === 'string') {
|
||||||
this.form.status = parseInt(this.form.status)
|
this.form.status = parseInt(this.form.status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理已选择的地区
|
// 处理已选择的地区
|
||||||
if (this.form.serviceCityIds) {
|
if (this.form.serviceCityIds) {
|
||||||
this.selectedAreas = typeof this.form.serviceCityIds === 'string'
|
console.log('处理服务区域数据:', this.form.serviceCityIds, '类型:', typeof this.form.serviceCityIds);
|
||||||
? this.form.serviceCityIds.split(',').map(Number).filter(n => !isNaN(n))
|
try {
|
||||||
: this.form.serviceCityIds
|
if (typeof this.form.serviceCityIds === 'string') {
|
||||||
|
// 处理可能是JSON字符串的情况
|
||||||
|
if (this.form.serviceCityIds.startsWith('[') && this.form.serviceCityIds.endsWith(']')) {
|
||||||
|
this.selectedAreas = JSON.parse(this.form.serviceCityIds).map(Number).filter(n => !isNaN(n));
|
||||||
|
} else {
|
||||||
|
this.selectedAreas = this.form.serviceCityIds.split(',').map(Number).filter(n => !isNaN(n));
|
||||||
|
}
|
||||||
|
} else if (Array.isArray(this.form.serviceCityIds)) {
|
||||||
|
this.selectedAreas = this.form.serviceCityIds.map(Number).filter(n => !isNaN(n));
|
||||||
|
} else {
|
||||||
|
this.selectedAreas = [];
|
||||||
|
}
|
||||||
|
console.log('解析后的服务区域:', this.selectedAreas);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析服务区域数据失败:', error);
|
||||||
|
this.selectedAreas = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.selectedAreas = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理已选择的技能
|
// 处理已选择的技能
|
||||||
if (this.form.skillIds) {
|
if (this.form.skillIds) {
|
||||||
this.selectedSkills = typeof this.form.skillIds === 'string'
|
console.log('处理技能数据:', this.form.skillIds, '类型:', typeof this.form.skillIds);
|
||||||
? this.form.skillIds.split(',').map(Number).filter(n => !isNaN(n))
|
try {
|
||||||
: this.form.skillIds
|
if (typeof this.form.skillIds === 'string') {
|
||||||
|
// 处理可能是JSON字符串的情况
|
||||||
|
if (this.form.skillIds.startsWith('[') && this.form.skillIds.endsWith(']')) {
|
||||||
|
this.selectedSkills = JSON.parse(this.form.skillIds).map(Number).filter(n => !isNaN(n));
|
||||||
|
} else {
|
||||||
|
this.selectedSkills = this.form.skillIds.split(',').map(Number).filter(n => !isNaN(n));
|
||||||
|
}
|
||||||
|
} else if (Array.isArray(this.form.skillIds)) {
|
||||||
|
this.selectedSkills = this.form.skillIds.map(Number).filter(n => !isNaN(n));
|
||||||
|
} else {
|
||||||
|
this.selectedSkills = [];
|
||||||
|
}
|
||||||
|
console.log('解析后的技能:', this.selectedSkills);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析技能数据失败:', error);
|
||||||
|
this.selectedSkills = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.selectedSkills = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理禁止接单时长
|
// 处理禁止接单时长
|
||||||
if (this.form.prohibitTimeNum) {
|
if (this.form.prohibitTimeNum) {
|
||||||
this.form.prohibitTimeNum = parseInt(this.form.prohibitTimeNum) || 0
|
this.form.prohibitTimeNum = parseInt(this.form.prohibitTimeNum) || 0
|
||||||
|
|
@ -194,6 +230,7 @@ export default {
|
||||||
visible(val) {
|
visible(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.getShenDataList()
|
this.getShenDataList()
|
||||||
|
this.getSkillList()
|
||||||
if (this.form.serviceCityPid) {
|
if (this.form.serviceCityPid) {
|
||||||
this.getShiDataList(this.form.serviceCityPid)
|
this.getShiDataList(this.form.serviceCityPid)
|
||||||
}
|
}
|
||||||
|
|
@ -208,21 +245,30 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getShenDataList() {
|
getShenDataList() {
|
||||||
|
console.log('UserEditDialog - 开始获取省份数据');
|
||||||
selectAreaList("100000").then(response => {
|
selectAreaList("100000").then(response => {
|
||||||
|
console.log('UserEditDialog - 获取省份数据成功:', response);
|
||||||
this.selectAreaShenDataList = response.data || []
|
this.selectAreaShenDataList = response.data || []
|
||||||
}).catch(() => {
|
console.log('UserEditDialog - 省份列表:', this.selectAreaShenDataList);
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('UserEditDialog - 获取省份数据失败:', error);
|
||||||
// 如果接口失败,使用默认数据
|
// 如果接口失败,使用默认数据
|
||||||
this.selectAreaShenDataList = [
|
this.selectAreaShenDataList = [
|
||||||
{ id: "610100", title: "西安市" },
|
{ id: "610100", title: "西安市" },
|
||||||
{ id: "610200", title: "铜川市" },
|
{ id: "610200", title: "铜川市" },
|
||||||
{ id: "610300", title: "宝鸡市" }
|
{ id: "610300", title: "宝鸡市" }
|
||||||
]
|
]
|
||||||
|
console.log('UserEditDialog - 使用默认省份数据:', this.selectAreaShenDataList);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getShiDataList(id) {
|
getShiDataList(id) {
|
||||||
|
console.log('UserEditDialog - 开始获取城市数据,省份ID:', id);
|
||||||
selectAreaList(id).then(response => {
|
selectAreaList(id).then(response => {
|
||||||
|
console.log('UserEditDialog - 获取城市数据成功:', response);
|
||||||
this.selectAreaShiDataList = response.data || []
|
this.selectAreaShiDataList = response.data || []
|
||||||
}).catch(() => {
|
console.log('UserEditDialog - 城市列表:', this.selectAreaShiDataList);
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('UserEditDialog - 获取城市数据失败:', error);
|
||||||
// 如果接口失败,使用默认数据
|
// 如果接口失败,使用默认数据
|
||||||
if (id === "610100") {
|
if (id === "610100") {
|
||||||
this.selectAreaShiDataList = [
|
this.selectAreaShiDataList = [
|
||||||
|
|
@ -237,9 +283,38 @@ export default {
|
||||||
{ id: "610116", title: "长安区" },
|
{ id: "610116", title: "长安区" },
|
||||||
{ id: "610117", title: "高陵区" }
|
{ id: "610117", title: "高陵区" }
|
||||||
]
|
]
|
||||||
|
console.log('UserEditDialog - 使用默认城市数据:', this.selectAreaShiDataList);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getSkillList() {
|
||||||
|
console.log('UserEditDialog - 开始获取技能列表');
|
||||||
|
getSiteSkillList().then(response => {
|
||||||
|
console.log('UserEditDialog - 获取技能列表成功:', response);
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.skillList = response.data || []
|
||||||
|
console.log('UserEditDialog - 技能列表:', this.skillList);
|
||||||
|
} else {
|
||||||
|
console.warn('UserEditDialog - 获取技能列表失败,使用默认数据');
|
||||||
|
// 如果接口失败,使用默认数据
|
||||||
|
this.skillList = [
|
||||||
|
{ id: 1, title: '水电工' },
|
||||||
|
{ id: 2, title: '油工师傅' },
|
||||||
|
{ id: 3, title: '改造维修' },
|
||||||
|
{ id: 4, title: '工程施工' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('UserEditDialog - 获取技能列表异常:', error);
|
||||||
|
// 如果接口失败,使用默认数据
|
||||||
|
this.skillList = [
|
||||||
|
{ id: 1, title: '水电工' },
|
||||||
|
{ id: 2, title: '油工师傅' },
|
||||||
|
{ id: 3, title: '改造维修' },
|
||||||
|
{ id: 4, title: '工程施工' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
},
|
||||||
handleProvinceChange() {
|
handleProvinceChange() {
|
||||||
if (this.form.serviceCityPid) {
|
if (this.form.serviceCityPid) {
|
||||||
this.getShiDataList(this.form.serviceCityPid)
|
this.getShiDataList(this.form.serviceCityPid)
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,18 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="累计提现" align="center" prop="propose" />
|
<el-table-column label="累计提现" align="center" prop="propose" />
|
||||||
|
<el-table-column label="服务区域" align="center" prop="serviceCityIds" width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.serviceCityIds">{{ formatServiceAreas(scope.row.serviceCityIds) }}</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="技能" align="center" prop="skillIds" width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.skillIds">{{ formatSkillNames(scope.row.skillIds) }}</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -298,6 +310,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { listUsers, getUsers, delUsers, addUsers, updateUsers,getUserDataList,changetypeStatus } from "@/api/system/users"
|
import { listUsers, getUsers, delUsers, addUsers, updateUsers,getUserDataList,changetypeStatus } from "@/api/system/users"
|
||||||
import { listWorkerLevel } from '@/api/system/WorkerLevel'
|
import { listWorkerLevel } from '@/api/system/WorkerLevel'
|
||||||
|
import { selectAreaList } from "@/api/system/WorkerApply"
|
||||||
|
import { getSiteSkillList } from "@/api/system/SiteSkill"
|
||||||
import UserEditDialog from './UserEditDialog.vue'
|
import UserEditDialog from './UserEditDialog.vue'
|
||||||
import WorkerMoneyLogTable from '@/views/system/workerMoneyLog/WorkerMoneyLogTable.vue'
|
import WorkerMoneyLogTable from '@/views/system/workerMoneyLog/WorkerMoneyLogTable.vue'
|
||||||
import WorkerMarginLogDetailTable from '@/views/system/WorkerMarginLog/WorkerMarginLogTable.vue'
|
import WorkerMarginLogDetailTable from '@/views/system/WorkerMarginLog/WorkerMarginLogTable.vue'
|
||||||
|
|
@ -371,13 +385,25 @@ export default {
|
||||||
workerLevelDialogVisible: false,
|
workerLevelDialogVisible: false,
|
||||||
workerLevelUserId: null,
|
workerLevelUserId: null,
|
||||||
workerLevelUserName: '',
|
workerLevelUserName: '',
|
||||||
|
// 地区数据缓存
|
||||||
|
areaDataCache: {},
|
||||||
|
// 技能数据缓存
|
||||||
|
skillDataCache: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList()
|
this.getList()
|
||||||
this.getlevelList();
|
this.getlevelList();
|
||||||
|
this.initAreaDataCache();
|
||||||
|
this.initSkillDataCache();
|
||||||
|
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
// 确保在组件挂载后重新获取数据,以便格式化方法能正常工作
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getList();
|
||||||
|
});
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询用户列表列表 */
|
/** 查询用户列表列表 */
|
||||||
getList() {
|
getList() {
|
||||||
|
|
@ -581,6 +607,175 @@ export default {
|
||||||
console.log('质保金发生变动,刷新师傅列表');
|
console.log('质保金发生变动,刷新师傅列表');
|
||||||
this.getList(); // 刷新师傅列表,更新质保金显示
|
this.getList(); // 刷新师傅列表,更新质保金显示
|
||||||
},
|
},
|
||||||
|
// 格式化服务区域显示
|
||||||
|
formatServiceAreas(serviceCityIds) {
|
||||||
|
if (!serviceCityIds) return '-';
|
||||||
|
try {
|
||||||
|
console.log('格式化服务区域,原始数据:', serviceCityIds, '类型:', typeof serviceCityIds);
|
||||||
|
|
||||||
|
// 如果是字符串,先转换为数组
|
||||||
|
let areaIds = [];
|
||||||
|
if (typeof serviceCityIds === 'string') {
|
||||||
|
// 处理可能是JSON字符串的情况
|
||||||
|
if (serviceCityIds.startsWith('[') && serviceCityIds.endsWith(']')) {
|
||||||
|
try {
|
||||||
|
areaIds = JSON.parse(serviceCityIds);
|
||||||
|
} catch (e) {
|
||||||
|
areaIds = serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
areaIds = serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
|
}
|
||||||
|
} else if (Array.isArray(serviceCityIds)) {
|
||||||
|
areaIds = serviceCityIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('解析后的地区ID数组:', areaIds);
|
||||||
|
console.log('地区数据缓存:', this.areaDataCache);
|
||||||
|
|
||||||
|
if (areaIds.length === 0) return '-';
|
||||||
|
|
||||||
|
// 从缓存中获取地区名称
|
||||||
|
const areaNames = areaIds.map(id => {
|
||||||
|
const cached = this.areaDataCache[id];
|
||||||
|
console.log(`地区ID ${id} 对应的缓存数据:`, cached);
|
||||||
|
return cached ? cached.title : id;
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = areaNames.join(', ');
|
||||||
|
console.log('格式化结果:', result);
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('格式化服务区域失败:', error);
|
||||||
|
return serviceCityIds;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 格式化技能名称显示
|
||||||
|
formatSkillNames(skillIds) {
|
||||||
|
if (!skillIds) return '-';
|
||||||
|
try {
|
||||||
|
console.log('格式化技能名称,原始数据:', skillIds, '类型:', typeof skillIds);
|
||||||
|
|
||||||
|
// 如果是字符串,先转换为数组
|
||||||
|
let skillIdArray = [];
|
||||||
|
if (typeof skillIds === 'string') {
|
||||||
|
// 处理可能是JSON字符串的情况
|
||||||
|
if (skillIds.startsWith('[') && skillIds.endsWith(']')) {
|
||||||
|
try {
|
||||||
|
skillIdArray = JSON.parse(skillIds);
|
||||||
|
} catch (e) {
|
||||||
|
skillIdArray = skillIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
skillIdArray = skillIds.split(',').map(id => id.trim()).filter(id => id);
|
||||||
|
}
|
||||||
|
} else if (Array.isArray(skillIds)) {
|
||||||
|
skillIdArray = skillIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('解析后的技能ID数组:', skillIdArray);
|
||||||
|
console.log('技能数据缓存:', this.skillDataCache);
|
||||||
|
|
||||||
|
if (skillIdArray.length === 0) return '-';
|
||||||
|
|
||||||
|
// 从缓存中获取技能名称
|
||||||
|
const skillNames = skillIdArray.map(id => {
|
||||||
|
const cached = this.skillDataCache[id];
|
||||||
|
console.log(`技能ID ${id} 对应的缓存数据:`, cached);
|
||||||
|
return cached ? cached.title : id;
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = skillNames.join(', ');
|
||||||
|
console.log('格式化结果:', result);
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('格式化技能名称失败:', error);
|
||||||
|
return skillIds;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 初始化地区数据缓存
|
||||||
|
initAreaDataCache() {
|
||||||
|
console.log('开始初始化地区数据缓存');
|
||||||
|
// 获取所有省份数据
|
||||||
|
selectAreaList("100000").then(response => {
|
||||||
|
console.log('获取省份数据成功:', response);
|
||||||
|
if (response.data) {
|
||||||
|
response.data.forEach(province => {
|
||||||
|
this.areaDataCache[province.id] = province;
|
||||||
|
console.log(`添加省份到缓存: ${province.id} -> ${province.title}`);
|
||||||
|
// 获取该省份下的城市数据
|
||||||
|
selectAreaList(province.id).then(cityResponse => {
|
||||||
|
console.log(`获取城市数据成功 (${province.id}):`, cityResponse);
|
||||||
|
if (cityResponse.data) {
|
||||||
|
cityResponse.data.forEach(city => {
|
||||||
|
this.areaDataCache[city.id] = city;
|
||||||
|
console.log(`添加城市到缓存: ${city.id} -> ${city.title}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error(`获取城市数据失败 (${province.id}):`, error);
|
||||||
|
// 如果获取城市数据失败,使用默认数据
|
||||||
|
if (province.id === "610100") {
|
||||||
|
const defaultCities = [
|
||||||
|
{ id: "610102", title: "新城区" },
|
||||||
|
{ id: "610103", title: "碑林区" },
|
||||||
|
{ id: "610104", title: "莲湖区" },
|
||||||
|
{ id: "610111", title: "灞桥区" },
|
||||||
|
{ id: "610112", title: "未央区" },
|
||||||
|
{ id: "610113", title: "雁塔区" },
|
||||||
|
{ id: "610114", title: "阎良区" },
|
||||||
|
{ id: "610115", title: "临潼区" },
|
||||||
|
{ id: "610116", title: "长安区" },
|
||||||
|
{ id: "610117", title: "高陵区" }
|
||||||
|
];
|
||||||
|
defaultCities.forEach(city => {
|
||||||
|
this.areaDataCache[city.id] = city;
|
||||||
|
console.log(`添加默认城市到缓存: ${city.id} -> ${city.title}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('获取省份数据失败:', error);
|
||||||
|
// 如果获取省份数据失败,使用默认数据
|
||||||
|
const defaultProvinces = [
|
||||||
|
{ id: "610100", title: "西安市" },
|
||||||
|
{ id: "610200", title: "铜川市" },
|
||||||
|
{ id: "610300", title: "宝鸡市" }
|
||||||
|
];
|
||||||
|
defaultProvinces.forEach(province => {
|
||||||
|
this.areaDataCache[province.id] = province;
|
||||||
|
console.log(`添加默认省份到缓存: ${province.id} -> ${province.title}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 初始化技能数据缓存
|
||||||
|
initSkillDataCache() {
|
||||||
|
console.log('开始初始化技能数据缓存');
|
||||||
|
getSiteSkillList().then(response => {
|
||||||
|
console.log('获取技能数据成功:', response);
|
||||||
|
if (response.code === 200 && response.data) {
|
||||||
|
response.data.forEach(skill => {
|
||||||
|
this.skillDataCache[skill.id] = skill;
|
||||||
|
console.log(`添加技能到缓存: ${skill.id} -> ${skill.title}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('获取技能数据失败:', error);
|
||||||
|
// 如果获取技能数据失败,使用默认数据
|
||||||
|
const defaultSkills = [
|
||||||
|
{ id: 1, title: '水电工' },
|
||||||
|
{ id: 2, title: '油工师傅' },
|
||||||
|
{ id: 3, title: '改造维修' },
|
||||||
|
{ id: 4, title: '工程施工' }
|
||||||
|
];
|
||||||
|
defaultSkills.forEach(skill => {
|
||||||
|
this.skillDataCache[skill.id] = skill;
|
||||||
|
console.log(`添加默认技能到缓存: ${skill.id} -> ${skill.title}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,670 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<!-- 派单操作区域 -->
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card class="box-card">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>派单操作</span>
|
||||||
|
</div>
|
||||||
|
<el-form :model="dispatchForm" :rules="dispatchRules" ref="dispatchForm" label-width="100px">
|
||||||
|
<el-form-item label="订单ID" prop="orderId">
|
||||||
|
<el-input v-model="dispatchForm.orderId" placeholder="请输入订单ID"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="派单类型">
|
||||||
|
<el-radio-group v-model="dispatchForm.dispatchType">
|
||||||
|
<el-radio :label="1">自动派单</el-radio>
|
||||||
|
<el-radio :label="2">手动派单</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="师傅ID" v-if="dispatchForm.dispatchType === 2" prop="workerId">
|
||||||
|
<el-input v-model="dispatchForm.workerId" placeholder="请输入师傅ID"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleDispatch" :loading="dispatchLoading">
|
||||||
|
{{ dispatchForm.dispatchType === 1 ? '自动派单' : '手动派单' }}
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="resetForm">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 实时统计区域 -->
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-card class="box-card">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>实时统计</span>
|
||||||
|
<el-button style="float: right; padding: 3px 0" type="text" @click="refreshStatistics">
|
||||||
|
刷新
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ statistics.todayDispatchCount || 0 }}</div>
|
||||||
|
<div class="stat-label">今日派单数</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ statistics.successRate || '0%' }}</div>
|
||||||
|
<div class="stat-label">成功率</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ statistics.avgResponseTime || '0ms' }}</div>
|
||||||
|
<div class="stat-label">平均响应时间</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ statistics.activeWorkers || 0 }}</div>
|
||||||
|
<div class="stat-label">活跃师傅数</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 派单历史列表 -->
|
||||||
|
<el-card class="box-card" style="margin-top: 20px;">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>派单历史</span>
|
||||||
|
<el-button style="float: right; padding: 3px 0" type="text" @click="handleQuery">
|
||||||
|
刷新
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="订单ID" prop="orderId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.orderId"
|
||||||
|
placeholder="请输入订单ID"
|
||||||
|
clearable
|
||||||
|
size="small"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="师傅姓名" prop="workerName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.workerName"
|
||||||
|
placeholder="请输入师傅姓名"
|
||||||
|
clearable
|
||||||
|
size="small"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="派单类型" prop="dispatchType">
|
||||||
|
<el-select v-model="queryParams.dispatchType" placeholder="派单类型" clearable size="small" style="width: 200px">
|
||||||
|
<el-option label="自动派单" :value="1" />
|
||||||
|
<el-option label="手动派单" :value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="派单结果" prop="dispatchResult">
|
||||||
|
<el-select v-model="queryParams.dispatchResult" placeholder="派单结果" clearable size="small" style="width: 200px">
|
||||||
|
<el-option label="成功" :value="1" />
|
||||||
|
<el-option label="失败" :value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="派单时间" prop="dispatchDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.dispatchDate"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
size="small"
|
||||||
|
style="width: 240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="mini"
|
||||||
|
@click="handleAdd"
|
||||||
|
v-hasPermi="['system:statistics:add']"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
icon="el-icon-edit"
|
||||||
|
size="mini"
|
||||||
|
:disabled="single"
|
||||||
|
@click="handleUpdate"
|
||||||
|
v-hasPermi="['system:statistics:edit']"
|
||||||
|
>修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
:disabled="multiple"
|
||||||
|
@click="handleDelete"
|
||||||
|
v-hasPermi="['system:statistics:remove']"
|
||||||
|
>删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-download"
|
||||||
|
size="mini"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['system:statistics:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="dispatchList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="订单ID" align="center" prop="orderId" />
|
||||||
|
<el-table-column label="师傅姓名" align="center" prop="workerName" />
|
||||||
|
<el-table-column label="服务名称" align="center" prop="serviceName" />
|
||||||
|
<el-table-column label="用户地址" align="center" prop="address" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column label="派单类型" align="center" prop="dispatchType">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="scope.row.dispatchType === 1 ? 'primary' : 'success'">
|
||||||
|
{{ scope.row.dispatchType === 1 ? '自动派单' : '手动派单' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="派单结果" align="center" prop="dispatchResult">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="scope.row.dispatchResult === 1 ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.dispatchResult === 1 ? '成功' : '失败' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="派单耗时" align="center" prop="dispatchTime">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ scope.row.dispatchTime }}ms
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="综合评分" align="center" prop="totalScore" />
|
||||||
|
<el-table-column label="派单时间" align="center" prop="dispatchDate" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.dispatchDate, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-view"
|
||||||
|
@click="handleView(scope.row)"
|
||||||
|
v-hasPermi="['system:statistics:query']"
|
||||||
|
>查看</el-button>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
@click="handleRedispatch(scope.row)"
|
||||||
|
v-if="scope.row.dispatchResult === 0"
|
||||||
|
v-hasPermi="['system:dispatch:redispatch']"
|
||||||
|
>重新派单</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 派单详情对话框 -->
|
||||||
|
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="订单ID" prop="orderId">
|
||||||
|
<el-input v-model="form.orderId" placeholder="请输入订单ID" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="师傅ID" prop="workerId">
|
||||||
|
<el-input v-model="form.workerId" placeholder="请输入师傅ID" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="师傅姓名" prop="workerName">
|
||||||
|
<el-input v-model="form.workerName" placeholder="请输入师傅姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="服务名称" prop="serviceName">
|
||||||
|
<el-input v-model="form.serviceName" placeholder="请输入服务名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="派单类型" prop="dispatchType">
|
||||||
|
<el-select v-model="form.dispatchType" placeholder="请选择派单类型">
|
||||||
|
<el-option label="自动派单" :value="1" />
|
||||||
|
<el-option label="手动派单" :value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="派单结果" prop="dispatchResult">
|
||||||
|
<el-select v-model="form.dispatchResult" placeholder="请选择派单结果">
|
||||||
|
<el-option label="成功" :value="1" />
|
||||||
|
<el-option label="失败" :value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="派单耗时" prop="dispatchTime">
|
||||||
|
<el-input v-model="form.dispatchTime" placeholder="请输入派单耗时" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="综合评分" prop="totalScore">
|
||||||
|
<el-input v-model="form.totalScore" placeholder="请输入综合评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="用户地址" prop="address">
|
||||||
|
<el-input v-model="form.address" type="textarea" placeholder="请输入用户地址" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="失败原因" prop="failureReason">
|
||||||
|
<el-input v-model="form.failureReason" type="textarea" placeholder="请输入失败原因" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="距离评分" prop="distanceScore">
|
||||||
|
<el-input v-model="form.distanceScore" placeholder="请输入距离评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="技能匹配评分" prop="skillMatchScore">
|
||||||
|
<el-input v-model="form.skillMatchScore" placeholder="请输入技能匹配评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="经验评分" prop="experienceScore">
|
||||||
|
<el-input v-model="form.experienceScore" placeholder="请输入经验评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="评分" prop="ratingScore">
|
||||||
|
<el-input v-model="form.ratingScore" placeholder="请输入评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="可用性评分" prop="availabilityScore">
|
||||||
|
<el-input v-model="form.availabilityScore" placeholder="请输入可用性评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="新师傅奖励评分" prop="newWorkerBonusScore">
|
||||||
|
<el-input v-model="form.newWorkerBonusScore" placeholder="请输入新师傅奖励评分" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="候选师傅数量" prop="candidateCount">
|
||||||
|
<el-input v-model="form.candidateCount" placeholder="请输入候选师傅数量" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="重试次数" prop="retryCount">
|
||||||
|
<el-input v-model="form.retryCount" placeholder="请输入重试次数" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="城市编码" prop="cityCode">
|
||||||
|
<el-input v-model="form.cityCode" placeholder="请输入城市编码" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="城市名称" prop="cityName">
|
||||||
|
<el-input v-model="form.cityName" placeholder="请输入城市名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 移除对已删除文件的引用,使用dispatch.js中的方法
|
||||||
|
import {
|
||||||
|
autoDispatch,
|
||||||
|
manualDispatch,
|
||||||
|
getDispatchDetail,
|
||||||
|
cancelDispatch,
|
||||||
|
redispatch
|
||||||
|
} from "@/api/system/dispatch";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Dispatch",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 派单统计表格数据
|
||||||
|
dispatchList: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
orderId: null,
|
||||||
|
workerName: null,
|
||||||
|
dispatchType: null,
|
||||||
|
dispatchResult: null,
|
||||||
|
dispatchDate: null
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
// 表单校验
|
||||||
|
rules: {
|
||||||
|
orderId: [
|
||||||
|
{ required: true, message: "订单ID不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
workerId: [
|
||||||
|
{ required: true, message: "师傅ID不能为空", trigger: "blur" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// 派单表单
|
||||||
|
dispatchForm: {
|
||||||
|
orderId: '',
|
||||||
|
dispatchType: 1,
|
||||||
|
workerId: ''
|
||||||
|
},
|
||||||
|
// 派单表单校验
|
||||||
|
dispatchRules: {
|
||||||
|
orderId: [
|
||||||
|
{ required: true, message: "订单ID不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
workerId: [
|
||||||
|
{ required: true, message: "师傅ID不能为空", trigger: "blur" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// 派单加载状态
|
||||||
|
dispatchLoading: false,
|
||||||
|
// 实时统计数据
|
||||||
|
statistics: {
|
||||||
|
todayDispatchCount: 0,
|
||||||
|
successRate: '0%',
|
||||||
|
avgResponseTime: '0ms',
|
||||||
|
activeWorkers: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
this.getRealTimeStatistics();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询派单统计列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
// 暂时使用模拟数据,因为后端接口可能还未实现
|
||||||
|
this.dispatchList = [];
|
||||||
|
this.total = 0;
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
// 取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.open = false;
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
// 表单重置
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
id: null,
|
||||||
|
orderId: null,
|
||||||
|
workerId: null,
|
||||||
|
workerName: null,
|
||||||
|
serviceId: null,
|
||||||
|
serviceName: null,
|
||||||
|
addressId: null,
|
||||||
|
address: null,
|
||||||
|
cityCode: null,
|
||||||
|
cityName: null,
|
||||||
|
dispatchType: null,
|
||||||
|
dispatchResult: null,
|
||||||
|
dispatchTime: null,
|
||||||
|
distanceScore: null,
|
||||||
|
skillMatchScore: null,
|
||||||
|
experienceScore: null,
|
||||||
|
ratingScore: null,
|
||||||
|
availabilityScore: null,
|
||||||
|
newWorkerBonusScore: null,
|
||||||
|
totalScore: null,
|
||||||
|
candidateCount: null,
|
||||||
|
retryCount: null,
|
||||||
|
failureReason: null,
|
||||||
|
dispatchDate: null,
|
||||||
|
remark: null
|
||||||
|
};
|
||||||
|
this.resetForm("form");
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
// 多选框选中数据
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.ids = selection.map(item => item.id)
|
||||||
|
this.single = selection.length!==1
|
||||||
|
this.multiple = !selection.length
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.reset();
|
||||||
|
this.open = true;
|
||||||
|
this.title = "添加派单统计";
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.reset();
|
||||||
|
// 暂时禁用修改功能
|
||||||
|
this.$modal.msgInfo("修改功能暂未实现");
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
// 暂时禁用提交功能
|
||||||
|
this.$modal.msgInfo("提交功能暂未实现");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const ids = row.id || this.ids;
|
||||||
|
this.$modal.confirm('是否确认删除派单统计编号为"' + ids + '"的数据项?').then(function() {
|
||||||
|
// 暂时禁用删除功能
|
||||||
|
return Promise.resolve();
|
||||||
|
}).then(() => {
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
handleExport() {
|
||||||
|
this.download('system/statistics/export', {
|
||||||
|
...this.queryParams
|
||||||
|
}, `dispatch_statistics_${new Date().getTime()}.xlsx`)
|
||||||
|
},
|
||||||
|
/** 查看按钮操作 */
|
||||||
|
handleView(row) {
|
||||||
|
this.reset();
|
||||||
|
// 暂时禁用查看功能
|
||||||
|
this.$modal.msgInfo("查看功能暂未实现");
|
||||||
|
},
|
||||||
|
/** 重新派单操作 */
|
||||||
|
handleRedispatch(row) {
|
||||||
|
this.$modal.confirm('是否确认重新派单订单ID为"' + row.orderId + '"?').then(function() {
|
||||||
|
return redispatch(row.orderId);
|
||||||
|
}).then(response => {
|
||||||
|
this.$modal.msgSuccess("重新派单成功");
|
||||||
|
this.getList();
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/** 派单操作 */
|
||||||
|
handleDispatch() {
|
||||||
|
this.$refs["dispatchForm"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.dispatchLoading = true;
|
||||||
|
if (this.dispatchForm.dispatchType === 1) {
|
||||||
|
// 自动派单
|
||||||
|
autoDispatch(this.dispatchForm.orderId).then(response => {
|
||||||
|
this.$modal.msgSuccess("自动派单成功");
|
||||||
|
this.resetDispatchForm();
|
||||||
|
this.getList();
|
||||||
|
this.getRealTimeStatistics();
|
||||||
|
}).catch(() => {
|
||||||
|
this.$modal.msgError("自动派单失败");
|
||||||
|
}).finally(() => {
|
||||||
|
this.dispatchLoading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 手动派单
|
||||||
|
manualDispatch(this.dispatchForm.orderId, this.dispatchForm.workerId).then(response => {
|
||||||
|
this.$modal.msgSuccess("手动派单成功");
|
||||||
|
this.resetDispatchForm();
|
||||||
|
this.getList();
|
||||||
|
this.getRealTimeStatistics();
|
||||||
|
}).catch(() => {
|
||||||
|
this.$modal.msgError("手动派单失败");
|
||||||
|
}).finally(() => {
|
||||||
|
this.dispatchLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 重置派单表单 */
|
||||||
|
resetDispatchForm() {
|
||||||
|
this.dispatchForm = {
|
||||||
|
orderId: '',
|
||||||
|
dispatchType: 1,
|
||||||
|
workerId: ''
|
||||||
|
};
|
||||||
|
this.resetForm("dispatchForm");
|
||||||
|
},
|
||||||
|
/** 重置表单 */
|
||||||
|
resetForm(formName) {
|
||||||
|
this.$refs[formName].resetFields();
|
||||||
|
},
|
||||||
|
/** 获取实时统计数据 */
|
||||||
|
getRealTimeStatistics() {
|
||||||
|
// 这里应该调用实时统计接口
|
||||||
|
// 暂时使用模拟数据
|
||||||
|
this.statistics = {
|
||||||
|
todayDispatchCount: Math.floor(Math.random() * 100) + 50,
|
||||||
|
successRate: (Math.random() * 20 + 80).toFixed(1) + '%',
|
||||||
|
avgResponseTime: Math.floor(Math.random() * 2000 + 500) + 'ms',
|
||||||
|
activeWorkers: Math.floor(Math.random() * 1000) + 500
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/** 刷新统计数据 */
|
||||||
|
refreshStatistics() {
|
||||||
|
this.getRealTimeStatistics();
|
||||||
|
this.$modal.msgSuccess("统计数据已刷新");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.stat-card {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-number {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #409EFF;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-card {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,522 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-card>
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>派单系统配置</span>
|
||||||
|
<el-button style="float: right; padding: 3px 0" type="text" @click="saveConfig">
|
||||||
|
保存配置
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-form :model="configForm" :rules="configRules" ref="configForm" label-width="200px">
|
||||||
|
<!-- 权重配置 -->
|
||||||
|
<el-divider content-position="left">权重配置</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="距离权重" prop="weightDistance">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.weightDistance"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:0-1,建议值:0.15</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="技能匹配权重" prop="weightSkillMatch">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.weightSkillMatch"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:0-1,建议值:0.25</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="经验权重" prop="weightExperience">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.weightExperience"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:0-1,建议值:0.15</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="评分权重" prop="weightRating">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.weightRating"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:0-1,建议值:0.20</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="可用性权重" prop="weightAvailability">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.weightAvailability"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:0-1,建议值:0.15</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="新师傅奖励权重" prop="weightNewWorkerBonus">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.weightNewWorkerBonus"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:0-1,建议值:0.10</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 距离配置 -->
|
||||||
|
<el-divider content-position="left">距离配置</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="最大距离(公里)" prop="maxDistance">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.maxDistance"
|
||||||
|
:min="10"
|
||||||
|
:max="100"
|
||||||
|
:step="1"
|
||||||
|
:precision="1"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:10-100公里,建议值:50</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="首选距离(公里)" prop="preferredDistance">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.preferredDistance"
|
||||||
|
:min="5"
|
||||||
|
:max="50"
|
||||||
|
:step="1"
|
||||||
|
:precision="1"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:5-50公里,建议值:20</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 新师傅配置 -->
|
||||||
|
<el-divider content-position="left">新师傅配置</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="新师傅订单数量阈值" prop="newWorkerOrderThreshold">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.newWorkerOrderThreshold"
|
||||||
|
:min="1"
|
||||||
|
:max="20"
|
||||||
|
:step="1"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:1-20单,建议值:5</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用新师傅奖励" prop="enableNewWorkerBonus">
|
||||||
|
<el-switch v-model="configForm.enableNewWorkerBonus" />
|
||||||
|
<span class="form-tip">是否为新师傅提供订单机会</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 功能开关 -->
|
||||||
|
<el-divider content-position="left">功能开关</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用距离限制" prop="enableDistanceLimit">
|
||||||
|
<el-switch v-model="configForm.enableDistanceLimit" />
|
||||||
|
<span class="form-tip">是否启用距离限制功能</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用技能匹配" prop="enableSkillMatch">
|
||||||
|
<el-switch v-model="configForm.enableSkillMatch" />
|
||||||
|
<span class="form-tip">是否启用技能匹配功能</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用经验评分" prop="enableExperienceScore">
|
||||||
|
<el-switch v-model="configForm.enableExperienceScore" />
|
||||||
|
<span class="form-tip">是否启用经验评分功能</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用评分系统" prop="enableRatingScore">
|
||||||
|
<el-switch v-model="configForm.enableRatingScore" />
|
||||||
|
<span class="form-tip">是否启用评分系统功能</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用可用性评分" prop="enableAvailabilityScore">
|
||||||
|
<el-switch v-model="configForm.enableAvailabilityScore" />
|
||||||
|
<span class="form-tip">是否启用可用性评分功能</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 性能配置 -->
|
||||||
|
<el-divider content-position="left">性能配置</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="自动派单超时时间(秒)" prop="autoDispatchTimeout">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.autoDispatchTimeout"
|
||||||
|
:min="10"
|
||||||
|
:max="60"
|
||||||
|
:step="5"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:10-60秒,建议值:30</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="最大重试次数" prop="maxRetryCount">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.maxRetryCount"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
:step="1"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
<span class="form-tip">范围:1-10次,建议值:3</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用日志记录" prop="enableLogging">
|
||||||
|
<el-switch v-model="configForm.enableLogging" />
|
||||||
|
<span class="form-tip">是否启用详细的日志记录</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="启用性能监控" prop="enablePerformanceMonitoring">
|
||||||
|
<el-switch v-model="configForm.enablePerformanceMonitoring" />
|
||||||
|
<span class="form-tip">是否启用性能监控功能</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 权重验证 -->
|
||||||
|
<el-divider content-position="left">权重验证</el-divider>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-alert
|
||||||
|
:title="weightValidation.title"
|
||||||
|
:type="weightValidation.type"
|
||||||
|
:description="weightValidation.description"
|
||||||
|
show-icon
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<el-divider content-position="left">操作</el-divider>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="saveConfig" :loading="saveLoading">保存配置</el-button>
|
||||||
|
<el-button @click="resetConfig">重置配置</el-button>
|
||||||
|
<el-button @click="loadDefaultConfig">加载默认配置</el-button>
|
||||||
|
<el-button @click="testConfig">测试配置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 配置预览 -->
|
||||||
|
<el-card style="margin-top: 20px;">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>配置预览</span>
|
||||||
|
<el-button style="float: right; padding: 3px 0" type="text" @click="refreshPreview">
|
||||||
|
刷新
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="总权重">{{ totalWeight }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="权重状态">
|
||||||
|
<el-tag :type="weightValidation.type === 'success' ? 'success' : 'danger'">
|
||||||
|
{{ weightValidation.type === 'success' ? '有效' : '无效' }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="距离权重">{{ configForm.weightDistance }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="技能匹配权重">{{ configForm.weightSkillMatch }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="经验权重">{{ configForm.weightExperience }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="评分权重">{{ configForm.weightRating }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="可用性权重">{{ configForm.weightAvailability }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="新师傅奖励权重">{{ configForm.weightNewWorkerBonus }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="最大距离">{{ configForm.maxDistance }}公里</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="首选距离">{{ configForm.preferredDistance }}公里</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="新师傅订单阈值">{{ configForm.newWorkerOrderThreshold }}单</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="超时时间">{{ configForm.autoDispatchTimeout }}秒</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="最大重试次数">{{ configForm.maxRetryCount }}次</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="功能开关">
|
||||||
|
<el-tag v-if="configForm.enableNewWorkerBonus" type="success" size="small">新师傅奖励</el-tag>
|
||||||
|
<el-tag v-if="configForm.enableDistanceLimit" type="success" size="small">距离限制</el-tag>
|
||||||
|
<el-tag v-if="configForm.enableSkillMatch" type="success" size="small">技能匹配</el-tag>
|
||||||
|
<el-tag v-if="configForm.enableExperienceScore" type="success" size="small">经验评分</el-tag>
|
||||||
|
<el-tag v-if="configForm.enableRatingScore" type="success" size="small">评分系统</el-tag>
|
||||||
|
<el-tag v-if="configForm.enableAvailabilityScore" type="success" size="small">可用性评分</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DispatchConfig",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 配置表单
|
||||||
|
configForm: {
|
||||||
|
// 权重配置
|
||||||
|
weightDistance: 0.15,
|
||||||
|
weightSkillMatch: 0.25,
|
||||||
|
weightExperience: 0.15,
|
||||||
|
weightRating: 0.20,
|
||||||
|
weightAvailability: 0.15,
|
||||||
|
weightNewWorkerBonus: 0.10,
|
||||||
|
|
||||||
|
// 距离配置
|
||||||
|
maxDistance: 50.0,
|
||||||
|
preferredDistance: 20.0,
|
||||||
|
|
||||||
|
// 新师傅配置
|
||||||
|
newWorkerOrderThreshold: 5,
|
||||||
|
enableNewWorkerBonus: true,
|
||||||
|
|
||||||
|
// 功能开关
|
||||||
|
enableDistanceLimit: true,
|
||||||
|
enableSkillMatch: true,
|
||||||
|
enableExperienceScore: true,
|
||||||
|
enableRatingScore: true,
|
||||||
|
enableAvailabilityScore: true,
|
||||||
|
|
||||||
|
// 性能配置
|
||||||
|
autoDispatchTimeout: 30,
|
||||||
|
maxRetryCount: 3,
|
||||||
|
enableLogging: true,
|
||||||
|
enablePerformanceMonitoring: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// 表单校验规则
|
||||||
|
configRules: {
|
||||||
|
weightDistance: [
|
||||||
|
{ required: true, message: "距离权重不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 0, max: 1, message: "距离权重必须在0-1之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
weightSkillMatch: [
|
||||||
|
{ required: true, message: "技能匹配权重不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 0, max: 1, message: "技能匹配权重必须在0-1之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
weightExperience: [
|
||||||
|
{ required: true, message: "经验权重不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 0, max: 1, message: "经验权重必须在0-1之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
weightRating: [
|
||||||
|
{ required: true, message: "评分权重不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 0, max: 1, message: "评分权重必须在0-1之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
weightAvailability: [
|
||||||
|
{ required: true, message: "可用性权重不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 0, max: 1, message: "可用性权重必须在0-1之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
weightNewWorkerBonus: [
|
||||||
|
{ required: true, message: "新师傅奖励权重不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 0, max: 1, message: "新师傅奖励权重必须在0-1之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
maxDistance: [
|
||||||
|
{ required: true, message: "最大距离不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 10, max: 100, message: "最大距离必须在10-100公里之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
preferredDistance: [
|
||||||
|
{ required: true, message: "首选距离不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 5, max: 50, message: "首选距离必须在5-50公里之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
newWorkerOrderThreshold: [
|
||||||
|
{ required: true, message: "新师傅订单数量阈值不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 1, max: 20, message: "新师傅订单数量阈值必须在1-20之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
autoDispatchTimeout: [
|
||||||
|
{ required: true, message: "自动派单超时时间不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 10, max: 60, message: "自动派单超时时间必须在10-60秒之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
maxRetryCount: [
|
||||||
|
{ required: true, message: "最大重试次数不能为空", trigger: "blur" },
|
||||||
|
{ type: "number", min: 1, max: 10, message: "最大重试次数必须在1-10之间", trigger: "blur" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 保存加载状态
|
||||||
|
saveLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算总权重
|
||||||
|
totalWeight() {
|
||||||
|
return (this.configForm.weightDistance +
|
||||||
|
this.configForm.weightSkillMatch +
|
||||||
|
this.configForm.weightExperience +
|
||||||
|
this.configForm.weightRating +
|
||||||
|
this.configForm.weightAvailability +
|
||||||
|
this.configForm.weightNewWorkerBonus).toFixed(2)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 权重验证
|
||||||
|
weightValidation() {
|
||||||
|
const total = parseFloat(this.totalWeight)
|
||||||
|
const isValid = Math.abs(total - 1.0) < 0.001
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: isValid ? 'success' : 'error',
|
||||||
|
title: isValid ? '权重配置有效' : '权重配置无效',
|
||||||
|
description: isValid
|
||||||
|
? `总权重为 ${this.totalWeight},配置正确`
|
||||||
|
: `总权重为 ${this.totalWeight},应该等于1.0`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 保存配置 */
|
||||||
|
saveConfig() {
|
||||||
|
this.$refs["configForm"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.saveLoading = true
|
||||||
|
|
||||||
|
// 这里应该调用后端API保存配置
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$modal.msgSuccess("配置保存成功")
|
||||||
|
this.saveLoading = false
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
this.$modal.msgError("请检查配置参数")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 重置配置 */
|
||||||
|
resetConfig() {
|
||||||
|
this.$modal.confirm('确定要重置所有配置吗?').then(() => {
|
||||||
|
this.configForm = {
|
||||||
|
weightDistance: 0.15,
|
||||||
|
weightSkillMatch: 0.25,
|
||||||
|
weightExperience: 0.15,
|
||||||
|
weightRating: 0.20,
|
||||||
|
weightAvailability: 0.15,
|
||||||
|
weightNewWorkerBonus: 0.10,
|
||||||
|
maxDistance: 50.0,
|
||||||
|
preferredDistance: 20.0,
|
||||||
|
newWorkerOrderThreshold: 5,
|
||||||
|
enableNewWorkerBonus: true,
|
||||||
|
enableDistanceLimit: true,
|
||||||
|
enableSkillMatch: true,
|
||||||
|
enableExperienceScore: true,
|
||||||
|
enableRatingScore: true,
|
||||||
|
enableAvailabilityScore: true,
|
||||||
|
autoDispatchTimeout: 30,
|
||||||
|
maxRetryCount: 3,
|
||||||
|
enableLogging: true,
|
||||||
|
enablePerformanceMonitoring: true
|
||||||
|
}
|
||||||
|
this.$modal.msgSuccess("配置已重置")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 加载默认配置 */
|
||||||
|
loadDefaultConfig() {
|
||||||
|
this.$modal.confirm('确定要加载默认配置吗?').then(() => {
|
||||||
|
this.configForm = {
|
||||||
|
weightDistance: 0.25,
|
||||||
|
weightSkillMatch: 0.20,
|
||||||
|
weightExperience: 0.15,
|
||||||
|
weightRating: 0.15,
|
||||||
|
weightAvailability: 0.15,
|
||||||
|
weightNewWorkerBonus: 0.10,
|
||||||
|
maxDistance: 50.0,
|
||||||
|
preferredDistance: 20.0,
|
||||||
|
newWorkerOrderThreshold: 5,
|
||||||
|
enableNewWorkerBonus: true,
|
||||||
|
enableDistanceLimit: true,
|
||||||
|
enableSkillMatch: true,
|
||||||
|
enableExperienceScore: true,
|
||||||
|
enableRatingScore: true,
|
||||||
|
enableAvailabilityScore: true,
|
||||||
|
autoDispatchTimeout: 30,
|
||||||
|
maxRetryCount: 3,
|
||||||
|
enableLogging: true,
|
||||||
|
enablePerformanceMonitoring: true
|
||||||
|
}
|
||||||
|
this.$modal.msgSuccess("默认配置已加载")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 测试配置 */
|
||||||
|
testConfig() {
|
||||||
|
this.$modal.msgInfo("配置测试功能开发中...")
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 刷新预览 */
|
||||||
|
refreshPreview() {
|
||||||
|
this.$modal.msgSuccess("预览已刷新")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.form-tip {
|
||||||
|
margin-left: 10px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-divider {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-descriptions {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tag {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
-- 派单评分记录表
|
||||||
|
-- 用于记录所有师傅的评分详情和各个影响因素的分值
|
||||||
|
-- 每天晚上12点定时任务更新
|
||||||
|
|
||||||
|
CREATE TABLE `dispatch_score_record` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`worker_id` bigint(20) NOT NULL COMMENT '师傅ID',
|
||||||
|
`worker_name` varchar(100) NOT NULL COMMENT '师傅姓名',
|
||||||
|
`worker_phone` varchar(20) DEFAULT NULL COMMENT '师傅电话',
|
||||||
|
`order_id` bigint(20) DEFAULT NULL COMMENT '订单ID(如果是在派单过程中记录)',
|
||||||
|
`service_id` bigint(20) DEFAULT NULL COMMENT '服务ID',
|
||||||
|
`user_address_id` bigint(20) DEFAULT NULL COMMENT '用户地址ID',
|
||||||
|
|
||||||
|
-- 各项评分
|
||||||
|
`distance_score` decimal(5,4) DEFAULT 0.0000 COMMENT '距离评分',
|
||||||
|
`skill_match_score` decimal(5,4) DEFAULT 0.0000 COMMENT '技能匹配评分',
|
||||||
|
`experience_score` decimal(5,4) DEFAULT 0.0000 COMMENT '经验评分',
|
||||||
|
`rating_score` decimal(5,4) DEFAULT 0.0000 COMMENT '评分权重',
|
||||||
|
`availability_score` decimal(5,4) DEFAULT 0.0000 COMMENT '可用性评分',
|
||||||
|
`new_worker_bonus_score` decimal(5,4) DEFAULT 0.0000 COMMENT '新师傅奖励评分',
|
||||||
|
`total_score` decimal(5,4) DEFAULT 0.0000 COMMENT '综合评分',
|
||||||
|
|
||||||
|
-- 各项权重
|
||||||
|
`weight_distance` decimal(5,4) DEFAULT 0.1500 COMMENT '距离权重',
|
||||||
|
`weight_skill_match` decimal(5,4) DEFAULT 0.2500 COMMENT '技能匹配权重',
|
||||||
|
`weight_experience` decimal(5,4) DEFAULT 0.1500 COMMENT '经验权重',
|
||||||
|
`weight_rating` decimal(5,4) DEFAULT 0.2000 COMMENT '评分权重',
|
||||||
|
`weight_availability` decimal(5,4) DEFAULT 0.1500 COMMENT '可用性权重',
|
||||||
|
`weight_new_worker_bonus` decimal(5,4) DEFAULT 0.1000 COMMENT '新师傅奖励权重',
|
||||||
|
|
||||||
|
-- 详细数据
|
||||||
|
`distance_km` decimal(10,2) DEFAULT NULL COMMENT '实际距离(公里)',
|
||||||
|
`skill_match_count` int(11) DEFAULT 0 COMMENT '匹配技能数量',
|
||||||
|
`total_skills_count` int(11) DEFAULT 0 COMMENT '总技能数量',
|
||||||
|
`completed_orders_count` int(11) DEFAULT 0 COMMENT '已完成订单数量',
|
||||||
|
`current_orders_count` int(11) DEFAULT 0 COMMENT '当前进行中订单数量',
|
||||||
|
`is_new_worker` tinyint(1) DEFAULT 0 COMMENT '是否新师傅(1是,0否)',
|
||||||
|
`registration_days` int(11) DEFAULT 0 COMMENT '注册天数',
|
||||||
|
|
||||||
|
-- 位置信息
|
||||||
|
`worker_latitude` varchar(20) DEFAULT NULL COMMENT '师傅纬度',
|
||||||
|
`worker_longitude` varchar(20) DEFAULT NULL COMMENT '师傅经度',
|
||||||
|
`user_latitude` varchar(20) DEFAULT NULL COMMENT '用户纬度',
|
||||||
|
`user_longitude` varchar(20) DEFAULT NULL COMMENT '用户经度',
|
||||||
|
`city_code` varchar(20) DEFAULT NULL COMMENT '城市编码',
|
||||||
|
`district_code` varchar(20) DEFAULT NULL COMMENT '区县编码',
|
||||||
|
|
||||||
|
-- 状态信息
|
||||||
|
`worker_status` int(11) DEFAULT 1 COMMENT '师傅状态(1启用,0禁用)',
|
||||||
|
`is_work` int(11) DEFAULT 1 COMMENT '是否工作(1是,0否)',
|
||||||
|
`is_stop` int(11) DEFAULT 0 COMMENT '是否停止(1是,0否)',
|
||||||
|
`has_unfinished_orders` tinyint(1) DEFAULT 0 COMMENT '是否有未完成订单(1是,0否)',
|
||||||
|
`is_available` tinyint(1) DEFAULT 1 COMMENT '是否可用(1是,0否)',
|
||||||
|
|
||||||
|
-- 排名信息
|
||||||
|
`rank_position` int(11) DEFAULT 0 COMMENT '排名位置',
|
||||||
|
`total_candidates` int(11) DEFAULT 0 COMMENT '总候选人数',
|
||||||
|
`is_selected` tinyint(1) DEFAULT 0 COMMENT '是否被选中(1是,0否)',
|
||||||
|
`selection_reason` varchar(500) DEFAULT NULL COMMENT '选中原因',
|
||||||
|
|
||||||
|
-- 时间信息
|
||||||
|
`score_calculation_time` datetime DEFAULT NULL COMMENT '评分计算时间',
|
||||||
|
`last_update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
|
||||||
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
|
||||||
|
-- 备注
|
||||||
|
`remark` varchar(1000) DEFAULT NULL COMMENT '备注信息',
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_worker_id` (`worker_id`),
|
||||||
|
KEY `idx_order_id` (`order_id`),
|
||||||
|
KEY `idx_total_score` (`total_score`),
|
||||||
|
KEY `idx_rank_position` (`rank_position`),
|
||||||
|
KEY `idx_is_selected` (`is_selected`),
|
||||||
|
KEY `idx_score_calculation_time` (`score_calculation_time`),
|
||||||
|
KEY `idx_worker_status` (`worker_status`),
|
||||||
|
KEY `idx_is_available` (`is_available`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='派单评分记录表';
|
||||||
|
|
||||||
|
-- 创建索引优化查询性能
|
||||||
|
CREATE INDEX `idx_worker_score_time` ON `dispatch_score_record` (`worker_id`, `score_calculation_time`);
|
||||||
|
CREATE INDEX `idx_score_rank` ON `dispatch_score_record` (`total_score` DESC, `rank_position`);
|
||||||
|
CREATE INDEX `idx_available_workers` ON `dispatch_score_record` (`is_available`, `total_score` DESC);
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
-- 派单统计表
|
||||||
|
CREATE TABLE `dispatch_statistics` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`order_id` bigint(20) DEFAULT NULL COMMENT '订单ID',
|
||||||
|
`worker_id` bigint(20) DEFAULT NULL COMMENT '师傅ID',
|
||||||
|
`worker_name` varchar(100) DEFAULT NULL COMMENT '师傅姓名',
|
||||||
|
`service_id` bigint(20) DEFAULT NULL COMMENT '服务ID',
|
||||||
|
`service_name` varchar(200) DEFAULT NULL COMMENT '服务名称',
|
||||||
|
`address_id` bigint(20) DEFAULT NULL COMMENT '用户地址ID',
|
||||||
|
`address` varchar(500) DEFAULT NULL COMMENT '用户地址',
|
||||||
|
`city_code` varchar(50) DEFAULT NULL COMMENT '城市编码',
|
||||||
|
`city_name` varchar(100) DEFAULT NULL COMMENT '城市名称',
|
||||||
|
`dispatch_type` int(11) DEFAULT NULL COMMENT '派单类型 1:自动派单 2:手动派单',
|
||||||
|
`dispatch_result` int(11) DEFAULT NULL COMMENT '派单结果 1:成功 0:失败',
|
||||||
|
`dispatch_time` bigint(20) DEFAULT NULL COMMENT '派单耗时(毫秒)',
|
||||||
|
`distance_score` decimal(5,2) DEFAULT NULL COMMENT '距离评分',
|
||||||
|
`skill_match_score` decimal(5,2) DEFAULT NULL COMMENT '技能匹配评分',
|
||||||
|
`experience_score` decimal(5,2) DEFAULT NULL COMMENT '经验评分',
|
||||||
|
`rating_score` decimal(5,2) DEFAULT NULL COMMENT '评分',
|
||||||
|
`availability_score` decimal(5,2) DEFAULT NULL COMMENT '可用性评分',
|
||||||
|
`new_worker_bonus_score` decimal(5,2) DEFAULT NULL COMMENT '新师傅奖励评分',
|
||||||
|
`total_score` decimal(5,2) DEFAULT NULL COMMENT '综合评分',
|
||||||
|
`candidate_count` int(11) DEFAULT NULL COMMENT '候选师傅数量',
|
||||||
|
`retry_count` int(11) DEFAULT NULL COMMENT '重试次数',
|
||||||
|
`failure_reason` varchar(500) DEFAULT NULL COMMENT '失败原因',
|
||||||
|
`dispatch_date` datetime DEFAULT NULL COMMENT '派单时间',
|
||||||
|
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_order_id` (`order_id`),
|
||||||
|
KEY `idx_worker_id` (`worker_id`),
|
||||||
|
KEY `idx_service_id` (`service_id`),
|
||||||
|
KEY `idx_city_code` (`city_code`),
|
||||||
|
KEY `idx_dispatch_date` (`dispatch_date`),
|
||||||
|
KEY `idx_dispatch_result` (`dispatch_result`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='派单统计表';
|
||||||
|
|
||||||
|
-- 插入示例数据
|
||||||
|
INSERT INTO `dispatch_statistics` (`order_id`, `worker_id`, `worker_name`, `service_id`, `service_name`, `address_id`, `address`, `city_code`, `city_name`, `dispatch_type`, `dispatch_result`, `dispatch_time`, `distance_score`, `skill_match_score`, `experience_score`, `rating_score`, `availability_score`, `new_worker_bonus_score`, `total_score`, `candidate_count`, `retry_count`, `failure_reason`, `dispatch_date`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1001, 201, '张师傅', 301, '空调维修', 401, '北京市朝阳区建国路88号', '110105', '朝阳区', 1, 1, 1500, 0.85, 0.90, 0.80, 0.88, 0.92, 0.00, 0.87, 5, 0, NULL, '2025-01-15 10:30:00', '2025-01-15 10:30:00', '2025-01-15 10:30:00'),
|
||||||
|
(1002, 202, '李师傅', 302, '水管维修', 402, '北京市海淀区中关村大街1号', '110108', '海淀区', 1, 1, 1200, 0.90, 0.95, 0.85, 0.92, 0.88, 0.00, 0.90, 4, 0, NULL, '2025-01-15 11:15:00', '2025-01-15 11:15:00', '2025-01-15 11:15:00'),
|
||||||
|
(1003, 203, '王师傅', 303, '电路维修', 403, '北京市西城区西单北大街120号', '110102', '西城区', 1, 0, 3000, 0.70, 0.60, 0.40, 0.75, 0.65, 1.00, 0.68, 3, 1, '技能不匹配', '2025-01-15 14:20:00', '2025-01-15 14:20:00', '2025-01-15 14:20:00'),
|
||||||
|
(1004, 204, '赵师傅', 304, '门窗安装', 404, '北京市东城区王府井大街255号', '110101', '东城区', 2, 1, 800, 0.95, 0.88, 0.90, 0.85, 0.95, 0.00, 0.91, 6, 0, NULL, '2025-01-15 16:45:00', '2025-01-15 16:45:00', '2025-01-15 16:45:00'),
|
||||||
|
(1005, 205, '刘师傅', 305, '家具安装', 405, '北京市丰台区丰台路168号', '110106', '丰台区', 1, 1, 1800, 0.80, 0.85, 0.75, 0.80, 0.85, 0.00, 0.81, 4, 0, NULL, '2025-01-15 18:30:00', '2025-01-15 18:30:00', '2025-01-15 18:30:00');
|
||||||
Loading…
Reference in New Issue