ソースを参照

Merge remote-tracking branch 'origin/sit-new-checkstand' into sit-new-checkstand

刘云鑫 2 週間 前
コミット
0c0503d576

+ 3 - 0
alien-dining/src/main/java/shop/alien/dining/AlienDiningApplication.java

@@ -6,9 +6,12 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
 import org.springframework.scheduling.annotation.EnableScheduling;
+import shop.alien.config.databases.MyBatisFieldHandler;
 
 @ComponentScan({"shop.alien.dining.*","shop.alien.util.*","shop.alien.config.http","shop.alien.config.properties"})
+@Import(MyBatisFieldHandler.class)
 @EnableSwaggerBootstrapUI
 @MapperScan({"shop.alien.mapper"})
 @SpringBootApplication

+ 0 - 2
alien-dining/src/main/java/shop/alien/dining/service/impl/DiningWalkInReservationServiceImpl.java

@@ -92,8 +92,6 @@ public class DiningWalkInReservationServiceImpl extends ServiceImpl<UserReservat
         entity.setReservationUserPhone(trimOrNull(dto.getReservationUserPhone()));
         entity.setCreatedUserId(userId);
         entity.setUpdatedUserId(userId);
-        entity.setCreatedTime(now);
-        entity.setUpdatedTime(now);
 
         this.save(entity);
 

+ 2 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreBookingTableVo.java

@@ -1,11 +1,13 @@
 package shop.alien.entity.store.vo;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * 预订服务桌号VO(包含分类名称)

+ 7 - 5
alien-store/src/main/java/shop/alien/store/controller/StoreBookingTableController.java

@@ -43,16 +43,18 @@ public class StoreBookingTableController {
             @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "Integer", paramType = "query", required = false),
             @ApiImplicitParam(name = "pageSize", value = "页容", dataType = "Integer", paramType = "query", required = false),
             @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query", required = true),
-            @ApiImplicitParam(name = "categoryId", value = "分类ID(可选,不传则查询全部)", dataType = "Integer", paramType = "query", required = false)
+            @ApiImplicitParam(name = "categoryId", value = "分类ID(可选,不传则查询全部)", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "type", value = "类型(1:美食 2:通用);不传则不过滤类型且排序同原逻辑", dataType = "Integer", paramType = "query", required = false)
     })
     @GetMapping("/list")
     public R<IPage<StoreBookingTableVo>> getTableList(
             @RequestParam(defaultValue = "1") Integer pageNum,
             @RequestParam(defaultValue = "10") Integer pageSize,
             @RequestParam Integer storeId,
-            @RequestParam(required = false) Integer categoryId) {
-        log.info("StoreBookingTableController.getTableList?pageNum={}, pageSize={}, storeId={}, categoryId={}", 
-                pageNum, pageSize, storeId, categoryId);
+            @RequestParam(required = false) Integer categoryId,
+            @RequestParam(required = false) Integer type) {
+        log.info("StoreBookingTableController.getTableList?pageNum={}, pageSize={}, storeId={}, categoryId={}, type={}", 
+                pageNum, pageSize, storeId, categoryId, type);
         
         if (storeId == null) {
             return R.fail("门店ID不能为空");
@@ -66,7 +68,7 @@ public class StoreBookingTableController {
         }
         
         try {
-            IPage<StoreBookingTableVo> page = storeBookingTableService.getTableListPage(pageNum, pageSize, storeId, categoryId);
+            IPage<StoreBookingTableVo> page = storeBookingTableService.getTableListPage(pageNum, pageSize, storeId, categoryId, type);
             return R.data(page);
         } catch (Exception e) {
             log.error("查询预订服务桌号列表失败", e);

+ 6 - 3
alien-store/src/main/java/shop/alien/store/service/StoreBookingTableService.java

@@ -21,18 +21,20 @@ public interface StoreBookingTableService extends IService<StoreTable> {
      *
      * @param storeId   门店ID
      * @param categoryId 分类ID(可选,null表示查询全部)
+     * @param type      类型(1:美食,2:通用);null 表示不按类型过滤且使用原排序(兼容旧调用)
      * @return List<StoreTable>
      */
-    List<StoreTable> getTableList(Integer storeId, Integer categoryId);
+    List<StoreTable> getTableList(Integer storeId, Integer categoryId, Integer type);
 
     /**
      * 查询预订服务桌号列表(包含分类名称)
      *
      * @param storeId   门店ID
      * @param categoryId 分类ID(可选,null表示查询全部)
+     * @param type      类型(1:美食,2:通用);null 表示不按类型过滤且使用原排序
      * @return List<StoreBookingTableVo>
      */
-    List<StoreBookingTableVo> getTableListWithCategoryName(Integer storeId, Integer categoryId);
+    List<StoreBookingTableVo> getTableListWithCategoryName(Integer storeId, Integer categoryId, Integer type);
 
     /**
      * 分页查询预订服务桌号列表(包含分类名称)
@@ -41,9 +43,10 @@ public interface StoreBookingTableService extends IService<StoreTable> {
      * @param pageSize  页容
      * @param storeId   门店ID
      * @param categoryId 分类ID(可选,null表示查询全部)
+     * @param type      类型(1:美食,2:通用);null 表示不按类型过滤且使用原排序
      * @return IPage<StoreBookingTableVo>
      */
-    IPage<StoreBookingTableVo> getTableListPage(Integer pageNum, Integer pageSize, Integer storeId, Integer categoryId);
+    IPage<StoreBookingTableVo> getTableListPage(Integer pageNum, Integer pageSize, Integer storeId, Integer categoryId, Integer type);
 
     /**
      * 按商户查询全部桌号,并按预订分类分组(商户ID 即门店 store_id)

+ 100 - 16
alien-store/src/main/java/shop/alien/store/service/impl/StoreBookingTableServiceImpl.java

@@ -24,10 +24,13 @@ import shop.alien.store.service.StoreBookingCategoryService;
 import shop.alien.store.service.StoreBookingTableService;
 import shop.alien.util.common.JwtUtil;
 
+import java.math.BigInteger;
+import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
+import java.util.Locale;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -46,6 +49,9 @@ import java.util.stream.Collectors;
 @Transactional
 public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableMapper, StoreTable> implements StoreBookingTableService {
 
+    /** 通用桌号「汉字及其他」组内排序 */
+    private static final Collator CHINESE_COLLATOR = Collator.getInstance(Locale.CHINA);
+
     private final StoreBookingCategoryService storeBookingCategoryService;
     private final UserReservationMapper userReservationMapper;
 
@@ -56,8 +62,8 @@ public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableM
     }
 
     @Override
-    public List<StoreTable> getTableList(Integer storeId, Integer categoryId) {
-        log.info("StoreBookingTableServiceImpl.getTableList?storeId={}, categoryId={}", storeId, categoryId);
+    public List<StoreTable> getTableList(Integer storeId, Integer categoryId, Integer type) {
+        log.info("StoreBookingTableServiceImpl.getTableList?storeId={}, categoryId={}, type={}", storeId, categoryId, type);
         
         LambdaQueryWrapper<StoreTable> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(StoreTable::getStoreId, storeId);
@@ -66,25 +72,36 @@ public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableM
         if (categoryId != null) {
             wrapper.eq(StoreTable::getCategoryId, categoryId);
         }
+
+        if (Integer.valueOf(1).equals(type) || Integer.valueOf(2).equals(type)) {
+            wrapper.eq(StoreTable::getType, type);
+        }
         
         // 查询所有数据,然后在Java中进行排序
         List<StoreTable> list = this.list(wrapper);
+
+        if (Integer.valueOf(2).equals(type)) {
+            // 通用(type=2):纯数字 → 字母+数字(同美食规则) → 汉字及其他;纯数字按数值正序,前导零按位长次之
+            list.sort(Comparator
+                    .comparing(StoreTable::getCategoryId, Comparator.nullsLast(Integer::compareTo))
+                    .thenComparing((a, b) -> compareGenericTypeTableNumbers(a.getTableNumber(), b.getTableNumber())));
+        } else {
+            // type 为 null 或 1:保持原逻辑(字母桌号优先于纯数字等,与历史一致)
+            list.sort(Comparator
+                    .comparing(StoreTable::getCategoryId, Comparator.nullsLast(Integer::compareTo))
+                    .thenComparing(table -> parseTableNumberForSort(table.getTableNumber())));
+        }
         
-        // 自定义排序:根据类别、字母(A-Z)、数字(由小到大)顺序排列
-        list.sort(Comparator
-                .comparing(StoreTable::getCategoryId, Comparator.nullsLast(Integer::compareTo)) // 先按类别排序
-                .thenComparing(table -> parseTableNumberForSort(table.getTableNumber()))); // 再按桌号排序
-        
-        log.info("getTableList 完成 storeId={} categoryId={} tableCount={}", storeId, categoryId, list.size());
+        log.info("getTableList 完成 storeId={} categoryId={} type={} tableCount={}", storeId, categoryId, type, list.size());
         return list;
     }
 
     @Override
-    public List<StoreBookingTableVo> getTableListWithCategoryName(Integer storeId, Integer categoryId) {
-        log.info("StoreBookingTableServiceImpl.getTableListWithCategoryName?storeId={}, categoryId={}", storeId, categoryId);
+    public List<StoreBookingTableVo> getTableListWithCategoryName(Integer storeId, Integer categoryId, Integer type) {
+        log.info("StoreBookingTableServiceImpl.getTableListWithCategoryName?storeId={}, categoryId={}, type={}", storeId, categoryId, type);
         
         // 先查询桌号列表
-        List<StoreTable> tableList = getTableList(storeId, categoryId);
+        List<StoreTable> tableList = getTableList(storeId, categoryId, type);
         
         // 查询所有分类信息,构建categoryId -> categoryName的映射
         List<StoreBookingCategory> categoryList = storeBookingCategoryService.list(
@@ -118,12 +135,12 @@ public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableM
     }
 
     @Override
-    public IPage<StoreBookingTableVo> getTableListPage(Integer pageNum, Integer pageSize, Integer storeId, Integer categoryId) {
-        log.info("StoreBookingTableServiceImpl.getTableListPage?pageNum={}, pageSize={}, storeId={}, categoryId={}", 
-                pageNum, pageSize, storeId, categoryId);
+    public IPage<StoreBookingTableVo> getTableListPage(Integer pageNum, Integer pageSize, Integer storeId, Integer categoryId, Integer type) {
+        log.info("StoreBookingTableServiceImpl.getTableListPage?pageNum={}, pageSize={}, storeId={}, categoryId={}, type={}", 
+                pageNum, pageSize, storeId, categoryId, type);
         
         // 先查询所有数据(因为需要自定义排序)
-        List<StoreBookingTableVo> allList = getTableListWithCategoryName(storeId, categoryId);
+        List<StoreBookingTableVo> allList = getTableListWithCategoryName(storeId, categoryId, type);
         
         // 计算分页信息
         int total = allList.size();
@@ -171,7 +188,7 @@ public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableM
         log.info("listTablesGroupedByMerchant 开始 merchantId={} tableName={}", merchantId, tableName);
         try {
             // merchantId 在本项目中与门店 storeId 语义一致
-            List<StoreBookingTableVo> all = getTableListWithCategoryName(merchantId, null);
+            List<StoreBookingTableVo> all = getTableListWithCategoryName(merchantId, null, null);
             all = filterBookingTablesByNameLike(all, tableName);
             Map<Integer, List<StoreBookingTableVo>> byCategory = groupTableVosByCategoryPreserveOrder(all);
             Map<Integer, String> categoryNameMap = loadCategoryNamesForStoreAndGroupKeys(merchantId, byCategory.keySet());
@@ -366,6 +383,69 @@ public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableM
     }
 
     /**
+     * 通用预订(type=2)桌号分组:0 纯数字、1 字母+数字(与美食相同解析规则)、2 汉字及其他、3 空
+     */
+    private static int classifyGenericTypeTableName(String tableNumber) {
+        if (tableNumber == null || tableNumber.trim().isEmpty()) {
+            return 3;
+        }
+        String s = tableNumber.trim();
+        if (s.matches("\\d+")) {
+            return 0;
+        }
+        boolean hasAsciiLetter = s.chars().anyMatch(c -> (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+        boolean hasDigit = s.chars().anyMatch(Character::isDigit);
+        if (hasAsciiLetter && hasDigit) {
+            return 1;
+        }
+        return 2;
+    }
+
+    /**
+     * 纯数字桌号:数值正序;同值按位数再按字典序(满足 1、2、001、002 等场景)
+     */
+    private static int comparePureNumericTableNames(String a, String b) {
+        String sa = a.trim();
+        String sb = b.trim();
+        BigInteger na = new BigInteger(sa);
+        BigInteger nb = new BigInteger(sb);
+        int c = na.compareTo(nb);
+        if (c != 0) {
+            return c;
+        }
+        int len = Integer.compare(sa.length(), sb.length());
+        if (len != 0) {
+            return len;
+        }
+        return sa.compareTo(sb);
+    }
+
+    /**
+     * 通用(type=2)桌号比较:先分组(纯数字 / 字母+数字 / 汉字),组内再按规则比
+     */
+    private static int compareGenericTypeTableNumbers(String a, String b) {
+        int ca = classifyGenericTypeTableName(a);
+        int cb = classifyGenericTypeTableName(b);
+        if (ca != cb) {
+            return Integer.compare(ca, cb);
+        }
+        switch (ca) {
+            case 0:
+                return comparePureNumericTableNames(a, b);
+            case 1:
+                return parseTableNumberForSortStatic(a).compareTo(parseTableNumberForSortStatic(b));
+            case 2:
+                String ta = a == null ? "" : a.trim();
+                String tb = b == null ? "" : b.trim();
+                return CHINESE_COLLATOR.compare(ta, tb);
+            default:
+                return CHINESE_COLLATOR.compare(
+                        a == null ? "" : a.trim(),
+                        b == null ? "" : b.trim());
+        }
+    }
+
+    /**
      * 解析桌号用于排序
      * 规则:字母(A-Z)优先,然后数字(由小到大)
      * 排序逻辑:
@@ -377,6 +457,10 @@ public class StoreBookingTableServiceImpl extends ServiceImpl<StoreBookingTableM
      * @return 排序键
      */
     private String parseTableNumberForSort(String tableNumber) {
+        return parseTableNumberForSortStatic(tableNumber);
+    }
+
+    private static String parseTableNumberForSortStatic(String tableNumber) {
         if (tableNumber == null || tableNumber.isEmpty()) {
             return "ZZZZZZZZZZ9999999999"; // 空值排在最后
         }

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

@@ -73,7 +73,7 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
 
         Map<String, List<StoreServiceFeeRule>> grouped = rulePage.getRecords().stream()
                 .collect(Collectors.groupingBy(this::groupKey));
-        Map<Integer, String> tableIdNameMap = storeBookingTableService.getTableListWithCategoryName(storeId, null).stream()
+        Map<Integer, String> tableIdNameMap = storeBookingTableService.getTableListWithCategoryName(storeId, null, null).stream()
                 .collect(Collectors.toMap(StoreBookingTableVo::getId, StoreBookingTableVo::getTableNumber, (a, b) -> a));
 
         List<StoreServiceFeeRuleListVo> records = new ArrayList<>();
@@ -255,7 +255,7 @@ public class StoreServiceFeeRuleServiceImpl implements StoreServiceFeeRuleServic
         if (storeId == null) {
             return R.fail("门店ID不能为空");
         }
-        List<StoreBookingTableVo> list = storeBookingTableService.getTableListWithCategoryName(storeId, categoryId);
+        List<StoreBookingTableVo> list = storeBookingTableService.getTableListWithCategoryName(storeId, categoryId, null);
         if (StringUtils.hasText(name)) {
             String keyword = name.trim();
             list = list.stream()

+ 2 - 2
alien-store/src/main/java/shop/alien/store/service/impl/UserReservationServiceImpl.java

@@ -742,7 +742,7 @@ public class UserReservationServiceImpl extends ServiceImpl<UserReservationMappe
         cal.add(Calendar.DAY_OF_MONTH, 1);
         Date dayEnd = cal.getTime();
 
-        List<StoreTable> storeTables = storeBookingTableService.getTableList(storeId, null);
+        List<StoreTable> storeTables = storeBookingTableService.getTableList(storeId, null, null);
         int[] range = getBookingRangeMinutes(storeId);
         int bookingStartMin = range[0];
         int bookingEndMin = range[1];
@@ -795,7 +795,7 @@ public class UserReservationServiceImpl extends ServiceImpl<UserReservationMappe
             return result;
         }
         // 门店下所有选座(桌),用于按“选座”维度计算约满
-        List<StoreTable> storeTables = storeBookingTableService.getTableList(storeId, null);
+        List<StoreTable> storeTables = storeBookingTableService.getTableList(storeId, null, null);
 //        if (storeTables == null) {
 //            storeTables = List.of();
 //        }