订单分润

This commit is contained in:
2025-08-24 02:24:46 +08:00
parent a2f072f23f
commit e3a64c251e
13 changed files with 451 additions and 8 deletions

View File

@ -0,0 +1,18 @@
package com.sczx.order.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum DistribTypeEnum {
COMPANY("COMPANY", "运营商"),
STORE("STORE", "门店"),
REFERRAL("REFERRAL", "推荐人"),
PLATFORM("PLATFORM", "平台"),
;
private final String code;
private final String msg;
}

View File

@ -35,7 +35,7 @@ public class PubOrderController {
return Result.ok(orderService.getOrderDetailByOrderNo(orderNo));
}
@ApiOperation(value = "根据订单查询订单详情")
@ApiOperation(value = "查询分润记录")
@PostMapping("/pageQueryOrderDistrib")
public Result<IPage<OrderDistribDTO>> pageQueryOrderDistrib(@RequestParam(name = "pageNo", required = false, defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize,
@ -43,5 +43,10 @@ public class PubOrderController {
return Result.ok(orderDistribService.pageQueryOrderDistrib(pageNo, pageSize, orderDistribQueryReq));
}
@ApiOperation(value = "订单分润")
@GetMapping("/distribOrder")
public Result<Boolean> distribOrder(@RequestParam("orderNo") String orderNo){
orderDistribService.saveOrderDistrib(orderNo);
return Result.ok(true);
}
}

View File

@ -137,6 +137,9 @@ public class OrderMainPO implements Serializable {
@ApiModelProperty("车损说明")
private String damageDesc;
@ApiModelProperty("是否分润")
private Integer distribed;
@ApiModelProperty("删除标志0代表存在 2代表删除")
private String delFlag;

View File

@ -1,13 +1,33 @@
package com.sczx.order.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.sczx.order.common.enums.DistribTypeEnum;
import com.sczx.order.dto.OrderDistribDTO;
import com.sczx.order.dto.OrderDistribQueryReq;
import com.sczx.order.exception.BizException;
import com.sczx.order.po.OrderDistribPO;
import com.sczx.order.po.OrderMainPO;
import com.sczx.order.repository.OrderDistribRepo;
import com.sczx.order.repository.OrderMainRepo;
import com.sczx.order.service.OrderDistribService;
import com.sczx.order.thirdpart.dto.BaseUserReferralDTO;
import com.sczx.order.thirdpart.dto.CompanyDTO;
import com.sczx.order.thirdpart.dto.CompanyStoreDTO;
import com.sczx.order.thirdpart.dto.SysConfigDTO;
import com.sczx.order.thirdpart.integration.StoreInteg;
import com.sczx.order.thirdpart.integration.UserInteg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
@ -16,13 +36,99 @@ public class OrderDistribServiceImpl implements OrderDistribService {
@Autowired
private OrderDistribRepo orderDistribRepo;
@Autowired
private OrderMainRepo orderMainRepo;
@Autowired
private StoreInteg storeInteg;
@Autowired
private UserInteg userInteg;
@Override
public IPage<OrderDistribDTO> pageQueryOrderDistrib(Integer pageNo, Integer pageSize, OrderDistribQueryReq orderDistribQueryReq) {
return orderDistribRepo.pageQueryOrderDistrib(pageNo, pageSize, orderDistribQueryReq);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void saveOrderDistrib(String orderNo) {
//TODO 获取订单分润信息
LambdaQueryWrapper<OrderMainPO> currentOrderWrapper = new LambdaQueryWrapper<>();
currentOrderWrapper.eq(OrderMainPO::getOrderNo, orderNo)
.eq(OrderMainPO::getDistribed, 0)
.eq(OrderMainPO::getDelFlag, "0").last(" limit 1");
OrderMainPO orderMainPO = orderMainRepo.getOne(currentOrderWrapper);
if(Objects.isNull(orderMainPO)){
throw new BizException("订单不存在或已分润");
}
List<OrderDistribPO> addOrderDistribPOList = Lists.newArrayList();
//平台分润,运营商表配置的分润比例是平台的
CompanyDTO companyDTO = storeInteg.getCompanyById(Integer.valueOf(orderMainPO.getOperatorId().toString()));
Integer sharingRatio = companyDTO.getSharingRatio();
OrderDistribPO platFormDistribPO = getOrderDistribPO(orderMainPO.getOrderId(),orderMainPO.getOrderNo(),DistribTypeEnum.PLATFORM.getCode(),sharingRatio.toString(),orderMainPO.getOrderAmount(),null,null,null);
addOrderDistribPOList.add(platFormDistribPO);
//门店分润
CompanyStoreDTO companyStoreDTO = storeInteg.getStoreById(Integer.valueOf(orderMainPO.getStoreId().toString()));
OrderDistribPO storeDistribPO = getOrderDistribPO(orderMainPO.getOrderId(),orderMainPO.getOrderNo(),DistribTypeEnum.STORE.getCode(),companyStoreDTO.getZucheRatio().toString(),orderMainPO.getOrderAmount(),null,Integer.valueOf(orderMainPO.getStoreId().toString()),null);
addOrderDistribPOList.add(storeDistribPO);
//推荐人分润
BaseUserReferralDTO baseUserReferralDTO = userInteg.getUserReferralByUserId(orderMainPO.getCustomerId());
if(Objects.nonNull(baseUserReferralDTO)
&& Objects.nonNull(baseUserReferralDTO.getReferralUserId())){
List<SysConfigDTO> configList = storeInteg.listConfigByConfigKey(Lists.newArrayList("sczx.invitation.day", "sczx.invitation.rate"));
String invitationDay = String.valueOf(configList.stream().filter(config -> "sczx.invitation.day".equals(config.getConfigKey())).findFirst().orElse(null));
LocalDate awardDeadline = baseUserReferralDTO.getCreateTime().toLocalDate().plusDays(Integer.parseInt(invitationDay));
//判断奖励是否过期
if(awardDeadline.isAfter(LocalDate.now())){
String invitationRate = String.valueOf(configList.stream().filter(config -> "sczx.invitation.rate".equals(config.getConfigKey())).findFirst().orElse(null));
OrderDistribPO referralDistribPO = getOrderDistribPO(orderMainPO.getOrderId(),orderMainPO.getOrderNo(),DistribTypeEnum.REFERRAL.getCode(),invitationRate,orderMainPO.getOrderAmount(),null,null,baseUserReferralDTO.getReferralUserId());
addOrderDistribPOList.add(referralDistribPO);
}
}
BigDecimal alreadyShareRate = addOrderDistribPOList.stream().map(OrderDistribPO::getDistribRate).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//运营商分润
String companyRate = String.valueOf(BigDecimal.ONE.subtract(alreadyShareRate).multiply(BigDecimal.valueOf(100)));
OrderDistribPO companyDistribPO = getOrderDistribPO(orderMainPO.getOrderId(),orderMainPO.getOrderNo(),DistribTypeEnum.COMPANY.getCode(),companyRate,orderMainPO.getOrderAmount(),Integer.valueOf(orderMainPO.getOperatorId().toString()),null,null);
addOrderDistribPOList.add(companyDistribPO);
orderDistribRepo.saveOrUpdateBatch(addOrderDistribPOList);
LambdaUpdateWrapper<OrderMainPO> updateMainWrapper = new LambdaUpdateWrapper<>();
updateMainWrapper.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId())
.set(OrderMainPO::getDistribed, 1);
orderMainRepo.update(updateMainWrapper);
}
/**
* 获取分润记录
* @param orderId
* @param orderNo
* @param distribType
* @param invitationRate
* @param orderAmount
* @param companyId
* @param storeId
* @param referralUserId
* @return
*/
private static OrderDistribPO getOrderDistribPO(Long orderId,String orderNo,String distribType,String invitationRate, BigDecimal orderAmount,Integer companyId,Integer storeId,Long referralUserId) {
BigDecimal referralRate = new BigDecimal(invitationRate).multiply(new BigDecimal("0.01"));
OrderDistribPO referralDistribPO = new OrderDistribPO();
if(DistribTypeEnum.COMPANY.getCode().equalsIgnoreCase(distribType)){
referralDistribPO.setCompanyId(companyId);
} else if(DistribTypeEnum.STORE.getCode().equalsIgnoreCase(distribType)){
referralDistribPO.setStoreId(storeId);
} else if(DistribTypeEnum.REFERRAL.getCode().equalsIgnoreCase(distribType)){
referralDistribPO.setReferralUserId(referralUserId);
}
referralDistribPO.setReferralUserId(referralUserId);
referralDistribPO.setOrderId(orderId);
referralDistribPO.setOrderNo(orderNo);
referralDistribPO.setDistribType(distribType);
referralDistribPO.setDistribRate(referralRate);
referralDistribPO.setDistribAmount(orderAmount.multiply(referralRate));
return referralDistribPO;
}
}

View File

@ -17,6 +17,7 @@ import com.sczx.order.po.OrderSubPO;
import com.sczx.order.repository.OrderCarImgRepo;
import com.sczx.order.repository.OrderMainRepo;
import com.sczx.order.repository.OrderSubRepo;
import com.sczx.order.service.OrderDistribService;
import com.sczx.order.service.OrderService;
import com.sczx.order.thirdpart.dto.*;
import com.sczx.order.thirdpart.dto.req.CarQueryConditionReq;
@ -27,6 +28,7 @@ import com.sczx.order.thirdpart.integration.StoreInteg;
import com.sczx.order.utils.JwtUtil;
import com.sczx.order.utils.OrderUtil;
import com.sczx.order.utils.RedisUtil;
import com.sczx.order.utils.ThreadPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -67,6 +69,9 @@ public class OrderServiceImpl implements OrderService {
@Autowired
private PayInteg payInteg;
@Autowired
private OrderDistribService orderDistribService;
@Override
public OrderMainPO queryOrderMainPoByOrderNo(String orderNo, String delFlag) {
LambdaQueryWrapper<OrderMainPO> currentOrderWrapper = new LambdaQueryWrapper<>();
@ -829,6 +834,11 @@ public class OrderServiceImpl implements OrderService {
orderCarImgRepo.saveBatch(carImagePOList);
}
//TODO 变更车辆状态
//异步执行分润
ThreadPoolUtils.getThreadPool().execute(() -> {
orderDistribService.saveOrderDistrib(returnCarReq.getOrderNo());
});
return orderDTO;
}

View File

@ -0,0 +1,57 @@
package com.sczx.order.thirdpart.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* <p>
* 用户引荐信息
* </p>
*
* @author zhangli
* @since 2025-08-19 23:47:42
*/
@Data
@ApiModel(value = "BaseUserReferralDTO对象", description = "用户引荐信息")
public class BaseUserReferralDTO {
@ApiModelProperty("id主键")
private Long id;
@ApiModelProperty("被引荐人id")
private Long userId;
@ApiModelProperty("被引荐人手机号")
private String userPhoneNumber;
@ApiModelProperty("引荐人id")
private Long referralUserId;
@ApiModelProperty("引荐人手机号")
private String referralUserPhoneNumber;
@ApiModelProperty("奖励截止日期")
private LocalDate awardDeadline;
@ApiModelProperty("奖励比例")
private BigDecimal awardRate;
@ApiModelProperty("引荐订单")
private String referralOrderNo;
@ApiModelProperty("删除标志0代表存在 2代表删除")
private String delFlag;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,165 @@
package com.sczx.order.thirdpart.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 运营商表
* </p>
*
* @author zhangli
* @since 2025-08-23 23:21:15
*/
@ApiModel(value = "CompanyPO对象", description = "运营商表")
@Data
public class CompanyDTO {
@ApiModelProperty("公司ID")
private Integer id;
@ApiModelProperty("公司名称")
private String companyName;
@ApiModelProperty("联系人姓名")
private String contactName;
@ApiModelProperty("联系电话")
private String phone;
@ApiModelProperty("公司地址")
private String address;
@ApiModelProperty("账户余额")
private BigDecimal balance;
@ApiModelProperty("押金/保证金金额")
private BigDecimal deposit;
@ApiModelProperty("公司类型(用数字表示的分类)")
private Integer type;
@ApiModelProperty("是否已删除")
private Boolean isDelete;
@ApiModelProperty("是否允许拆分账单")
private Boolean allowSplitBill;
@ApiModelProperty("最大百分比")
private BigDecimal maxPercentage;
@ApiModelProperty("是否可新增套餐")
private String isAddRules;
@ApiModelProperty("租车平台分成比例")
private Integer sharingRatio;
@ApiModelProperty("微信支付模式")
private String wechatPayModel;
@ApiModelProperty("微信收款商户号")
private String wechatReceivingAccount;
@ApiModelProperty("微信收款密钥")
private String wechatKey;
@ApiModelProperty("计费模式")
private Integer chargeMode;
@ApiModelProperty("计费参数")
private BigDecimal chargeParam;
@ApiModelProperty("是否允许修改")
private Boolean allowChange;
@ApiModelProperty("渠道/通路ID")
private Integer channelId;
@ApiModelProperty("运营商管理城市")
private String citys;
@ApiModelProperty("运营商管理城市")
private String cityName;
@ApiModelProperty("支付宝支付模式")
private Integer aliPayModel;
@ApiModelProperty("支付宝收款商户号")
private String aliReceivingAccount;
@ApiModelProperty("支付宝收款密钥")
private String aliKey;
@ApiModelProperty("服务费收费订单类型")
private String serviceOrderType;
@ApiModelProperty("分账订单类型")
private String splitOrderType;
@ApiModelProperty("微信公共平台余额")
private BigDecimal wechatBalance;
@ApiModelProperty("支付宝公共平台余额")
private BigDecimal alipayBalance;
@ApiModelProperty("邀请奖励模式")
private Integer inviteRewardMode;
@ApiModelProperty("邀请奖励参数")
private BigDecimal inviteRewardParam;
@ApiModelProperty("奖励方式")
private Integer rewardType;
@ApiModelProperty("奖励参数")
private BigDecimal rewardParam;
@ApiModelProperty("是否预约")
private Boolean isReservation;
@ApiModelProperty("预约时长")
private Integer reservationDuration;
@ApiModelProperty("预约次数")
private Integer reservationNumber;
@ApiModelProperty("部门状态0正常 1停用")
private String status;
@ApiModelProperty("删除标志0代表存在 2代表删除")
private String delFlag;
@ApiModelProperty("创建者")
private String createBy;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("更新者")
private String updateBy;
@ApiModelProperty("更新时间")
private LocalDateTime updateTime;
private String extend1;
private String extend2;
private String extend3;
private String extend4;
private String extend5;
@ApiModelProperty("充电平台运营商ID")
private Long bOpId;
}

View File

@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "CompanyStoreDTO对象", description = "门店信息")
public class CompanyStoreDTO {
@ -55,4 +57,12 @@ public class CompanyStoreDTO {
@ApiModelProperty("门店编号")
private String storeNumber;
@ApiModelProperty("租车分成比例")
private BigDecimal zucheRatio;
@ApiModelProperty("租电分成比例")
private BigDecimal zudianRatio;
@ApiModelProperty("以租代售分成比例")
private BigDecimal daishouRatio;
}

View File

@ -1,28 +1,35 @@
package com.sczx.order.thirdpart.facade;
import com.sczx.order.common.Result;
import com.sczx.order.thirdpart.dto.CompanyDTO;
import com.sczx.order.thirdpart.dto.CompanyStoreDTO;
import com.sczx.order.thirdpart.dto.SysConfigDTO;
import com.sczx.order.thirdpart.dto.SysDictDataDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "sczx-store", url = "${sczx-store.ribbon.listOfServers:}")
public interface StoreFacade {
@RequestMapping("/pub/getStoreById")
@GetMapping("/pub/getStoreById")
Result<CompanyStoreDTO> getStoreById(@RequestParam(name = "storeId") Integer storeId);
@GetMapping("/pub/getCompanyById")
Result<CompanyDTO> getCompanyById(@RequestParam(name = "companyId") Integer companyId);
@GetMapping("/sys/getDictDataByDicTypeAndValue")
Result<SysDictDataDTO> getDictDataByDicTypeAndValue(@RequestParam(name = "dicType") String dicType, @RequestParam(name = "dicValue") String dicValue);
@PostMapping("/listConfigByConfigKey")
@PostMapping("/sys/listConfigByConfigKey")
Result<List<SysConfigDTO>> listConfigByConfigKey(@RequestBody List<String> configKeys);
@GetMapping("/getConfigByConfigKey")
@GetMapping("/sys/getConfigByConfigKey")
Result<SysConfigDTO> getConfigByConfigKey(@RequestParam(name = "configKey") String configKey);
}

View File

@ -0,0 +1,14 @@
package com.sczx.order.thirdpart.facade;
import com.sczx.order.common.Result;
import com.sczx.order.thirdpart.dto.BaseUserReferralDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "sczx-user", url = "${sczx-user.ribbon.listOfServers:}")
public interface UserFacade {
@GetMapping("/referral/getUserReferralByUserId")
Result<BaseUserReferralDTO> getUserReferralByUserId(@RequestParam("userId") Long userId);
}

View File

@ -2,6 +2,7 @@ package com.sczx.order.thirdpart.integration;
import com.sczx.order.common.Result;
import com.sczx.order.exception.InnerException;
import com.sczx.order.thirdpart.dto.CompanyDTO;
import com.sczx.order.thirdpart.dto.CompanyStoreDTO;
import com.sczx.order.thirdpart.dto.SysConfigDTO;
import com.sczx.order.thirdpart.dto.SysDictDataDTO;
@ -32,6 +33,19 @@ public class StoreInteg {
return null;
}
public CompanyDTO getCompanyById(Integer companyId){
try{
Result<CompanyDTO> result = storeFacade.getCompanyById(companyId);
if(result.isSuccess()){
return result.getData();
}
} catch (Exception e){
log.error("根据运营商id获取运营商信息失败",e);
throw new InnerException("根据运营商id获取运营商信息失败");
}
return null;
}
public SysDictDataDTO getDictDataByDicTypeAndValue(String dicType, String dicValue){
try{
Result<SysDictDataDTO> result = storeFacade.getDictDataByDicTypeAndValue(dicType, dicValue);

View File

@ -0,0 +1,30 @@
package com.sczx.order.thirdpart.integration;
import com.sczx.order.common.Result;
import com.sczx.order.exception.InnerException;
import com.sczx.order.thirdpart.dto.BaseUserReferralDTO;
import com.sczx.order.thirdpart.facade.UserFacade;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class UserInteg {
@Autowired
private UserFacade userFacade;
public BaseUserReferralDTO getUserReferralByUserId(Long userId) {
try{
Result<BaseUserReferralDTO> result = userFacade.getUserReferralByUserId(userId);
if(result.isSuccess()){
return result.getData();
}
} catch (Exception e){
log.error("获取用户推荐信息失败",e);
throw new InnerException("获取用户推荐信息失败");
}
return null;
}
}

View File

@ -8,4 +8,8 @@ sczx-car:
sczx-singlepay:
ribbon:
listOfServers: http://115.190.8.52:8019
listOfServers: http://115.190.8.52:8019
sczx-user:
ribbon:
listOfServers: http://115.190.8.52:8081