|
@@ -18,6 +18,7 @@ import com.ylx.common.exception.ServiceException;
|
|
|
import com.ylx.common.utils.*;
|
|
import com.ylx.common.utils.*;
|
|
|
import com.ylx.common.weixinPay.enums.WxPayTypeEnum;
|
|
import com.ylx.common.weixinPay.enums.WxPayTypeEnum;
|
|
|
import com.ylx.common.weixinPay.service.WxPayV3Service;
|
|
import com.ylx.common.weixinPay.service.WxPayV3Service;
|
|
|
|
|
+import com.ylx.coupon.service.CouponService;
|
|
|
import com.ylx.fareSetting.service.IMaProjectFareSettingService;
|
|
import com.ylx.fareSetting.service.IMaProjectFareSettingService;
|
|
|
import com.ylx.massage.domain.MaProject;
|
|
import com.ylx.massage.domain.MaProject;
|
|
|
import com.ylx.massage.domain.MaTechnician;
|
|
import com.ylx.massage.domain.MaTechnician;
|
|
@@ -25,7 +26,6 @@ import com.ylx.massage.domain.TGeoFence;
|
|
|
import com.ylx.massage.domain.TWxUser;
|
|
import com.ylx.massage.domain.TWxUser;
|
|
|
import com.ylx.massage.mapper.MaProjectMapper;
|
|
import com.ylx.massage.mapper.MaProjectMapper;
|
|
|
import com.ylx.massage.mapper.MaTechnicianMapper;
|
|
import com.ylx.massage.mapper.MaTechnicianMapper;
|
|
|
-import com.ylx.coupon.service.CouponService;
|
|
|
|
|
import com.ylx.massage.service.IMaTechnicianService;
|
|
import com.ylx.massage.service.IMaTechnicianService;
|
|
|
import com.ylx.massage.service.TGeoFenceService;
|
|
import com.ylx.massage.service.TGeoFenceService;
|
|
|
import com.ylx.massage.service.TWxUserService;
|
|
import com.ylx.massage.service.TWxUserService;
|
|
@@ -414,7 +414,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
order.setCouponId(dto.getCouponId());
|
|
order.setCouponId(dto.getCouponId());
|
|
|
order.setCreateTime(DateUtils.getNowDate());
|
|
order.setCreateTime(DateUtils.getNowDate());
|
|
|
order.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode());
|
|
order.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode());
|
|
|
- order.setExecStatus(0);
|
|
|
|
|
|
|
+ order.setExecStatus(ExecStatusEnum.WAIT_DEPART.getCode());
|
|
|
order.setDispatchedStatus(DispatchedStatusEnum.UN_DISPATCHED.getCode());
|
|
order.setDispatchedStatus(DispatchedStatusEnum.UN_DISPATCHED.getCode());
|
|
|
order.setPaymentMethod(dto.getPaymentMethod());
|
|
order.setPaymentMethod(dto.getPaymentMethod());
|
|
|
|
|
|
|
@@ -924,6 +924,16 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public void startService(MerchantOrderOperateDTO dto) {
|
|
public void startService(MerchantOrderOperateDTO dto) {
|
|
|
|
|
|
|
|
|
|
+ // 校验图片不能为null
|
|
|
|
|
+ if (ObjectUtil.isEmpty(dto.getImageUrls())) {
|
|
|
|
|
+ throw new ServiceException("请至少上传1张图片");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 再检查是否有空/空白字符串
|
|
|
|
|
+ if (dto.getImageUrls().stream().anyMatch(StrUtil::isBlank)) {
|
|
|
|
|
+ throw new ServiceException("图片URL列表中不能包含空值或空白字符串");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 1. 获取当前登录商户
|
|
// 1. 获取当前登录商户
|
|
|
WxLoginUser loginUser = getCurrentWxLoginUser();
|
|
WxLoginUser loginUser = getCurrentWxLoginUser();
|
|
|
Long merchantId = Long.parseLong(loginUser.getId());
|
|
Long merchantId = Long.parseLong(loginUser.getId());
|
|
@@ -1031,21 +1041,11 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
WxLoginUser loginUser = getCurrentWxLoginUser();
|
|
WxLoginUser loginUser = getCurrentWxLoginUser();
|
|
|
Long merchantId = Long.parseLong(loginUser.getId());
|
|
Long merchantId = Long.parseLong(loginUser.getId());
|
|
|
Long orderId = dto.getOrderId();
|
|
Long orderId = dto.getOrderId();
|
|
|
- String code = dto.getCode();
|
|
|
|
|
- String phone = dto.getPhone();
|
|
|
|
|
-
|
|
|
|
|
- // 手机号或者验证码 校验
|
|
|
|
|
- if (ObjectUtil.hasNull(phone, code)) {
|
|
|
|
|
- throw new ServiceException("手机号或者验证码不能为空");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!validateVerifyCode(phone, code)) {
|
|
|
|
|
- throw new ServiceException("验证码错误");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ String phoneTail = dto.getPhoneTail();
|
|
|
|
|
|
|
|
// 查询订单
|
|
// 查询订单
|
|
|
TOrder order = baseMapper.selectOne(Wrappers.lambdaQuery(TOrder.class)
|
|
TOrder order = baseMapper.selectOne(Wrappers.lambdaQuery(TOrder.class)
|
|
|
- .select(TOrder::getId, TOrder::getMerchantId, TOrder::getStatus)
|
|
|
|
|
|
|
+ .select(TOrder::getId, TOrder::getMerchantId, TOrder::getExecStatus, TOrder::getContactPhoneNumber)
|
|
|
.eq(TOrder::getId, orderId)
|
|
.eq(TOrder::getId, orderId)
|
|
|
.eq(TOrder::getMerchantId, merchantId)
|
|
.eq(TOrder::getMerchantId, merchantId)
|
|
|
.eq(TOrder::getIsDelete, NOT_DELETE));
|
|
.eq(TOrder::getIsDelete, NOT_DELETE));
|
|
@@ -1053,26 +1053,44 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
throw new ServiceException("订单不存在或不属于当前商户");
|
|
throw new ServiceException("订单不存在或不属于当前商户");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 状态仅允许待服务
|
|
|
|
|
- Integer status = order.getStatus();
|
|
|
|
|
- if (!OrderStatusEnum.PENDING_SERVICE.getCode().equals(status)) {
|
|
|
|
|
- throw new ServiceException("仅【待服务】订单可签到到达,当前状态:" + OrderStatusEnum.getInfoByCode(status));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Integer execStatus = order.getExecStatus();
|
|
|
|
|
|
|
|
- // 更新到达信息
|
|
|
|
|
|
|
+ // 更新签到信息、履约信息
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
LambdaUpdateWrapper<TOrder> update = Wrappers.lambdaUpdate(TOrder.class)
|
|
LambdaUpdateWrapper<TOrder> update = Wrappers.lambdaUpdate(TOrder.class)
|
|
|
- .set(TOrder::getArrivedTime, now)
|
|
|
|
|
- .set(TOrder::getSignTime, now)
|
|
|
|
|
.set(TOrder::getUpdateTime, now)
|
|
.set(TOrder::getUpdateTime, now)
|
|
|
.set(TOrder::getUpdateBy, loginUser.getCNickName())
|
|
.set(TOrder::getUpdateBy, loginUser.getCNickName())
|
|
|
- .set(TOrder::getArrivalPhoto, StrUtil.join(",", dto.getImageUrls()))
|
|
|
|
|
- .eq(TOrder::getId, orderId)
|
|
|
|
|
- .eq(TOrder::getStatus, status);
|
|
|
|
|
|
|
+ .set(TOrder::getExecStatus, ExecStatusEnum.ARRIVED.getCode())
|
|
|
|
|
+ .eq(TOrder::getId, orderId);
|
|
|
|
|
+
|
|
|
|
|
+ // 自动区分两种业务:phoneTail非空=签到;空=纯到达
|
|
|
|
|
+ boolean isSignMode = StrUtil.isNotBlank(phoneTail);
|
|
|
|
|
+ if (isSignMode) {
|
|
|
|
|
+ log.info("商户上门签到操作,订单ID:{},商户ID:{},客户尾号:{}", orderId, merchantId, phoneTail);
|
|
|
|
|
+ if (ObjectUtil.notEqual(ExecStatusEnum.WAIT_DEPART.getCode(), execStatus)) {
|
|
|
|
|
+ throw new ServiceException("仅【待出发】订单可签到,当前状态:" + ExecStatusEnum.getInfoByCode(execStatus));
|
|
|
|
|
+ }
|
|
|
|
|
+ // 上门签到:执行全部手机号校验、状态强限制、写入signTime
|
|
|
|
|
+ if (phoneTail.length() != 4 || !StrUtil.isNumeric(phoneTail)) {
|
|
|
|
|
+ throw new ServiceException("手机号后4位必须为4位数字");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!PhoneUtils.matchPhoneTail4(order.getContactPhoneNumber(), phoneTail)) {
|
|
|
|
|
+ throw new ServiceException("手机号后4位不正确");
|
|
|
|
|
+ }
|
|
|
|
|
+ update.set(TOrder::getSignTime, now);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.info("纯标记订单到达操作,订单ID:{},商户ID:{}", orderId, merchantId);
|
|
|
|
|
+ if (ObjectUtil.notEqual(ExecStatusEnum.DEPARTED.getCode(), execStatus)) {
|
|
|
|
|
+ throw new ServiceException("仅【待出发】订单可签到,当前状态:" + ExecStatusEnum.getInfoByCode(execStatus));
|
|
|
|
|
+ }
|
|
|
|
|
+ update.set(TOrder::getArrivedTime, now);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
int count = baseMapper.update(null, update);
|
|
int count = baseMapper.update(null, update);
|
|
|
if (count <= 0) {
|
|
if (count <= 0) {
|
|
|
- throw new ServiceException("订单状态已变更,请刷新重试");
|
|
|
|
|
|
|
+ throw new ServiceException("订单履约状态已变更,请刷新重试");
|
|
|
}
|
|
}
|
|
|
|
|
+ log.info("订单到达操作执行完成,订单ID:{}", orderId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -1117,7 +1135,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
vo.setAppointmentTimeRange(formatTimeRange(order.getAppointmentStartTime(), order.getProjectDuration()));
|
|
vo.setAppointmentTimeRange(formatTimeRange(order.getAppointmentStartTime(), order.getProjectDuration()));
|
|
|
|
|
|
|
|
// 3. 联系信息脱敏处理
|
|
// 3. 联系信息脱敏处理
|
|
|
- vo.setContactPhoneNumber(PhoneUtils.maskPhoneNumber(order.getContactPhoneNumber()));
|
|
|
|
|
|
|
+ vo.setContactPhoneNumber(PhoneUtils.maskPhoneNumberStrict(order.getContactPhoneNumber()));
|
|
|
|
|
|
|
|
// 4. 计算距离与告警提示 (依赖地理围栏表 t_geo_fence)
|
|
// 4. 计算距离与告警提示 (依赖地理围栏表 t_geo_fence)
|
|
|
List<TGeoFence> validFenceList = geoFenceService.selectValidFences(order.getCityCode());
|
|
List<TGeoFence> validFenceList = geoFenceService.selectValidFences(order.getCityCode());
|
|
@@ -1188,6 +1206,46 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
|
|
|
return voList;
|
|
return voList;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void startGoOut(MerchantOrderOperateDTO dto) {
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 获取当前登录商户
|
|
|
|
|
+ WxLoginUser loginUser = getCurrentWxLoginUser();
|
|
|
|
|
+ Long merchantId = Long.parseLong(loginUser.getId());
|
|
|
|
|
+ Long orderId = dto.getOrderId();
|
|
|
|
|
+
|
|
|
|
|
+ // 查询订单
|
|
|
|
|
+ TOrder order = baseMapper.selectOne(Wrappers.lambdaQuery(TOrder.class)
|
|
|
|
|
+ .select(TOrder::getId, TOrder::getMerchantId, TOrder::getStatus)
|
|
|
|
|
+ .eq(TOrder::getId, orderId)
|
|
|
|
|
+ .eq(TOrder::getMerchantId, merchantId)
|
|
|
|
|
+ .eq(TOrder::getIsDelete, NOT_DELETE));
|
|
|
|
|
+ if (ObjectUtil.isNull(order)) {
|
|
|
|
|
+ throw new ServiceException("订单不存在或不属于当前商户");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取履约状态
|
|
|
|
|
+ Integer execStatus = order.getExecStatus();
|
|
|
|
|
+ if (!ExecStatusEnum.WAIT_DEPART.getCode().equals(execStatus)) {
|
|
|
|
|
+ throw new ServiceException("仅【待出发/待签到】订单可修改为已出发,当前状态:" + ExecStatusEnum.getInfoByCode(execStatus));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新出发信息、履约信息
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ LambdaUpdateWrapper<TOrder> update = Wrappers.lambdaUpdate(TOrder.class)
|
|
|
|
|
+ .set(TOrder::getDepartedTime, now)
|
|
|
|
|
+ .set(TOrder::getUpdateTime, now)
|
|
|
|
|
+ .set(TOrder::getUpdateBy, loginUser.getCNickName())
|
|
|
|
|
+ .set(TOrder::getExecStatus, ExecStatusEnum.DEPARTED.getCode())
|
|
|
|
|
+ .eq(TOrder::getId, orderId);
|
|
|
|
|
+ int count = baseMapper.update(null, update);
|
|
|
|
|
+ if (count <= 0) {
|
|
|
|
|
+ throw new ServiceException("订单履约状态已变更,请刷新重试");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 判断预约时段是否与已有订单冲突(含30分钟缓冲)
|
|
* 判断预约时段是否与已有订单冲突(含30分钟缓冲)
|
|
|
*/
|
|
*/
|