Przeglądaj źródła

收银台功能 服务费 功能修改 合表修改

liudongzhi 2 tygodni temu
rodzic
commit
6d95885038

+ 17 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreServiceFeeRule.java

@@ -12,6 +12,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.time.LocalTime;
 import java.util.Date;
 
 /**
@@ -59,6 +60,22 @@ public class StoreServiceFeeRule {
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date endDate;
 
+    @ApiModelProperty("桌台ID")
+    @TableField("table_id")
+    private Integer tableId;
+
+    @ApiModelProperty("星期掩码,按位表示周一到周日(示例:周一+周三 = 5)")
+    @TableField("weekday_mask")
+    private Integer weekdayMask;
+
+    @ApiModelProperty("开始时间")
+    @TableField("start_time")
+    private LocalTime startTime;
+
+    @ApiModelProperty("结束时间")
+    @TableField("end_time")
+    private LocalTime endTime;
+
     @TableLogic
     @TableField("delete_flag")
     private Integer deleteFlag;

+ 133 - 214
alien-store/src/main/java/shop/alien/store/service/impl/StoreServiceFeeRuleServiceImpl.java

@@ -2,7 +2,6 @@ package shop.alien.store.service.impl;
 
 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.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
@@ -12,16 +11,12 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.StoreServiceFeeRule;
-import shop.alien.entity.store.StoreServiceFeeRuleSlot;
-import shop.alien.entity.store.StoreServiceFeeRuleTable;
 import shop.alien.entity.store.dto.StoreServiceFeeRuleSaveDto;
 import shop.alien.entity.store.dto.StoreServiceFeeRuleSlotDto;
 import shop.alien.entity.store.vo.StoreBookingTableVo;
 import shop.alien.entity.store.vo.StoreServiceFeeRuleDetailVo;
 import shop.alien.entity.store.vo.StoreServiceFeeRuleListVo;
 import shop.alien.mapper.StoreServiceFeeRuleMapper;
-import shop.alien.mapper.StoreServiceFeeRuleSlotMapper;
-import shop.alien.mapper.StoreServiceFeeRuleTableMapper;
 import shop.alien.store.service.StoreBookingTableService;
 import shop.alien.store.service.StoreServiceFeeRuleService;
 import shop.alien.util.common.JwtUtil;
@@ -55,8 +50,6 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
     private final StoreServiceFeeRuleMapper ruleMapper;
-    private final StoreServiceFeeRuleTableMapper ruleTableMapper;
-    private final StoreServiceFeeRuleSlotMapper ruleSlotMapper;
     private final StoreBookingTableService storeBookingTableService;
 
     @Override
@@ -78,26 +71,38 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         wrapper.orderByDesc(StoreServiceFeeRule::getUpdatedTime);
         IPage<StoreServiceFeeRule> rulePage = ruleMapper.selectPage(page, wrapper);
 
-        List<Integer> ruleIds = rulePage.getRecords().stream().map(StoreServiceFeeRule::getId).collect(Collectors.toList());
-        Map<Integer, Integer> tableCountMap = buildRuleTableCountMap(ruleIds);
-        Map<Integer, List<String>> ruleTableNamesMap = buildRuleTableNamesMap(storeId, ruleIds);
-
-        List<StoreServiceFeeRuleListVo> records = rulePage.getRecords().stream().map(rule -> {
-            StoreServiceFeeRuleListVo vo = new StoreServiceFeeRuleListVo();
-            vo.setId(rule.getId());
-            vo.setStoreId(rule.getStoreId());
-            vo.setFeeName(rule.getFeeName());
-            vo.setFeeType(rule.getFeeType());
-            vo.setFeeValue(rule.getFeeValue());
-            vo.setStatus(rule.getStatus());
-            vo.setEffectiveMode(rule.getEffectiveMode());
-            vo.setUpdatedTime(rule.getUpdatedTime());
-            vo.setTableCount(tableCountMap.getOrDefault(rule.getId(), 0));
-            vo.setTableNameList(ruleTableNamesMap.getOrDefault(rule.getId(), Collections.emptyList()));
-            return vo;
-        }).collect(Collectors.toList());
-
-        Page<StoreServiceFeeRuleListVo> result = new Page<>(pn, ps, rulePage.getTotal());
+        Map<String, List<StoreServiceFeeRule>> grouped = rulePage.getRecords().stream()
+                .collect(Collectors.groupingBy(this::groupKey));
+        Map<Integer, String> tableIdNameMap = storeBookingTableService.getTableListWithCategoryName(storeId, null).stream()
+                .collect(Collectors.toMap(StoreBookingTableVo::getId, StoreBookingTableVo::getTableNumber, (a, b) -> a));
+
+        List<StoreServiceFeeRuleListVo> records = new ArrayList<>();
+        for (List<StoreServiceFeeRule> group : grouped.values()) {
+            StoreServiceFeeRule head = group.get(0);
+            // 按桌台展开:每个桌台一条记录
+            Map<Integer, List<StoreServiceFeeRule>> byTable = group.stream()
+                    .filter(r -> r.getTableId() != null)
+                    .collect(Collectors.groupingBy(StoreServiceFeeRule::getTableId));
+            for (Map.Entry<Integer, List<StoreServiceFeeRule>> entry : byTable.entrySet()) {
+                Integer tableId = entry.getKey();
+                List<StoreServiceFeeRule> tableRows = entry.getValue();
+                StoreServiceFeeRuleListVo vo = new StoreServiceFeeRuleListVo();
+                vo.setId(tableRows.stream().map(StoreServiceFeeRule::getId).min(Integer::compareTo).orElse(head.getId()));
+                vo.setStoreId(head.getStoreId());
+                vo.setFeeName(head.getFeeName());
+                vo.setFeeType(head.getFeeType());
+                vo.setFeeValue(head.getFeeValue());
+                vo.setStatus(head.getStatus());
+                vo.setEffectiveMode(head.getEffectiveMode());
+                vo.setUpdatedTime(tableRows.stream().map(StoreServiceFeeRule::getUpdatedTime).filter(d -> d != null).max(Date::compareTo).orElse(head.getUpdatedTime()));
+                String tableName = tableIdNameMap.getOrDefault(tableId, "");
+                vo.setTableCount(1);
+                vo.setTableNameList(StringUtils.hasText(tableName) ? Collections.singletonList(tableName) : Collections.emptyList());
+                records.add(vo);
+            }
+        }
+
+        Page<StoreServiceFeeRuleListVo> result = new Page<>(pn, ps, records.size());
         result.setRecords(records);
         return R.data(result);
     }
@@ -112,6 +117,27 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
             return R.fail("服务费规则不存在");
         }
 
+        // 同组且同桌台的规则(用于编辑当前桌台下的时段)
+        LambdaQueryWrapper<StoreServiceFeeRule> sameGroupWrapper = new LambdaQueryWrapper<StoreServiceFeeRule>()
+                .eq(StoreServiceFeeRule::getStoreId, rule.getStoreId())
+                .eq(StoreServiceFeeRule::getFeeName, rule.getFeeName())
+                .eq(StoreServiceFeeRule::getFeeType, rule.getFeeType())
+                .eq(StoreServiceFeeRule::getFeeValue, rule.getFeeValue())
+                .eq(StoreServiceFeeRule::getStatus, rule.getStatus())
+                .eq(StoreServiceFeeRule::getEffectiveMode, rule.getEffectiveMode())
+                .eq(StoreServiceFeeRule::getTableId, rule.getTableId());
+        if (rule.getStartDate() == null) {
+            sameGroupWrapper.isNull(StoreServiceFeeRule::getStartDate);
+        } else {
+            sameGroupWrapper.eq(StoreServiceFeeRule::getStartDate, rule.getStartDate());
+        }
+        if (rule.getEndDate() == null) {
+            sameGroupWrapper.isNull(StoreServiceFeeRule::getEndDate);
+        } else {
+            sameGroupWrapper.eq(StoreServiceFeeRule::getEndDate, rule.getEndDate());
+        }
+        List<StoreServiceFeeRule> sameGroupSameTable = ruleMapper.selectList(sameGroupWrapper);
+
         StoreServiceFeeRuleDetailVo vo = new StoreServiceFeeRuleDetailVo();
         vo.setId(rule.getId());
         vo.setStoreId(rule.getStoreId());
@@ -122,14 +148,16 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         vo.setEffectiveMode(rule.getEffectiveMode());
         vo.setStartDate(formatDate(rule.getStartDate()));
         vo.setEndDate(formatDate(rule.getEndDate()));
-
-        List<StoreServiceFeeRuleTable> tableList = ruleTableMapper.selectList(
-                new LambdaQueryWrapper<StoreServiceFeeRuleTable>().eq(StoreServiceFeeRuleTable::getRuleId, id));
-        vo.setTableIds(tableList.stream().map(StoreServiceFeeRuleTable::getTableId).collect(Collectors.toList()));
-
-        List<StoreServiceFeeRuleSlot> slotList = ruleSlotMapper.selectList(
-                new LambdaQueryWrapper<StoreServiceFeeRuleSlot>().eq(StoreServiceFeeRuleSlot::getRuleId, id));
-        vo.setSlots(slotList.stream().map(this::toSlotDto).collect(Collectors.toList()));
+        // 仅返回当前卡片对应的桌台
+        vo.setTableIds(rule.getTableId() == null ? Collections.emptyList() : Collections.singletonList(rule.getTableId()));
+        // 仅返回当前桌台下该服务费名称的时段
+        vo.setSlots(sameGroupSameTable.stream().map(r -> {
+            StoreServiceFeeRuleSlotDto s = new StoreServiceFeeRuleSlotDto();
+            s.setWeekdayMask(r.getWeekdayMask());
+            s.setStartTime(r.getStartTime() != null ? r.getStartTime().format(TIME_FORMATTER) : null);
+            s.setEndTime(r.getEndTime() != null ? r.getEndTime().format(TIME_FORMATTER) : null);
+            return s;
+        }).collect(Collectors.toList()));
         log.info("StoreServiceFeeRuleServiceImpl.getRuleDetail?接口出参vo={}", vo);
         return R.data(vo);
     }
@@ -142,15 +170,19 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
             return R.fail(checkMsg);
         }
         Integer userId = getCurrentUserId();
-        // 以桌为主体,选择了几个桌就生成几条主表记录
+        // 以桌台 × 时段为粒度写入主表多行
         List<Integer> createdIds = new ArrayList<>();
         for (Integer tableId : dto.getTableIds()) {
-            StoreServiceFeeRule rule = new StoreServiceFeeRule();
-            fillRuleFromDto(rule, dto, userId, false);
-            ruleMapper.insert(rule);
-            // 为该条主表记录仅绑定当前桌台,并写入时段
-            saveChildrenForSingleTable(rule.getId(), dto, tableId, userId);
-            createdIds.add(rule.getId());
+            for (StoreServiceFeeRuleSlotDto slot : dto.getSlots()) {
+                StoreServiceFeeRule rule = new StoreServiceFeeRule();
+                fillRuleFromDto(rule, dto, userId, false);
+                rule.setTableId(tableId);
+                rule.setWeekdayMask(slot.getWeekdayMask());
+                rule.setStartTime(LocalTime.parse(slot.getStartTime(), TIME_FORMATTER));
+                rule.setEndTime(LocalTime.parse(slot.getEndTime(), TIME_FORMATTER));
+                ruleMapper.insert(rule);
+                createdIds.add(rule.getId());
+            }
         }
         return R.data(createdIds);
     }
@@ -169,15 +201,31 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
             return R.fail(checkMsg);
         }
 
+        // 删除同组旧记录并重建
+        List<StoreServiceFeeRule> sameGroup = ruleMapper.selectList(new LambdaQueryWrapper<StoreServiceFeeRule>()
+                .eq(StoreServiceFeeRule::getStoreId, existing.getStoreId())
+                .eq(StoreServiceFeeRule::getFeeName, existing.getFeeName())
+                .eq(StoreServiceFeeRule::getFeeType, existing.getFeeType())
+                .eq(StoreServiceFeeRule::getFeeValue, existing.getFeeValue())
+                .eq(StoreServiceFeeRule::getStatus, existing.getStatus())
+                .eq(StoreServiceFeeRule::getEffectiveMode, existing.getEffectiveMode())
+                .eq(StoreServiceFeeRule::getStartDate, existing.getStartDate())
+                .eq(StoreServiceFeeRule::getEndDate, existing.getEndDate()));
+        for (StoreServiceFeeRule r : sameGroup) {
+            ruleMapper.deleteById(r.getId());
+        }
         Integer userId = getCurrentUserId();
-        StoreServiceFeeRule updateRule = new StoreServiceFeeRule();
-        updateRule.setId(dto.getId());
-        fillRuleFromDto(updateRule, dto, userId, true);
-        ruleMapper.updateById(updateRule);
-
-        ruleTableMapper.delete(new LambdaQueryWrapper<StoreServiceFeeRuleTable>().eq(StoreServiceFeeRuleTable::getRuleId, dto.getId()));
-        ruleSlotMapper.delete(new LambdaQueryWrapper<StoreServiceFeeRuleSlot>().eq(StoreServiceFeeRuleSlot::getRuleId, dto.getId()));
-        saveChildren(dto.getId(), dto, userId);
+        for (Integer tableId : dto.getTableIds()) {
+            for (StoreServiceFeeRuleSlotDto slotDto : dto.getSlots()) {
+                StoreServiceFeeRule rule = new StoreServiceFeeRule();
+                fillRuleFromDto(rule, dto, userId, true);
+                rule.setTableId(tableId);
+                rule.setWeekdayMask(slotDto.getWeekdayMask());
+                rule.setStartTime(LocalTime.parse(slotDto.getStartTime(), TIME_FORMATTER));
+                rule.setEndTime(LocalTime.parse(slotDto.getEndTime(), TIME_FORMATTER));
+                ruleMapper.insert(rule);
+            }
+        }
         return R.data(true);
     }
 
@@ -190,9 +238,15 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         if (existing == null) {
             return R.fail("服务费规则不存在");
         }
-        ruleMapper.deleteById(id);
-        ruleTableMapper.delete(new LambdaQueryWrapper<StoreServiceFeeRuleTable>().eq(StoreServiceFeeRuleTable::getRuleId, id));
-        ruleSlotMapper.delete(new LambdaQueryWrapper<StoreServiceFeeRuleSlot>().eq(StoreServiceFeeRuleSlot::getRuleId, id));
+        ruleMapper.delete(new LambdaQueryWrapper<StoreServiceFeeRule>()
+                .eq(StoreServiceFeeRule::getStoreId, existing.getStoreId())
+                .eq(StoreServiceFeeRule::getFeeName, existing.getFeeName())
+                .eq(StoreServiceFeeRule::getFeeType, existing.getFeeType())
+                .eq(StoreServiceFeeRule::getFeeValue, existing.getFeeValue())
+                .eq(StoreServiceFeeRule::getStatus, existing.getStatus())
+                .eq(StoreServiceFeeRule::getEffectiveMode, existing.getEffectiveMode())
+                .eq(StoreServiceFeeRule::getStartDate, existing.getStartDate())
+                .eq(StoreServiceFeeRule::getEndDate, existing.getEndDate()));
         return R.data(true);
     }
 
@@ -224,21 +278,10 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         if (candidates == null || candidates.isEmpty()) {
             return 0;
         }
-        List<Integer> ruleIds = candidates.stream().map(StoreServiceFeeRule::getId).collect(Collectors.toList());
-        List<StoreServiceFeeRuleSlot> allSlots = ruleSlotMapper.selectList(
-                new LambdaQueryWrapper<StoreServiceFeeRuleSlot>().in(StoreServiceFeeRuleSlot::getRuleId, ruleIds));
-        Map<Integer, List<StoreServiceFeeRuleSlot>> slotMap = allSlots.stream()
-                .collect(Collectors.groupingBy(StoreServiceFeeRuleSlot::getRuleId));
-
         int closed = 0;
         for (StoreServiceFeeRule rule : candidates) {
             LocalDate endDate = new java.sql.Date(rule.getEndDate().getTime()).toLocalDate();
-            LocalTime maxEndTime = slotMap.getOrDefault(rule.getId(), Collections.emptyList())
-                    .stream()
-                    .map(StoreServiceFeeRuleSlot::getEndTime)
-                    .filter(t -> t != null)
-                    .max(LocalTime::compareTo)
-                    .orElse(LocalTime.of(23, 59, 59));
+            LocalTime maxEndTime = rule.getEndTime() != null ? rule.getEndTime() : LocalTime.of(23, 59, 59);
             LocalDateTime expireAt = LocalDateTime.of(endDate, maxEndTime);
             if (!now.isBefore(expireAt)) {
                 StoreServiceFeeRule update = new StoreServiceFeeRule();
@@ -256,44 +299,9 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         return closed;
     }
 
-    private Map<Integer, Integer> buildRuleTableCountMap(List<Integer> ruleIds) {
-        if (ruleIds == null || ruleIds.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        List<StoreServiceFeeRuleTable> tableList = ruleTableMapper.selectList(
-                new LambdaQueryWrapper<StoreServiceFeeRuleTable>().in(StoreServiceFeeRuleTable::getRuleId, ruleIds));
-        Map<Integer, Set<Integer>> temp = new HashMap<>();
-        for (StoreServiceFeeRuleTable row : tableList) {
-            temp.computeIfAbsent(row.getRuleId(), k -> new HashSet<>()).add(row.getTableId());
-        }
-        Map<Integer, Integer> countMap = new HashMap<>();
-        temp.forEach((k, v) -> countMap.put(k, v.size()));
-        return countMap;
-    }
-
-    private Map<Integer, List<String>> buildRuleTableNamesMap(Integer storeId, List<Integer> ruleIds) {
-        if (ruleIds == null || ruleIds.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        List<StoreServiceFeeRuleTable> relations = ruleTableMapper.selectList(
-                new LambdaQueryWrapper<StoreServiceFeeRuleTable>().in(StoreServiceFeeRuleTable::getRuleId, ruleIds));
-        if (relations == null || relations.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        Map<Integer, String> tableIdNameMap = storeBookingTableService.getTableListWithCategoryName(storeId, null).stream()
-                .collect(Collectors.toMap(StoreBookingTableVo::getId, StoreBookingTableVo::getTableNumber, (a, b) -> a));
-
-        Map<Integer, List<String>> groupedNames = new HashMap<>();
-        for (StoreServiceFeeRuleTable relation : relations) {
-            String tableNumber = tableIdNameMap.get(relation.getTableId());
-            if (!StringUtils.hasText(tableNumber)) {
-                continue;
-            }
-            groupedNames.computeIfAbsent(relation.getRuleId(), k -> new ArrayList<>()).add(tableNumber);
-        }
-        Map<Integer, List<String>> result = new HashMap<>();
-        groupedNames.forEach((ruleId, names) -> result.put(ruleId, names.stream().distinct().collect(Collectors.toList())));
-        return result;
+    private String groupKey(StoreServiceFeeRule r) {
+        return r.getStoreId() + "|" + r.getFeeName() + "|" + r.getFeeType() + "|" + r.getFeeValue() + "|" + r.getStatus()
+                + "|" + r.getEffectiveMode() + "|" + formatDate(r.getStartDate()) + "|" + formatDate(r.getEndDate());
     }
 
     private void fillRuleFromDto(StoreServiceFeeRule rule, StoreServiceFeeRuleSaveDto dto, Integer userId, boolean isUpdate) {
@@ -317,49 +325,7 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         }
     }
 
-    private void saveChildren(Integer ruleId, StoreServiceFeeRuleSaveDto dto, Integer userId) {
-        for (Integer tableId : dto.getTableIds()) {
-            StoreServiceFeeRuleTable row = new StoreServiceFeeRuleTable();
-            row.setRuleId(ruleId);
-            row.setStoreId(dto.getStoreId());
-            row.setTableId(tableId);
-            row.setCreatedUserId(userId);
-            row.setUpdatedUserId(userId);
-            ruleTableMapper.insert(row);
-        }
-
-        for (StoreServiceFeeRuleSlotDto slotDto : dto.getSlots()) {
-            StoreServiceFeeRuleSlot slot = new StoreServiceFeeRuleSlot();
-            slot.setRuleId(ruleId);
-            slot.setWeekdayMask(slotDto.getWeekdayMask());
-            slot.setStartTime(LocalTime.parse(slotDto.getStartTime(), TIME_FORMATTER));
-            slot.setEndTime(LocalTime.parse(slotDto.getEndTime(), TIME_FORMATTER));
-            slot.setCreatedUserId(userId);
-            slot.setUpdatedUserId(userId);
-            ruleSlotMapper.insert(slot);
-        }
-    }
-
-    private void saveChildrenForSingleTable(Integer ruleId, StoreServiceFeeRuleSaveDto dto, Integer tableId, Integer userId) {
-        StoreServiceFeeRuleTable row = new StoreServiceFeeRuleTable();
-        row.setRuleId(ruleId);
-        row.setStoreId(dto.getStoreId());
-        row.setTableId(tableId);
-        row.setCreatedUserId(userId);
-        row.setUpdatedUserId(userId);
-        ruleTableMapper.insert(row);
-
-        for (StoreServiceFeeRuleSlotDto slotDto : dto.getSlots()) {
-            StoreServiceFeeRuleSlot slot = new StoreServiceFeeRuleSlot();
-            slot.setRuleId(ruleId);
-            slot.setWeekdayMask(slotDto.getWeekdayMask());
-            slot.setStartTime(LocalTime.parse(slotDto.getStartTime(), TIME_FORMATTER));
-            slot.setEndTime(LocalTime.parse(slotDto.getEndTime(), TIME_FORMATTER));
-            slot.setCreatedUserId(userId);
-            slot.setUpdatedUserId(userId);
-            ruleSlotMapper.insert(slot);
-        }
-    }
+    // 子表已合并到主表,辅助保存方法不再需要
 
     private String validateAndCheckConflict(StoreServiceFeeRuleSaveDto dto, Integer excludeRuleId) {
         String basicMsg = validateBasic(dto);
@@ -371,28 +337,15 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         List<Integer> tableIdsForNameCheck = dto.getTableIds() == null ? Collections.emptyList()
                 : dto.getTableIds().stream().distinct().collect(Collectors.toList());
         if (!tableIdsForNameCheck.isEmpty()) {
-            List<StoreServiceFeeRuleTable> sameTableRelations = ruleTableMapper.selectList(
-                    new LambdaQueryWrapper<StoreServiceFeeRuleTable>()
-                            .eq(StoreServiceFeeRuleTable::getStoreId, dto.getStoreId())
-                            .in(StoreServiceFeeRuleTable::getTableId, tableIdsForNameCheck));
-            if (!sameTableRelations.isEmpty()) {
-                List<Integer> sameTableRuleIds = sameTableRelations.stream()
-                        .map(StoreServiceFeeRuleTable::getRuleId)
-                        .distinct()
-                        .collect(Collectors.toList());
-                if (excludeRuleId != null) {
-                    sameTableRuleIds = sameTableRuleIds.stream()
-                            .filter(id -> !id.equals(excludeRuleId))
-                            .collect(Collectors.toList());
-                }
-                if (!sameTableRuleIds.isEmpty()) {
-                    LambdaQueryWrapper<StoreServiceFeeRule> sameTableNameWrapper = new LambdaQueryWrapper<>();
-                    sameTableNameWrapper.in(StoreServiceFeeRule::getId, sameTableRuleIds)
-                            .eq(StoreServiceFeeRule::getFeeName, dto.getFeeName().trim());
-                    if (ruleMapper.selectCount(sameTableNameWrapper) > 0) {
-                        return "同桌台下服务费名称已存在";
-                    }
-                }
+            LambdaQueryWrapper<StoreServiceFeeRule> sameName = new LambdaQueryWrapper<>();
+            sameName.eq(StoreServiceFeeRule::getStoreId, dto.getStoreId())
+                    .in(StoreServiceFeeRule::getTableId, tableIdsForNameCheck)
+                    .eq(StoreServiceFeeRule::getFeeName, dto.getFeeName().trim());
+            if (excludeRuleId != null) {
+                sameName.ne(StoreServiceFeeRule::getId, excludeRuleId);
+            }
+            if (ruleMapper.selectCount(sameName) > 0) {
+                return "同桌台下服务费名称已存在";
             }
         }
 
@@ -463,24 +416,9 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
 
     private String checkTimeConflict(StoreServiceFeeRuleSaveDto dto, Integer excludeRuleId) {
         List<Integer> tableIds = dto.getTableIds().stream().distinct().collect(Collectors.toList());
-        // 找到这些桌台对应的已启用规则
-        LambdaQueryWrapper<StoreServiceFeeRuleTable> tableWrapper = new LambdaQueryWrapper<>();
-        tableWrapper.eq(StoreServiceFeeRuleTable::getStoreId, dto.getStoreId())
-                .in(StoreServiceFeeRuleTable::getTableId, tableIds);
-        List<StoreServiceFeeRuleTable> relationList = ruleTableMapper.selectList(tableWrapper);
-        if (relationList.isEmpty()) {
-            return null;
-        }
-
-        Map<Integer, Set<Integer>> ruleTableMap = new HashMap<>();
-        for (StoreServiceFeeRuleTable rt : relationList) {
-            ruleTableMap.computeIfAbsent(rt.getRuleId(), k -> new HashSet<>()).add(rt.getTableId());
-        }
-
-        List<Integer> candidateRuleIds = new ArrayList<>(ruleTableMap.keySet());
         LambdaQueryWrapper<StoreServiceFeeRule> ruleWrapper = new LambdaQueryWrapper<>();
-        ruleWrapper.in(StoreServiceFeeRule::getId, candidateRuleIds)
-                .eq(StoreServiceFeeRule::getStoreId, dto.getStoreId())
+        ruleWrapper.eq(StoreServiceFeeRule::getStoreId, dto.getStoreId())
+                .in(StoreServiceFeeRule::getTableId, tableIds)
                 .eq(StoreServiceFeeRule::getStatus, 1);
         if (excludeRuleId != null) {
             ruleWrapper.ne(StoreServiceFeeRule::getId, excludeRuleId);
@@ -489,11 +427,6 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         if (existRules.isEmpty()) {
             return null;
         }
-        List<Integer> validRuleIds = existRules.stream().map(StoreServiceFeeRule::getId).collect(Collectors.toList());
-        List<StoreServiceFeeRuleSlot> allExistSlots = ruleSlotMapper.selectList(
-                new LambdaQueryWrapper<StoreServiceFeeRuleSlot>().in(StoreServiceFeeRuleSlot::getRuleId, validRuleIds));
-        Map<Integer, List<StoreServiceFeeRuleSlot>> slotMap = allExistSlots.stream()
-                .collect(Collectors.groupingBy(StoreServiceFeeRuleSlot::getRuleId));
 
         Date newStartDate = MODE_CUSTOM.equals(dto.getEffectiveMode()) ? parseDate(dto.getStartDate()) : toDate(LocalDate.of(1970, 1, 1));
         Date newEndDate = MODE_CUSTOM.equals(dto.getEffectiveMode()) ? parseDate(dto.getEndDate()) : toDate(LocalDate.of(2099, 12, 31));
@@ -505,27 +438,19 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
             if (!isDateOverlap(newStartDate, newEndDate, oldStart, oldEnd)) {
                 continue;
             }
-            List<StoreServiceFeeRuleSlot> oldSlots = slotMap.getOrDefault(existRule.getId(), Collections.emptyList());
-            if (oldSlots.isEmpty()) {
-                continue;
-            }
             for (StoreServiceFeeRuleSlotDto ns : newSlots) {
                 LocalTime nsStart = LocalTime.parse(ns.getStartTime(), TIME_FORMATTER);
                 LocalTime nsEnd = LocalTime.parse(ns.getEndTime(), TIME_FORMATTER);
-                for (StoreServiceFeeRuleSlot os : oldSlots) {
-                    if ((ns.getWeekdayMask() & os.getWeekdayMask()) <= 0) {
-                        continue;
-                    }
-                    if (isTimeOverlap(nsStart, nsEnd, os.getStartTime(), os.getEndTime())) {
-                        Set<Integer> overlapTables = new HashSet<>(ruleTableMap.getOrDefault(existRule.getId(), Collections.emptySet()));
-                        overlapTables.retainAll(new HashSet<>(tableIds));
-                        if (!overlapTables.isEmpty()) {
-                            String tableTip = overlapTables.stream().sorted(Comparator.naturalOrder()).map(String::valueOf).collect(Collectors.joining(","));
-                            if (!dto.getFeeType().equals(existRule.getFeeType())) {
-                                return "桌台[" + tableTip + "]在该时间段已配置其他类型服务费";
-                            }
-                            return "桌台[" + tableTip + "]服务费时间重叠,请调整生效日期/星期/时间";
+                if ((ns.getWeekdayMask() & (existRule.getWeekdayMask() == null ? 0 : existRule.getWeekdayMask())) <= 0) {
+                    continue;
+                }
+                if (isTimeOverlap(nsStart, nsEnd, existRule.getStartTime(), existRule.getEndTime())) {
+                    Integer tableId = existRule.getTableId();
+                    if (tableId != null && tableIds.contains(tableId)) {
+                        if (!dto.getFeeType().equals(existRule.getFeeType())) {
+                            return "桌台[" + tableId + "]在该时间段已配置其他类型服务费";
                         }
+                        return "桌台[" + tableId + "]服务费时间重叠,请调整生效日期/星期/时间";
                     }
                 }
             }
@@ -557,13 +482,7 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         return java.sql.Date.valueOf(localDate);
     }
 
-    private StoreServiceFeeRuleSlotDto toSlotDto(StoreServiceFeeRuleSlot slot) {
-        StoreServiceFeeRuleSlotDto dto = new StoreServiceFeeRuleSlotDto();
-        dto.setWeekdayMask(slot.getWeekdayMask());
-        dto.setStartTime(slot.getStartTime() != null ? slot.getStartTime().format(TIME_FORMATTER) : null);
-        dto.setEndTime(slot.getEndTime() != null ? slot.getEndTime().format(TIME_FORMATTER) : null);
-        return dto;
-    }
+    // 子表已移除,无需转换方法
 
     private Integer getCurrentUserId() {
         try {