|
|
@@ -1,410 +0,0 @@
|
|
|
-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.fasterxml.jackson.databind.ObjectMapper;
|
|
|
-import com.jeeplus.hotelorder.dish.domain.*;
|
|
|
-import com.jeeplus.hotelorder.dish.mapper.*;
|
|
|
-import com.jeeplus.hotelorder.dish.service.dto.HotelDishDTO;
|
|
|
-import com.jeeplus.hotelorder.order.domain.HotelOrder;
|
|
|
-import com.jeeplus.hotelorder.order.mapper.HotelOrderMapper;
|
|
|
-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.Arrays;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.UUID;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-@Service
|
|
|
-@Transactional(rollbackFor = Exception.class)
|
|
|
-public class HotelDishService extends ServiceImpl<HotelDishMapper, HotelDish> {
|
|
|
-
|
|
|
- private static final Logger log = LoggerFactory.getLogger(HotelDishService.class);
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelDishMapper hotelDishMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelDishSpecMapper hotelDishSpecMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelDishSpecOptionMapper hotelDishSpecOptionMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelDishAdditionMapper hotelDishAdditionMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelDishCategoryMapper hotelDishCategoryMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelDishLogMapper hotelDishLogMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private HotelOrderMapper hotelOrderMapper;
|
|
|
-
|
|
|
- private static final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
-
|
|
|
- /**
|
|
|
- * 管理后台菜品分页查询(含分类名称)
|
|
|
- */
|
|
|
- public IPage<HotelDishDTO> findAdminPage(Page<HotelDish> page, HotelDishDTO queryDTO) {
|
|
|
- IPage<HotelDish> result = hotelDishMapper.selectAdminPage(page, queryDTO.getCategoryId(), queryDTO.getStatus(), queryDTO.getName());
|
|
|
- return convertToDtoPage(result);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 客户端菜品列表(只查在售且未售罄)
|
|
|
- */
|
|
|
- public IPage<HotelDishDTO> findClientPage(Page<HotelDish> page, HotelDishDTO queryDTO) {
|
|
|
- IPage<HotelDish> result = hotelDishMapper.selectClientList(page, queryDTO.getCategoryId(), queryDTO.getKeyword());
|
|
|
- return convertToDtoPage(result);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Entity分页结果转DTO分页结果
|
|
|
- */
|
|
|
- private IPage<HotelDishDTO> convertToDtoPage(IPage<HotelDish> result) {
|
|
|
- IPage<HotelDishDTO> dtoPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
|
|
|
- List<HotelDishDTO> dtoList = result.getRecords().stream().map(this::entityToDto).collect(Collectors.toList());
|
|
|
- dtoPage.setRecords(dtoList);
|
|
|
- return dtoPage;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Entity转DTO
|
|
|
- */
|
|
|
- private HotelDishDTO entityToDto(HotelDish entity) {
|
|
|
- HotelDishDTO dto = new HotelDishDTO();
|
|
|
- dto.setId(entity.getId());
|
|
|
- dto.setName(entity.getName());
|
|
|
- dto.setCategoryId(entity.getCategoryId());
|
|
|
- dto.setPrice(entity.getPrice());
|
|
|
- dto.setImage(entity.getImage());
|
|
|
- dto.setDescription(entity.getDescription());
|
|
|
- dto.setTags(entity.getTags());
|
|
|
- dto.setPrepTime(entity.getPrepTime());
|
|
|
- dto.setSales(entity.getSales());
|
|
|
- dto.setStatus(entity.getStatus());
|
|
|
- dto.setSoldOut(entity.getSoldOut());
|
|
|
- dto.setIsRecommended(entity.getIsRecommended());
|
|
|
- dto.setSortOrder(entity.getSortOrder());
|
|
|
- dto.setCategoryName(entity.getCategoryName());
|
|
|
- dto.setSpecGroups(entity.getSpecGroups());
|
|
|
- dto.setAdditions(entity.getAdditions());
|
|
|
- dto.setCreateTime(entity.getCreateTime());
|
|
|
- dto.setUpdateTime(entity.getUpdateTime());
|
|
|
- return dto;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * DTO转Entity
|
|
|
- */
|
|
|
- private HotelDish dtoToEntity(HotelDishDTO dto) {
|
|
|
- HotelDish entity = new HotelDish();
|
|
|
- entity.setId(dto.getId());
|
|
|
- entity.setName(dto.getName());
|
|
|
- entity.setCategoryId(dto.getCategoryId());
|
|
|
- entity.setPrice(dto.getPrice());
|
|
|
- entity.setImage(dto.getImage());
|
|
|
- entity.setDescription(dto.getDescription());
|
|
|
- entity.setTags(dto.getTags());
|
|
|
- entity.setPrepTime(dto.getPrepTime());
|
|
|
- entity.setSales(dto.getSales());
|
|
|
- entity.setStatus(dto.getStatus());
|
|
|
- entity.setSoldOut(dto.getSoldOut());
|
|
|
- entity.setIsRecommended(dto.getIsRecommended());
|
|
|
- entity.setSortOrder(dto.getSortOrder());
|
|
|
- return entity;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 查询菜品详情
|
|
|
- */
|
|
|
- public HotelDishDTO getDetail(String id) {
|
|
|
- HotelDish dish = hotelDishMapper.selectById(id);
|
|
|
- if (dish != null) {
|
|
|
- fillDishDetail(dish);
|
|
|
- }
|
|
|
- return dish != null ? entityToDto(dish) : null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 填充菜品的规格组和加料信息
|
|
|
- */
|
|
|
- private void fillDishDetail(HotelDish dish) {
|
|
|
- QueryWrapper<HotelDishSpec> specQw = new QueryWrapper<>();
|
|
|
- specQw.eq("dish_id", dish.getId()).eq("del_flag", 0).orderByAsc("sort_order");
|
|
|
- List<HotelDishSpec> specs = hotelDishSpecMapper.selectList(specQw);
|
|
|
- for (HotelDishSpec spec : specs) {
|
|
|
- QueryWrapper<HotelDishSpecOption> optQw = new QueryWrapper<>();
|
|
|
- optQw.eq("spec_id", spec.getId()).eq("del_flag", 0).orderByAsc("sort_order");
|
|
|
- spec.setOptions(hotelDishSpecOptionMapper.selectList(optQw));
|
|
|
- }
|
|
|
- dish.setSpecGroups(specs);
|
|
|
- QueryWrapper<HotelDishAddition> addQw = new QueryWrapper<>();
|
|
|
- addQw.eq("dish_id", dish.getId()).eq("del_flag", 0).orderByAsc("sort_order");
|
|
|
- dish.setAdditions(hotelDishAdditionMapper.selectList(addQw));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 新增/编辑菜品(管理后台)
|
|
|
- */
|
|
|
- public String saveDish(HotelDishDTO dto) {
|
|
|
- if (StringUtils.isBlank(dto.getId())) {
|
|
|
- HotelDish dish = dtoToEntity(dto);
|
|
|
- dish.setId(UUID.randomUUID().toString().replace("-", ""));
|
|
|
- dish.setDelFlag(0);
|
|
|
- if (dish.getStatus() == null) {
|
|
|
- dish.setStatus("ON_SALE");
|
|
|
- }
|
|
|
- if (dish.getSales() == null) {
|
|
|
- dish.setSales(0);
|
|
|
- }
|
|
|
- if (dish.getSoldOut() == null) {
|
|
|
- dish.setSoldOut(0);
|
|
|
- }
|
|
|
- hotelDishMapper.insert(dish);
|
|
|
- saveLog(dish.getId(), dish.getName(), "CREATE", null, toJson(dish), "新增菜品");
|
|
|
- log.info("新增菜品: {}", dish.getName());
|
|
|
- } else {
|
|
|
- HotelDish oldDish = hotelDishMapper.selectById(dto.getId());
|
|
|
- String oldJson = oldDish != null ? toJson(oldDish) : null;
|
|
|
- HotelDish dish = dtoToEntity(dto);
|
|
|
- hotelDishMapper.updateById(dish);
|
|
|
- saveLog(dish.getId(), dish.getName() != null ? dish.getName() : (oldDish != null ? oldDish.getName() : ""), "EDIT", oldJson, toJson(dish), "编辑菜品");
|
|
|
- log.info("编辑菜品: {}", dish.getName());
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除菜品(级联删除规格组和加料,需校验未完成订单)
|
|
|
- */
|
|
|
- public String deleteDish(String id) {
|
|
|
- HotelDish dish = hotelDishMapper.selectById(id);
|
|
|
- if (dish == null) {
|
|
|
- throw new RuntimeException("菜品不存在");
|
|
|
- }
|
|
|
- // 校验未完成订单
|
|
|
- checkUnfinishedOrders(id);
|
|
|
- // 软删除菜品
|
|
|
- dish.setDelFlag(1);
|
|
|
- hotelDishMapper.updateById(dish);
|
|
|
- // 级联软删除规格组
|
|
|
- QueryWrapper<HotelDishSpec> specQw = new QueryWrapper<>();
|
|
|
- specQw.eq("dish_id", id).eq("del_flag", 0);
|
|
|
- List<HotelDishSpec> specs = hotelDishSpecMapper.selectList(specQw);
|
|
|
- for (HotelDishSpec spec : specs) {
|
|
|
- spec.setDelFlag(1);
|
|
|
- hotelDishSpecMapper.updateById(spec);
|
|
|
- QueryWrapper<HotelDishSpecOption> optQw = new QueryWrapper<>();
|
|
|
- optQw.eq("spec_id", spec.getId()).eq("del_flag", 0);
|
|
|
- List<HotelDishSpecOption> options = hotelDishSpecOptionMapper.selectList(optQw);
|
|
|
- for (HotelDishSpecOption opt : options) {
|
|
|
- opt.setDelFlag(1);
|
|
|
- hotelDishSpecOptionMapper.updateById(opt);
|
|
|
- }
|
|
|
- }
|
|
|
- // 软删除加料
|
|
|
- QueryWrapper<HotelDishAddition> addQw = new QueryWrapper<>();
|
|
|
- addQw.eq("dish_id", id).eq("del_flag", 0);
|
|
|
- List<HotelDishAddition> additions = hotelDishAdditionMapper.selectList(addQw);
|
|
|
- for (HotelDishAddition add : additions) {
|
|
|
- add.setDelFlag(1);
|
|
|
- hotelDishAdditionMapper.updateById(add);
|
|
|
- }
|
|
|
- saveLog(id, dish.getName(), "DELETE", toJson(dish), null, "删除菜品");
|
|
|
- log.info("删除菜品: {}", dish.getName());
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 标记售罄
|
|
|
- */
|
|
|
- public String markSoldOut(String id) {
|
|
|
- HotelDish dish = hotelDishMapper.selectById(id);
|
|
|
- if (dish != null) {
|
|
|
- dish.setSoldOut(1);
|
|
|
- hotelDishMapper.updateById(dish);
|
|
|
- saveLog(id, dish.getName(), "SOLD_OUT", null, null, "标记售罄");
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 恢复上架(取消售罄)
|
|
|
- */
|
|
|
- public String restoreDish(String id) {
|
|
|
- HotelDish dish = hotelDishMapper.selectById(id);
|
|
|
- if (dish != null) {
|
|
|
- dish.setSoldOut(0);
|
|
|
- dish.setStatus("ON_SALE");
|
|
|
- hotelDishMapper.updateById(dish);
|
|
|
- saveLog(id, dish.getName(), "RESTORE", null, null, "恢复上架");
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新菜品状态(上架/下架)
|
|
|
- */
|
|
|
- public String updateStatus(String id, String status) {
|
|
|
- HotelDish dish = hotelDishMapper.selectById(id);
|
|
|
- if (dish == null) {
|
|
|
- throw new RuntimeException("菜品不存在");
|
|
|
- }
|
|
|
- dish.setStatus(status);
|
|
|
- hotelDishMapper.updateById(dish);
|
|
|
- String opType = "ON_SALE".equals(status) ? "ON_SALE" : "OFF_SHELF";
|
|
|
- saveLog(id, dish.getName(), opType, null, null, "ON_SALE".equals(status) ? "上架" : "下架");
|
|
|
- log.info("菜品状态变更: {} -> {}", dish.getName(), status);
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 批量操作
|
|
|
- */
|
|
|
- public String batchOperate(List<String> ids, String operation) {
|
|
|
- for (String id : ids) {
|
|
|
- switch (operation) {
|
|
|
- case "ON_SALE":
|
|
|
- updateStatus(id, "ON_SALE");
|
|
|
- break;
|
|
|
- case "OFF_SHELF":
|
|
|
- updateStatus(id, "OFF_SHELF");
|
|
|
- break;
|
|
|
- case "SOLD_OUT":
|
|
|
- markSoldOut(id);
|
|
|
- break;
|
|
|
- case "RESTORE":
|
|
|
- restoreDish(id);
|
|
|
- break;
|
|
|
- case "DELETE":
|
|
|
- deleteDish(id);
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new RuntimeException("不支持的操作类型: " + operation);
|
|
|
- }
|
|
|
- }
|
|
|
- return "批量操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 校验菜品是否有未完成订单
|
|
|
- */
|
|
|
- private void checkUnfinishedOrders(String dishId) {
|
|
|
- QueryWrapper<HotelOrder> qw = new QueryWrapper<>();
|
|
|
- qw.in("status", Arrays.asList("PREPARING", "READY", "DELIVERING", "ACCEPTED"))
|
|
|
- .eq("del_flag", 0);
|
|
|
- List<HotelOrder> orders = hotelOrderMapper.selectList(qw);
|
|
|
- if (!orders.isEmpty()) {
|
|
|
- throw new RuntimeException("该菜品存在未完成的订单,无法删除");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 保存操作日志
|
|
|
- */
|
|
|
- private void saveLog(String dishId, String dishName, String operationType, String oldValue, String newValue, String remark) {
|
|
|
- HotelDishLog logEntity = new HotelDishLog();
|
|
|
- logEntity.setId(UUID.randomUUID().toString().replace("-", ""));
|
|
|
- logEntity.setDishId(dishId);
|
|
|
- logEntity.setDishName(dishName);
|
|
|
- logEntity.setOperationType(operationType);
|
|
|
- logEntity.setOldValue(oldValue);
|
|
|
- logEntity.setNewValue(newValue);
|
|
|
- logEntity.setRemark(remark);
|
|
|
- logEntity.setDelFlag(0);
|
|
|
- hotelDishLogMapper.insert(logEntity);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 简单转JSON(用于日志记录)
|
|
|
- */
|
|
|
- private String toJson(Object obj) {
|
|
|
- if (obj == null) return null;
|
|
|
- try {
|
|
|
- return objectMapper.writeValueAsString(obj);
|
|
|
- } catch (Exception e) {
|
|
|
- return obj.toString();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // ============ 规格和加料方法 ============
|
|
|
-
|
|
|
- public String saveSpec(HotelDishSpec spec) {
|
|
|
- if (StringUtils.isBlank(spec.getId())) {
|
|
|
- spec.setId(UUID.randomUUID().toString().replace("-", ""));
|
|
|
- spec.setDelFlag(0);
|
|
|
- hotelDishSpecMapper.insert(spec);
|
|
|
- } else {
|
|
|
- hotelDishSpecMapper.updateById(spec);
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- public String deleteSpec(String id) {
|
|
|
- HotelDishSpec spec = hotelDishSpecMapper.selectById(id);
|
|
|
- if (spec == null) {
|
|
|
- throw new RuntimeException("规格组不存在");
|
|
|
- }
|
|
|
- spec.setDelFlag(1);
|
|
|
- hotelDishSpecMapper.updateById(spec);
|
|
|
- QueryWrapper<HotelDishSpecOption> optQw = new QueryWrapper<>();
|
|
|
- optQw.eq("spec_id", id).eq("del_flag", 0);
|
|
|
- List<HotelDishSpecOption> options = hotelDishSpecOptionMapper.selectList(optQw);
|
|
|
- for (HotelDishSpecOption opt : options) {
|
|
|
- opt.setDelFlag(1);
|
|
|
- hotelDishSpecOptionMapper.updateById(opt);
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- public String saveSpecOption(HotelDishSpecOption option) {
|
|
|
- if (StringUtils.isBlank(option.getId())) {
|
|
|
- option.setId(UUID.randomUUID().toString().replace("-", ""));
|
|
|
- option.setDelFlag(0);
|
|
|
- hotelDishSpecOptionMapper.insert(option);
|
|
|
- } else {
|
|
|
- hotelDishSpecOptionMapper.updateById(option);
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- public String saveAddition(HotelDishAddition addition) {
|
|
|
- if (StringUtils.isBlank(addition.getId())) {
|
|
|
- addition.setId(UUID.randomUUID().toString().replace("-", ""));
|
|
|
- addition.setDelFlag(0);
|
|
|
- hotelDishAdditionMapper.insert(addition);
|
|
|
- } else {
|
|
|
- hotelDishAdditionMapper.updateById(addition);
|
|
|
- }
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- public String deleteAddition(String id) {
|
|
|
- HotelDishAddition addition = hotelDishAdditionMapper.selectById(id);
|
|
|
- if (addition == null) {
|
|
|
- throw new RuntimeException("加料不存在");
|
|
|
- }
|
|
|
- addition.setDelFlag(1);
|
|
|
- hotelDishAdditionMapper.updateById(addition);
|
|
|
- return "操作成功";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 销量排行
|
|
|
- */
|
|
|
- public List<HotelDishDTO> salesRanking(int limit) {
|
|
|
- List<HotelDish> list = hotelDishMapper.selectSalesRanking(limit);
|
|
|
- return list.stream().map(this::entityToDto).collect(Collectors.toList());
|
|
|
- }
|
|
|
-}
|