202506211807

This commit is contained in:
张潘 2025-06-21 18:07:11 +08:00
parent 266742ca2d
commit 395170f9b4
14 changed files with 5232 additions and 4776 deletions

View File

@ -7,6 +7,18 @@
<groupId>com.ruoyi</groupId>
<version>3.8.9</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-system</artifactId>

View File

@ -71,6 +71,8 @@ public class PayNotifyController extends BaseController {
@Autowired
private IWorkerMarginLogService workerMarginLogService;
@Autowired
private IWorkerMoneyLogService workerMoneyLogService;
/**
* 商品支付回调接口
*
@ -406,7 +408,8 @@ public class PayNotifyController extends BaseController {
// 7. 处理订单支付成功后的业务逻辑
handleOrderAmountPaymentSuccess(order, paymentInfo);
calculateCommissionMoney(order.getOrderId(), order.getUid(),order.getWorkerId());
calculateCommissionAndRecord(order.getOrderId(),order.getWorkerId());
//calculateCommissionMoney(order.getOrderId(), order.getUid(),order.getWorkerId());
logger.info("订单金额支付回调处理成功,订单号:{}", outTradeNo);
return buildSuccessResponse();
@ -835,60 +838,75 @@ public class PayNotifyController extends BaseController {
/**
* 分佣
*
* @return 商品标题
*/
public Map<String, Object> calculateCommissionMoney(String orderId,long oid, Long workerId
public Map<String, Object> calculateCommissionAndRecord(
String orderId,
Long workerId
) {
// 结果
Map<String, Object> result = new HashMap<>();
BigDecimal totalPrice = BigDecimal.ZERO;
BigDecimal margin = BigDecimal.ZERO;
BigDecimal reduction = BigDecimal.ZERO;
BigDecimal servicePrice = BigDecimal.ZERO;
BigDecimal doorPrice = BigDecimal.ZERO;
BigDecimal totalCommission = BigDecimal.ZERO; // 师傅最终佣金
BigDecimal margin = BigDecimal.ZERO; // 质保金
BigDecimal reduction = BigDecimal.ZERO; // 优惠金额
BigDecimal servicePrice = BigDecimal.ZERO; // 服务费用
BigDecimal materialPrice = BigDecimal.ZERO; // 材料费用如有可补充
BigDecimal doorPrice = BigDecimal.ZERO; // 上门费
BigDecimal cr = BigDecimal.ZERO; // 师傅等级分佣比例
// 1. 查询订单日志
logger.info("【分佣计算】开始计算orderId={}, workerId={}", orderId, workerId);
// 1. 查询订单日志(type=2,5paid=2give_up=null)
OrderLog orderLogQuery = new OrderLog();
orderLogQuery.setOrderId(orderId);
List<OrderLog> orderLogList = orderLogService.selectOrderLogList(orderLogQuery);
//List<OrderLog> orderLogList = orderLogService.selectOrderLogListByWorker(orderId, workerId);
logger.info("【分佣计算】查询订单日志完成,日志数量={}", orderLogList.size());
// 2. 查询订单和商品
Order order = orderService.selectOrderById(oid);
Order order = orderService.selectOrderByOrderId(orderId);
logger.info("【分佣计算】查询订单完成order={}", order != null ? order.getId() : null);
ServiceGoods product = null;
if (order != null && order.getProductId() != null) {
product = serviceGoodsService.selectServiceGoodsById(order.getProductId());
logger.info("【分佣计算】查询商品完成productId={}", product != null ? product.getId() : null);
}
// 3. 查询师傅信息
Users worker = usersService.selectUsersById(workerId);
logger.info("【分佣计算】查询师傅信息完成worker={}", worker != null ? worker.getId() : null);
// 4. 计算佣金上门费优惠金额
// 4. 计算各项费用
for (OrderLog log : orderLogList) {
logger.info("【分佣计算】处理日志logId={}, type={}, workerCost={}, reductionPrice={}",
log.getId(), log.getType(), log.getWorkerCost(), log.getReductionPrice());
if (log.getType() != null && log.getType().intValue() == 5) {
// type=5 评估报价
WorkerLevel levelInfo = workerLevelService.selectWorkerLevelByLevel(Long.valueOf(worker.getLevel()));
BigDecimal cr = (levelInfo != null && levelInfo.getCr() != null) ? new BigDecimal(levelInfo.getCr()).divide(new BigDecimal(100)) : BigDecimal.ZERO;
totalPrice = totalPrice.add(log.getWorkerCost().multiply(cr).setScale(2, BigDecimal.ROUND_HALF_UP));
logger.info("【分佣计算】查询师傅等级level={}, cr={}", worker.getLevel(), levelInfo != null ? levelInfo.getCr() : null);
if (levelInfo != null && levelInfo.getCr() != null) {
cr = new BigDecimal(levelInfo.getCr()).divide(new BigDecimal(100));
}
// 师傅分佣
BigDecimal commission = log.getWorkerCost().multiply(cr).setScale(2, BigDecimal.ROUND_HALF_UP);
totalCommission = totalCommission.add(commission);
logger.info("【分佣计算】type=5分佣金额={}, 当前总佣金={}", commission, totalCommission);
// 服务费用
servicePrice = log.getWorkerCost().add(log.getReductionPrice() != null ? log.getReductionPrice() : BigDecimal.ZERO);
logger.info("【分佣计算】type=5服务费用={}", servicePrice);
}
if (log.getType() != null && log.getType().intValue() == 2) {
// type=2 上门费
totalPrice = totalPrice.add(log.getWorkerCost());
totalCommission = totalCommission.add(log.getWorkerCost());
doorPrice = log.getWorkerCost();
logger.info("【分佣计算】type=2上门费={}, 当前总佣金={}", doorPrice, totalCommission);
}
if (log.getReductionPrice() != null) {
reduction = reduction.add(log.getReductionPrice());
logger.info("【分佣计算】累计优惠金额={}", reduction);
}
}
// 5. 判断是否需要扣除质保金
if (product != null && product.getMargin() != null && worker != null && worker.getMargin() != null
&& product.getMargin().compareTo(worker.getMargin()) > 0) {
logger.info("【分佣计算】需要扣除质保金商品margin={}, 师傅margin={}", product.getMargin(), worker.getMargin());
// 查系统配置
SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
BigDecimal marginPercent = BigDecimal.ZERO;
@ -898,12 +916,16 @@ public class PayNotifyController extends BaseController {
if (json.containsKey("margin")) {
marginPercent = new BigDecimal(json.getString("margin")).divide(new BigDecimal(100));
}
} catch (Exception ignore) {}
} catch (Exception e) {
logger.error("【分佣计算】解析质保金配置异常", e);
}
margin = totalPrice.multiply(marginPercent).setScale(2, BigDecimal.ROUND_HALF_UP);
}
margin = totalCommission.multiply(marginPercent).setScale(2, BigDecimal.ROUND_HALF_UP);
logger.info("【分佣计算】初步计算质保金={}, 配置比例={}", margin, marginPercent);
// 超过质保金则扣少点
if (worker.getMargin().add(margin).compareTo(product.getMargin()) > 0) {
margin = product.getMargin().subtract(worker.getMargin());
logger.info("【分佣计算】质保金超限,实际扣除={}", margin);
}
// 插入质保金明细
WorkerMarginLog marginLog = new WorkerMarginLog();
@ -911,23 +933,166 @@ public class PayNotifyController extends BaseController {
marginLog.setUid(workerId);
marginLog.setOrderId(order != null ? order.getOrderId() : null);
marginLog.setPrice(margin);
// marginLog.setCreatedAt(new Date());
// marginLog.setUpdatedAt(new Date());
workerMarginLogService.insertWorkerMarginLog(marginLog);
logger.info("【分佣计算】插入质保金明细完成");
}
// 6. 返回
result.put("commission", totalPrice);
result.put("margin", margin);
result.put("reduction", reduction);
result.put("service_price", servicePrice);
result.put("door_price", doorPrice);
// 6. 计算最终佣金
BigDecimal finalCommission = totalCommission.subtract(margin);
logger.info("【分佣计算】最终佣金={}", finalCommission);
// 7. 更新师傅账户佣金佣金总额质保金
if (worker != null) {
BigDecimal newCommission = (worker.getCommission() != null ? worker.getCommission() : BigDecimal.ZERO).add(finalCommission);
BigDecimal newTotalComm = (worker.getTotalComm() != null ? worker.getTotalComm() : BigDecimal.ZERO).add(finalCommission);
BigDecimal newMargin = (worker.getMargin() != null ? worker.getMargin() : BigDecimal.ZERO).add(margin);
worker.setCommission(newCommission);
worker.setTotalComm(newTotalComm);
worker.setMargin(newMargin);
usersService.updateUsers(worker);
logger.info("【分佣计算】更新师傅账户完成commission={}, total_comm={}, margin={}", newCommission, newTotalComm, newMargin);
}
// 8. 插入师傅金额记录
WorkerMoneyLog moneyLog = new WorkerMoneyLog();
moneyLog.setWorkerId(workerId);
moneyLog.setOid(order.getId());
moneyLog.setOrderId(order != null ? order.getOrderId() : null);
moneyLog.setPrice(finalCommission);
moneyLog.setType(1); // 1=收入
moneyLog.setServicePrice(servicePrice);
moneyLog.setReductionPrice(reduction);
moneyLog.setCr(cr.multiply(new BigDecimal(100)).intValue()); // 百分比
moneyLog.setMergin(margin);
moneyLog.setDoorPrice(doorPrice);
workerMoneyLogService.insertWorkerMoneyLog(moneyLog);
logger.info("【分佣计算】插入师傅金额记录完成");
// 9. 组装返回
result.put("commission", finalCommission); // 师傅最终佣金
result.put("margin", margin); // 质保金
result.put("service_price", servicePrice); // 服务费用
result.put("material_price", materialPrice); // 材料费用如有可补充
result.put("reduction", reduction); // 优惠金额
result.put("door_price", doorPrice); // 上门费
result.put("cr", cr); // 师傅分佣比例
// 10. 公式说明
result.put("formula", "最终佣金 = (服务项目金额 * 师傅等级分佣比例 + 上门费) - 质保金\n"
+ "质保金 = 总佣金 * 配置质保金比例且不超过商品margin-师傅margin\n"
+ "服务费用 = 评估报价worker_cost + reduction_price\n"
+ "上门费 = type=2的worker_cost\n"
+ "优惠金额 = 所有reduction_price之和");
logger.info("【分佣计算】计算结束,返回结果={}", result);
return result;
}
// /**
// * 分佣
// *
//
// * @return 商品标题
// */
// public Map<String, Object> calculateCommissionMoney(String orderId,long oid, Long workerId
// ) {
// // 结果
// Map<String, Object> result = new HashMap<>();
// BigDecimal totalPrice = BigDecimal.ZERO;
// BigDecimal margin = BigDecimal.ZERO;
// BigDecimal reduction = BigDecimal.ZERO;
// BigDecimal servicePrice = BigDecimal.ZERO;
// BigDecimal doorPrice = BigDecimal.ZERO;
//
// // 1. 查询订单日志
// OrderLog orderLogQuery = new OrderLog();
// orderLogQuery.setOrderId(orderId);
// List<OrderLog> orderLogList = orderLogService.selectOrderLogList(orderLogQuery);
// //List<OrderLog> orderLogList = orderLogService.selectOrderLogListByWorker(orderId, workerId);
//
// // 2. 查询订单和商品
// Order order = orderService.selectOrderById(oid);
// ServiceGoods product = null;
// if (order != null && order.getProductId() != null) {
// product = serviceGoodsService.selectServiceGoodsById(order.getProductId());
// }
//
// // 3. 查询师傅信息
// Users worker = usersService.selectUsersById(workerId);
//
// // 4. 计算佣金上门费优惠金额
// for (OrderLog log : orderLogList) {
// BigDecimal workerCost =new BigDecimal(0);
// if (log.getWorkerCost() != null) {
// workerCost = log.getWorkerCost();
// }
// if (log.getType() != null && log.getType().intValue() == 5) {
// // type=5 评估报价
// WorkerLevel levelInfo = workerLevelService.selectWorkerLevelByLevel(Long.valueOf(worker.getLevel()));
// BigDecimal cr = (levelInfo != null && levelInfo.getCr() != null) ? new BigDecimal(levelInfo.getCr()).divide(new BigDecimal(100)) : BigDecimal.ZERO;
// totalPrice = totalPrice.add(workerCost.multiply(cr).setScale(2, BigDecimal.ROUND_HALF_UP));
// servicePrice = workerCost.add(log.getReductionPrice() != null ? log.getReductionPrice() : BigDecimal.ZERO);
// }
// if (log.getType() != null && log.getType().intValue() == 2) {
// // type=2 上门费
// totalPrice = totalPrice.add(log.getWorkerCost());
// doorPrice = log.getWorkerCost();
// }
// if (log.getReductionPrice() != null) {
// reduction = reduction.add(log.getReductionPrice());
// }
// }
//
// // 5. 判断是否需要扣除质保金
// if (product != null && product.getMargin() != null && worker != null && worker.getMargin() != null
// && product.getMargin().compareTo(worker.getMargin()) > 0) {
// // 查系统配置
// SiteConfig config = siteConfigService.selectSiteConfigByName("config_one");
// BigDecimal marginPercent = BigDecimal.ZERO;
// if (config != null && config.getValue() != null) {
// try {
// JSONObject json = JSONObject.parseObject(config.getValue());
// if (json.containsKey("margin")) {
// marginPercent = new BigDecimal(json.getString("margin")).divide(new BigDecimal(100));
// }
// } catch (Exception ignore) {}
// }
// margin = totalPrice.multiply(marginPercent).setScale(2, BigDecimal.ROUND_HALF_UP);
// // 超过质保金则扣少点
// if (worker.getMargin().add(margin).compareTo(product.getMargin()) > 0) {
// margin = product.getMargin().subtract(worker.getMargin());
// }
// // 插入质保金明细
// WorkerMarginLog marginLog = new WorkerMarginLog();
// marginLog.setOid(order.getId());
// marginLog.setUid(workerId);
// marginLog.setOrderId(order != null ? order.getOrderId() : null);
// marginLog.setPrice(margin);
//// marginLog.setCreatedAt(new Date());
//// marginLog.setUpdatedAt(new Date());
// workerMarginLogService.insertWorkerMarginLog(marginLog);
// //修改师傅质保金和分佣情况
// worker.setCommission(totalPrice);
// // hpinnworkerzhe.setTotalComm();
// }
//
// // 6. 返回
// result.put("commission", totalPrice);
// result.put("margin", margin);
// result.put("reduction", reduction);
// result.put("service_price", servicePrice);
// result.put("door_price", doorPrice);
// return result;
// }
/**
* 获取商品标题
*

View File

@ -68,6 +68,7 @@ public class WXsendMsgUtil {
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getAccessToken();
ResponseEntity<String> responseEntity =
restTemplate.postForEntity(url, wxMssVo, String.class);
System.out.println("0001responseEntity.getBody()" + responseEntity.getBody());
return responseEntity.getBody();
}

View File

@ -80,6 +80,10 @@ public class CouponUser extends BaseEntity
@Excel(name = "1未使用 2已使用 3:已失效")
private Long status;
private Boolean isUse;
private String suitTitle;
private String tag;
/** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Date createdAt;
@ -262,6 +266,30 @@ public class CouponUser extends BaseEntity
this.uname = uname;
}
public Boolean getIsUse() {
return isUse;
}
public void setIsUse(Boolean isUse) {
this.isUse = isUse;
}
public String getSuitTitle() {
return suitTitle;
}
public void setSuitTitle(String suitTitle) {
this.suitTitle = suitTitle;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -31,6 +31,10 @@ public interface CouponUserMapper
*/
public List<CouponUser> selectCouponUserList(CouponUser couponUser);
public List<CouponUser> selectCouponUserNoList(CouponUser couponUser);
/**
* 新增优惠券领取记录
*

View File

@ -27,6 +27,8 @@ public interface OrderLogMapper
*/
public OrderLog selectDataTheFirstNew(Long oid);
public int selectCountOrderLogByOrderId(String orderId);
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog);
public List<OrderLog> selectOrderLogByOrderId(String orderId);
/**

View File

@ -36,6 +36,8 @@ public interface ICouponUserService
*/
public List<CouponUser> selectCouponUserList(CouponUser couponUser);
public List<CouponUser> selectCouponUserNoList(CouponUser couponUser);
/**
* 新增优惠券领取记录
*

View File

@ -20,7 +20,7 @@ public interface IOrderLogService
public OrderLog selectOrderLogById(Long id);
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog);
/**
* 查询最新一条日志记录
*

View File

@ -57,7 +57,10 @@ public class CouponUserServiceImpl implements ICouponUserService
{
return couponUserMapper.selectCouponUserList(couponUser);
}
public List<CouponUser> selectCouponUserNoList(CouponUser couponUser) {
return couponUserMapper.selectCouponUserNoList(couponUser);
}
/**
* 新增优惠券领取记录
*

View File

@ -32,7 +32,9 @@ public class OrderLogServiceImpl implements IOrderLogService
}
public OrderLog selectOneByOidTypeWorkerIdPaid(OrderLog orderLog){
return orderLogMapper.selectOneByOidTypeWorkerIdPaid(orderLog);
}
/**
* 查询最新一条日志记录
*

View File

@ -30,8 +30,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select count(0) from coupon_user where coupon_id=#{couponId}
</select>
<select id="selectCouponUserNoList" parameterType="CouponUser" resultMap="CouponUserResult">
<include refid="selectCouponUserVo"/>
<where>
<if test="status != null "> and status = #{status}</if>
<if test="uid != null "> and uid = #{uid}</if>
and lose_time != '永久有效'
and NOW() > DATE_FORMAT(lose_time, '%Y-%m-%d')
</where>
order by id desc
</select>
<select id="selectCouponUserList" parameterType="CouponUser" resultMap="CouponUserResult">
<include refid="selectCouponUserVo"/>
<where>
@ -39,7 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="couponId != null "> and coupon_id = #{couponId}</if>
<if test="couponTitle != null and couponTitle != ''"> and coupon_title = #{couponTitle}</if>
<if test="couponPrice != null "> and coupon_price = #{couponPrice}</if>
<if test="minPrice != null "> and min_price = #{minPrice}</if>
<if test="minPrice != null "> and min_price > #{minPrice}</if>
<if test="addTime != null "> and add_time = #{addTime}</if>
<if test="loseTime != null and loseTime != ''"> and lose_time = #{loseTime}</if>
<if test="useTime != null "> and use_time = #{useTime}</if>

View File

@ -52,6 +52,10 @@
select id, title, price, min_price, start_time, end_time, count, is_permanent, status, coupon_time, product_id, type, receive_type, sort, cate_id, user_ids, created_at, updated_at, deleted_at from coupons
</sql>
<select id="selectCouponsList" parameterType="Coupons" resultMap="CouponsResult">
<include refid="selectCouponsVo"/>
<where>
@ -61,6 +65,9 @@
<if test="type != null "> and type = #{type}</if>
<if test="sort != null and sort != ''"> and sort = #{sort}</if>
<if test="isPermanent != null and isPermanent != ''"> and is_permanent = #{isPermanent}</if>
<if test="searchValue != null and searchValue != ''">
and type in (1,2)
</if>
<if test="priceMin != null and priceMax != null">
and price BETWEEN #{priceMin} AND #{priceMax}

View File

@ -76,6 +76,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</select>
<select id="selectOneByOidTypeWorkerIdPaid" parameterType="OrderLog" resultMap="OrderLogResult">
<include refid="selectOrderLogVo"/>
<where>
<if test="oid != null "> and oid = #{oid}</if>
<if test="orderId != null and orderId != ''"> and order_id = #{orderId}</if>
<if test="type != null "> and type = #{type}</if>
<if test="deposit != null "> and deposit = #{deposit}</if>
<if test="depPaid != null "> and dep_paid = #{depPaid}</if>
<if test="depPayTime != null "> and dep_pay_time = #{depPayTime}</if>
<if test="depLogId != null and depLogId != ''"> and dep_log_id = #{depLogId}</if>
<if test="price != null "> and price = #{price}</if>
<if test="paid != null "> and paid = #{paid}</if>
<if test="workerId != null "> and worker_id = #{workerId}</if>
</where>
order by updated_at DESC limit 1
</select>
<select id="selectCountOrderLogByOrderId" parameterType="String" resultType="Integer">
select count(*) from order_log where order_id = #{orderId}
</select>