|
|
@@ -0,0 +1,246 @@
|
|
|
+package com.ylx.massage.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.ylx.common.exception.ServiceException;
|
|
|
+import com.ylx.common.utils.SecurityUtils;
|
|
|
+import com.ylx.common.utils.StringUtils;
|
|
|
+import com.ylx.massage.domain.TFareFreeRule;
|
|
|
+import com.ylx.massage.domain.TXiangmu;
|
|
|
+import com.ylx.massage.domain.vo.FareFreeRuleVo;
|
|
|
+import com.ylx.massage.domain.vo.TimeRangeVo;
|
|
|
+import com.ylx.massage.mapper.TFareFreeRuleMapper;
|
|
|
+import com.ylx.massage.service.TFareFreeRuleService;
|
|
|
+import com.ylx.massage.service.TXiangmuService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 免车费规则服务实现类
|
|
|
+ *
|
|
|
+ * @author system
|
|
|
+ * @since 2024-01-13
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class TFareFreeRuleServiceImpl extends ServiceImpl<TFareFreeRuleMapper, TFareFreeRule>
|
|
|
+ implements TFareFreeRuleService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TXiangmuService xiangmuService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增免车费规则
|
|
|
+ *
|
|
|
+ * @param fareFreeRule 免车费规则
|
|
|
+ * @return boolean 是否成功
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean addFareFreeRule(TFareFreeRule fareFreeRule) {
|
|
|
+ // 1. 参数校验
|
|
|
+ validateFareFreeRule(fareFreeRule);
|
|
|
+
|
|
|
+ // 2. 检查是否存在启用的规则
|
|
|
+ LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(TFareFreeRule::getTechId, fareFreeRule.getTechId()).eq(TFareFreeRule::getEnable, 1)
|
|
|
+ .eq(TFareFreeRule::getProjectId, fareFreeRule.getProjectId());
|
|
|
+ long count = this.count(wrapper);
|
|
|
+ if (count > 0) {
|
|
|
+ throw new ServiceException("已存在启用的免车费规则,请先禁用后再添加");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 设置时间
|
|
|
+ fareFreeRule.setCreateTime(LocalDateTime.now());
|
|
|
+ fareFreeRule.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ // 4. 保存
|
|
|
+ return this.save(fareFreeRule);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改免车费规则
|
|
|
+ *
|
|
|
+ * @param fareFreeRule 免车费规则
|
|
|
+ * @return 是否成功
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean updateFareFreeRule(TFareFreeRule fareFreeRule) {
|
|
|
+ // 1. 参数校验
|
|
|
+ if (StringUtils.isBlank(fareFreeRule.getId())) {
|
|
|
+ throw new ServiceException("规则ID不能为空");
|
|
|
+ }
|
|
|
+ validateFareFreeRule(fareFreeRule);
|
|
|
+
|
|
|
+ // 2. 查询原规则
|
|
|
+ TFareFreeRule existingRule = this.getById(fareFreeRule.getId());
|
|
|
+ if (existingRule == null) {
|
|
|
+ throw new ServiceException("免车费规则不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 4. 如果启用规则,检查是否存在其他启用的规则
|
|
|
+ if (fareFreeRule.getEnable() == 1 && !existingRule.getEnable().equals(fareFreeRule.getEnable())) {
|
|
|
+ LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(TFareFreeRule::getTechId, fareFreeRule.getTechId())
|
|
|
+ .eq(TFareFreeRule::getEnable, 1)
|
|
|
+ .ne(TFareFreeRule::getId, fareFreeRule.getId());
|
|
|
+ long count = this.count(wrapper);
|
|
|
+ if (count > 0) {
|
|
|
+ throw new ServiceException("已存在启用的免车费规则,请先禁用后再启用");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 更新时间
|
|
|
+ fareFreeRule.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ // 6. 更新
|
|
|
+ return this.updateById(fareFreeRule);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询免车费规则列表
|
|
|
+ *
|
|
|
+ * @param deptId 部门ID
|
|
|
+ * @return 免车费规则VO列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<FareFreeRuleVo> listFareFreeRules(String deptId) {
|
|
|
+ // 1. 查询规则列表
|
|
|
+ LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(TFareFreeRule::getTechId, deptId)
|
|
|
+ .orderByDesc(TFareFreeRule::getCreateTime);
|
|
|
+ List<TFareFreeRule> ruleList = this.list(wrapper);
|
|
|
+
|
|
|
+ // 2. 转换为VO
|
|
|
+ return ruleList.stream().map(rule -> {
|
|
|
+ FareFreeRuleVo vo = new FareFreeRuleVo();
|
|
|
+ BeanUtils.copyProperties(rule, vo);
|
|
|
+
|
|
|
+ // 转换时间段
|
|
|
+ if (CollectionUtil.isNotEmpty(rule.getTimeRanges())) {
|
|
|
+ List<TimeRangeVo> timeRangeVos = rule.getTimeRanges().stream().map(timeRange ->
|
|
|
+ TimeRangeVo.builder()
|
|
|
+ .startTime(timeRange.getStartTime())
|
|
|
+ .endTime(timeRange.getEndTime())
|
|
|
+ .build()
|
|
|
+ ).collect(Collectors.toList());
|
|
|
+ vo.setTimeRanges(timeRangeVos);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询项目名称
|
|
|
+ if (StringUtils.isNotBlank(rule.getProjectId())) {
|
|
|
+ String projectNames = "";
|
|
|
+ TXiangmu xiangmu = xiangmuService.getById(rule.getProjectId());
|
|
|
+ if (xiangmu != null && StringUtils.isNotBlank(xiangmu.getcTitle())) {
|
|
|
+ projectNames = xiangmu.getcTitle();
|
|
|
+ }
|
|
|
+ vo.setProjectNames(projectNames.isEmpty() ? null : projectNames);
|
|
|
+ }
|
|
|
+
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断订单是否满足免车费条件
|
|
|
+ *
|
|
|
+ * @param projectIds 服务项目ID列表
|
|
|
+ * @param distance 订单距离(公里)
|
|
|
+ * @param deptId 部门ID
|
|
|
+ * @return true-免车费,false-不免车费
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public boolean isFareFree(List<String> projectIds, Integer distance, String deptId) {
|
|
|
+ // 1. 参数校验
|
|
|
+ if (CollectionUtil.isEmpty(projectIds) || distance == null || distance <= 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查询启用的免车费规则
|
|
|
+ LambdaQueryWrapper<TFareFreeRule> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(TFareFreeRule::getTechId, deptId)
|
|
|
+ .eq(TFareFreeRule::getEnable, 1)
|
|
|
+ .eq(TFareFreeRule::getIsDelete, 0)
|
|
|
+ .last("LIMIT 1");
|
|
|
+ TFareFreeRule rule = this.getOne(wrapper);
|
|
|
+
|
|
|
+ // 3. 如果没有启用的规则,不免车费
|
|
|
+ if (rule == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 校验服务项目(订单的项目ID必须在规则的项目ID列表中)
|
|
|
+ if (StringUtils.isBlank(rule.getProjectId())) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ boolean projectMatch = projectIds.stream()
|
|
|
+ .anyMatch(projectId -> rule.getProjectId().equals(projectId));
|
|
|
+ if (!projectMatch) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 校验距离(订单距离必须 >= 规则的最小距离)
|
|
|
+ if (distance < rule.getMinDistance()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 所有条件满足,免车费
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验免车费规则参数
|
|
|
+ *
|
|
|
+ * @param fareFreeRule 免车费规则
|
|
|
+ */
|
|
|
+ private void validateFareFreeRule(TFareFreeRule fareFreeRule) {
|
|
|
+ // 1. 校验服务项目
|
|
|
+ if (StringUtils.isBlank(fareFreeRule.getProjectId())) {
|
|
|
+ throw new ServiceException("请至少选择一个服务项目");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 校验时间段
|
|
|
+ if (CollectionUtil.isEmpty(fareFreeRule.getTimeRanges())) {
|
|
|
+ throw new ServiceException("请至少添加一个服务时间段");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 校验时间段格式
|
|
|
+ for (TFareFreeRule.TimeRange timeRange : fareFreeRule.getTimeRanges()) {
|
|
|
+ if (StringUtils.isBlank(timeRange.getStartTime()) || StringUtils.isBlank(timeRange.getEndTime())) {
|
|
|
+ throw new ServiceException("时间段开始时间和结束时间不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验时间格式
|
|
|
+ if (!timeRange.getStartTime().matches("^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$") ||
|
|
|
+ !timeRange.getEndTime().matches("^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")) {
|
|
|
+ throw new ServiceException("时间格式错误,请使用 HH:mm 格式(如:08:00)");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验时间范围
|
|
|
+ if (timeRange.getStartTime().compareTo(timeRange.getEndTime()) >= 0) {
|
|
|
+ throw new ServiceException("开始时间必须小于结束时间");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 校验距离
|
|
|
+ if (fareFreeRule.getMinDistance() == null || fareFreeRule.getMinDistance() <= 0) {
|
|
|
+ throw new ServiceException("订单距离必须大于0");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 校验是否启用
|
|
|
+ if (fareFreeRule.getEnable() == null || (fareFreeRule.getEnable() != 0 && fareFreeRule.getEnable() != 1)) {
|
|
|
+ throw new ServiceException("是否启用参数错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|