This commit is contained in:
邱贞招 2024-10-16 16:13:46 +08:00
parent 79ed366be9
commit 10942e6f1d
29 changed files with 439 additions and 70 deletions

View File

@ -2,11 +2,14 @@ package com.ruoyi.web.controller.app;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AsArticleClassify;
import com.ruoyi.common.core.domain.entity.RlUser;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.EtArticle;
import com.ruoyi.system.domain.RlFunction;
import com.ruoyi.system.domain.agent.RlAgent;
@ -66,6 +69,9 @@ public class AppController extends BaseController
@Autowired
private IRlArticleClassifyService asArticleClassifyService;
@Resource
private IRlUserService userService;
/**
* 查询城市列表
*/
@ -356,4 +362,16 @@ public class AppController extends BaseController
return success(asArticleClassifies);
}
/**
* 修改用户类型
*/
@PostMapping("/changeUserType")
public AjaxResult changeUserType(Long userId, String userType)
{
RlUser user = new RlUser();
user.setUserId(userId);
user.setUserType(userType);
return toAjax(userService.updateUser(user));
}
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.web.controller.appAgent;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Log;
@ -11,6 +12,7 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.domain.accessory.RlAccessory;
import com.ruoyi.system.domain.agent.RlAgentVO;
import com.ruoyi.system.domain.device.RlDeviceQuery;
import com.ruoyi.system.domain.device.RlDeviceVO;
import com.ruoyi.system.domain.model.RlModel;
@ -98,7 +100,11 @@ public class AppAgentController extends BaseController
@GetMapping("/orderList")
public AjaxResult orderList(RlOrderQuery order)
{
order.setMerchantId(getUserId());
RlAgentVO rlAgentVO = rlAgentService.selectRlAgentByUserId(getUserId());
if(ObjectUtil.isNull(rlAgentVO)){
throw new ServiceException("根据userid【"+getUserId()+"】代理商【"+rlAgentVO+"】不存在");
}
order.setAgentId(rlAgentVO.getAgentId());
logger.info("订单列表请求order=【"+JSON.toJSONString(order)+"");
authorityVerify();
List<RlOrderVO> rlOrderVOS = orderService.selectRlOrderList(order);
@ -136,6 +142,9 @@ public class AppAgentController extends BaseController
private void addVerify(RlModelQuery model) {
if(model.getAgentId() == null){
RlUserExt rlUserExt = rlUserExtService.selectRlUserExtByUserId(getUserId());
if(rlUserExt.getAgentId() == null){
throw new ServiceException("用户【"+getUserId()+"】未绑定代理商");
}
model.setAgentId(rlUserExt.getAgentId());
}
if(StrUtil.isBlank(model.getModel())){

View File

@ -130,7 +130,7 @@ public class AppAdminController extends BaseController
log.info("【微信登录/wxlogin】areaId参数【mobileCode={}】", mobileCode);
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.wxloing(mobileCode,jsCode);
String token = loginService.wxloing(mobileCode,jsCode,ServiceConstants.APPLET_TYPE_MERCHANT);
ajax.put(Constants.TOKEN, token);
return ajax;
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.web.controller.system;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.RlUser;
import com.ruoyi.common.core.domain.entity.SysMenu;
@ -130,7 +131,7 @@ public class SysLoginController
log.info("【微信登录/wxlogin】areaId参数【mobileCode={}】", mobileCode);
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.wxloing(mobileCode,jsCode);
String token = loginService.wxloing(mobileCode,jsCode, ServiceConstants.APPLET_TYPE_USER);
ajax.put(Constants.TOKEN, token);
return ajax;
}

View File

@ -193,8 +193,12 @@ geo:
# 高德地图key web服务 手续费
key: 834f1f029671d84272554528311ff0f1
wx:
appid: wx21a50f113c30d41a
appSecret: 58b0876e09e7783105b50336408cbd63
# 用户端
appid1: wx21a50f113c30d41a
appSecret1: 58b0876e09e7783105b50336408cbd63
# 商家端
appid2: wxc89e4a21f3907a53
appSecret2: de917328e1a0102749b3c87ecfc09942
et:
# 手续费 4/1000 千分之几
handlingCharge: 5.4

View File

@ -518,6 +518,20 @@ public class ServiceConstants {
public static final String PROFITSHARING_TYPE_PLATFORM = "2";
/**----------------------------分账类型start----------------------------*/
/**----------------------------分账状态start----------------------------*/
/**
* 分账状态: 0-未出账
*/
public static final String DIVIDEND_STATUS_NOT_SETTLED = "0";
/**
* 分账状态: 1-已分成
*/
public static final String DIVIDEND_STATUS_SETTLED = "1";
/**----------------------------分账状态end----------------------------*/
/**----------------------------退款类型start----------------------------*/
/** 还车类型:1-正常还车2-辅助还车
@ -765,7 +779,7 @@ public class ServiceConstants {
/**----------------------------用户类型start----------------------------*/
/**
* 00 - 系统用户
* 00 - 系统用户未分配
*/
public static final String USER_TYPE_SYSTEM = "00";
@ -789,6 +803,11 @@ public class ServiceConstants {
*/
public static final String USER_TYPE_DISPATCHER = "04";
/**
* 09 - 超级管理员
*/
public static final String USER_TYPE_ADMIN = "09";
/**----------------------------用户类型end----------------------------*/
/**----------------------------订单操作类型start----------------------------*/
@ -838,7 +857,22 @@ public class ServiceConstants {
*/
public static final String ORDER_OPERATION_DEDUCTION = "9";
/**----------------------------订单操作类型end----------------------------*/
/**----------------------------订单操作类型end----------------------------*/
/**----------------------------小程序类型start----------------------------*/
/**
* 小程序类型: 1-用户端
*/
public static final String APPLET_TYPE_USER = "1";
/**
* 小程序类型: 2-商家端
*/
public static final String APPLET_TYPE_MERCHANT = "2";
/**----------------------------小程序类型end----------------------------*/

View File

@ -7,11 +7,14 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.wx.AccessTokenUtil;
import com.ruoyi.common.utils.wx.vo.WeChatMiniAuthorizeVo;
import com.ruoyi.common.core.domain.entity.RlUser;
import com.ruoyi.system.domain.userExt.RlUserExt;
import com.ruoyi.system.service.IRlUserExtService;
import com.ruoyi.system.service.IRlUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@ -67,14 +70,20 @@ public class SysLoginService
@Autowired
private ISysConfigService configService;
@Resource
private IRlUserService eUserService;
@Autowired
private IRlUserExtService rlUserExtService;
@Value("${wx.appid}")
private String appId;
@Value("${wx.appid1}")
private String appId1;
@Value("${wx.appSecret}")
private String appSecret;
@Value("${wx.appSecret1}")
private String appSecret1;
@Value("${wx.appid2}")
private String appId2;
@Value("${wx.appSecret2}")
private String appSecret2;
@Value("${password}")
private String password;
@ -252,9 +261,18 @@ public class SysLoginService
/**
* 微信登录
*/
public String wxloing(String mobileCode,String jsCode) {
public String wxloing(String mobileCode,String jsCode,String appletType) {
String appId = null;
String appSecret = null ;
if(ServiceConstants.APPLET_TYPE_USER.equals(appletType)){
appId = appId1;
appSecret = appSecret1;
}else{
appId = appId2;
appSecret = appSecret2;
}
//根据jsCode换取openid
String openId = getOpenId(jsCode);
String openId = getOpenId(jsCode,appId,appSecret);
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
String phoneNumber = null;
RlUser user = null;
@ -275,7 +293,7 @@ public class SysLoginService
throw new ServiceException("凭证无效");
}
phoneNumber = wxMaPhoneNumberInfo.getPhoneNumber();
user = eUserService.selectUserByWxopenid(openId);
user = userService.selectUserByWxopenid(openId);
if(ObjectUtil.isEmpty(user)){
RlUser asUser = new RlUser();
asUser.setUserName(phoneNumber);
@ -285,11 +303,17 @@ public class SysLoginService
asUser.setPassword(SecurityUtils.encryptPassword(Constants.CUSTOM_LOGIN_WX));
asUser.setCreateTime(DateUtils.getNowDate());
asUser.setWxopenid(openId);
asUser.setUserType(ServiceConstants.USER_TYPE_SYSTEM);
log.info("【微信登录/wxlogin】用户不存在自动注册用户【{}】", JSON.toJSON(asUser));
int i = eUserService.insertUser(asUser);
int i = userService.insertUser(asUser);
if(i>0 && ServiceConstants.APPLET_TYPE_USER.equals(appletType)){
/** 创建用户扩展表内容,默认的用户角色是00未分配*/
int i1= insertUserExt(asUser);
}
user = asUser;
}else{
int i = eUserService.updateUser(user);
int i = userService.updateUser(user);
}
Authentication authentication = null; // 用户验证
try {
@ -315,6 +339,13 @@ public class SysLoginService
return tokenService.createToken(loginUser);
}
private int insertUserExt(RlUser asUser) {
RlUserExt rlUserExt = new RlUserExt();
rlUserExt.setUserId(asUser.getUserId());
rlUserExt.setExtId(asUser.getUserId());
return rlUserExtService.insertRlUserExt(rlUserExt);
}
/**
* 记录app登录信息
*
@ -326,7 +357,7 @@ public class SysLoginService
rlUser.setUserId(userId);
rlUser.setLoginIp(IpUtils.getIpAddr());
rlUser.setLoginDate(DateUtils.getNowDate());
eUserService.updateUserProfile(rlUser);
userService.updateUserProfile(rlUser);
}
/**
@ -369,7 +400,7 @@ public class SysLoginService
return null;
}
private String getOpenId(String jsCode) {
private String getOpenId(String jsCode,String appId, String appSecret) {
//根据jsCode换取openid
String url = StrUtil.format("https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code", appId, appSecret, jsCode);
String s = HttpUtils.sendGet(url);

View File

@ -46,9 +46,6 @@ public class UserDetailsServiceImpl implements UserDetailsService
@Autowired
private SysPermissionService permissionService;
@Value("${wx.appid}")
private String appId;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{

View File

@ -58,4 +58,12 @@ public class RlDividendDetail extends BaseEntity
@Excel(name = "分红比例")
private BigDecimal dividendProportion;
/** 退款金额 */
@Excel(name = "退款金额")
private BigDecimal refundAmount;
/** 状态 */
@Excel(name = "状态")
private String status;
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.domain.order;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.system.domain.RlFunction;
import com.ruoyi.system.domain.accessory.RlAccessoryVO;
import com.ruoyi.system.domain.deliveryOrder.RlDeliveryOrder;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetailVO;
import com.ruoyi.system.domain.orderOper.RlOrderOper;
import com.ruoyi.system.domain.rule.RlFeeRule;
@ -62,4 +63,9 @@ public class RlOrderVO extends RlOrder{
private BigDecimal refundableDeposit; // 押金
/** 配送单状态 */
private String deliveryStatus;
/** 配送单对象 */
private RlDeliveryOrder deliveryOrder;
}

View File

@ -29,6 +29,14 @@ public interface RlAgentMapper
*/
public RlAgentVO selectRlAgentByCityId(Long cityId);
/**
* 根据用户id查询代理商
*
* @param userId 用户id
* @return 代理商
*/
public RlAgentVO selectRlAgentByUserId(Long userId);
/**
* 查询代理商列表
*

View File

@ -99,7 +99,7 @@ public interface RlOrderMapper
/**
* 根据sn查询正在进行中的订单
*/
List<RlOrderVO> getInProgressOrder(@Param("sn") String sn, @Param("userId") Long userId);
List<RlOrderVO> getInProgressOrder(String sn);
// /**
// * 扫码绑定车辆

View File

@ -29,6 +29,14 @@ public interface IRlAgentService
*/
public RlAgentVO selectRlAgentByCityId(Long cityId);
/**
* 根据用户id查询代理商
*
* @param userId 用户id
* @return 代理商
*/
public RlAgentVO selectRlAgentByUserId(Long userId);
/**
* 查询代理商列表
*

View File

@ -21,6 +21,14 @@ public interface IRlDeliveryOrderService
*/
public RlDeliveryOrder selectRlDeliveryOrderByDeliveryId(Long deliveryId);
/**
* 查询配送工单
*
* @param orderNo 订单号
* @return 配送工单
*/
public RlDeliveryOrder selectRlDeliveryOrderByOrderNo(String orderNo);
/**
* 查询配送工单列表
*

View File

@ -2,7 +2,9 @@ package com.ruoyi.system.service;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetail;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetailVO;
import com.ruoyi.system.domain.order.RlOrder;
import java.math.BigDecimal;
import java.util.List;
/**
@ -60,4 +62,31 @@ public interface IRlDividendDetailService
* @return 结果
*/
public int deleteRlDividendDetailById(Long id);
/**
* 记录分成比例
*
* @param originalOrder 原始订单对象
* @param userType 用户类型商户代理商
* @return 结果
*/
public int calculationDividend(RlOrder originalOrder,String userType);
/**
* 计算分成金额
*
* @param rlDividendDetails 分成明细列表
* @param totalDividendAmount 分账总金额
* @return 结果
*/
public int calculationAmount(List<RlDividendDetailVO> rlDividendDetails, BigDecimal totalDividendAmount);
/**
* 更新退款金额
*
* @param id 分成明细id
* @param userRefundAmount 用户退款金额
* @return 结果
*/
public int updateRefundAmount(Long id, BigDecimal userRefundAmount);
}

View File

@ -4,7 +4,6 @@ import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.RlUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.wx.domain.NotifyEventType;
import com.ruoyi.common.utils.DateUtils;
@ -13,9 +12,9 @@ import com.ruoyi.system.domain.EtCallbackLog;
import com.ruoyi.system.domain.channel.ChannelVO;
import com.ruoyi.system.domain.deliveryOrder.RlDeliveryOrder;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetail;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetailVO;
import com.ruoyi.system.domain.order.RlOrder;
import com.ruoyi.system.domain.refund.RlRefund;
import com.ruoyi.system.domain.userExt.RlUserExt;
import com.ruoyi.system.mapper.EtCallbackLogMapper;
import com.ruoyi.system.service.*;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
@ -36,7 +35,7 @@ import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -85,6 +84,9 @@ public class CallbackServiceImpl implements CallbackService {
@Resource
private IRlAgentService agentService;
@Autowired
private IRlOrderOperService orderOperService;
/**
* 微信支付回调
@ -172,40 +174,46 @@ public class CallbackServiceImpl implements CallbackService {
logger.error("【微信支付回调】更新订单信息失败");
throw new ServiceException("【微信支付回调】更新订单信息失败");
}
/** 计算分成 所有合伙人的分成明细*/
calculationDividend(originalOrder);
/** 计算分成金额更新分成状态 */
BigDecimal totalDividendAmount = originalOrder.getLeaseFee().add(originalOrder.getOverdueFee());
RlDividendDetail rlDividendDetail = new RlDividendDetail();
rlDividendDetail.setOrderNo(originalOrder.getOrderNo());
List<RlDividendDetailVO> rlDividendDetailVOS = dividendDetailService.selectRlDividendDetailList(rlDividendDetail);
dividendDetailService.calculationAmount(rlDividendDetailVOS,totalDividendAmount);
// 批量生成账变记录
generateChangeBalance(rlDividendDetailVOS,originalOrder);
/** 记录订单履历 */
if(orderOperService.recordOrderHistory(originalOrder.getOrderNo(),ServiceConstants.ORDER_OPERATION_PAY,
originalOrder.getStatus(),updateOrder.getStatus(),BigDecimal.ZERO,originalOrder.getPayFee(),originalOrder.getUserId(),originalOrder.getPhone(),"订单支付:已支付 "+originalOrder.getPayFee()+"")){
throw new ServiceException("【订单履历-支付】更新订单信息失败");
}
logger.info("=================【微信支付回调】全部结束!!!!!==================");
return Boolean.TRUE;
});
if(!execute)throw new ServiceException("微信支付回调失败");
}
private void calculationDividend(RlOrder originalOrder) {
RlUserExt rlUserExt = userExtService.selectRlUserExtByUserId(originalOrder.getMerchantId());
RlUser rlUser = userService.selectUserById(rlUserExt.getUserId());
RlDividendDetail rlDividendDetail = new RlDividendDetail();
rlDividendDetail.setAgentId(originalOrder.getAgentId());
rlDividendDetail.setPartnerId(rlUserExt.getUserId());
rlDividendDetail.setOrderNo(originalOrder.getOrderNo());
rlDividendDetail.setTotalAmount(originalOrder.getPayFee());
BigDecimal needDividendAmount = originalOrder.getLeaseFee().add(originalOrder.getOverdueFee());//租赁费和逾期费进行分成
logger.info("【微信支付回调】租赁费和逾期费进行分成============"+needDividendAmount);
// 保留两位小数点
BigDecimal dividendAmount = rlUserExt.getDividendProportion().multiply(needDividendAmount)
.setScale(2, RoundingMode.HALF_UP);
logger.info("【微信支付回调】计算出来的分成金额===分成人{}========="+needDividendAmount,rlUserExt.getUserId());
rlDividendDetail.setDividendAmount(dividendAmount);
rlDividendDetail.setDividendProportion(rlUserExt.getDividendProportion());
rlDividendDetail.setCreateTime(DateUtils.getNowDate());
rlDividendDetail.setPartnerName(rlUser.getUserName());
rlDividendDetail.setPartnerPhone(rlUser.getPhonenumber());
rlDividendDetail.setPartnerType(rlUser.getUserType());
int i = dividendDetailService.insertRlDividendDetail(rlDividendDetail);
if(i>0){
logger.info("=================【微信支付回调】计算合作人分成成功==================");
private void generateChangeBalance(List<RlDividendDetailVO> rlDividendDetailVOS, RlOrder originalOrder) {
for(RlDividendDetailVO dividendDetail:rlDividendDetailVOS){
String busType;
if(originalOrder.getType().equals(ServiceConstants.ORDER_TYPE_LEASE)){
busType = ServiceConstants.RIDE_ORDER;
}else{
busType = ServiceConstants.RENEW_ORDER;
}
// 用户生成账变
int i = changeBalanceService.generateChanggeBalance(originalOrder.getOrderNo(), originalOrder.getOutTradeNo(), ServiceConstants.FLOW_TYPE_INCOME,
busType, dividendDetail.getDividendAmount(), dividendDetail.getPartnerId(), dividendDetail.getPartnerName(), dividendDetail.getPartnerPhone());
if(i==0){
throw new ServiceException("【微信支付回调】用户【"+dividendDetail.getPartnerName()+"】生成账变失败");
}
}
}
// private List<RlUserVO> getPartnerList(Long merchantId) {
// RlUserQuery rlUserQuery = new RlUserQuery();
// String[] typeList = {"02","03"};

View File

@ -78,6 +78,14 @@ public class RlAgentServiceImpl implements IRlAgentService
return rlAgentVO;
}
@Override
public RlAgentVO selectRlAgentByUserId(Long userId) {
RlAgentVO rlAgentVO = rlAgentMapper.selectRlAgentByUserId(userId);
if(ObjectUtil.isNull(rlAgentVO)){
throw new RuntimeException("代理商不存在");
}
return rlAgentVO;
}
/**

View File

@ -62,6 +62,17 @@ public class RlDeliveryOrderServiceImpl implements IRlDeliveryOrderService
return rlDeliveryOrderMapper.selectRlDeliveryOrderByDeliveryId(deliveryId);
}
/**
* 根据订单号查询配送工单
*
* @param orderNo 订单号
* @return 配送工单
*/
@Override
public RlDeliveryOrder selectRlDeliveryOrderByOrderNo(String orderNo) {
return rlDeliveryOrderMapper.selectRlDeliveryOrderByOrderNo(orderNo);
}
/**
* 查询配送工单列表
*

View File

@ -118,6 +118,9 @@ public class RlDeviceServiceImpl extends ServiceImpl<RlDeviceMapper, RlDevice> i
@Autowired
private IRlOnlineLogService eOnlineLogService;
@Autowired
private IRlOrderOperService orderOperService;
//
// @Autowired
// private IEtRefundService etRefundService;
@ -1372,7 +1375,7 @@ public class RlDeviceServiceImpl extends ServiceImpl<RlDeviceMapper, RlDevice> i
throw new ServiceException("远程关锁失败");
}
/** 8.判断是否在店铺附近 先根据手机定位判断,再跟进车辆定位判断,如果两个都不在,则提示不在附近*/
/** 2.1.判断是否在店铺附近 先根据手机定位判断,再跟进车辆定位判断,如果两个都不在,则提示不在附近*/
boolean nearStore = isNearStore(orderQuery, device);
if(!nearStore){
throw new ServiceException("不在店铺附近,请前往店铺还车");
@ -1410,6 +1413,11 @@ public class RlDeviceServiceImpl extends ServiceImpl<RlDeviceMapper, RlDevice> i
if(i==0){
throw new ServiceException("更新订单状态失败");
}
/** 7. 记录订单履历*/
if(orderOperService.recordOrderHistory(orderNo,ServiceConstants.ORDER_OPERATION_RETURN_END,
order.getStatus(),updateOrder.getStatus(),order.getPayFee(),order.getPayFee(),order.getUserId(),order.getPhone(),"已还车")){
throw new ServiceException("【记录订单履历失败】");
}
log.info("还车成功");
return Boolean.TRUE;
}else{

View File

@ -1,13 +1,24 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.RlUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.agent.RlAgentVO;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetail;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetailVO;
import com.ruoyi.system.domain.order.RlOrder;
import com.ruoyi.system.domain.userExt.RlUserExt;
import com.ruoyi.system.mapper.RlDividendDetailMapper;
import com.ruoyi.system.service.IRlDividendDetailService;
import com.ruoyi.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
/**
@ -16,12 +27,25 @@ import java.util.List;
* @author qzz
* @date 2024-10-10
*/
@Slf4j
@Service
public class RlDividendDetailServiceImpl implements IRlDividendDetailService
{
@Autowired
@Resource
private RlDividendDetailMapper rlDividendDetailMapper;
@Resource
private IRlUserExtService userExtService;
@Autowired
private IRlUserService userService;
@Autowired
private IRlAgentService agentService;
@Autowired
private IRlChangeBalanceService changeBalanceService;
/**
* 查询分账明细
*
@ -94,4 +118,82 @@ public class RlDividendDetailServiceImpl implements IRlDividendDetailService
{
return rlDividendDetailMapper.deleteRlDividendDetailById(id);
}
/**
* 计算分账金额
* @param originalOrder
* @return
*/
@Override
public int calculationDividend(RlOrder originalOrder,String userType) {
RlUserExt rlUserExt;
RlUser rlUser ;
if(userType.equals(ServiceConstants.USER_TYPE_MERCHANT)){
rlUserExt = userExtService.selectRlUserExtByUserId(originalOrder.getMerchantId());
rlUser = userService.selectUserById(rlUserExt.getUserId());
}else if(userType.equals(ServiceConstants.USER_TYPE_AGENT)){
RlAgentVO rlAgentVO = agentService.selectRlAgentByAgentId(originalOrder.getAgentId());
rlUserExt = userExtService.selectRlUserExtByUserId(rlAgentVO.getUserid());
rlUser = userService.selectUserById(rlUserExt.getUserId());
}else{
throw new ServiceException("用户类型有误");
}
RlDividendDetail rlDividendDetail = new RlDividendDetail();
rlDividendDetail.setAgentId(originalOrder.getAgentId());
rlDividendDetail.setPartnerId(rlUserExt.getUserId());
rlDividendDetail.setOrderNo(originalOrder.getOrderNo());
rlDividendDetail.setTotalAmount(originalOrder.getPayFee());
rlDividendDetail.setDividendProportion(rlUserExt.getDividendProportion());
rlDividendDetail.setCreateTime(DateUtils.getNowDate());
rlDividendDetail.setPartnerName(rlUser.getUserName());
rlDividendDetail.setPartnerPhone(rlUser.getPhonenumber());
rlDividendDetail.setPartnerType(rlUser.getUserType());
rlDividendDetail.setStatus(ServiceConstants.DIVIDEND_STATUS_NOT_SETTLED);
int i = insertRlDividendDetail(rlDividendDetail);
if(i>0){
log.info("=================【微信支付回调】计算合作人分成成功==================");
}
return i;
}
/**
* 计算分账金额
* @param rlDividendDetails
* @return
*/
@Override
public int calculationAmount(List<RlDividendDetailVO> rlDividendDetails,BigDecimal totalDividendAmount) {
log.info("【计算分账金额】计算分账金额开始============");
for(RlDividendDetailVO dividendDetail:rlDividendDetails){
log.info("【计算分账金额】租赁费和逾期费进行分成============"+totalDividendAmount);
RlUserExt rlUserExt = userExtService.selectRlUserExtByUserId(dividendDetail.getPartnerId());
if(ObjectUtil.isNull(rlUserExt)){
throw new ServiceException("用户【"+dividendDetail.getPartnerName()+"】不存在");
}
// 保留两位小数点
BigDecimal dividendAmount = rlUserExt.getDividendProportion().multiply(totalDividendAmount)
.setScale(2, RoundingMode.HALF_UP);
dividendDetail.setDividendAmount(dividendAmount);
dividendDetail.setStatus(ServiceConstants.DIVIDEND_STATUS_SETTLED);
updateRlDividendDetail(dividendDetail);
}
return 1;
}
/**
* 更新退款金额
*
* @param id 分成明细id
* @param userRefundAmount 用户退款金额
* @return 结果
*/
@Override
public int updateRefundAmount(Long id, BigDecimal userRefundAmount) {
RlDividendDetail rlDividendDetail = new RlDividendDetail();
rlDividendDetail.setRefundAmount(userRefundAmount);
rlDividendDetail.setId(id);
return rlDividendDetailMapper.updateRlDividendDetail(rlDividendDetail);
}
}

View File

@ -108,7 +108,7 @@ public class RlOrderOperServiceImpl implements IRlOrderOperService
rlOrderOper.setOperPhone(phone);
rlOrderOper.setCreateTime(DateUtils.getNowDate());
rlOrderOper.setDetails(detail);
return false;
return rlOrderOperMapper.insertRlOrderOper(rlOrderOper) > 0;
}

View File

@ -15,6 +15,8 @@ import com.ruoyi.common.utils.wx.vo.PrepayResponseVO;
import com.ruoyi.system.domain.RlFunction;
import com.ruoyi.system.domain.accessory.RlAccessoryVO;
import com.ruoyi.system.domain.agent.RlAgent;
import com.ruoyi.system.domain.agent.RlAgentVO;
import com.ruoyi.system.domain.deliveryOrder.RlDeliveryOrder;
import com.ruoyi.system.domain.device.RlDevice;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetail;
import com.ruoyi.system.domain.dividendDetail.RlDividendDetailVO;
@ -113,6 +115,12 @@ public class RlOrderServiceImpl implements IRlOrderService
@Autowired
private IRlChangeBalanceService changeBalanceService;
@Resource
private IRlDividendDetailService dividendDetailService;
@Autowired
private IRlDeliveryOrderService deliveryOrderService;
/**
* 查询订单
*
@ -191,6 +199,12 @@ public class RlOrderServiceImpl implements IRlOrderService
List<RlDividendDetailVO> rlDividendDetails = rlDividendDetailService.selectRlDividendDetailList(rlDividendDetail);
order.setRlDividendDetails(rlDividendDetails);
RlDeliveryOrder deliveryOrder = deliveryOrderService.selectRlDeliveryOrderByOrderNo(orderNo);
if(ObjectUtil.isNotNull(deliveryOrder)){
order.setDeliveryStatus(deliveryOrder.getStatus());
order.setDeliveryOrder(deliveryOrder);
}
/** 显示可退款金额 根据订单号查询可退款金额 refundableAmount*/
getRefundable(orderNo, order);
return order;
@ -356,16 +370,26 @@ public class RlOrderServiceImpl implements IRlOrderService
StoreVo storeVo = storeService.selectSmStoreById(order.getStoreId());
if(ObjectUtil.isNotNull(storeVo)){
order.setMerchantId(storeVo.getMerchantId());
order.setReturnAddress(storeVo.getAddress());
order.setReturnStoreId(storeVo.getStoreId());
}
/** 计算价格 */
onceMoreCalculatePrice(order);
order.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_PAID);
RlModelVO rlModelVO = modelService.selectEModelByModelId(order.getModelId());
if(ObjectUtil.isNotNull(rlModelVO)){
order.setModel(rlModelVO.getModel());
}
/** 记录分成比例,状态为未出账 */
int i1 = dividendDetailService.calculationDividend(order,ServiceConstants.USER_TYPE_MERCHANT);
if (i1 < 1) {
throw new RuntimeException("记录商户分成失败");
}
int i2 = dividendDetailService.calculationDividend(order,ServiceConstants.USER_TYPE_AGENT);
if (i2 < 1) {
throw new RuntimeException("记录代理商分成失败");
}
int i = orderMapper.insertRlOrder(order);
if (i < 1) {
throw new RuntimeException("下单失败");
@ -514,10 +538,12 @@ public class RlOrderServiceImpl implements IRlOrderService
}
RlOrder rlOrder = new RlOrder();
rlOrder.setOrderNo(orderNo);
rlOrder.setPaid(ServiceConstants.ORDER_PAY_STATUS_NON_PAYMENT);
rlOrder.setStatus(ServiceConstants.ORDER_STATUS_CANCE);
int i = orderMapper.updateRlOrderByOrderNo(rlOrder);
if(i>0){
/** 记录订单履历 */
orderOperService.recordOrderHistory(orderNo,ServiceConstants.ORDER_OPERATION_USER_CANCEL,
order.getStatus(),rlOrder.getStatus(),order.getPayFee(),order.getPayFee(),order.getUserId(),order.getPhone(),"取消订单");
return true;
}
return false;
@ -533,9 +559,9 @@ public class RlOrderServiceImpl implements IRlOrderService
rlOrder.setDeductionAmount(money);
int i = orderMapper.updateRlOrderByOrderNo(rlOrder);
/** 记录订单履历 */
RlOrderVO orde = orderMapper.selectRlOrderByOrderNo(orderNo);
RlOrderVO order = orderMapper.selectRlOrderByOrderNo(orderNo);
if(orderOperService.recordOrderHistory(orderNo,ServiceConstants.ORDER_OPERATION_DEDUCTION,
orde.getStatus(),orde.getStatus(),orde.getPayFee(),orde.getPayFee(),orde.getUserId(),orde.getPhone(),"车损扣款:扣款金额:"+money+",实际押金退款:"+orde.getDeposit()+"-"+money)){
order.getStatus(),order.getStatus(),order.getPayFee(),order.getPayFee(),order.getUserId(),order.getPhone(),"车损扣款:扣款金额:"+money+",实际押金退款:"+order.getDeposit()+"-"+money)){
throw new ServiceException("【改价】更新订单信息失败");
}
return i>0;
@ -563,6 +589,17 @@ public class RlOrderServiceImpl implements IRlOrderService
if(!ServiceConstants.ORDER_STATUS_ORDER_END.equals(order.getStatus())){
throw new ServiceException("订单状态异常,不能退款", HttpStatus.ERROR);
}
// /** 更新订单信息*/
// RlOrder updateOrder = new RlOrder();
// updateOrder.setOrderNo(orderNo);
// updateOrder.setRefundAmount(remainingDeposit);
// updateOrder.setStatus(ServiceConstants.ORDER_STATUS_REFUND);
// int i = orderMapper.updateRlOrderByOrderNo(updateOrder);
/** 记录订单履历*/
if(orderOperService.recordOrderHistory(orderNo,ServiceConstants.ORDER_OPERATION_RETURN_END,
order.getStatus(),order.getStatus(),order.getPayFee(),order.getPayFee(),order.getUserId(),order.getPhone(),"已退款:-"+remainingDeposit+"")){
throw new ServiceException("【记录订单履历失败】");
}
// 执行退还剩余押金操作
wxPayService.refund(order, "审核后退押金",remainingDeposit,order.getOutTradeNo());
return null;
@ -610,6 +647,10 @@ public class RlOrderServiceImpl implements IRlOrderService
refundDividendHandle(rlOrderVO, refundPercentage);
/** 4.记录退款表 创建退款对象*/
String outRefundNo = saveRefundObj(rlOrderVO, finalRefundAmount, dispatchFee, deliveryFee, leaseFee);
if(orderOperService.recordOrderHistory(rlOrderVO.getOrderNo(),ServiceConstants.ORDER_OPERATION_REFUND,
rlOrderVO.getStatus(),rlOrderVO.getStatus(),rlOrderVO.getPayFee(),rlOrderVO.getPayFee(),rlOrderVO.getUserId(),rlOrderVO.getPhone(),"已退款: "+finalRefundAmount+"")){
throw new ServiceException("【改价】更新订单信息失败");
}
/** 5. 发起退款 */
wxPayService.refund(rlOrderVO, "商家退款金额", finalRefundAmount,outRefundNo);
return Boolean.TRUE;
@ -648,8 +689,9 @@ public class RlOrderServiceImpl implements IRlOrderService
int i = changeBalanceService.generateChanggeBalance(rlOrderVO.getOrderNo(), rlOrderVO.getOutTradeNo(), ServiceConstants.FLOW_TYPE_DISBURSE,
ServiceConstants.ORDER_REFUND, userRefundAmount, rlUserExt.getUserId(), user.getUserName(), user.getPhonenumber());
if(i<=0)throw new ServiceException("用户【"+user.getPhonenumber()+"】新增账变失败");
/** todo 4.3 分成比例? */
/** todo 4.3 更新分成表中的退款金额 */
int i1 = rlDividendDetailService.updateRefundAmount(detail.getId(), userRefundAmount);
if(i1<=0)throw new ServiceException("【退款】更新分成表中的退款金额失败");
}
}
@ -753,8 +795,7 @@ public class RlOrderServiceImpl implements IRlOrderService
*/
@Override
public RlOrderVO getInProgressOrder(String sn) {
Long userId = SecurityUtils.getUserId();
List<RlOrderVO> orders = orderMapper.getInProgressOrder(sn,userId);
List<RlOrderVO> orders = orderMapper.getInProgressOrder(sn);
if(ObjectUtil.isNotNull(orders.size()) && orders.size() > 0){
return orders.get(0);
}

View File

@ -313,7 +313,6 @@ public class RlUserServiceImpl implements IRlUserService{
@Transactional
public int updateUser(RlUser user)
{
Long userId = user.getUserId();
return rlUserMapper.updateUser(user);
}

View File

@ -72,10 +72,10 @@ public class WxPayService implements IWxPayService {
private static final String PREPAY_LOCK = "prepay:";
@Value("${wx.appid}")
@Value("${wx.appid1}")
private String appId;
@Value("${wx.appSecret}")
@Value("${wx.appSecret1}")
private String appSecret;
@Override

View File

@ -476,11 +476,14 @@ public class StoreServiceImpl implements RlStoreService
/**
* 根据定位获取附近店铺列表
* 车型为空的过滤
* 距离太远的过滤
*/
@Override
public List<StoreVo> getStoreListByLocation(StoreQuery query) {
BigDecimal radiusFromQuery = query.getRadius();
double radiusInMeters = (radiusFromQuery != null) ? radiusFromQuery.doubleValue() : Double.parseDouble(sysConfigService.selectConfigByKey("nearby.store")) * 1000;
log.info("搜索附近【{}】米范围分润店铺", radiusInMeters);
// 根据定位获取附近方圆X公里的店铺列表
double userLon = Double.parseDouble(query.getPhoneLon());
double userLat = Double.parseDouble(query.getPhoneLat());
@ -490,6 +493,11 @@ public class StoreServiceImpl implements RlStoreService
List<StoreVo> nearbyStores = allStores.stream()
.map(store -> {
List<RlModelVO> list = modelService.selectEModelListByStoreId(store.getStoreId());
log.info("店铺【{}】的车型列表:{}", store.getStoreId(), list);
// 如果 list 为空或为 null直接返回 null
if (list == null || list.isEmpty()) {
return null;
}
store.setModels(list);
/** 日均 */
// 计算最低价格
@ -512,6 +520,8 @@ public class StoreServiceImpl implements RlStoreService
store.setDistance(formattedDistance); // 设置距离
return store; // 返回更新后的 store
})
.filter(Objects::nonNull) // 过滤掉为 null store 对象
.filter(store -> store.getRentalCar() > 0) // 过滤掉租赁车辆数量为 0 的店铺
.filter(store -> store.getDistance() <= radiusInMeters) // 过滤距离
.sorted(Comparator.comparingDouble(StoreVo::getDistance)) // 根据距离排序
.collect(Collectors.toList());

View File

@ -1,9 +1,11 @@
package com.ruoyi.system.task;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.order.RlOrder;
import com.ruoyi.system.domain.order.RlOrderQuery;
import com.ruoyi.system.domain.order.RlOrderVO;
import com.ruoyi.system.service.IRlOrderOperService;
import com.ruoyi.system.service.IRlOrderService;
import com.ruoyi.system.service.IWxPayService;
import lombok.extern.slf4j.Slf4j;
@ -32,6 +34,9 @@ public class RlTask {
@Resource
private IRlOrderService orderService;
@Autowired
private IRlOrderOperService orderOperService;
/**
@ -60,7 +65,13 @@ public class RlTask {
RlOrder rlOrder = new RlOrder();
rlOrder.setOrderId(orderVO.getOrderId());
rlOrder.setStatus(ServiceConstants.ORDER_STATUS_AUTO_CANCEL);
orderService.updateRlOrder(rlOrder);
int i = orderService.updateRlOrder(rlOrder);
if(i>0){
if(orderOperService.recordOrderHistory(orderVO.getOrderNo(),ServiceConstants.ORDER_OPERATION_SYSTEM_CANCEL,
orderVO.getStatus(),rlOrder.getStatus(),orderVO.getPayFee(),orderVO.getPayFee(),orderVO.getUserId(),orderVO.getPhone(),"超时系统自动取消")){
throw new ServiceException("【记录订单履历--超时系统自动取消失败】");
}
}
}
}
log.info("-------------------【定时任务】处理过期订单---结束----------------");

View File

@ -36,6 +36,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where a.city_id = #{cityId}
</select>
<select id="selectRlAgentByUserId" parameterType="Long" resultMap="RlAgentResult">
<include refid="selectRlAgentVo"/>
where a.userid = #{userid}
</select>
<insert id="insertRlAgent" parameterType="RlAgent" useGeneratedKeys="true" keyProperty="agentId">
insert into rl_agent
<trim prefix="(" suffix=")" suffixOverrides=",">

View File

@ -7,7 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="RlDividendDetailVO" id="RlDividendDetailResult" autoMapping="true" />
<sql id="selectRlDividendDetailVo">
select dd.id, dd.agent_id, a.name agentName, dd.partner_id, dd.partner_name, dd.partner_phone, dd.partner_type, dd.order_no,
select dd.id, dd.agent_id, a.name agentName, dd.partner_id, dd.partner_name, dd.partner_phone, dd.partner_type, dd.order_no,dd.status,dd.refund_amount,
dd.total_amount, dd.dividend_amount, dd.dividend_proportion, dd.create_time from rl_dividend_detail dd
left join rl_agent a on a.agent_id = dd.agent_id
</sql>
@ -45,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="dividendAmount != null">dividend_amount,</if>
<if test="dividendProportion != null">dividend_proportion,</if>
<if test="createTime != null">create_time,</if>
<if test="status != null">status,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="agentId != null">#{agentId},</if>
@ -57,6 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="dividendAmount != null">#{dividendAmount},</if>
<if test="dividendProportion != null">#{dividendProportion},</if>
<if test="createTime != null">#{createTime},</if>
<if test="status != null">#{status},</if>
</trim>
</insert>
@ -72,6 +74,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="totalAmount != null">total_amount = #{totalAmount},</if>
<if test="dividendAmount != null">dividend_amount = #{dividendAmount},</if>
<if test="dividendProportion != null">dividend_proportion = #{dividendProportion},</if>
<if test="refundAmount != null">refund_amount = #{refundAmount},</if>
<if test="createTime != null">create_time = #{createTime},</if>
</trim>
where id = #{id}

View File

@ -213,7 +213,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="getInProgressOrder" resultType="com.ruoyi.system.domain.order.RlOrderVO">
<include refid="selectRlOrderDetail"/>
where o.sn = #{sn} and o.status = 4 and o.user_id = #{userId}
where o.sn = #{sn} and o.status = 4
order by create_time desc
</select>
@ -281,6 +281,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="returnAddress != null">return_address,</if>
<if test="returnLon != null">return_lon,</if>
<if test="returnLat != null">return_lat,</if>
<if test="returnStoreId != null">return_store_id,</if>
<if test="autoCancelTime != null">auto_cancel_time,</if>
<if test="cost != null">cost,</if>
</trim>
@ -346,6 +347,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="returnAddress != null">#{returnAddress},</if>
<if test="returnLon != null">#{returnLon},</if>
<if test="returnLat != null">#{returnLat},</if>
<if test="returnStoreId != null">#{returnStoreId},</if>
<if test="autoCancelTime != null">#{autoCancelTime},</if>
<if test="cost != null">#{cost},</if>
</trim>