123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- package com.ylx.massage.service.impl;
- import cn.hutool.core.collection.CollectionUtil;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
- import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
- import com.baomidou.mybatisplus.core.toolkit.StringUtils;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.ylx.common.constant.MassageConstants;
- import com.ylx.common.core.domain.R;
- import com.ylx.common.exception.ServiceException;
- import com.ylx.massage.domain.*;
- import com.ylx.massage.domain.vo.CouponReceiveVo;
- import com.ylx.massage.enums.BillTypeEnum;
- import com.ylx.massage.enums.DiscountTypeEnum;
- import com.ylx.massage.enums.JsStatusEnum;
- import com.ylx.massage.enums.OrderStatusEnum;
- import com.ylx.massage.mapper.TOrderMapper;
- import com.ylx.massage.service.*;
- import com.ylx.massage.utils.DateTimeUtils;
- import com.ylx.massage.utils.MassageUtil;
- import com.ylx.massage.utils.OrderNumberGenerator;
- import org.apache.commons.compress.utils.Lists;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import javax.annotation.Resource;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.time.LocalDateTime;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * 订单表 服务实现类
- */
- @Service
- public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements TOrderService {
- @Resource
- private TOrderMapper orderMapper;
- @Resource
- private TWxUserService wxUserService;
- @Resource
- private TRechargeService rechargeService;
- @Resource
- private TXiangmuService xiangmuService;
- @Resource
- private OrderNumberGenerator generator;
- @Resource
- private TJsService jsService;
- @Resource
- private TAddressService addressService;
- @Resource
- private TConsumptionLogService consumptionLogService;
- @Resource
- private MassageUtil massageUtil;
- @Resource
- private CouponReceiveService couponReceiveService;
- // @Resource
- // private TInfoService infoService;
- public Boolean isFree(String jsId, BigDecimal distance) {
- TJs js = jsService.getById(jsId);
- Date date = new Date();
- //白天免车费(07.30-20.00)
- long current = Long.parseLong(DateTimeUtils.numTime(date));
- if (current >= MassageConstants.START_FREE && current <= MassageConstants.END_FREE) {
- if (js.getDaytimeMileage().compareTo(distance) >= 0) {
- //免车费
- return Boolean.TRUE;
- } else {
- return Boolean.FALSE;
- }
- } else {
- //夜间免车费(20.00-07.30)
- if (js.getNigthMileage().compareTo(distance) >= 0) {
- //免车费
- return Boolean.TRUE;
- } else {
- return Boolean.FALSE;
- }
- }
- }
- /**
- * 添加订单
- *
- * @param order
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public TOrder addOrder(TOrder order) {
- if (StringUtils.isBlank(order.getcJsId())) {
- throw new ServiceException("请选择技师");
- }
- if (order.getcGoods().isEmpty()) {
- throw new ServiceException("请选择项目");
- }
- //计算车费
- if (order.getDistance() != null) {
- //判断是否可以免车费
- if (!this.isFree(order.getcJsId(), order.getDistance())) {
- BigDecimal bigDecimal = massageUtil.calculateTaxiFare(order.getDistance());
- order.setFare(bigDecimal.setScale(MassageConstants.INTEGER_TWO, RoundingMode.HALF_UP));
- }
- }
- //优惠卷减免
- List<CouponReceiveVo> coupons = couponReceiveService.getByOpenId(order.getcOpenId());
- BigDecimal preferential = this.setCoupon(coupons);
- order.setPreferential(preferential);
- //订单价格
- List<TXiangmu> list = JSONObject.parseArray(order.getcGoods().toJSONString(), TXiangmu.class);
- BigDecimal sum = list.stream().map(TXiangmu::getSum).reduce(BigDecimal.ZERO, BigDecimal::add);
- order.setdTotalMoney(sum);
- //总价 = 订单 + 车费 - 优惠
- order.setTotalPrice(sum.add(Optional.ofNullable(order.getFare()).orElse(BigDecimal.ZERO)).subtract(preferential));
- if (order.getOrderType() == 2) {
- //升级订单 补差价
- TOrder partOrder = this.getByNo(order.getParentNo());
- order.setPriceDifference(order.getTotalPrice().subtract(partOrder.getTotalPrice()));
- }
- //获取用户默认地址
- TAddress address = addressService.getByOpenId(order.getcOpenId());
- if (address == null) {
- throw new ServiceException("请先添加地址");
- }
- order.setcAddress(address.getAddress());
- order.setcPhone(address.getPhone());
- order.setcName(address.getUserName());
- order.setAtlasAdd(address.getAtlasAdd());
- order.setOrderNo(generator.generateNextOrderNumber(OrderNumberGenerator.KEY_PREFIX_ORDER));
- order.setnStatus(OrderStatusEnum.WAIT_PAY.getCode());
- order.setDtCreateTime(LocalDateTime.now());
- save(order);
- return order;
- }
- private BigDecimal setCoupon(List<CouponReceiveVo> coupons) {
- //过滤过期的优惠券
- coupons = coupons.stream().filter(coupon -> coupon.getExpirationTime().after(new Date())).collect(Collectors.toList());
- //无门槛优惠券
- List<CouponReceiveVo> collect = coupons.stream().filter(coupon -> coupon.getDiscountType().equals(DiscountTypeEnum.NO_THRESHOLD.getCode())).collect(Collectors.toList());
- //删除优惠卷
- couponReceiveService.removeCoupons(collect);
- //计算优惠金额
- return collect.stream().map(CouponReceiveVo::getDiscountValue).reduce(BigDecimal.ZERO, BigDecimal::add);
- }
- @Override
- public void payNotifyOrder(String outTradeNo) {
- TOrder orderNew = this.getByNo(outTradeNo);
- TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
- orderPayManage(user, orderNew);
- }
- /**
- * 支付订单
- *
- * @param order
- */
- @Override
- public R payOrder(TOrder order) throws Exception {
- // 根据orderid查询订单信息
- TOrder orderNew = getById(order.getcId());
- if (!orderNew.getnStatus().equals(OrderStatusEnum.WAIT_PAY.getCode())) {
- throw new ServiceException("该订单已经支付或者超时被取消");
- }
- if (StringUtils.isBlank(orderNew.getParentNo())) {
- TJs js = jsService.getById(orderNew.getcJsId());
- if (null == js || js.getnStatus().equals(JsStatusEnum.JS_SERVICE.getCode())) {
- throw new ServiceException("该技师已在服务中请重新下单");
- }
- }
- //判断支付方式
- if (order.getPayType().equals(MassageConstants.INTEGER_ONE)) {
- //微信支付
- R resp = rechargeService.getPay(orderNew.getOrderNo(), orderNew.getTotalPrice(), orderNew.getcOpenId(), BillTypeEnum.WX_PAY.getInfo(),BillTypeEnum.WX_PAY.getCode().toString());
- return resp;
- }
- // 从对应账户扣款
- TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
- if (null == user) {
- throw new ServiceException("用户不存在");
- }
- if (user.getdBalance().compareTo(orderNew.getTotalPrice()) < MassageConstants.INTEGER_ZERO) {
- throw new ServiceException("账户金额不够请充值");
- } else {
- orderPayManage(user, orderNew);
- return R.ok();
- }
- }
- @Transactional(rollbackFor = Exception.class)
- public void orderPayManage(TWxUser user, TOrder orderNew) {
- // 更新用户金额 及下单此时
- TWxUser paramUser = new TWxUser();
- paramUser.setcOpenid(user.getcOpenid());
- if (!orderNew.getPayType().equals(MassageConstants.INTEGER_ONE)){
- paramUser.setdBalance(user.getdBalance().subtract(orderNew.getTotalPrice()));
- }
- paramUser.setdMoney(user.getdMoney().add(orderNew.getTotalPrice()));
- paramUser.setnNum(user.getnNum() + MassageConstants.INTEGER_ZERO);
- paramUser.setId(user.getId());
- wxUserService.updateById(paramUser);
- //增加消费记录
- TConsumptionLog tConsumptionLog = new TConsumptionLog();
- tConsumptionLog.setAmount(orderNew.getTotalPrice().negate());
- tConsumptionLog.setBillNo(orderNew.getOrderNo());
- tConsumptionLog.setOpenId(orderNew.getcOpenId());
- if (!orderNew.getPayType().equals(MassageConstants.INTEGER_ONE)){
- tConsumptionLog.setBillType(BillTypeEnum.BALANCE_PAYMENT.getCode());
- tConsumptionLog.setNote("余额支付");
- }else{
- tConsumptionLog.setBillType(BillTypeEnum.WX_PAY.getCode());
- tConsumptionLog.setNote("微信支付");
- }
- consumptionLogService.save(tConsumptionLog);
- // 更新项目数据
- JSONArray objects = orderNew.getcGoods();
- objects.forEach(item -> {
- UpdateWrapper<TXiangmu> wrapper = new UpdateWrapper<>();
- // 获取参数
- wrapper.lambda().eq(TXiangmu::getcId, ((JSONObject) item).getString("cId"));
- // 设置数量
- wrapper.setSql(" n_sale_number = n_sale_number + " + ((JSONObject) item).getInteger("number"));
- xiangmuService.update(wrapper);
- });
- TOrder orderParam = new TOrder();
- orderParam.setcId(orderNew.getcId());
- orderParam.setnStatus(OrderStatusEnum.WAIT_JD.getCode());
- //加钟的订单支付完直接服务中
- if (StringUtils.isNotBlank(orderNew.getParentNo())) {
- orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
- }
- // orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
- //更新及技师状态
- updateJs(orderNew);
- updateById(orderParam);
- }
- /**
- * 拒绝订单
- *
- * @param order
- */
- @Override
- public Boolean jujue(TOrder order) {
- TOrder orderNew = getById(order.getcId());
- TWxUser user = wxUserService.getById(orderNew.getcOpenId());
- // 更新用户金额 及下单此时
- TWxUser paramUser = new TWxUser();
- paramUser.setcOpenid(user.getcOpenid());
- // 金额归还对应账户
- paramUser.setdBalance(user.getdBalance().add(orderNew.getdTotalMoney()));
- // 消费金额对应减少
- paramUser.setdMoney(user.getdMoney().subtract(orderNew.getdTotalMoney()));
- // 下单次数减一
- paramUser.setnNum(user.getnNum() - MassageConstants.INTEGER_ONE);
- wxUserService.updateById(paramUser);
- // 更新项目数据
- JSONArray objects = orderNew.getcGoods();
- objects.forEach(item -> {
- UpdateWrapper<TXiangmu> wrapper = new UpdateWrapper<>();
- // 获取参数
- wrapper.lambda().eq(TXiangmu::getcId, ((JSONObject) item).getString("cId"));
- // 设置数量
- wrapper.setSql(" n_sale_number = n_sale_number - " + ((JSONObject) item).getInteger("number"));
- xiangmuService.update(wrapper);
- });
- TOrder orderParam = new TOrder();
- orderParam.setcId(orderNew.getcId());
- orderParam.setnStatus(OrderStatusEnum.REFUSE.getCode());
- return updateById(orderParam);
- }
- /**
- * 确认服务完成
- *
- * @param order
- * @return
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean confirm(TOrder order) {
- // 获取订单信息
- TOrder orderNew = getById(order);
- // 更新技师信息
- TJs jsParam = new TJs();
- jsParam.setId(orderNew.getcJsId());
- jsParam.setnStatus(JsStatusEnum.JS_SERVICEABLE.getCode());
- // 更新技师状态
- jsService.updateById(jsParam);
- // 更新技师钱包金额
- TJs jsById = jsService.getById(orderNew.getcJsId());
- // 获取技师抽成
- BigDecimal multiply = orderNew.getdTotalMoney().multiply(new BigDecimal(jsById.getnBili()));
- multiply = multiply.divide(new BigDecimal(100), MassageConstants.INTEGER_TWO, RoundingMode.HALF_UP);
- // 获取技师所对应的用户
- TWxUser jsUser = wxUserService.getByOpenId(jsById.getcOpenId());
- // 更新余额
- jsUser.setdBalance(jsUser.getdBalance().add(multiply));
- // 更新总钱数
- jsUser.setdAllMoney(jsUser.getdAllMoney().add(multiply));
- wxUserService.updateById(jsUser);
- //增加消费记录
- TConsumptionLog tConsumptionLog = new TConsumptionLog();
- tConsumptionLog.setAmount(multiply);
- tConsumptionLog.setBillNo(orderNew.getOrderNo());
- tConsumptionLog.setOpenId(jsUser.getcOpenid());
- tConsumptionLog.setBillType(BillTypeEnum.INCOME.getCode());
- tConsumptionLog.setNote("技师收益");
- consumptionLogService.save(tConsumptionLog);
- // // 如果该技师有推荐人员
- // if(StringUtils.isNotBlank(jsUser.getcUpUser())){
- // // 获取技师上级对应的用户
- // TWxUser jsUp = wxUserService.getById(jsUser.getcUpUser());
- // // 获取基本信息
- // List<TInfo> list = infoService.list();
- // BigDecimal up = orderNew.getdTotalMoney().multiply(new BigDecimal(list.get(0).getnBili()));
- // up = up.divide(new BigDecimal(100),2, RoundingMode.HALF_UP);
- // // 更新余额
- // jsUp.setdBalance(jsUp.getdBalance().add(up));
- // // 更新总钱数
- // jsUp.setdAllMoney(jsUp.getdAllMoney().add(up));
- // wxUserService.updateById(jsUp);
- // }
- // 更新订单
- orderNew.setnStatus(OrderStatusEnum.WAIT_EVALUATE.getCode());
- return updateById(orderNew);
- }
- /**
- * 取消订单
- *
- * @param order
- * @return
- */
- @Override
- public Boolean cancle(TOrder order) {
- // 获取订单信息
- // 根据orderid查询订单信息
- TOrder orderNew = getById(order.getcId());
- //待接单
- // if (Objects.equals(orderNew.getnStatus(), OrderStatusEnum.WAIT_JD.getCode())) {
- // TWxUser user = wxUserService.getById(orderNew.getcOpenId());
- // // 更新用户金额 及下单此时
- // TWxUser paramUser = new TWxUser();
- // paramUser.setcOpenid(user.getcOpenid());
- // // 金额归还对应账户
- // paramUser.setdBalance(user.getdBalance().add(orderNew.getdTotalMoney()));
- // // 消费金额对应减少
- // paramUser.setdMoney(user.getdMoney().subtract(orderNew.getdTotalMoney()));
- // // 下单次数减一
- // paramUser.setnNum(user.getnNum() - MassageConstants.INTEGER_ONE);
- // wxUserService.updateById(paramUser);
- //
- // // 更新项目数据
- // JSONArray objects = orderNew.getcGoods();
- // objects.forEach(item -> {
- // UpdateWrapper<TXiangmu> wrapper = new UpdateWrapper<>();
- // // 获取参数
- // wrapper.lambda().eq(TXiangmu::getcId, ((JSONObject) item).getString("cId"));
- // // 设置数量
- // wrapper.setSql(" n_sale_number = n_sale_number - " + ((JSONObject) item).getInteger("number"));
- // xiangmuService.update(wrapper);
- // });
- // TOrder orderParam = new TOrder();
- // orderParam.setcId(orderNew.getcId());
- // orderParam.setnStatus(OrderStatusEnum.CANCEL.getCode());
- // return updateById(orderParam);
- //
- // } else
- if (Objects.equals(orderNew.getnStatus(), OrderStatusEnum.WAIT_PAY.getCode())) {
- //待付款
- TOrder orderParam = new TOrder();
- orderParam.setcId(orderNew.getcId());
- orderParam.setnStatus(OrderStatusEnum.CANCEL.getCode());
- return updateById(orderParam);
- } else {
- return false;
- }
- }
- @Override
- public TOrder getByNo(String orderNo) {
- LambdaQueryWrapper<TOrder> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
- return this.getOne(objectLambdaQueryWrapper.eq(TOrder::getOrderNo, orderNo));
- }
- private TOrder gettOrder(TOrder order) {
- LambdaUpdateWrapper<TOrder> objectLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
- objectLambdaUpdateWrapper.eq(TOrder::getOrderNo, order.getOrderNo());
- return this.getOne(objectLambdaUpdateWrapper);
- }
- @Override
- public Page<TOrder> getAll(Page<TOrder> page, TOrder param) {
- Page<TOrder> orderPage = orderMapper.getAll(page, param);
- if (orderPage != null && CollectionUtil.isNotEmpty(orderPage.getRecords())) {
- ArrayList<TOrder> orders = Lists.newArrayList();
- orderPage.getRecords().forEach(order -> {
- order.setStatusName(OrderStatusEnum.getDescByCode(order.getnStatus()));
- orders.add(order);
- });
- orderPage.setRecords(orders);
- }
- return orderPage;
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public void takingOrders(TOrder order) {
- if (order == null || StringUtils.isBlank(order.getcId())) {
- throw new IllegalArgumentException("订单对象不能为空");
- }
- TOrder orderNew = this.getById(order);
- // 检查订单对应的技师是否存在
- // updateJs (orderNew);
- // 更新订单状态
- TOrder orderParam = new TOrder();
- orderParam.setcId(order.getcId());
- orderParam.setnStatus(OrderStatusEnum.RECEIVED_ORDER.getCode());
- this.updateById(orderParam);
- }
- private void updateJs(TOrder orderNew) {
- TJs js = jsService.getById(orderNew.getcJsId());
- if (js == null) {
- throw new IllegalStateException("无法找到对应的技师");
- }
- // 更新技师状态
- js.setnStatus(JsStatusEnum.JS_SERVICE.getCode());
- // 确保js.getnNum()不为null,避免 NullPointerException
- int num = js.getnNum() == null ? 0 : js.getnNum();
- js.setnNum(num + MassageConstants.INTEGER_ONE);
- jsService.updateById(js);
- }
- }
|