| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261 |
- package com.ylx.massage.service.impl;
- import cn.hutool.core.collection.CollectionUtil;
- import cn.hutool.json.JSONUtil;
- 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.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.config.WechatAccountConfig;
- import com.ylx.common.constant.MassageConstants;
- import com.ylx.common.core.domain.R;
- import com.ylx.common.exception.ServiceException;
- import com.ylx.common.utils.SecurityUtils;
- import com.ylx.massage.domain.*;
- import com.ylx.massage.domain.vo.*;
- 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.*;
- import lombok.extern.slf4j.Slf4j;
- 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.LocalDate;
- import java.time.LocalDateTime;
- import java.time.LocalTime;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * 订单表 服务实现类
- */
- @Service
- @Slf4j
- public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements TOrderService {
- @Resource
- private TOrderMapper orderMapper;
- @Resource
- private WechatAccountConfig wxPayProperties;
- @Resource
- private LocationUtil locationUtil;
- @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 CouponService couponService;
- @Resource
- private WeChatUtil weChatUtil;
- @Resource
- private RefundVoucherService refundVoucherService;
- @Resource
- private OrderValidationService orderValidationService;
- @Resource
- private OrderNotificationService orderNotificationService;
- @Resource
- private OrderAllocationLogService allocationLogService;
- /**
- * 判断是否免车费
- * 时间段判断:
- * - 白天时段(7:30-20:00):距离 ≤ 技师白天免车费里程 → 免费
- * - 夜间时段(20:00-7:30):距离 ≤ 技师夜间免车费里程 → 免费
- *
- * @param js
- * @param distance
- * @return Boolean
- */
- public Boolean isFree(TJs js, BigDecimal distance) {
- 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
- * @return TOrder
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public TOrder addOrder(TOrder order) {
- String jsId = order.getcJsId();
- // 1. 基础参数校验
- if (StringUtils.isBlank(jsId)) {
- throw new ServiceException("请选择技师");
- }
- if (order.getcGoods().isEmpty()) {
- throw new ServiceException("请选择项目");
- }
- TJs js = jsService.getById(jsId);
- if (js == null) {
- throw new ServiceException("技师不存在");
- }
- Integer techType = js.getTechType();
- // 虚拟技师
- if(techType.equals(1)){
- //虚拟技师订单
- order.setVirtualOrderFlag(1);
- //虚拟技师订单未分配
- order.setVirtualOrderAllocation(1);
- }else{
- //真实订单
- order.setVirtualOrderFlag(0);
- order.setVirtualOrderAllocation(0);
- }
- // 2. 【新增】订单状态锁校验 - 检查技师是否可以接单
- // 确保技师没有进行中的订单,保证服务时间互斥
- log.info("开始校验技师 {} 是否可以接单,订单号:{}", order.getcJsId(), order.getOrderNo());
- orderValidationService.canAcceptOrder(order.getcJsId(), order);
- log.info("技师 {} 接单校验通过,继续创建订单", order.getcJsId());
- //优惠卷减免
- // List<CouponReceiveVo> coupons = couponReceiveService.getByOpenId(order.getcOpenId());
- // BigDecimal preferential = this.setCoupon(coupons);
- // order.setPreferential(preferential);
- // 生成订单号
- order.setOrderNo(generator.generateNextOrderNumber(OrderNumberGenerator.KEY_PREFIX_ORDER));
- //订单价格
- 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);
- //获取用户默认地址
- TAddress address = addressService.getByOpenId(order.getcOpenId());
- if (address == null) {
- throw new ServiceException("请先添加地址");
- }
- //添加技师位置信息
- locationUtil.geoAdd(LocationUtil.GEO_KEY_USER, js.getcOpenId() + order.getOrderNo(), Double.parseDouble(js.getLongitude().toString()), Double.parseDouble(js.getLatitude().toString()));
- //添加用户位置信息
- locationUtil.geoAdd(LocationUtil.GEO_KEY_USER, order.getcOpenId() + order.getOrderNo(), Double.parseDouble(address.getLongitude().toString()), Double.parseDouble(address.getLatitude().toString()));
- //计算距离
- double distance = locationUtil.getDistance(js.getcOpenId() + order.getOrderNo(), order.getcOpenId() + order.getOrderNo());
- log.info("技师与用户之间的距离:{}", distance);
- locationUtil.remove(LocationUtil.GEO_KEY_USER, js.getcOpenId() + order.getOrderNo(), order.getcOpenId() + order.getOrderNo());
- order.setDistance(new BigDecimal(distance));
- //计算车费
- if (order.getDistance() != null && order.getDistance().compareTo(BigDecimal.ZERO) > 0 && StringUtils.isBlank(order.getParentNo())) {
- //判断是否可以免车费
- if (!this.isFree(js, order.getDistance())) {
- BigDecimal bigDecimal = massageUtil.calculateTaxiFare(order.getDistance(), js.getDeptId());
- order.setFare(bigDecimal.setScale(MassageConstants.INTEGER_TWO, RoundingMode.HALF_UP));
- }
- }
- //总价 = 订单 + 车费
- order.setTotalPrice(sum.add(Optional.ofNullable(order.getFare()).orElse(BigDecimal.ZERO)));
- if (order.getParentNo() != null && order.getOrderType() == 2) {
- //升级订单 补差价
- TOrder partOrder = this.getByNo(order.getParentNo());
- order.setPriceDifference(order.getTotalPrice().subtract(partOrder.getTotalPrice()));
- }
- order.setAddress(address.getAddress());
- order.setName(address.getName());
- order.setLatitude(address.getLatitude());
- order.setLongitude(address.getLongitude());
- order.setcPhone(address.getPhone());
- order.setcName(address.getUserName());
- order.setAtlasAdd(address.getAtlasAdd());
- order.setDeptId(js.getDeptId());
- order.setDeptName(js.getCity());
- //设置订单状态:待支付
- order.setnStatus(OrderStatusEnum.WAIT_PAY.getCode());
- order.setDtCreateTime(LocalDateTime.now());
- Date date = DateTimeUtils.addMinute(new Date(), 10);
- order.setcTime(DateTimeUtils.formatDate(date, "yyyy-MM-dd HH:mm:ss"));
- 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) {
- //查询未支付的订单
- LambdaQueryWrapper<TOrder> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(TOrder::getOrderNo, outTradeNo).eq(TOrder::getnStatus, OrderStatusEnum.WAIT_PAY.getCode());
- TOrder orderNew = this.getOne(queryWrapper);
- if (orderNew == null) {
- log.error("订单 {} 未支付状态不存在", outTradeNo);
- return;
- }
- // 设置微信支付
- orderNew.setPayType(1);
- TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
- orderPayManage(user, orderNew);
- }
- @Override
- public Object updateAddressById(TOrder borrow) {
- TOrder order = this.getById(borrow.getcId());
- if (borrow.getLatitude() != null && borrow.getLatitude() != 0 && borrow.getLongitude() != null && borrow.getLongitude() != 0) {
- order.setAtlasAdd(borrow.getAtlasAdd());
- order.setcName(borrow.getcName());
- order.setcPhone(borrow.getcPhone());
- order.setName(borrow.getName());
- order.setAddress(borrow.getAddress());
- order.setLatitude(borrow.getLatitude());
- order.setLongitude(borrow.getLongitude());
- TJs js = jsService.getById(order.getcJsId());
- //添加位置信息
- locationUtil.geoAdd(LocationUtil.GEO_KEY_USER, js.getcOpenId() + order.getOrderNo(), Double.parseDouble(js.getLongitude().toString()), Double.parseDouble(js.getLatitude().toString()));
- locationUtil.geoAdd(LocationUtil.GEO_KEY_USER, order.getcOpenId() + order.getOrderNo(), Double.parseDouble(borrow.getLongitude().toString()), Double.parseDouble(borrow.getLatitude().toString()));
- double distance = locationUtil.getDistance(js.getcOpenId() + order.getOrderNo(), order.getcOpenId() + order.getOrderNo());
- locationUtil.remove(LocationUtil.GEO_KEY_USER, js.getcOpenId() + order.getOrderNo(), order.getcOpenId() + order.getOrderNo());
- order.setDistance(new BigDecimal(distance));
- //计算车费
- if (order.getDistance() != null && order.getDistance().compareTo(BigDecimal.ZERO) > 0) {
- //判断是否可以免车费
- if (!this.isFree(js, order.getDistance())) {
- BigDecimal bigDecimal = massageUtil.calculateTaxiFare(order.getDistance(), order.getDeptId());
- order.setFare(bigDecimal.setScale(MassageConstants.INTEGER_TWO, RoundingMode.HALF_UP));
- }
- }
- order.setTotalPrice(order.getdTotalMoney().add(Optional.ofNullable(order.getFare()).orElse(BigDecimal.ZERO)));
- this.updateById(order);
- }
- return order;
- }
- @Override
- public Object depart(TOrder order) {
- LambdaQueryWrapper<TOrder> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(TOrder::getcId, order.getcId()).eq(TOrder::getnStatus, OrderStatusEnum.RECEIVED_ORDER.getCode());
- //设置订单状态:已出发
- order.setnStatus(OrderStatusEnum.DEPART.getCode());
- order.setDepartTime(new Date());
- order.setDepartLongitude(Optional.ofNullable(order.getDepartLongitude()).orElse(BigDecimal.ZERO));
- order.setDepartLatitude(Optional.ofNullable(order.getDepartLatitude()).orElse(BigDecimal.ZERO));
- return this.update(order, wrapper);
- }
- @Override
- public Integer getOrderNum(String jsid, Date startDate, Date endDate) {
- return orderMapper.getOrderNum(jsid, startDate, endDate);
- }
- @Override
- public Integer getAddNum(String jsid, Date startDate, Date endDate) {
- return orderMapper.getAddNum(jsid, startDate, endDate);
- }
- @Override
- public Integer getUpgradeNum(String jsid, Date startDate, Date endDate) {
- return orderMapper.getUpgradeNum(jsid, startDate, endDate);
- }
- @Override
- public BigDecimal getTurnover(String jsid, Date startDate, Date endDate) {
- return orderMapper.getTurnover(jsid, startDate, endDate);
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public TOrder transferOrder(TOrder order) {
- // ========== 第1步:参数校验 ==========
- if (StringUtils.isBlank(order.getcId())) {
- throw new ServiceException("订单id不能为空");
- }
- if (StringUtils.isBlank(order.getcJsId())) {
- throw new ServiceException("转单技师ID不能为空");
- }
- // 定义操作结果(默认为失败)
- Integer operationResult = 1; // 1-失败
- // 定义操作记录所需的变量
- String orderId = null;
- String orderNo = null;
- String oldTechnicianId = null;
- String oldTechnicianName = null;
- Integer oldTechnicianStatusBefore = null;
- Integer oldTechnicianStatusAfter = null;
- String newTechnicianId = null;
- String newTechnicianName = null;
- Integer newTechnicianStatusBefore = null;
- Integer newTechnicianStatusAfter = null;
- Integer orderStatusBefore = null;
- Integer orderStatusAfter = null;
- String operatorId = null;
- String operatorName = null;
- String operationReason = "虚拟订单分配";
- try {
- // ========== 第2步:查询原订单信息 ==========
- TOrder oldOrder = this.getById(order.getcId());
- if (oldOrder == null) {
- throw new ServiceException("订单不存在");
- }
- //原技师ID
- oldTechnicianId = oldOrder.getcJsId();
- //新技师ID
- newTechnicianId = order.getcJsId();
- // 记录订单操作前状态
- orderStatusBefore = oldOrder.getnStatus();
- orderId = oldOrder.getcId();
- orderNo = oldOrder.getOrderNo();
- log.info("开始转单操作 - 订单号:{}, 原技师ID:{}, 新技师ID:{}, 订单状态:{}", oldOrder.getOrderNo(), oldTechnicianId, newTechnicianId, orderStatusBefore);
- // ========== 第3步:查询原技师信息 ==========
- TJs oldTechnician = jsService.getById(oldTechnicianId);
- if (oldTechnician == null) {
- throw new ServiceException("原技师不存在");
- }
- oldTechnicianName = oldTechnician.getcName();
- oldTechnicianStatusBefore = oldTechnician.getnStatus();
- // ========== 第4步:查询新技师信息 ==========
- TJs newTechnician = jsService.getById(newTechnicianId);
- if (newTechnician == null) {
- throw new ServiceException("新技师不存在");
- }
- newTechnicianName = newTechnician.getcName();
- newTechnicianStatusBefore = newTechnician.getnStatus();
- // ========== 第5步:更新订单技师信息 ==========
- oldOrder.setOldJsId(oldTechnicianId); // 保存原技师ID
- oldOrder.setcJsId(newTechnicianId); // 更新为新技师ID
- log.info("更新订单技师 - 订单号:{}, 原技师:[ID:{}, 姓名:{}], 新技师:[ID:{}, 姓名:{}]", oldOrder.getOrderNo(), oldTechnicianId, oldTechnicianName, newTechnicianId, newTechnicianName);
- if (!this.updateById(oldOrder)) {
- throw new ServiceException("转单失败:更新订单技师信息失败");
- }
- // 记录订单操作后状态(转单后状态通常保持不变)
- orderStatusAfter = oldOrder.getnStatus();
- // ========== 第6步:更新新技师状态(可服务 → 服务中)==========
- TJs newJsUpdate = new TJs();
- newJsUpdate.setId(newTechnicianId);
- newJsUpdate.setnStatus(JsStatusEnum.JS_SERVICE.getCode());
- if (!jsService.updateById(newJsUpdate)) {
- throw new ServiceException("转单失败:更新新技师状态失败");
- }
- newTechnicianStatusAfter = JsStatusEnum.JS_SERVICE.getCode();
- // ========== 第7步:更新原技师状态(服务中 → 可服务)==========
- TJs oldJsUpdate = new TJs();
- oldJsUpdate.setId(oldTechnicianId);
- oldJsUpdate.setnStatus(JsStatusEnum.JS_SERVICEABLE.getCode());
- if (!jsService.updateById(oldJsUpdate)) {
- throw new ServiceException("转单失败:更新原技师状态失败");
- }
- oldTechnicianStatusAfter = JsStatusEnum.JS_SERVICEABLE.getCode();
- log.info("更新技师状态完成 - 新技师:{} {}→{}, 原技师:{} {}→{}",
- newTechnicianName, getStatusName(newTechnicianStatusBefore), getStatusName(newTechnicianStatusAfter),
- oldTechnicianName, getStatusName(oldTechnicianStatusBefore), getStatusName(oldTechnicianStatusAfter));
- // ========== 第8步:获取操作人信息 ==========
- operatorId = SecurityUtils.getUserId() != null ? SecurityUtils.getUserId().toString() : "ADMIN";
- operatorName = SecurityUtils.getUsername() != null ? SecurityUtils.getUsername() : "系统管理员";
- // ========== 第9步:转单成功,设置操作结果为成功 ==========
- operationResult = 0; // 0-成功
- log.info("转单操作完成 - 订单号:{}", oldOrder.getOrderNo());
- return oldOrder;
- } catch (ServiceException e) {
- // 业务异常,操作失败
- log.error("转单操作失败 - 订单号:{}, 错误信息:{}", orderNo, e.getMessage());
- operationResult = 1; // 1-失败
- throw e;
- } catch (Exception e) {
- // 系统异常,操作失败
- log.error("转单操作异常 - 订单号:{}, 异常信息:{}", orderNo, e.getMessage(), e);
- operationResult = 1; // 1-失败
- throw new ServiceException("转单操作异常:" + e.getMessage());
- } finally {
- // ========== 第10步:记录转单操作日志(无论成功或失败都记录)==========
- try {
- // 只有在获取到基本信息后才记录日志
- if (orderId != null && orderNo != null && oldTechnicianId != null && newTechnicianId != null) {
- allocationLogService.recordTransferOrder(
- orderId, // orderId
- orderNo, // orderNo
- oldTechnicianId, // oldTechnicianId
- oldTechnicianName, // oldTechnicianName
- oldTechnicianStatusBefore, // oldTechnicianStatusBefore
- oldTechnicianStatusAfter, // oldTechnicianStatusAfter
- newTechnicianId, // newTechnicianId
- newTechnicianName, // newTechnicianName
- newTechnicianStatusBefore, // newTechnicianStatusBefore
- newTechnicianStatusAfter, // newTechnicianStatusAfter
- orderStatusBefore, // orderStatusBefore
- orderStatusAfter, // orderStatusAfter
- operatorId, // operatorId
- operatorName, // operatorName
- operationReason, // operationReason
- operationResult // operationResult(0-成功,1-失败)
- );
- String resultDesc = operationResult == 0 ? "成功" : "失败";
- log.info("转单操作记录已保存 - 订单号:{}, 操作结果:{}", orderNo, resultDesc);
- }
- } catch (Exception e) {
- // 记录日志失败不影响转单操作
- log.error("记录转单操作日志失败 - 订单号:{}, 错误信息:{}", orderNo, e.getMessage(), e);
- }
- }
- }
- /**
- * 获取技师状态名称
- *
- * @param status 状态码
- * @return String 状态名称
- */
- private String getStatusName(Integer status) {
- if (status == null) {
- return "未知";
- }
- switch (status) {
- case 0:
- return "可服务";
- case 1:
- return "服务中";
- case 2:
- return "不可服务";
- default:
- return "未知(" + status + ")";
- }
- }
- @Override
- public List<HomeBlock> getBlock(Date start, Date end, String deptId) {
- return orderMapper.getBlock(start, end, deptId);
- }
- @Override
- public OrderVerificationVo verification(TOrder order) {
- if (StringUtils.isBlank(order.getCouponReceiveId())) {
- throw new ServiceException("认领优惠券id为空");
- }
- if (StringUtils.isBlank(order.getcId())) {
- throw new ServiceException("订单id为空");
- }
- OrderVerificationVo orderVerificationVo = new OrderVerificationVo();
- TOrder tOrder = this.getById(order.getcId());
- orderVerificationVo.setCouponReceiveId(order.getCouponReceiveId());
- CouponReceive couponReceive = couponReceiveService.getById(order.getCouponReceiveId());
- Coupon coupon = couponService.getById(couponReceive.getCouponId());
- log.info("订单信息,{}", tOrder);
- log.info("优惠卷信息,{}", coupon);
- //折扣券
- if (coupon.getDiscountType() == 2) {
- //判断门槛金额
- if (tOrder.getTotalPrice().compareTo(coupon.getThresholdAmount()) >= 0) {
- //折扣值
- BigDecimal divide = coupon.getRebValue().divide(new BigDecimal(10));
- //优惠后的金额 = 订单总金额*折扣值
- BigDecimal bigDecimal = tOrder.getTotalPrice().multiply(divide).setScale(MassageConstants.INTEGER_TWO, RoundingMode.HALF_UP);
- //优惠值
- orderVerificationVo.setPreferential(tOrder.getTotalPrice().subtract(bigDecimal));
- orderVerificationVo.setTotalPrice(bigDecimal);
- } else {
- throw new ServiceException("不满足优惠券门槛金额");
- }
- } else {
- if (tOrder.getTotalPrice().compareTo(coupon.getThresholdAmount()) >= 0) {
- //优惠值
- orderVerificationVo.setPreferential(coupon.getDiscountValue());
- orderVerificationVo.setTotalPrice(tOrder.getTotalPrice().subtract(coupon.getDiscountValue()));
- } else {
- throw new ServiceException("不满足优惠券门槛金额");
- }
- }
- if (orderVerificationVo.getTotalPrice().compareTo(BigDecimal.ZERO) < 0) {
- throw new ServiceException("当前项目不可用");
- }
- return orderVerificationVo;
- }
- private TOrder getOrder(TOrder tOrder) {
- if (updateById(tOrder)) {
- return tOrder;
- } else {
- throw new ServiceException("优惠券核销失败");
- }
- }
- /**
- * 支付订单
- *
- * @param order
- * @return R
- */
- @Override
- public R payOrder(TOrder order) throws Exception {
- // 根据订单ID查询订单信息
- TOrder orderNew = getById(order.getcId());
- if (!orderNew.getnStatus().equals(OrderStatusEnum.WAIT_PAY.getCode())) {
- throw new ServiceException("该订单已经支付或者超时被取消");
- }
- TJs js = jsService.getById(orderNew.getcJsId());
- if (StringUtils.isBlank(orderNew.getParentNo())) {
- if (null == js || js.getnStatus().equals(JsStatusEnum.JS_SERVICE.getCode())) {
- throw new ServiceException("该技师已在服务中请重新下单");
- }
- }
- orderNew.setPayType(order.getPayType());
- //优惠券核销
- if (StringUtils.isNotBlank(order.getCouponReceiveId())) {
- orderNew.setCouponReceiveId(order.getCouponReceiveId());
- orderNew.setPreferential(order.getPreferential());
- orderNew.setTotalPrice(order.getTotalPrice());
- if (!updateById(orderNew)) {
- 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());
- //添加待接单消息通知(技师侧)这块的逻辑在回调接口中
- //orderNotificationService.sendPendingRemindNotification(orderNew);
- return resp;
- }
- TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
- if (null == user) {
- throw new ServiceException("用户不存在");
- }
- //现金支付
- if (order.getPayType().equals(MassageConstants.INTEGER_THREE)) {
- //现金支付
- orderPayManage(user, orderNew);
- //添加待接单消息通知(技师侧)
- orderNotificationService.sendPendingRemindNotification(orderNew);
- return R.ok();
- }
- if (user.getdBalance().compareTo(orderNew.getTotalPrice()) < MassageConstants.INTEGER_ZERO) {
- throw new ServiceException("账户金额不够请充值");
- } else {
- orderPayManage(user, orderNew);
- //添加待接单消息通知(技师侧)
- orderNotificationService.sendPendingRemindNotification(orderNew);
- return R.ok();
- }
- }
- /**
- * 新订单通知
- *
- * @param order
- */
- public void newOrderNotification(TOrder order) {
- cn.hutool.json.JSONObject param = JSONUtil.createObj();
- //订单号
- param.set("character_string9", JSONUtil.createObj().set("value", order.getOrderNo()));
- //电话
- param.set("phone_number14", JSONUtil.createObj().set("value", order.getcPhone()));
- param.set("thing18", JSONUtil.createObj().set("value", order.getcName()));
- param.set("time6", JSONUtil.createObj().set("value", DateTimeUtils.formatDate(new Date(), DateTimeUtils.DATE_NUMBER_YEAR_MONTH_FORMAT)));
- param.set("thing27", JSONUtil.createObj().set("value", order.getName()));
- TJs js = jsService.getById(order.getcJsId());
- weChatUtil.notification(js.getcOpenId(), wxPayProperties.getTemplateId1(), param);
- }
- /**
- * 订单支付管理
- *
- * @param user
- * @param orderNew
- */
- @Transactional(rollbackFor = Exception.class)
- public void orderPayManage(TWxUser user, TOrder orderNew) {
- //更新优惠卷状态
- if (StringUtils.isNotBlank(orderNew.getCouponReceiveId())) {
- CouponReceive couponReceive = new CouponReceive();
- couponReceive.setId(orderNew.getCouponReceiveId());
- couponReceive.setUseState(MassageConstants.INTEGER_TWO);
- if (!couponReceiveService.updateById(couponReceive)) {
- log.error("优惠券状态更新失败id:,{}", orderNew.getCouponReceiveId());
- }
- }
- // 更新用户金额 及下单此时
- TWxUser paramUser = new TWxUser();
- paramUser.setcOpenid(user.getcOpenid());
- // 余额支付
- if (orderNew.getPayType().equals(MassageConstants.INTEGER_TWO)) {
- paramUser.setdBalance(user.getdBalance().subtract(orderNew.getTotalPrice()));
- }
- paramUser.setdMoney(user.getdMoney().add(orderNew.getTotalPrice()));
- paramUser.setnNum(user.getnNum() + MassageConstants.INTEGER_ONE);
- 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_TWO)) {
- tConsumptionLog.setBillType(BillTypeEnum.BALANCE_PAYMENT.getCode());
- tConsumptionLog.setNote("余额支付");
- } else if(orderNew.getPayType().equals(MassageConstants.INTEGER_ONE)){
- tConsumptionLog.setBillType(BillTypeEnum.WX_PAY.getCode());
- tConsumptionLog.setNote("微信支付");
- } else {
- tConsumptionLog.setBillType(BillTypeEnum.CASH_PAYMENT.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.setPayType(orderNew.getPayType());
- orderParam.setcId(orderNew.getcId());
- orderParam.setnStatus(OrderStatusEnum.WAIT_JD.getCode());
- orderParam.setPayTime(new Date());
- //加钟的订单支付完直接服务中
- if (StringUtils.isNotBlank(orderNew.getParentNo())) {
- orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
- }
- // orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
- //更新及技师状态
- updateJs(orderNew);
- updateById(orderParam);
- //
- //this.newOrderNotification(orderNew);
- //添加待接单消息通知(技师侧)
- orderNotificationService.sendPendingRemindNotification(orderNew);
- //电话通知
- TJs js = jsService.getById(orderNew.getcJsId());
- Sendvoice.sendPhone(js.getcPhone());
- }
- /**
- * 拒绝订单
- *
- * @param order
- */
- @Override
- public Boolean jujue(TOrder order) {
- TOrder orderNew = getById(order.getcId());
- TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
- // 更新用户金额 及下单此时
- TWxUser paramUser = new TWxUser();
- paramUser.setcOpenid(user.getcOpenid());
- paramUser.setId(user.getId());
- // 余额记录
- TConsumptionLog tConsumptionLog = new TConsumptionLog();
- tConsumptionLog.setAmount(orderNew.getTotalPrice());
- tConsumptionLog.setBillNo(orderNew.getOrderNo());
- tConsumptionLog.setOpenId(orderNew.getcOpenId());
- if (orderNew.getPayType() == 2) {
- // 金额归还对应账户
- paramUser.setdBalance(user.getdBalance().add(orderNew.getTotalPrice()));
- tConsumptionLog.setBillType(BillTypeEnum.REFUSE_ACCEPT_REFUND.getCode());
- tConsumptionLog.setNote("拒绝接单退款到余额");
- } else {
- // 微信支付
- // 生成退款单退款
- RefundVoucher refundVoucher = new RefundVoucher();
- refundVoucher.setRefundNo(generator.generateNextOrderNumber(OrderNumberGenerator.KEY_PREFIX_REFUND));
- refundVoucher.setOrderNo(orderNew.getOrderNo());
- refundVoucher.setMoney(orderNew.getTotalPrice());
- refundVoucher.setOpenId(orderNew.getcOpenId());
- refundVoucher.setReStatus(MassageConstants.INTEGER_ZERO);
- refundVoucher.setReason("技师拒绝接单");
- refundVoucherService.save(refundVoucher);
- tConsumptionLog.setBillType(BillTypeEnum.REFUSE_ACCEPT_REFUND.getCode());
- tConsumptionLog.setNote("拒绝接单退款到余额");
- // 微信退款原路返回
- rechargeService.refund(refundVoucher.getRefundNo(), null, orderNew.getOrderNo(), orderNew.getTotalPrice());
- }
- consumptionLogService.save(tConsumptionLog);
- //退优惠卷
- if (StringUtils.isNotBlank(orderNew.getCouponReceiveId())) {
- CouponReceive couponReceive = couponReceiveService.getById(orderNew.getCouponReceiveId());
- couponReceive.setUseState(MassageConstants.INTEGER_ZERO);
- couponReceiveService.updateById(couponReceive);
- }
- log.info("余额支付退款user:{}", user);
- // 消费金额对应减少
- paramUser.setdMoney(user.getdMoney().subtract(orderNew.getTotalPrice()));
- // 下单次数减一
- 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());
- orderParam.setReasonRefusal(order.getReasonRefusal());
- updateJs(orderNew);
- return updateById(orderParam);
- }
- /**
- * 确认服务完成
- *
- * @param order
- * @return Boolean
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean confirm(TOrder order) {
- // 获取订单信息
- TOrder orderNew = getById(order.getcId());
- if (!orderNew.getnStatus().equals(OrderStatusEnum.SERVICE.getCode())) {
- throw new ServiceException("订单状态不是服务中");
- }
- // 更新技师信息
- TJs jsParam = new TJs();
- jsParam.setId(orderNew.getcJsId());
- jsParam.setnStatus(JsStatusEnum.JS_SERVICEABLE.getCode());
- //判断热度标识
- List<TOrder> list = list(new LambdaQueryWrapper<TOrder>().eq(TOrder::getcJsId, orderNew.getcJsId())
- .ge(TOrder::getDtCreateTime, DateTimeUtils.addDays(new Date(), -3))
- .ge(TOrder::getnStatus, OrderStatusEnum.WAIT_EVALUATE.getCode()));
- if (list.size() >= 2) {
- // 设置热度标识:1
- jsParam.setnB3(MassageConstants.INTEGER_ONE);
- }
- // 更新技师状态
- jsService.updateById(jsParam);
- // 更新技师钱包金额
- TJs jsById = jsService.getById(orderNew.getcJsId());
- // 获取技师抽成
- BigDecimal multiply = orderNew.getTotalPrice().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.getByOpenId(jsUser.getcUpUser());
- extracted(orderNew, jsUp);
- //二级
- if (StringUtils.isNotBlank(jsUp.getcUpUser())) {
- TWxUser jsUpTwo = wxUserService.getByOpenId(jsUp.getcUpUser());
- extracted(orderNew, jsUpTwo);
- //三级
- if (StringUtils.isNotBlank(jsUpTwo.getcUpUser())) {
- TWxUser jsUpThree = wxUserService.getByOpenId(jsUpTwo.getcUpUser());
- extracted(orderNew, jsUpThree);
- }
- }
- }
- // 更新订单
- // 订单状态:待评价
- orderNew.setnStatus(OrderStatusEnum.WAIT_EVALUATE.getCode());
- orderNew.setEndTime(LocalDateTime.now());
- updateById(orderNew);
- // 添加订单完成消息通知(用户侧)
- orderNotificationService.sendCompletedNotification(orderNew);
- return true;
- }
- private void extracted(TOrder orderNew, TWxUser jsUp) {
- log.info("TOrderServiceImpl->extracted->jsUp,{}", JSONUtil.toJsonStr(jsUp));
- log.info("TOrderServiceImpl->extracted->orderNew,{}",JSONUtil.toJsonStr(orderNew));
- BigDecimal up = orderNew.getdTotalMoney().multiply(new BigDecimal("10"));
- up = up.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
- // 更新余额
- jsUp.setdBalance(jsUp.getdBalance().add(up));
- // 更新总钱数
- jsUp.setdAllMoney(jsUp.getdAllMoney().add(up));
- jsUp.setDistributionAmount(up);
- wxUserService.updateById(jsUp);
- //记录分销收益
- TConsumptionLog tConsumptionLog = new TConsumptionLog();
- tConsumptionLog.setAmount(up);
- tConsumptionLog.setBillNo(orderNew.getOrderNo());
- tConsumptionLog.setOpenId(jsUp.getcOpenid());
- tConsumptionLog.setBillType(BillTypeEnum.DISTRIBUTION.getCode());
- tConsumptionLog.setNote("分销收益");
- consumptionLogService.save(tConsumptionLog);
- }
- /**
- * 获取技师当天可预约时间
- *
- * @param technicianId 技师ID
- * @param dateStr 查询日期(格式:yyyy-MM-dd),为null则查询当天
- * @return 技师当天可预约时间VO
- */
- @Override
- public TechnicianAvailabilityVo getTechnicianAvailability(String technicianId, String dateStr) {
- // 1. 参数校验
- if (StringUtils.isBlank(technicianId)) {
- throw new ServiceException("技师ID不能为空");
- }
- // 2. 查询技师信息
- TJs js = jsService.getById(technicianId);
- if (js == null) {
- throw new ServiceException("技师不存在");
- }
- // 3. 解析日期,默认为当天
- LocalDate queryDate;
- if (StringUtils.isBlank(dateStr)) {
- queryDate = LocalDate.now();
- } else {
- try {
- queryDate = LocalDate.parse(dateStr);
- } catch (Exception e) {
- throw new ServiceException("日期格式错误,请使用 yyyy-MM-dd 格式");
- }
- }
- // 4. 定义当天的所有时间段(以30分钟为间隔,从00:00到23:30)
- List<TimeSlotVo> timeSlots = new ArrayList<>();
- for (int hour = 0; hour < 24; hour++) {
- // 每小时生成两个时间段:xx:00 和 xx:30
- timeSlots.add(TimeSlotVo.builder()
- .time(String.format("%02d:00", hour))
- .available(true)
- .build());
- timeSlots.add(TimeSlotVo.builder()
- .time(String.format("%02d:30", hour))
- .available(true)
- .build());
- }
- // 5. 查询技师当天所有进行中的订单
- // 开始时间
- LocalDateTime startOfDay = queryDate.atStartOfDay();
- // 结束时间
- LocalDateTime endOfDay = queryDate.plusDays(1).atStartOfDay();
- log.info("开始时间:{},结束时间:{}", startOfDay, endOfDay);
- LambdaQueryWrapper<TOrder> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(TOrder::getcJsId, technicianId)
- .in(TOrder::getnStatus, OrderStatusEnum.WAIT_JD.getCode(),
- OrderStatusEnum.RECEIVED_ORDER.getCode(),
- OrderStatusEnum.DEPART.getCode(),
- OrderStatusEnum.ARRIVED.getCode(),
- OrderStatusEnum.SERVICE.getCode())
- .ge(TOrder::getDtCreateTime, startOfDay)
- .lt(TOrder::getDtCreateTime, endOfDay)
- .eq(TOrder::getIsDelete, 0);
- List<TOrder> orders = this.list(queryWrapper);
- log.info("技师{},在{}天共有 {} 个进行中的订单", technicianId, queryDate, orders.size());
- // 6. 标记不可预约的时间段
- LocalDateTime now = LocalDateTime.now();
- for (TOrder order : orders) {
- // 6.1 计算订单的开始时间和结束时间
- LocalDateTime orderStart = OrderTimeRangeUtils.estimateStartTime(order);
- LocalDateTime orderEnd = OrderTimeRangeUtils.estimateEndTime(order);
- if (orderStart == null || orderEnd == null) {
- log.warn("订单 {} 的时间信息不完整,跳过", order.getOrderNo());
- continue;
- }
- // 6.2 限制在查询日期范围内
- LocalDateTime effectiveStart = orderStart.isBefore(startOfDay) ? startOfDay : orderStart;
- LocalDateTime effectiveEnd = orderEnd.isAfter(endOfDay) ? endOfDay : orderEnd;
- // 6.3 标记不可预约的时间段
- markTimeSlotsUnavailable(timeSlots, effectiveStart, effectiveEnd, order.getOrderNo());
- }
- // 7. 根据查询日期判断是否可预约
- LocalDate today = LocalDate.now();
- if (queryDate.isBefore(today)) {
- // 查询日期是过去的日期,所有时间段都不可预约
- markAllTimeSlotsUnavailable(timeSlots, "日期已过期");
- } else if (queryDate.equals(today)) {
- // 查询日期是今天,标记过去的时间为不可预约
- markPastTimeSlotsUnavailable(timeSlots, now);
- }
- // 查询日期是未来的日期,所有时间段默认可预约,无需处理
- // 8. 构建返回结果
- return TechnicianAvailabilityVo.builder()
- .date(queryDate.toString())
- .technicianId(technicianId)
- .technicianName(js.getcName())
- .timeSlots(timeSlots)
- .build();
- }
- /**
- * 标记指定时间范围内的时间段为不可预约
- *
- * @param timeSlots 时间段列表
- * @param start 开始时间
- * @param end 结束时间
- * @param orderNo 订单号
- */
- private void markTimeSlotsUnavailable(List<TimeSlotVo> timeSlots, LocalDateTime start, LocalDateTime end, String orderNo) {
- LocalDate date = start.toLocalDate();
- LocalTime startTime = start.toLocalTime();
- LocalTime endTime = end.toLocalTime();
- for (TimeSlotVo slot : timeSlots) {
- LocalTime slotTime = LocalTime.parse(slot.getTime());
- // 判断时间段是否在订单时间范围内
- boolean isInRange = !slotTime.isBefore(startTime) && slotTime.isBefore(endTime);
- if (isInRange) {
- slot.setAvailable(false);
- slot.setReason("已有订单");
- slot.setOrderNo(orderNo);
- }
- }
- }
- /**
- * 标记所有时间段为不可预约
- *
- * @param timeSlots 时间段列表
- * @param reason 不可预约原因
- */
- private void markAllTimeSlotsUnavailable(List<TimeSlotVo> timeSlots, String reason) {
- for (TimeSlotVo slot : timeSlots) {
- slot.setAvailable(false);
- slot.setReason(reason);
- slot.setOrderNo(null);
- }
- }
- /**
- * 标记过去的时间段为不可预约
- *
- * @param timeSlots 时间段列表
- * @param now 当前时间
- */
- private void markPastTimeSlotsUnavailable(List<TimeSlotVo> timeSlots, LocalDateTime now) {
- LocalTime currentTime = now.toLocalTime();
- for (TimeSlotVo slot : timeSlots) {
- LocalTime slotTime = LocalTime.parse(slot.getTime());
- // 如果当前时间已经过了这个时间段,标记为不可预约
- if (slotTime.isBefore(currentTime)) {
- slot.setAvailable(false);
- slot.setReason("已过期");
- slot.setOrderNo(null);
- }
- }
- }
- /**
- * 取消订单
- *
- * @param order
- * @return Boolean
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean cancle(TOrder order) {
- // 获取订单信息
- // 根据orderid查询订单信息
- TOrder orderNew = getById(order.getcId());
- //待接单
- if (Objects.equals(orderNew.getnStatus(), OrderStatusEnum.WAIT_JD.getCode())) {
- TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
- // 更新用户金额 及下单此时
- TWxUser paramUser = new TWxUser();
- paramUser.setId(user.getId());
- paramUser.setcOpenid(user.getcOpenid());
- TConsumptionLog tConsumptionLog = new TConsumptionLog();
- tConsumptionLog.setAmount(orderNew.getTotalPrice());
- tConsumptionLog.setBillNo(orderNew.getOrderNo());
- tConsumptionLog.setOpenId(orderNew.getcOpenId());
- // 余额支付
- if (orderNew.getPayType() == 2) {
- // 金额归还对应账户
- paramUser.setdBalance(user.getdBalance().add(orderNew.getTotalPrice()));
- // 余额记录
- tConsumptionLog.setBillType(BillTypeEnum.CANCEL_ACCEPT_REFUND.getCode());
- tConsumptionLog.setNote("取消订单退款到余额");
- //自己取消的不退优惠卷
- } else {
- // 微信支付
- // 生成退款单退款
- RefundVoucher refundVoucher = new RefundVoucher();
- refundVoucher.setRefundNo(generator.generateNextOrderNumber(OrderNumberGenerator.KEY_PREFIX_REFUND));
- refundVoucher.setOrderNo(orderNew.getOrderNo());
- refundVoucher.setMoney(orderNew.getTotalPrice());
- refundVoucher.setOpenId(orderNew.getcOpenId());
- refundVoucher.setReStatus(MassageConstants.INTEGER_ZERO);
- refundVoucher.setReason("技师拒绝接单");
- refundVoucherService.save(refundVoucher);
- tConsumptionLog.setBillType(BillTypeEnum.CANCEL_WX_REFUND.getCode());
- tConsumptionLog.setNote("取消订单退款到微信");
- // 微信退款原路返回
- rechargeService.refund(refundVoucher.getRefundNo(), null, orderNew.getOrderNo(), orderNew.getTotalPrice());
- }
- consumptionLogService.save(tConsumptionLog);
- // 消费金额对应减少
- paramUser.setdMoney(user.getdMoney().subtract(orderNew.getTotalPrice()));
- // 下单次数减一
- 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());
- //更新技师状态
- TJs tJs = new TJs();
- tJs.setId(orderNew.getcJsId());
- tJs.setnStatus(JsStatusEnum.JS_SERVICEABLE.getCode());
- jsService.updateById(tJs);
- updateById(orderParam);
- // 添加取消订单通知(用户侧)
- orderNotificationService.sendCancelledNotification(orderNew);
- // 添加取消订单通知(技师侧)
- orderNotificationService.sendTechnicianCancelledNotification(orderNew);
- return true;
- } else if (Objects.equals(orderNew.getnStatus(), OrderStatusEnum.WAIT_PAY.getCode())) {//待付款
- TOrder orderParam = new TOrder();
- orderParam.setcId(orderNew.getcId());
- orderParam.setnStatus(OrderStatusEnum.CANCEL.getCode());
- updateById(orderParam);
- // 添加取消订单通知
- orderNotificationService.sendCancelledNotification(orderNew);
- // 添加取消订单通知(技师侧)
- orderNotificationService.sendTechnicianCancelledNotification(orderNew);
- return true;
- } 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 order) {
- Page<TOrder> orderPage = orderMapper.getAll(page, order);
- if (orderPage != null && CollectionUtil.isNotEmpty(orderPage.getRecords())) {
- ArrayList<TOrder> ordersList = Lists.newArrayList();
- orderPage.getRecords().forEach(orders -> {
- orders.setStatusName(OrderStatusEnum.getDescByCode(orders.getnStatus()));
- orders.setJsPhone(orders.getJs().getcPhone());
- orders.setJsName(orders.getJs().getcName());
- if (StringUtils.isEmpty(orders.getcTime())) {
- orders.setRemainingTime(0L);
- }
- if (StringUtils.isNotBlank(orders.getcTime()) && DateTimeUtils.dateStringToStamp(orders.getcTime()) > DateTimeUtils.dateToStamp(new Date())) {
- orders.setRemainingTime((DateTimeUtils.dateStringToStamp(orders.getcTime()) - DateTimeUtils.dateToStamp(new Date())) / 1000);
- }
- if (StringUtils.isNotBlank(orders.getcTime()) && DateTimeUtils.dateStringToStamp(orders.getcTime()) < DateTimeUtils.dateToStamp(new Date())) {
- orders.setRemainingTime(0L);
- }
- if (StringUtils.isNotBlank(orders.getOldJsId())) {
- orders.setOldJs(jsService.getById(orders.getOldJsId()));
- }
- ordersList.add(orders);
- });
- orderPage.setRecords(ordersList);
- }
- return orderPage;
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public void takingOrders(TOrder order) {
- String orderId = order.getcId();
- if (orderId == null || StringUtils.isBlank(orderId)) {
- throw new IllegalArgumentException("订单ID不能为空");
- }
- TOrder orderNew = this.getById(orderId);
- // 【新增】订单状态锁校验 - 检查技师是否可以接单
- log.info("开始校验技师 {} 是否可以接单,订单号:{}", orderNew.getcJsId(), orderNew.getOrderNo());
- orderValidationService.canAcceptOrder(orderNew.getcJsId(), orderNew);
- log.info("技师 {} 接单校验通过,继续接单流程", orderNew.getcJsId());
- // 检查订单对应的技师是否存在
- // updateJs (orderNew);
- TOrder orderParam = new TOrder();
- orderParam.setcId(orderId);
- //设置订单状态:已接单
- orderParam.setnStatus(OrderStatusEnum.RECEIVED_ORDER.getCode());
- orderParam.setAcceptanceTime(LocalDateTime.now());
- this.updateById(orderParam);
- // 已接单消息通知(用户侧)
- orderNotificationService.sendReceivedNotification(orderNew);
- // 已接单消息通知(技师侧)
- orderNotificationService.sendTechnicianReceivedNotification(orderNew);
- }
- private void updateJs(TOrder orderNew) {
- TJs js = jsService.getById(orderNew.getcJsId());
- if (js == null) {
- throw new IllegalStateException("无法找到对应的技师");
- }
- if (Objects.equals(js.getnStatus(), JsStatusEnum.JS_SERVICEABLE.getCode())) {
- // 更新技师状态
- js.setnStatus(JsStatusEnum.JS_SERVICE.getCode());
- // 确保js.getnNum()不为null,避免 NullPointerException
- int num = js.getnNum() == null ? 0 : js.getnNum();
- js.setnNum(num + MassageConstants.INTEGER_ONE);
- } else {
- // 更新技师状态
- js.setnStatus(JsStatusEnum.JS_SERVICEABLE.getCode());
- // 确保js.getnNum()不为null,避免 NullPointerException
- int num = js.getnNum() == null ? 0 : js.getnNum();
- js.setnNum(num - MassageConstants.INTEGER_ONE);
- }
- jsService.updateById(js);
- }
- }
|