手动结束订单

This commit is contained in:
19173159168
2025-08-27 22:49:31 +08:00
parent c946f7a344
commit 32a9bc8c39
9 changed files with 173 additions and 53 deletions

View File

@ -152,7 +152,11 @@ public class ZcOrderMainController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult manualEndOrder(Long orderId) public AjaxResult manualEndOrder(Long orderId)
{ {
return toAjax(zcOrderMainService.updateManualEndOrder(orderId)); int flag = zcOrderMainService.updateManualEndOrder(orderId);
if(flag > 0) {
}
return toAjax(flag);
} }
} }

View File

@ -0,0 +1,36 @@
package com.ruoyi.orders.dto;
import java.math.BigDecimal;
public class StoreOrderStats {
/** 门店名称 */
private String storeName;
/** 订单金额 */
private BigDecimal orderAmount;
// 构造函数
public StoreOrderStats() {}
public StoreOrderStats(String storeName, BigDecimal orderAmount) {
this.storeName = storeName;
this.orderAmount = orderAmount;
}
// Getter 和 Setter 方法
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public BigDecimal getOrderAmount() {
return orderAmount;
}
public void setOrderAmount(BigDecimal orderAmount) {
this.orderAmount = orderAmount;
}
}

View File

@ -3,6 +3,8 @@ package com.ruoyi.orders.mapper;
import java.util.List; import java.util.List;
import com.ruoyi.orders.domain.ZcOrderMain; import com.ruoyi.orders.domain.ZcOrderMain;
import com.ruoyi.orders.domain.ZcOrderSub; import com.ruoyi.orders.domain.ZcOrderSub;
import com.ruoyi.orders.dto.StoreOrderStats;
import org.apache.ibatis.annotations.Param;
/** /**
* 租车订单Mapper接口 * 租车订单Mapper接口
@ -91,4 +93,12 @@ public interface ZcOrderMainMapper
* @return 结果 * @return 结果
*/ */
public int deleteZcOrderSubByOrderId(Long orderId); public int deleteZcOrderSubByOrderId(Long orderId);
/**
* 查询门店订单统计排名前N条
*
* @param limit 前N条记录
* @return 门店订单统计列表
*/
List<StoreOrderStats> selectTopStoreOrderStats(@Param("limit") int limit);
} }

View File

@ -2,6 +2,7 @@ package com.ruoyi.orders.service;
import java.util.List; import java.util.List;
import com.ruoyi.orders.domain.ZcOrderMain; import com.ruoyi.orders.domain.ZcOrderMain;
import com.ruoyi.orders.dto.StoreOrderStats;
/** /**
* 租车订单Service接口 * 租车订单Service接口
@ -63,4 +64,12 @@ public interface IZcOrderMainService
public int updateManualEndOrder(Long orderId); public int updateManualEndOrder(Long orderId);
/**
* 获取门店订单统计排名前N条
*
* @param limit 前N条记录
* @return 门店订单统计列表
*/
List<StoreOrderStats> getTopStoreOrderStats(int limit);
} }

View File

@ -10,6 +10,7 @@ import com.ruoyi.operation.domain.ZcCar;
import com.ruoyi.operation.service.IZcCarService; import com.ruoyi.operation.service.IZcCarService;
import com.ruoyi.operation.util.CarStatusEnum; import com.ruoyi.operation.util.CarStatusEnum;
import com.ruoyi.orders.dto.RefundRequest; import com.ruoyi.orders.dto.RefundRequest;
import com.ruoyi.orders.dto.StoreOrderStats;
import com.ruoyi.orders.service.IZcOrderSubService; import com.ruoyi.orders.service.IZcOrderSubService;
import com.ruoyi.orders.util.OrderStatusEnum; import com.ruoyi.orders.util.OrderStatusEnum;
import com.ruoyi.orders.util.OrderUtil; import com.ruoyi.orders.util.OrderUtil;
@ -18,6 +19,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -149,7 +151,7 @@ public class ZcOrderMainServiceImpl implements IZcOrderMainService
zcOrderMainMapper.deleteZcOrderSubByOrderId(orderId); zcOrderMainMapper.deleteZcOrderSubByOrderId(orderId);
return zcOrderMainMapper.deleteZcOrderMainByOrderId(orderId); return zcOrderMainMapper.deleteZcOrderMainByOrderId(orderId);
} }
@Transactional
@Override @Override
public int updateManualEndOrder(Long orderId) { public int updateManualEndOrder(Long orderId) {
// 1. 参数校验 // 1. 参数校验
@ -172,33 +174,9 @@ public class ZcOrderMainServiceImpl implements IZcOrderMainService
logger.error("退款处理失败订单ID: {}", orderId); logger.error("退款处理失败订单ID: {}", orderId);
throw new RuntimeException("退款处理失败"); throw new RuntimeException("退款处理失败");
} }
// 4. 退款成功后,更新订单状态 (计算逾期费用,更新订单状态)
// 4. 退款成功后,更新订单状态 int flag = updateRefundZcOrderMain(orderId, queryOrder);
ZcOrderMain zcOrderMain = new ZcOrderMain(); // 5. 释放车辆状态
zcOrderMain.setOrderId(orderId);
zcOrderMain.setOrderStatus(OrderStatusEnum.MANUAL_END.getCode());
zcOrderMain.setUpdateBy(ShiroUtils.getSysUser().getLoginName());
zcOrderMain.setUpdateTime(DateUtils.getNowDate());
zcOrderMain.setEndOrderTime(DateUtils.getNowDate());
// 5. 计算逾期费用
long overdueDays = DateUtils.daysBetween(queryOrder.getEndRentTime(), DateUtils.getNowDate());
if (overdueDays > 0) {
zcOrderMain.setOverdueDays(overdueDays);
zcOrderMain.setOverdueAmount(queryOrder.getOverdueFee().multiply(new BigDecimal(overdueDays)));
} else {
zcOrderMain.setOverdueDays(0L);
zcOrderMain.setOverdueAmount(BigDecimal.ZERO);
}
// 6. 更新订单状态
int flag = zcOrderMainMapper.updateZcOrderMain(zcOrderMain);
if (flag <= 0) {
logger.error("更新订单状态失败订单ID: {}", orderId);
throw new RuntimeException("更新订单状态失败");
}
// 7. 释放车辆状态
ZcCar zcCar = new ZcCar(); ZcCar zcCar = new ZcCar();
zcCar.setId(queryOrder.getVehicleId()); zcCar.setId(queryOrder.getVehicleId());
zcCar.setStatus(CarStatusEnum.CAR_STATUS_0.getCode()); zcCar.setStatus(CarStatusEnum.CAR_STATUS_0.getCode());
@ -206,6 +184,7 @@ public class ZcOrderMainServiceImpl implements IZcOrderMainService
logger.info("手动结束订单处理完成订单ID: {}", orderId); logger.info("手动结束订单处理完成订单ID: {}", orderId);
return flag; return flag;
} catch (Exception e) { } catch (Exception e) {
logger.error("手动结束订单处理异常订单ID: " + orderId, e); logger.error("手动结束订单处理异常订单ID: " + orderId, e);
throw new RuntimeException("手动结束订单处理失败: " + e.getMessage(), e); throw new RuntimeException("手动结束订单处理失败: " + e.getMessage(), e);
@ -250,35 +229,80 @@ public class ZcOrderMainServiceImpl implements IZcOrderMainService
refundSub.setRefundId(suborderNo); refundSub.setRefundId(suborderNo);
refundSub.setCreateTime(DateUtils.getNowDate()); refundSub.setCreateTime(DateUtils.getNowDate());
// 调用退款接口并检查结果 // // 调用退款接口并检查结果
boolean bool = callRefundApi(querySub, suborderNo, refundAmount, queryOrder.getOperatorId()); // boolean bool = callRefundApi(querySub, suborderNo, refundAmount, queryOrder.getOperatorId());
if(bool) { // if(bool) {
// 创建退款成功子订单 // // 创建退款成功子订单
zcOrderSubService.insertZcOrderSub(refundSub); // zcOrderSubService.insertZcOrderSub(refundSub);
} // }
return bool; // return bool;
// 在新事务中插入退款子订单
insertRefundSubInNewTransaction(refundSub);
// 调用退款接口并检查结果(此时数据库中已有退款订单数据)
return callRefundApi(refundSub, queryOrder.getOperatorId());
} }
return true; // 如果没有押金子订单,认为退款成功 return true; // 如果没有押金子订单,认为退款成功
} }
/**
* 在新事务中插入退款子订单
* @param refundSub 退款子订单
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertRefundSubInNewTransaction(ZcOrderSub refundSub) {
zcOrderSubService.insertZcOrderSub(refundSub);
}
@Transactional
public int updateRefundZcOrderMain(Long orderId, ZcOrderMain queryOrder){
// 4. 退款成功后,更新订单状态
ZcOrderMain zcOrderMain = new ZcOrderMain();
zcOrderMain.setOrderId(orderId);
zcOrderMain.setOrderStatus(OrderStatusEnum.MANUAL_END.getCode());
zcOrderMain.setUpdateBy(ShiroUtils.getSysUser().getLoginName());
zcOrderMain.setUpdateTime(DateUtils.getNowDate());
zcOrderMain.setEndOrderTime(DateUtils.getNowDate());
// 计算逾期费用
long overdueDays = DateUtils.daysBetween(queryOrder.getEndRentTime(), DateUtils.getNowDate());
if (overdueDays > 0) {
zcOrderMain.setOverdueDays(overdueDays);
zcOrderMain.setOverdueAmount(queryOrder.getOverdueFee().multiply(new BigDecimal(overdueDays)));
} else {
zcOrderMain.setOverdueDays(0L);
zcOrderMain.setOverdueAmount(BigDecimal.ZERO);
}
// 更新订单状态
int flag = zcOrderMainMapper.updateZcOrderMain(zcOrderMain);
if (flag <= 0) {
logger.error("更新订单状态失败订单ID: {}", orderId);
throw new RuntimeException("更新订单状态失败");
}
logger.info("更新订单状态成功订单ID: {}", orderId);
return flag;
}
/** /**
* 调用退款接口 * 调用退款接口
* @param querySub 原始押金子订单 * @param refundSub
* @param refundNo 退款单号
* @param refundAmount 退款金额
* @param operatorId 运营商ID * @param operatorId 运营商ID
* @return 退款是否成功 * @return 退款是否成功
*/ */
private boolean callRefundApi(ZcOrderSub querySub, String refundNo, BigDecimal refundAmount, Long operatorId) { private boolean callRefundApi(ZcOrderSub refundSub, Long operatorId) {
String refundNo = refundSub.getRefundId();
try { try {
// 准备退款请求参数 // 准备退款请求参数
RefundRequest refundRequest = new RefundRequest(); RefundRequest refundRequest = new RefundRequest();
refundRequest.setCompanyId(operatorId);// 运营商id refundRequest.setCompanyId(operatorId);// 运营商id
refundRequest.setOutTradeNo(querySub.getPaymentId()); // 子订单押金payment_id refundRequest.setOutTradeNo(refundSub.getPaymentId()); // 原始押金子订单payment_id
refundRequest.setOutRefundNo(refundNo);// 退款子订单编号 refundRequest.setOutRefundNo(refundNo);// 退款子订单编号
refundRequest.setRefundDesc("手动结束订单退款");// 退款描述 refundRequest.setRefundDesc("手动结束订单退款");// 退款描述
refundRequest.setTotalFee(new BigDecimal(0)); refundRequest.setTotalFee(new BigDecimal(0));
refundRequest.setRefundFee(refundAmount); // 退款金额 refundRequest.setRefundFee(refundSub.getAmount().multiply(new BigDecimal(100))); // 退款金额
// 发送HTTP请求调用退款接口 // 发送HTTP请求调用退款接口
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
@ -349,4 +373,17 @@ public class ZcOrderMainServiceImpl implements IZcOrderMainService
} }
} }
} }
/**
* 获取门店订单统计排名前N条
*
* @param limit 前N条记录
* @return 门店订单统计列表
*/
@Override
public List<StoreOrderStats> getTopStoreOrderStats(int limit) {
return zcOrderMainMapper.selectTopStoreOrderStats(limit);
}
} }

View File

@ -6,6 +6,8 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.utils.*; import com.ruoyi.common.utils.*;
import com.ruoyi.orders.dto.StoreOrderStats;
import com.ruoyi.orders.service.IZcOrderMainService;
import com.ruoyi.system.domain.SysNotice; import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService; import com.ruoyi.system.service.ISysNoticeService;
import com.ruoyi.system.service.ISysUserOnlineService; import com.ruoyi.system.service.ISysUserOnlineService;
@ -48,6 +50,8 @@ public class SysIndexController extends BaseController
private ISysUserOnlineService sysUserOnlineService; private ISysUserOnlineService sysUserOnlineService;
@Autowired @Autowired
private ISysNoticeService noticeService; private ISysNoticeService noticeService;
@Autowired
private IZcOrderMainService zcOrderMainService;
// 系统首页 // 系统首页
@GetMapping("/index") @GetMapping("/index")
@ -146,6 +150,10 @@ public class SysIndexController extends BaseController
// HomeStatisticsVo homeStatisticsVo = idWarningMemberService.selectHomeStatistics(); // HomeStatisticsVo homeStatisticsVo = idWarningMemberService.selectHomeStatistics();
// mmap.put("homeStatisticsVo", homeStatisticsVo); // mmap.put("homeStatisticsVo", homeStatisticsVo);
// 获取门店订单统计数据
List<StoreOrderStats> storeOrderStats = zcOrderMainService.getTopStoreOrderStats(9);
mmap.put("storeOrderStats", storeOrderStats);
List<SysNotice> sysNotices = noticeService.selectHomeNoticeList(); List<SysNotice> sysNotices = noticeService.selectHomeNoticeList();
mmap.put("sysNotices", sysNotices); mmap.put("sysNotices", sysNotices);

View File

@ -7,7 +7,7 @@ ruoyi:
# 版权年份 # 版权年份
copyrightYear: 2025 copyrightYear: 2025
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: false
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath # 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
#profile: D:/ruoyi/uploadPath #profile: D:/ruoyi/uploadPath
profile: /home/sczx/uploadPath profile: /home/sczx/uploadPath
@ -147,7 +147,7 @@ csrf:
# Swagger配置 # Swagger配置
swagger: swagger:
# 是否开启swagger # 是否开启swagger
enabled: true enabled: false
# 阿里云 OSS 配置 # 阿里云 OSS 配置
aliyun: aliyun:

View File

@ -281,4 +281,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach> </foreach>
</insert> </insert>
<select id="selectTopStoreOrderStats" resultType="com.ruoyi.orders.dto.StoreOrderStats">
SELECT
b.name as storeName,
SUM(a.order_amount) as orderAmount
FROM zc_order_main a LEFT JOIN zc_company_store b on a.store_id = b.id
WHERE a.order_status in ('AUTO_END','MANUAL_END')
AND a.del_flag = '0'
AND b.del_flag = '0'
GROUP BY a.store_id
ORDER BY orderAmount DESC
LIMIT #{limit}
</select>
</mapper> </mapper>

View File

@ -356,15 +356,17 @@
</div> </div>
<div class="box-body chat" style="height: 100%"> <div class="box-body chat" style="height: 100%">
<ul class="list-unstyled"> <ul class="list-unstyled">
<li><span class="badge">1</span> 工专路一号店 <span class="pull-right">323,234</span></li> <th:block th:each="storeStat,stat : ${storeOrderStats}">
<li><span class="badge">2</span> 工专路二号店 <span class="pull-right">323,234</span></li> <li>
<li><span class="badge">3</span> 工专路三号店 <span class="pull-right">323,234</span></li> <span class="badge" th:text="${stat.index + 1}"></span>
<li><span class="badge">4</span> 工专路四号店 <span class="pull-right">323,234</span></li> <span th:text="${storeStat.storeName}"></span>
<li><span class="badge">5</span> 工专路五号店 <span class="pull-right">323,234</span></li> <span class="pull-right" th:text="${storeStat.orderAmount}"></span>
<li><span class="badge">6</span> 工专路六号店 <span class="pull-right">323,234</span></li> </li>
<li><span class="badge">7</span> 工专路七号店 <span class="pull-right">323,234</span></li> </th:block>
<li><span class="badge">8</span> 工专路八号店 <span class="pull-right">323,234</span></li> <!-- 默认展示内容,当无数据时显示 -->
<li><span class="badge">9</span> 工专路九号店 <span class="pull-right">323,234</span></li> <th:block th:if="${storeOrderStats == null or storeOrderStats.isEmpty()}">
<li><span class="badge">1</span> 暂无数据 <span class="pull-right">0</span></li>
</th:block>
</ul> </ul>
</div> </div>
</div> </div>