Ver código fonte

酒店管理。菜品管理、房间管理部分代码

徐滕 1 dia atrás
pai
commit
95ccc91448

+ 88 - 0
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/controller/HotelDishSpecGroupController.java

@@ -0,0 +1,88 @@
+package com.jeeplus.hotelorder.dish.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.hotelorder.dish.domain.HotelDishSpecGroup;
+import com.jeeplus.hotelorder.dish.service.HotelDishSpecGroupService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 菜品规格组管理Controller
+ * @author jeeplus
+ */
+@Api(tags = "菜品规格组管理")
+@RestController
+@RequestMapping(value = "/dishSpecGroup")
+public class HotelDishSpecGroupController {
+
+    @Resource
+    private HotelDishSpecGroupService hotelDishSpecGroupService;
+
+    /**
+     * 分页查询规格组
+     * @param specGroup 查询条件
+     * @param page 分页参数
+     * @return 分页结果
+     * @throws Exception 查询异常
+     */
+    @ApiOperation(value = "分页查询规格组")
+    @GetMapping("page")
+    public ResponseEntity<IPage<HotelDishSpecGroup>> page(HotelDishSpecGroup specGroup, Page<HotelDishSpecGroup> page) throws Exception {
+        IPage<HotelDishSpecGroup> result = hotelDishSpecGroupService.findPage(page, specGroup);
+        return ResponseEntity.ok(result);
+    }
+
+    /**
+     * 根据菜品ID查询所有规格组(含选项)
+     * @param dishId 菜品ID
+     * @return 规格组列表
+     */
+    @ApiOperation(value = "根据菜品ID查询规格组")
+    @GetMapping("findByDishId")
+    public ResponseEntity<List<HotelDishSpecGroup>> findByDishId(@RequestParam("dishId") String dishId) {
+        List<HotelDishSpecGroup> list = hotelDishSpecGroupService.findByDishId(dishId);
+        return ResponseEntity.ok(list);
+    }
+
+    /**
+     * 查询规格组详情
+     * @param id 规格组ID
+     * @return 规格组信息
+     */
+    @ApiOperation(value = "查询规格组详情")
+    @GetMapping("queryById")
+    public ResponseEntity<HotelDishSpecGroup> queryById(@RequestParam("id") String id) {
+        HotelDishSpecGroup specGroup = hotelDishSpecGroupService.queryById(id);
+        return ResponseEntity.ok(specGroup);
+    }
+
+    /**
+     * 新增/编辑规格组
+     * @param specGroup 规格组信息
+     * @return 操作结果
+     */
+    @ApiOperation(value = "新增/编辑规格组")
+    @PostMapping("save")
+    public ResponseEntity<String> save(@RequestBody HotelDishSpecGroup specGroup) {
+        String result = hotelDishSpecGroupService.saveSpecGroup(specGroup);
+        return ResponseEntity.ok(result);
+    }
+
+    /**
+     * 删除规格组(含级联删除选项)
+     * @param id 规格组ID
+     * @return 操作结果
+     */
+    @ApiOperation(value = "删除规格组")
+    @PostMapping("delete/{id}")
+    public ResponseEntity<String> delete(@PathVariable String id) {
+        hotelDishSpecGroupService.deleteSpecGroup(id);
+        return ResponseEntity.ok("删除成功");
+    }
+}

+ 88 - 0
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/controller/HotelDishSpecOptionController.java

@@ -0,0 +1,88 @@
+package com.jeeplus.hotelorder.dish.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.hotelorder.dish.domain.HotelDishSpecOption;
+import com.jeeplus.hotelorder.dish.service.HotelDishSpecOptionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 菜品规格选项管理Controller
+ * @author jeeplus
+ */
+@Api(tags = "菜品规格选项管理")
+@RestController
+@RequestMapping(value = "/dishSpecOption")
+public class HotelDishSpecOptionController {
+
+    @Resource
+    private HotelDishSpecOptionService hotelDishSpecOptionService;
+
+    /**
+     * 分页查询规格选项
+     * @param specOption 查询条件
+     * @param page 分页参数
+     * @return 分页结果
+     * @throws Exception 查询异常
+     */
+    @ApiOperation(value = "分页查询规格选项")
+    @GetMapping("page")
+    public ResponseEntity<IPage<HotelDishSpecOption>> page(HotelDishSpecOption specOption, Page<HotelDishSpecOption> page) throws Exception {
+        IPage<HotelDishSpecOption> result = hotelDishSpecOptionService.findPage(page, specOption);
+        return ResponseEntity.ok(result);
+    }
+
+    /**
+     * 根据规格组ID查询所有选项
+     * @param groupId 规格组ID
+     * @return 选项列表
+     */
+    @ApiOperation(value = "根据规格组ID查询选项")
+    @GetMapping("findByGroupId")
+    public ResponseEntity<List<HotelDishSpecOption>> findByGroupId(@RequestParam("groupId") String groupId) {
+        List<HotelDishSpecOption> list = hotelDishSpecOptionService.findByGroupId(groupId);
+        return ResponseEntity.ok(list);
+    }
+
+    /**
+     * 查询规格选项详情
+     * @param id 选项ID
+     * @return 选项信息
+     */
+    @ApiOperation(value = "查询规格选项详情")
+    @GetMapping("queryById")
+    public ResponseEntity<HotelDishSpecOption> queryById(@RequestParam("id") String id) {
+        HotelDishSpecOption specOption = hotelDishSpecOptionService.queryById(id);
+        return ResponseEntity.ok(specOption);
+    }
+
+    /**
+     * 新增/编辑规格选项
+     * @param specOption 选项信息
+     * @return 操作结果
+     */
+    @ApiOperation(value = "新增/编辑规格选项")
+    @PostMapping("save")
+    public ResponseEntity<String> save(@RequestBody HotelDishSpecOption specOption) {
+        String result = hotelDishSpecOptionService.saveSpecOption(specOption);
+        return ResponseEntity.ok(result);
+    }
+
+    /**
+     * 删除规格选项
+     * @param id 选项ID
+     * @return 操作结果
+     */
+    @ApiOperation(value = "删除规格选项")
+    @PostMapping("delete/{id}")
+    public ResponseEntity<String> delete(@PathVariable String id) {
+        hotelDishSpecOptionService.deleteSpecOption(id);
+        return ResponseEntity.ok("删除成功");
+    }
+}

+ 44 - 0
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/domain/HotelDishSpecGroup.java

@@ -0,0 +1,44 @@
+package com.jeeplus.hotelorder.dish.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import com.jeeplus.core.query.QueryType;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 菜品规格组实体
+ * @author jeeplus
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName(value = "hotel_dish_spec_group")
+public class HotelDishSpecGroup extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 关联菜品ID */
+    @Query(tableColumn = "dish_id", type = QueryType.EQ)
+    private String dishId;
+
+    /** 规格组名称(如:熟度、酱汁) */
+    private String groupName;
+
+    /** 是否必选: 0-可选, 1-必选 */
+    private Integer required;
+
+    /** 排序号 */
+    private Integer sortOrder;
+
+    /** 关联菜品名称(非DB字段,查询时填充) */
+    @TableField(exist = false)
+    private String dishName;
+
+    /** 规格选项列表(非DB字段) */
+    @TableField(exist = false)
+    private List<HotelDishSpecOption> options;
+}

+ 16 - 4
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/domain/HotelDishSpecOption.java

@@ -2,9 +2,17 @@ package com.jeeplus.hotelorder.dish.domain;
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import com.jeeplus.core.query.QueryType;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.math.BigDecimal;
+
+/**
+ * 菜品规格选项实体
+ * @author jeeplus
+ */
 @Data
 @EqualsAndHashCode(callSuper = false)
 @TableName(value = "hotel_dish_spec_option")
@@ -12,12 +20,16 @@ public class HotelDishSpecOption extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
 
-    /** 规格组ID */
-    private String specId;
+    /** 关联规格组ID */
+    @Query(tableColumn = "group_id", type = QueryType.EQ)
+    private String groupId;
 
-    /** 选项名称(如: 大份、小份) */
+    /** 选项名称(如:三分熟、黑椒汁) */
     private String optionName;
 
-    /** 排序权重 */
+    /** 加价金额 */
+    private BigDecimal priceExtra;
+
+    /** 排序号 */
     private Integer sortOrder;
 }

+ 13 - 0
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/mapper/HotelDishSpecGroupMapper.java

@@ -0,0 +1,13 @@
+package com.jeeplus.hotelorder.dish.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jeeplus.hotelorder.dish.domain.HotelDishSpecGroup;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 菜品规格组Mapper
+ * @author jeeplus
+ */
+@Mapper
+public interface HotelDishSpecGroupMapper extends BaseMapper<HotelDishSpecGroup> {
+}

+ 4 - 13
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/mapper/HotelDishSpecOptionMapper.java

@@ -3,20 +3,11 @@ package com.jeeplus.hotelorder.dish.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jeeplus.hotelorder.dish.domain.HotelDishSpecOption;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
 
+/**
+ * 菜品规格选项Mapper
+ * @author jeeplus
+ */
 @Mapper
 public interface HotelDishSpecOptionMapper extends BaseMapper<HotelDishSpecOption> {
-
-    /**
-     * 根据规格组ID查询选项
-     */
-    List<HotelDishSpecOption> selectBySpecId(@Param("specId") String specId);
-
-    /**
-     * 根据规格组ID删除选项(软删除)
-     */
-    int deleteBySpecId(@Param("specId") String specId);
 }

+ 192 - 0
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/service/HotelDishSpecGroupService.java

@@ -0,0 +1,192 @@
+package com.jeeplus.hotelorder.dish.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jeeplus.core.query.QueryWrapperGenerator;
+import com.jeeplus.hotelorder.dish.domain.HotelDish;
+import com.jeeplus.hotelorder.dish.domain.HotelDishSpecGroup;
+import com.jeeplus.hotelorder.dish.domain.HotelDishSpecOption;
+import com.jeeplus.hotelorder.dish.mapper.HotelDishMapper;
+import com.jeeplus.hotelorder.dish.mapper.HotelDishSpecGroupMapper;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * 菜品规格组服务类
+ * @author jeeplus
+ */
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class HotelDishSpecGroupService extends ServiceImpl<HotelDishSpecGroupMapper, HotelDishSpecGroup> {
+
+    private static final Logger log = LoggerFactory.getLogger(HotelDishSpecGroupService.class);
+
+    @Resource
+    private HotelDishSpecGroupMapper hotelDishSpecGroupMapper;
+
+    @Resource
+    private HotelDishMapper hotelDishMapper;
+
+    @Resource
+    private HotelDishSpecOptionService hotelDishSpecOptionService;
+
+    /**
+     * 分页查询规格组
+     * @param page 分页参数
+     * @param specGroup 查询条件
+     * @return 分页结果
+     * @throws Exception 查询异常
+     */
+    public IPage<HotelDishSpecGroup> findPage(Page<HotelDishSpecGroup> page, HotelDishSpecGroup specGroup) throws Exception {
+        // 处理菜品名称搜索(非DB字段,需先查菜品ID再过滤)
+        String dishName = specGroup.getDishName();
+        specGroup.setDishName(null); // 清除非DB字段,避免QueryWrapperGenerator处理
+        QueryWrapper<HotelDishSpecGroup> queryWrapper = QueryWrapperGenerator.buildQueryCondition(specGroup, HotelDishSpecGroup.class);
+        queryWrapper.eq("del_flag", 0);
+        // 按菜品名称模糊搜索
+        if (StringUtils.isNotBlank(dishName)) {
+            QueryWrapper<HotelDish> dishQw = new QueryWrapper<>();
+            dishQw.like("name", dishName).eq("del_flag", 0);
+            List<HotelDish> dishes = hotelDishMapper.selectList(dishQw);
+            if (dishes.isEmpty()) {
+                // 没有匹配的菜品,返回空结果
+                return new Page<>(page.getCurrent(), page.getSize(), 0);
+            }
+            List<String> matchedIds = new ArrayList<>();
+            for (HotelDish dish : dishes) {
+                matchedIds.add(dish.getId());
+            }
+            queryWrapper.in("dish_id", matchedIds);
+        }
+        queryWrapper.orderByAsc("sort_order");
+        IPage<HotelDishSpecGroup> result = hotelDishSpecGroupMapper.selectPage(page, queryWrapper);
+        // 填充菜品名称和选项列表
+        fillDishName(result.getRecords());
+        fillOptions(result.getRecords());
+        return result;
+    }
+
+    /**
+     * 根据菜品ID查询所有规格组(含选项)
+     * @param dishId 菜品ID
+     * @return 规格组列表(含选项)
+     */
+    public List<HotelDishSpecGroup> findByDishId(String dishId) {
+        QueryWrapper<HotelDishSpecGroup> qw = new QueryWrapper<>();
+        qw.eq("dish_id", dishId).eq("del_flag", 0).orderByAsc("sort_order");
+        List<HotelDishSpecGroup> groups = hotelDishSpecGroupMapper.selectList(qw);
+        // 填充每个规格组的选项列表
+        for (HotelDishSpecGroup group : groups) {
+            List<HotelDishSpecOption> options = hotelDishSpecOptionService.findByGroupId(group.getId());
+            group.setOptions(options);
+        }
+        return groups;
+    }
+
+    /**
+     * 根据ID查询规格组
+     * @param id 规格组ID
+     * @return 规格组信息
+     */
+    public HotelDishSpecGroup queryById(String id) {
+        return hotelDishSpecGroupMapper.selectById(id);
+    }
+
+    /**
+     * 保存规格组(新增/编辑)
+     * @param specGroup 规格组信息
+     * @return 操作结果
+     */
+    public String saveSpecGroup(HotelDishSpecGroup specGroup) {
+        if (StringUtils.isBlank(specGroup.getId())) {
+            specGroup.setId(UUID.randomUUID().toString().replace("-", ""));
+            specGroup.setDelFlag(0);
+            if (specGroup.getRequired() == null) {
+                specGroup.setRequired(0);
+            }
+            if (specGroup.getSortOrder() == null) {
+                specGroup.setSortOrder(0);
+            }
+            hotelDishSpecGroupMapper.insert(specGroup);
+            log.info("新增规格组: {}", specGroup.getGroupName());
+        } else {
+            hotelDishSpecGroupMapper.updateById(specGroup);
+            log.info("编辑规格组: {}", specGroup.getGroupName());
+        }
+        return "操作成功";
+    }
+
+    /**
+     * 删除规格组(同时删除其下所有选项)
+     * @param id 规格组ID
+     */
+    public void deleteSpecGroup(String id) {
+        // 删除规格组
+        hotelDishSpecGroupMapper.deleteById(id);
+        // 删除关联的规格选项
+        hotelDishSpecOptionService.deleteByGroupId(id);
+        log.info("删除规格组及其选项: {}", id);
+    }
+
+    /**
+     * 批量填充选项列表
+     * @param groups 规格组列表
+     */
+    private void fillOptions(List<HotelDishSpecGroup> groups) {
+        if (groups == null || groups.isEmpty()) {
+            return;
+        }
+        for (HotelDishSpecGroup group : groups) {
+            List<HotelDishSpecOption> options = hotelDishSpecOptionService.findByGroupId(group.getId());
+            group.setOptions(options);
+        }
+    }
+
+    /**
+     * 批量填充菜品名称
+     * @param groups 规格组列表
+     */
+    private void fillDishName(List<HotelDishSpecGroup> groups) {
+        if (groups == null || groups.isEmpty()) {
+            return;
+        }
+        // 收集所有菜品ID
+        Set<String> dishIds = new HashSet<>();
+        for (HotelDishSpecGroup group : groups) {
+            if (StringUtils.isNotBlank(group.getDishId())) {
+                dishIds.add(group.getDishId());
+            }
+        }
+        if (dishIds.isEmpty()) {
+            return;
+        }
+        // 批量查询菜品
+        QueryWrapper<HotelDish> qw = new QueryWrapper<>();
+        qw.in("id", dishIds).eq("del_flag", 0);
+        List<HotelDish> dishes = hotelDishMapper.selectList(qw);
+        Map<String, String> nameMap = new HashMap<>();
+        for (HotelDish dish : dishes) {
+            nameMap.put(dish.getId(), dish.getName());
+        }
+        // 填充名称
+        for (HotelDishSpecGroup group : groups) {
+            if (StringUtils.isNotBlank(group.getDishId())) {
+                group.setDishName(nameMap.get(group.getDishId()));
+            }
+        }
+    }
+}

+ 111 - 0
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/dish/service/HotelDishSpecOptionService.java

@@ -0,0 +1,111 @@
+package com.jeeplus.hotelorder.dish.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jeeplus.core.query.QueryWrapperGenerator;
+import com.jeeplus.hotelorder.dish.domain.HotelDishSpecOption;
+import com.jeeplus.hotelorder.dish.mapper.HotelDishSpecOptionMapper;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 菜品规格选项服务类
+ * @author jeeplus
+ */
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class HotelDishSpecOptionService extends ServiceImpl<HotelDishSpecOptionMapper, HotelDishSpecOption> {
+
+    private static final Logger log = LoggerFactory.getLogger(HotelDishSpecOptionService.class);
+
+    @Resource
+    private HotelDishSpecOptionMapper hotelDishSpecOptionMapper;
+
+    /**
+     * 分页查询规格选项
+     * @param page 分页参数
+     * @param specOption 查询条件
+     * @return 分页结果
+     * @throws Exception 查询异常
+     */
+    public IPage<HotelDishSpecOption> findPage(Page<HotelDishSpecOption> page, HotelDishSpecOption specOption) throws Exception {
+        QueryWrapper<HotelDishSpecOption> queryWrapper = QueryWrapperGenerator.buildQueryCondition(specOption, HotelDishSpecOption.class);
+        queryWrapper.eq("del_flag", 0);
+        queryWrapper.orderByAsc("sort_order");
+        return hotelDishSpecOptionMapper.selectPage(page, queryWrapper);
+    }
+
+    /**
+     * 根据规格组ID查询所有选项
+     * @param groupId 规格组ID
+     * @return 选项列表
+     */
+    public List<HotelDishSpecOption> findByGroupId(String groupId) {
+        QueryWrapper<HotelDishSpecOption> qw = new QueryWrapper<>();
+        qw.eq("group_id", groupId).eq("del_flag", 0).orderByAsc("sort_order");
+        return hotelDishSpecOptionMapper.selectList(qw);
+    }
+
+    /**
+     * 根据ID查询规格选项
+     * @param id 选项ID
+     * @return 选项信息
+     */
+    public HotelDishSpecOption queryById(String id) {
+        return hotelDishSpecOptionMapper.selectById(id);
+    }
+
+    /**
+     * 保存规格选项(新增/编辑)
+     * @param specOption 选项信息
+     * @return 操作结果
+     */
+    public String saveSpecOption(HotelDishSpecOption specOption) {
+        if (StringUtils.isBlank(specOption.getId())) {
+            specOption.setId(UUID.randomUUID().toString().replace("-", ""));
+            specOption.setDelFlag(0);
+            if (specOption.getPriceExtra() == null) {
+                specOption.setPriceExtra(BigDecimal.ZERO);
+            }
+            if (specOption.getSortOrder() == null) {
+                specOption.setSortOrder(0);
+            }
+            hotelDishSpecOptionMapper.insert(specOption);
+            log.info("新增规格选项: {}", specOption.getOptionName());
+        } else {
+            hotelDishSpecOptionMapper.updateById(specOption);
+            log.info("编辑规格选项: {}", specOption.getOptionName());
+        }
+        return "操作成功";
+    }
+
+    /**
+     * 根据规格组ID删除所有选项
+     * @param groupId 规格组ID
+     */
+    public void deleteByGroupId(String groupId) {
+        QueryWrapper<HotelDishSpecOption> qw = new QueryWrapper<>();
+        qw.eq("group_id", groupId);
+        hotelDishSpecOptionMapper.delete(qw);
+        log.info("删除规格组下所有选项: groupId={}", groupId);
+    }
+
+    /**
+     * 删除规格选项
+     * @param id 选项ID
+     */
+    public void deleteSpecOption(String id) {
+        hotelDishSpecOptionMapper.deleteById(id);
+        log.info("删除规格选项: {}", id);
+    }
+}

+ 113 - 22
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/hotelconfig/controller/HotelConfigController.java

@@ -1,6 +1,7 @@
 package com.jeeplus.hotelorder.hotelconfig.controller;
 
-import com.jeeplus.common.utils.ResponseUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jeeplus.hotelorder.hotelconfig.domain.HotelBusinessHours;
 import com.jeeplus.hotelorder.hotelconfig.domain.HotelConfig;
 import com.jeeplus.hotelorder.hotelconfig.service.HotelConfigService;
@@ -10,47 +11,137 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.util.List;
 
+/**
+ * 酒店配置管理Controller
+ * @author jeeplus
+ */
+@Api(tags = "酒店配置管理")
 @RestController
 @RequestMapping(value = "/config")
-@Api(tags = "酒店配置管理")
 public class HotelConfigController {
 
     @Resource
     private HotelConfigService hotelConfigService;
 
-    @GetMapping("get")
+    /**
+     * 获取酒店配置
+     * @return 酒店配置信息
+     */
     @ApiOperation(value = "获取酒店配置")
-    public ResponseEntity<?> getConfig() {
+    @GetMapping("get")
+    public ResponseEntity<HotelConfig> getConfig() {
         HotelConfig config = hotelConfigService.getConfig();
-        return ResponseUtil.newInstance()
-                .add("config", config)
-                .ok("操作成功");
+        return ResponseEntity.ok(config);
     }
 
-    @PostMapping("save")
+    /**
+     * 保存/更新酒店配置
+     * @param config 酒店配置信息
+     * @return 操作结果
+     */
     @ApiOperation(value = "保存/更新酒店配置")
-    public ResponseEntity<?> saveConfig(@RequestBody HotelConfig config) {
-        return ResponseUtil.newInstance().ok(hotelConfigService.saveConfig(config));
+    @PostMapping("save")
+    public ResponseEntity<String> saveConfig(@RequestBody HotelConfig config) {
+        String result = hotelConfigService.saveConfig(config);
+        return ResponseEntity.ok(result);
     }
 
+    // ==================== 营业时段管理 ====================
+
+    /**
+     * 分页查询营业时段
+     * @param businessHours 查询条件
+     * @param page 分页参数
+     * @return 分页结果
+     * @throws Exception 查询异常
+     */
+    @ApiOperation(value = "分页查询营业时段")
     @GetMapping("businessHours/list")
-    @ApiOperation(value = "获取营业时段列表")
-    public ResponseEntity<?> getBusinessHoursList() {
-        return ResponseUtil.newInstance()
-                .add("list", hotelConfigService.getBusinessHoursList())
-                .ok("操作成功");
+    public ResponseEntity<IPage<HotelBusinessHours>> businessHoursList(HotelBusinessHours businessHours, Page<HotelBusinessHours> page) throws Exception {
+        IPage<HotelBusinessHours> result = hotelConfigService.findBusinessHoursPage(page, businessHours);
+        return ResponseEntity.ok(result);
     }
 
-    @PostMapping("businessHours/save")
+    /**
+     * 获取营业时段列表(全部,含禁用)
+     * @return 营业时段列表
+     */
+    @ApiOperation(value = "获取营业时段列表(全部)")
+    @GetMapping("businessHours/all")
+    public ResponseEntity<List<HotelBusinessHours>> getBusinessHoursList() {
+        List<HotelBusinessHours> list = hotelConfigService.getBusinessHoursList();
+        return ResponseEntity.ok(list);
+    }
+
+    /**
+     * 获取启用的营业时段(顾客端用)
+     * @return 启用的营业时段列表
+     */
+    @ApiOperation(value = "获取启用的营业时段")
+    @GetMapping("businessHours/enabled")
+    public ResponseEntity<List<HotelBusinessHours>> getEnabledBusinessHoursList() {
+        List<HotelBusinessHours> list = hotelConfigService.getEnabledBusinessHoursList();
+        return ResponseEntity.ok(list);
+    }
+
+    /**
+     * 检查当前是否在营业时段内(顾客端用)
+     * @return 当前营业时段信息,不在营业时段则返回null
+     */
+    @ApiOperation(value = "检查当前营业状态")
+    @GetMapping("businessHours/checkCurrent")
+    public ResponseEntity<HotelBusinessHours> checkCurrentBusinessHours() {
+        HotelBusinessHours current = hotelConfigService.checkCurrentBusinessHours();
+        return ResponseEntity.ok(current);
+    }
+
+    /**
+     * 查询营业时段详情
+     * @param id 营业时段ID
+     * @return 营业时段信息
+     */
+    @ApiOperation(value = "查询营业时段详情")
+    @GetMapping("businessHours/queryById")
+    public ResponseEntity<HotelBusinessHours> queryBusinessHoursById(@RequestParam("id") String id) {
+        HotelBusinessHours hours = hotelConfigService.getBusinessHoursById(id);
+        return ResponseEntity.ok(hours);
+    }
+
+    /**
+     * 保存营业时段(新增/编辑)
+     * @param hours 营业时段信息
+     * @return 操作结果
+     */
     @ApiOperation(value = "保存营业时段")
-    public ResponseEntity<?> saveBusinessHours(@RequestBody HotelBusinessHours hours) {
-        return ResponseUtil.newInstance().ok(hotelConfigService.saveBusinessHours(hours));
+    @PostMapping("businessHours/save")
+    public ResponseEntity<String> saveBusinessHours(@RequestBody HotelBusinessHours hours) {
+        String result = hotelConfigService.saveBusinessHours(hours);
+        return ResponseEntity.ok(result);
+    }
+
+    /**
+     * 切换营业时段状态(启用/禁用)
+     * @param id 营业时段ID
+     * @return 操作结果
+     */
+    @ApiOperation(value = "切换营业时段状态")
+    @PostMapping("businessHours/toggle/{id}")
+    public ResponseEntity<String> toggleBusinessHours(@PathVariable String id) {
+        String result = hotelConfigService.toggleBusinessHours(id);
+        return ResponseEntity.ok(result);
     }
 
-    @PostMapping("businessHours/toggle")
-    @ApiOperation(value = "紧急暂停/恢复营业")
-    public ResponseEntity<?> toggleBusinessHours(@RequestParam String id, @RequestParam Integer enabled) {
-        return ResponseUtil.newInstance().ok(hotelConfigService.toggleBusinessHours(id, enabled));
+    /**
+     * 删除营业时段
+     * @param id 营业时段ID
+     * @return 操作结果
+     */
+    @ApiOperation(value = "删除营业时段")
+    @PostMapping("businessHours/delete/{id}")
+    public ResponseEntity<String> deleteBusinessHours(@PathVariable String id) {
+        hotelConfigService.deleteBusinessHours(id);
+        return ResponseEntity.ok("删除成功");
     }
 }

+ 21 - 7
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/hotelconfig/domain/HotelBusinessHours.java

@@ -2,9 +2,15 @@ package com.jeeplus.hotelorder.hotelconfig.domain;
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import com.jeeplus.core.query.QueryType;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+/**
+ * 营业时段配置实体
+ * @author jeeplus
+ */
 @Data
 @EqualsAndHashCode(callSuper = false)
 @TableName(value = "hotel_business_hours")
@@ -12,18 +18,26 @@ public class HotelBusinessHours extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
 
-    /** 时段名称(如: 早餐、午餐、晚餐) */
-    private String name;
+    /** 星期几(0=周日,1=周一,...,6=周六,NULL=每天) */
+    private Integer dayOfWeek;
 
-    /** 开始时间 */
+    /** 餐段标识(breakfast/lunch/dinner/night) */
+    @Query(tableColumn = "meal_type", type = QueryType.EQ)
+    private String mealType;
+
+    /** 餐段名称(如:早餐、午餐、晚餐、夜宵) */
+    private String mealName;
+
+    /** 开始时间(如:08:00) */
     private String startTime;
 
-    /** 结束时间 */
+    /** 结束时间(如:10:00) */
     private String endTime;
 
-    /** 是否启用 */
-    private Integer enabled;
+    /** 状态: ENABLED-启用, DISABLED-禁用 */
+    @Query(tableColumn = "status", type = QueryType.EQ)
+    private String status;
 
-    /** 排序权重 */
+    /** 排序 */
     private Integer sortOrder;
 }

+ 114 - 20
jeeplus-modules/jeeplus-hotel-order/src/main/java/com/jeeplus/hotelorder/hotelconfig/service/HotelConfigService.java

@@ -1,20 +1,35 @@
 package com.jeeplus.hotelorder.hotelconfig.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jeeplus.core.query.QueryWrapperGenerator;
 import com.jeeplus.hotelorder.hotelconfig.domain.HotelBusinessHours;
 import com.jeeplus.hotelorder.hotelconfig.domain.HotelConfig;
 import com.jeeplus.hotelorder.hotelconfig.mapper.HotelBusinessHoursMapper;
 import com.jeeplus.hotelorder.hotelconfig.mapper.HotelConfigMapper;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
+/**
+ * 酒店配置服务类
+ * @author jeeplus
+ */
 @Service
-public class HotelConfigService {
+@Transactional(rollbackFor = Exception.class)
+public class HotelConfigService extends ServiceImpl<HotelConfigMapper, HotelConfig> {
+
+    private static final Logger log = LoggerFactory.getLogger(HotelConfigService.class);
 
     @Resource
     private HotelConfigMapper hotelConfigMapper;
@@ -24,6 +39,7 @@ public class HotelConfigService {
 
     /**
      * 获取酒店配置
+     * @return 酒店配置信息
      */
     public HotelConfig getConfig() {
         QueryWrapper<HotelConfig> qw = new QueryWrapper<>();
@@ -33,62 +49,140 @@ public class HotelConfigService {
 
     /**
      * 保存/更新酒店配置
+     * @param config 酒店配置信息
+     * @return 操作结果
      */
-    @Transactional(rollbackFor = Exception.class)
     public String saveConfig(HotelConfig config) {
         HotelConfig existing = getConfig();
         if (existing == null) {
             config.setId(UUID.randomUUID().toString().replace("-", ""));
-            config.setCreateTime(new Date());
-            config.setUpdateTime(new Date());
             config.setDelFlag(0);
             hotelConfigMapper.insert(config);
+            log.info("新增酒店配置: {}", config.getHotelName());
         } else {
             config.setId(existing.getId());
-            config.setUpdateTime(new Date());
             hotelConfigMapper.updateById(config);
+            log.info("更新酒店配置: {}", config.getHotelName());
         }
         return "操作成功";
     }
 
+    // ==================== 营业时段管理 ====================
+
+    /**
+     * 分页查询营业时段
+     * @param page 分页参数
+     * @param businessHours 查询条件
+     * @return 分页结果
+     * @throws Exception 查询异常
+     */
+    public IPage<HotelBusinessHours> findBusinessHoursPage(Page<HotelBusinessHours> page, HotelBusinessHours businessHours) throws Exception {
+        QueryWrapper<HotelBusinessHours> queryWrapper = QueryWrapperGenerator.buildQueryCondition(businessHours, HotelBusinessHours.class);
+        queryWrapper.eq("del_flag", 0);
+        queryWrapper.orderByAsc("sort_order");
+        return hotelBusinessHoursMapper.selectPage(page, queryWrapper);
+    }
+
     /**
-     * 获取营业时段列表
+     * 获取营业时段列表(全部,含禁用)
+     * @return 营业时段列表
      */
     public List<HotelBusinessHours> getBusinessHoursList() {
         QueryWrapper<HotelBusinessHours> qw = new QueryWrapper<>();
-        qw.orderByAsc("sort_order");
+        qw.eq("del_flag", 0).orderByAsc("sort_order");
+        return hotelBusinessHoursMapper.selectList(qw);
+    }
+
+    /**
+     * 获取所有启用的营业时段
+     * @return 启用的营业时段列表
+     */
+    public List<HotelBusinessHours> getEnabledBusinessHoursList() {
+        QueryWrapper<HotelBusinessHours> qw = new QueryWrapper<>();
+        qw.eq("status", "ENABLED").eq("del_flag", 0).orderByAsc("sort_order");
         return hotelBusinessHoursMapper.selectList(qw);
     }
 
     /**
-     * 保存营业时段
+     * 检查当前是否在营业时段内
+     * 按星期几匹配(优先具体星期,其次NULL=每天),时间字符串比较判断是否在时段内
+     * @return 当前营业时段信息,不在营业时段则返回null
+     */
+    public HotelBusinessHours checkCurrentBusinessHours() {
+        Calendar calendar = Calendar.getInstance();
+        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1; // 0=周日
+        String currentTime = String.format("%02d:%02d", calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
+
+        QueryWrapper<HotelBusinessHours> qw = new QueryWrapper<>();
+        qw.eq("status", "ENABLED").eq("del_flag", 0);
+        qw.and(w -> w.eq("day_of_week", dayOfWeek).or().isNull("day_of_week"));
+        qw.orderByAsc("sort_order");
+
+        List<HotelBusinessHours> hoursList = hotelBusinessHoursMapper.selectList(qw);
+        for (HotelBusinessHours hours : hoursList) {
+            if (currentTime.compareTo(hours.getStartTime()) >= 0 && currentTime.compareTo(hours.getEndTime()) < 0) {
+                return hours;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 查询营业时段详情
+     * @param id 营业时段ID
+     * @return 营业时段信息
+     */
+    public HotelBusinessHours getBusinessHoursById(String id) {
+        return hotelBusinessHoursMapper.selectById(id);
+    }
+
+    /**
+     * 保存营业时段(新增/编辑)
+     * @param hours 营业时段信息
+     * @return 操作结果
      */
-    @Transactional(rollbackFor = Exception.class)
     public String saveBusinessHours(HotelBusinessHours hours) {
-        if (hours.getId() == null || hours.getId().isEmpty()) {
+        if (StringUtils.isBlank(hours.getId())) {
             hours.setId(UUID.randomUUID().toString().replace("-", ""));
-            hours.setCreateTime(new Date());
-            hours.setUpdateTime(new Date());
             hours.setDelFlag(0);
+            if (StringUtils.isBlank(hours.getStatus())) {
+                hours.setStatus("ENABLED");
+            }
+            if (hours.getSortOrder() == null) {
+                hours.setSortOrder(0);
+            }
             hotelBusinessHoursMapper.insert(hours);
+            log.info("新增营业时段: {}", hours.getMealName());
         } else {
-            hours.setUpdateTime(new Date());
             hotelBusinessHoursMapper.updateById(hours);
+            log.info("编辑营业时段: {}", hours.getMealName());
         }
         return "操作成功";
     }
 
     /**
-     * 紧急暂停/恢复营业
+     * 切换营业时段状态(启用/禁用)
+     * @param id 营业时段ID
+     * @return 操作结果
      */
-    @Transactional(rollbackFor = Exception.class)
-    public String toggleBusinessHours(String id, Integer enabled) {
+    public String toggleBusinessHours(String id) {
         HotelBusinessHours hours = hotelBusinessHoursMapper.selectById(id);
-        if (hours != null) {
-            hours.setEnabled(enabled);
-            hours.setUpdateTime(new Date());
-            hotelBusinessHoursMapper.updateById(hours);
+        if (hours == null) {
+            throw new RuntimeException("营业时段不存在");
         }
+        String newStatus = "ENABLED".equals(hours.getStatus()) ? "DISABLED" : "ENABLED";
+        hours.setStatus(newStatus);
+        hotelBusinessHoursMapper.updateById(hours);
+        log.info("营业时段状态变更: {} -> {}", hours.getMealName(), newStatus);
         return "操作成功";
     }
+
+    /**
+     * 删除营业时段
+     * @param id 营业时段ID
+     */
+    public void deleteBusinessHours(String id) {
+        hotelBusinessHoursMapper.deleteById(id);
+        log.info("删除营业时段: {}", id);
+    }
 }