Forráskód Böngészése

Merge remote-tracking branch 'origin/v1.8'

1 hónapja
szülő
commit
9e97070abb
33 módosított fájl, 1303 hozzáadás és 26 törlés
  1. 8 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/TourGroupController.java
  2. 3 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/TourGroupService.java
  3. 34 1
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourGroupServiceImpl.java
  4. 0 4
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourMemberImpl.java
  5. 31 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/OwnGroupVo.java
  6. 1 1
      application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/controller/TakeOutProjectController.java
  7. 4 2
      application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/controller/WechatDeliveryOrderController.java
  8. 5 5
      application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/controller/WechatFoodIndexController.java
  9. 9 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/vo/shopfood/SelectShopFoodVo.java
  10. 13 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/vo/shopfood/WechatBestNewShopVo.java
  11. 13 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/vo/shopfood/WechatSelectShopVo.java
  12. 338 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/RestaurantAreaMenuController.java
  13. 9 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/RestaurantTypeController.java
  14. 24 1
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourImComplaitController.java
  15. 33 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/RestaurantAreaMenuMapper.java
  16. 8 2
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/DeliveryOrderItemsMapper.xml
  17. 100 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/RestaurantAreaMenuMapper.xml
  18. 3 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/RestaurantFoodInfoMapper.xml
  19. 16 4
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/RestaurantInfoMapper.xml
  20. 7 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/DeliveryOrderItemsDto.java
  21. 85 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/RestaurantAreaMenuDto.java
  22. 10 2
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/RestaurantInfoDto.java
  23. 13 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/DeliveryOrderItems.java
  24. 98 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/RestaurantAreaMenu.java
  25. 6 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/RestaurantFoodInfo.java
  26. 30 2
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/RestaurantInfo.java
  27. 96 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/RestaurantAreaMenuService.java
  28. 168 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/RestaurantAreaMenuServiceImpl.java
  29. 14 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/DeliveryOrderItemsVo.java
  30. 86 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/RestaurantAreaMenuVo.java
  31. 6 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/RestaurantFoodInfoVo.java
  32. 26 2
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/RestaurantInfoVo.java
  33. 6 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourImComplaitVo.java

+ 8 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/TourGroupController.java

@@ -30,6 +30,7 @@ import com.tourism.common.redis.cache.SessionCacheHelper;
 import com.tourism.webadmin.app.website.dto.*;
 import com.tourism.webadmin.app.website.service.TourGroupService;
 import com.tourism.webadmin.app.website.service.TourMemberService;
+import com.tourism.webadmin.app.website.vo.OwnGroupVo;
 import com.tourism.webadmin.app.website.vo.TourGroupInvitationVo;
 import com.tourism.webadmin.back.model.*;
 import com.tourism.webadmin.back.model.constant.IsTrue;
@@ -666,4 +667,11 @@ public class TourGroupController {
         return ResponseResult.success(groupId);
     }
 
+    /**
+     * 查询登录用户的群聊
+     */
+    @GetMapping("/getOwnGroup")
+    public ResponseResult<List<OwnGroupVo> > getOwnGroup() {
+        return ResponseResult.success(tourGroupService.getOwnGroup());
+     }
 }

+ 3 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/TourGroupService.java

@@ -5,6 +5,7 @@ import com.tourism.webadmin.app.website.dto.CreateGroupDto;
 import com.tourism.webadmin.app.website.dto.CreateMemberDto;
 import com.tourism.webadmin.app.website.dto.MessageDTO;
 import com.tourism.webadmin.app.website.dto.UpdateGroupDto;
+import com.tourism.webadmin.app.website.vo.OwnGroupVo;
 import com.tourism.webadmin.back.model.TourImGroup;
 import com.tourism.webadmin.back.model.TourImGroupInvitation;
 import com.tourism.webadmin.back.model.TourUser;
@@ -47,4 +48,6 @@ public interface TourGroupService extends IService<TourImGroup> {
     boolean isAdmin(Long groupId,Long userId);
 
     String createMember(CreateMemberDto params);
+
+    List<OwnGroupVo> getOwnGroup();
 }

+ 34 - 1
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourGroupServiceImpl.java

@@ -1,5 +1,6 @@
 package com.tourism.webadmin.app.website.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -15,6 +16,7 @@ import com.tourism.webadmin.app.website.controller.SystemMessageController;
 import com.tourism.webadmin.app.website.dto.*;
 import com.tourism.webadmin.app.website.service.TourGroupService;
 import com.tourism.webadmin.app.website.service.TourMemberService;
+import com.tourism.webadmin.app.website.vo.OwnGroupVo;
 import com.tourism.webadmin.back.dao.TourImGroupMapper;
 import com.tourism.webadmin.back.model.TourImGroup;
 import com.tourism.webadmin.back.model.TourImGroupInvitation;
@@ -180,8 +182,10 @@ public class TourGroupServiceImpl extends ServiceImpl<TourImGroupMapper, TourImG
             Map<String, Set<TourUser>> userByGroupId = tourMemberService.getUserByGroupId(ids);
 
             Set<TourUser> tourUsers = userByGroupId.get(group.getId().toString());
+            //人数小于1没有需要通知的人直接返回
             if(tourUsers.size()<=1)return;
             for (TourUser user : tourUsers) {
+                //不需要通知自己
                 if(user.getUserId().equals(userId)){
                     continue;
                 }
@@ -193,7 +197,7 @@ public class TourGroupServiceImpl extends ServiceImpl<TourImGroupMapper, TourImG
                 systemMessageDTO.setTitle("群通知");
                 systemMessageDTO.setGetUserId(user.getUserId().toString());//接收人
                 systemMessageDTO.setSendUserId(userId.toString());//处理人
-                systemMessageDTO.setGroupId(userId.toString());//群ID
+                systemMessageDTO.setGroupId(group.getId().toString());//群ID
                 systemMessageController.sendMessage(systemMessageDTO);
             }
             LambdaQueryWrapper<TourImMember> query = Wrappers.<TourImMember>lambdaQuery().eq(TourImMember::getGroupId, group.getId()).eq(TourImMember::getDataState, 1);
@@ -397,6 +401,35 @@ public class TourGroupServiceImpl extends ServiceImpl<TourImGroupMapper, TourImG
         return groupId;
     }
 
+    @Override
+    public List<OwnGroupVo> getOwnGroup() {
+        Long userId = TokenData.takeFromRequest().getUserId();
+        //获取登录用户加入了那些群聊
+        LambdaQueryWrapper<TourImGroup> query = Wrappers.<TourImGroup>lambdaQuery().eq(TourImGroup::getLeaderId, userId)
+                .eq(TourImGroup::getBannedStatus,1)
+                .eq(TourImGroup::getDataState, 1)
+                .eq(TourImGroup::getNoticeType, 2)
+                .orderByDesc(TourImGroup::getCreateTime);
+        List<TourImGroup> list = tourImGroupService.list(query);
+        List<OwnGroupVo> result = BeanUtil.copyToList(list, OwnGroupVo.class);
+        if(list.isEmpty()) return null;
+        List<String> collect = list.stream().map(o->o.getId().toString()).collect(Collectors.toList());
+        Map<String, Set<TourUser>> userMap = tourMemberService.getUserByGroupId(collect);
+        for (OwnGroupVo vo : result) {
+            Set<TourUser> tourUsers = userMap.get(vo.getId().toString());
+            vo.setNumCount(tourUsers.size());
+            if(vo.getNumCount()==0)continue;
+            int i=0;
+            List<String> heardImage = vo.getHeardImage();
+            for(TourUser user:tourUsers){
+                heardImage.add(user.getHeadImageUrl());
+                i++;
+                if(i>10) break;
+            }
+        }
+        return result;
+    }
+
     /**
      *  通过
      */

+ 0 - 4
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourMemberImpl.java

@@ -442,7 +442,6 @@ public class TourMemberImpl extends ServiceImpl<TourImMemberMapper, TourImMember
         // 群聊ID
         for (TourImMember l : list) {
             TourUser uUser = userMap.get(l.getUserId());
-            TourUser pUser= userMap.get(l.getPartnerId());
             Set<TourUser> tourUsers = map.get(l.getGroupId().toString());
             if(tourUsers==null){
                 tourUsers=new HashSet<TourUser>();
@@ -451,9 +450,6 @@ public class TourMemberImpl extends ServiceImpl<TourImMemberMapper, TourImMember
             if(uUser!=null){
                 tourUsers.add(uUser);
             }
-            if(pUser!=null){
-                tourUsers.add(pUser);
-            }
         }
        return map;
     }

+ 31 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/OwnGroupVo.java

@@ -0,0 +1,31 @@
+package com.tourism.webadmin.app.website.vo;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class OwnGroupVo {
+    /**
+     * id。
+     */
+    private String id;
+    /**
+     * 群聊名称。
+     */
+    private String groupName;
+    /**
+     * 群聊头像。
+     */
+    private List<String> heardImage=new ArrayList<>();
+    /**
+     * 人数
+     */
+    private int numCount;
+    /**
+     *创建时间
+     */
+    private Date createTime;
+}

+ 1 - 1
application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/controller/TakeOutProjectController.java

@@ -117,7 +117,7 @@ public class TakeOutProjectController {
         RestaurantInfo restaurantInfo = MyModelUtil.copyTo(tourismRestaurantInfoToWebDto, RestaurantInfo.class);
         String orderBy = MyOrderParam.buildOrderBy(tourismRestaurantInfoToWebDto.getOrderParamList(), RestaurantInfo.class);
         List<RestaurantInfo> restaurantInfoList =
-                restaurantInfoService.getRestaurantInfoList(restaurantInfo, orderBy);
+                restaurantInfoService.getRestaurantInfoListWithRelation(restaurantInfo, orderBy);
         MyPageData<RestaurantInfoVo> restaurantInfoVoMyPageData = MyPageUtil.makeResponseData(restaurantInfoList, RestaurantInfoVo.class);
         List<RestaurantInfoVo> dataList = restaurantInfoVoMyPageData.getDataList();
         dataList.stream().forEach(item ->

+ 4 - 2
application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/controller/WechatDeliveryOrderController.java

@@ -86,7 +86,9 @@ public class WechatDeliveryOrderController {
         //查询订单详情
         if (!deliveryOrderList.isEmpty()) {
             Set<String> orderIds = deliveryOrderList.stream().map(e -> e.getId()).collect(Collectors.toSet());
-            List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsVoList(orderIds);
+            List<Long> list = orderIds.stream().map(Long::parseLong).collect(Collectors.toList());
+            List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsListWithRelation(DeliveryOrderItems.builder().orderIds(list).build(), null);
+//            List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsVoList(orderIds);
             List<DeliveryOrderItemsVo> deliveryOrderItemsVos = MyModelUtil.copyCollectionTo(items, DeliveryOrderItemsVo.class);
             //做成map,方便匹配
             Map<String, List<DeliveryOrderItemsVo>> collect1 = deliveryOrderItemsVos.stream().collect(Collectors.groupingBy(DeliveryOrderItemsVo::getOrderId));
@@ -125,7 +127,7 @@ public class WechatDeliveryOrderController {
         deliveryOrderService.maskFieldData(deliveryOrder, null);
         DeliveryOrderVo deliveryOrderVo = MyModelUtil.copyTo(deliveryOrder, DeliveryOrderVo.class);
         DeliveryOrderItems build = DeliveryOrderItems.builder().orderId(deliveryOrderVo.getId()).build();
-        List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsList(build, "create_time");
+        List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsListWithRelation(build, "create_time");
         //items转为vo
         deliveryOrderVo.setItemList(MyModelUtil.copyCollectionTo(items, DeliveryOrderItemsVo.class));
         return ResponseResult.success(deliveryOrderVo);

+ 5 - 5
application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/controller/WechatFoodIndexController.java

@@ -106,7 +106,7 @@ public class WechatFoodIndexController {
 //        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, RestaurantInfo.class);
 
         PageMethod.startPage(1, 4, true);
-        List<RestaurantFoodInfo> foodInfoList = restaurantFoodInfoService.getRestaurantFoodInfoList(filter, null);
+        List<RestaurantFoodInfo> foodInfoList = restaurantFoodInfoService.getRestaurantFoodInfoListWithRelation(filter, null);
         MyPageData<RestaurantFoodInfoVo> pageData = MyPageUtil.makeResponseData(foodInfoList, RestaurantFoodInfoVo.class);
         List<RestaurantFoodInfoVo> list = pageData.getDataList();
         list.stream().forEach(o->{
@@ -197,7 +197,7 @@ public class WechatFoodIndexController {
         if (orderNum==2) myOrderParam.add(new MyOrderParam.OrderInfo("createTime",false,null));
         String orderBy = MyOrderParam.buildOrderBy(myOrderParam, RestaurantInfo.class);
 
-        List<RestaurantInfo> list = restaurantInfoService.getRestaurantInfoList(filter, orderBy);
+        List<RestaurantInfo> list = restaurantInfoService.getRestaurantInfoListWithRelation(filter, orderBy);
         MyPageData<WechatSelectShopVo> pageData = MyPageUtil.makeResponseData(list, WechatSelectShopVo.class);
         if (pageData.getDataList() == null || pageData.getDataList().isEmpty()) {
             return ResponseResult.success(null);
@@ -217,7 +217,7 @@ public class WechatFoodIndexController {
             filter1.setEnable(1);
             filter1.setDataState(1);
             filter1.setRestaurantId(shopVo.getId());
-            List<RestaurantFoodInfo> infoList = restaurantFoodInfoService.getRestaurantFoodInfoList(filter1, null);
+            List<RestaurantFoodInfo> infoList = restaurantFoodInfoService.getRestaurantFoodInfoListWithRelation(filter1, null);
             List<SelectShopFoodVo> foodVos = MyPageUtil.makeResponseData(infoList, SelectShopFoodVo.class).getDataList();
 
             foodVos.stream().forEach(o->{
@@ -256,7 +256,7 @@ public class WechatFoodIndexController {
         myOrderParam.add(new MyOrderParam.OrderInfo("createTime",false,null));
         String orderBy = MyOrderParam.buildOrderBy(myOrderParam, RestaurantInfo.class);
 
-        List<RestaurantInfo> infoList = restaurantInfoService.getRestaurantInfoList(filter, orderBy);
+        List<RestaurantInfo> infoList = restaurantInfoService.getRestaurantInfoListWithRelation(filter, orderBy);
         List<WechatBestNewShopVo> shopVos = MyPageUtil.makeResponseData(infoList, WechatBestNewShopVo.class).getDataList();
         shopVos.stream().forEach(o->{
             List<String> strings = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), o.getUrl());
@@ -367,7 +367,7 @@ public class WechatFoodIndexController {
             PageMethod.startPage(shopFoodDto.getPageNum(), shopFoodDto.getPageSize(), true);
         }
 
-        List<RestaurantFoodInfo> infoList = restaurantFoodInfoService.getRestaurantFoodInfoList(filter1, null);
+        List<RestaurantFoodInfo> infoList = restaurantFoodInfoService.getRestaurantFoodInfoListWithRelation(filter1, null);
         MyPageData<RestaurantFoodInfoVo> pageData = MyPageUtil.makeResponseData(infoList, RestaurantFoodInfoVo.class);
         List<RestaurantFoodInfoVo> infoVos = pageData.getDataList();
 

+ 9 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/vo/shopfood/SelectShopFoodVo.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * SelectShopFoodVo接口。
@@ -54,4 +55,12 @@ public class SelectShopFoodVo {
     private String priceUnit;
     @Schema(description = "销量")
     private Integer sales;
+
+    /**
+     * priceUnit 全局字典关联数据。
+     */
+    @Schema(description = "priceUnit 全局字典关联数据")
+    private Map<String, Object> priceUnitDictMap;
+
+
 }

+ 13 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/vo/shopfood/WechatBestNewShopVo.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 优选新店Vo。
@@ -69,4 +70,16 @@ public class WechatBestNewShopVo {
     @TableField(value = "total_sales")
     private Long totalSales;
 
+    /**
+     * 价格单位。
+     */
+    @Schema(description = "价格单位")
+    private String priceUnit;
+
+    /**
+     * priceUnit 全局字典关联数据。
+     */
+    @Schema(description = "priceUnit 全局字典关联数据")
+    private Map<String, Object> priceUnitDictMap;
+
 }

+ 13 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/wechat/vo/shopfood/WechatSelectShopVo.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 精选好店Vo。
@@ -101,4 +102,16 @@ public class WechatSelectShopVo {
     @Schema(description = "销量")
     private Long totalSales;
 
+    /**
+     * 价格单位。
+     */
+    @Schema(description = "价格单位")
+    private String priceUnit;
+
+    /**
+     * priceUnit 全局字典关联数据。
+     */
+    @Schema(description = "priceUnit 全局字典关联数据")
+    private Map<String, Object> priceUnitDictMap;
+
 }

+ 338 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/RestaurantAreaMenuController.java

@@ -0,0 +1,338 @@
+package com.tourism.webadmin.back.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.ObjectUtil;
+import com.tourism.common.log.annotation.OperationLog;
+import com.tourism.common.log.model.constant.SysOperationLogType;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.webadmin.back.vo.*;
+import com.tourism.webadmin.back.dto.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.*;
+import com.tourism.common.core.constant.*;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.tourism.common.additional.config.ApplicationConfig;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * 餐馆区域管理操作控制器类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "餐馆区域管理管理接口")
+@Slf4j
+@RestController
+@RequestMapping("/admin/app/restaurantAreaMenu")
+public class RestaurantAreaMenuController {
+
+    @Autowired
+    private ApplicationConfig appConfig;
+    @Autowired
+    private RestaurantAreaMenuService restaurantAreaMenuService;
+
+    /**
+     * 新增餐馆区域管理数据。
+     *
+     * @param restaurantAreaMenuDto 新增对象。
+     * @return 应答结果对象,包含新增对象主键Id。
+     */
+    @ApiOperationSupport(ignoreParameters = {"restaurantAreaMenuDto.id"})
+    @SaCheckPermission("restaurantAreaMenu.add")
+    @OperationLog(type = SysOperationLogType.ADD)
+    @PostMapping("/add")
+    public ResponseResult<Long> add(@MyRequestBody RestaurantAreaMenuDto restaurantAreaMenuDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(restaurantAreaMenuDto, false);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        RestaurantAreaMenu restaurantAreaMenu = MyModelUtil.copyTo(restaurantAreaMenuDto, RestaurantAreaMenu.class);
+        // 验证关联Id的数据合法性
+        CallResult callResult = restaurantAreaMenuService.verifyRelatedData(restaurantAreaMenu, null);
+        if (!callResult.isSuccess()) {
+            return ResponseResult.errorFrom(callResult);
+        }
+        // 验证父Id的数据合法性
+        RestaurantAreaMenu parentRestaurantAreaMenu;
+        if (MyCommonUtil.isNotBlankOrNull(restaurantAreaMenu.getParentId())) {
+            parentRestaurantAreaMenu = restaurantAreaMenuService.getById(restaurantAreaMenu.getParentId());
+            if (parentRestaurantAreaMenu == null) {
+                errorMessage = "数据验证失败,关联的父节点并不存在,请刷新后重试!";
+                return ResponseResult.error(ErrorCodeEnum.DATA_PARENT_ID_NOT_EXIST, errorMessage);
+            }
+        }
+        restaurantAreaMenu = restaurantAreaMenuService.saveNew(restaurantAreaMenu);
+        return ResponseResult.success(restaurantAreaMenu.getId());
+    }
+
+    /**
+     * 更新餐馆区域管理数据。
+     *
+     * @param restaurantAreaMenuDto 更新对象。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("restaurantAreaMenu.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/update")
+    public ResponseResult<Void> update(@MyRequestBody RestaurantAreaMenuDto restaurantAreaMenuDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(restaurantAreaMenuDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        RestaurantAreaMenu restaurantAreaMenu = MyModelUtil.copyTo(restaurantAreaMenuDto, RestaurantAreaMenu.class);
+        RestaurantAreaMenu originalRestaurantAreaMenu = restaurantAreaMenuService.getById(restaurantAreaMenu.getId());
+        if (originalRestaurantAreaMenu == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        // 验证关联Id的数据合法性
+        CallResult callResult = restaurantAreaMenuService.verifyRelatedData(restaurantAreaMenu, originalRestaurantAreaMenu);
+        if (!callResult.isSuccess()) {
+            return ResponseResult.errorFrom(callResult);
+        }
+        // 验证父Id的数据合法性
+        if (MyCommonUtil.isNotBlankOrNull(restaurantAreaMenu.getParentId())
+                && ObjectUtil.notEqual(restaurantAreaMenu.getParentId(), originalRestaurantAreaMenu.getParentId())) {
+            RestaurantAreaMenu parentRestaurantAreaMenu = restaurantAreaMenuService.getById(restaurantAreaMenu.getParentId());
+            if (parentRestaurantAreaMenu == null) {
+                // NOTE: 修改下面方括号中的话述
+                errorMessage = "数据验证失败,关联的 [父节点] 并不存在,请刷新后重试!";
+                return ResponseResult.error(ErrorCodeEnum.DATA_PARENT_ID_NOT_EXIST, errorMessage);
+            }
+        }
+        if (!restaurantAreaMenuService.update(restaurantAreaMenu, originalRestaurantAreaMenu)) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 删除餐馆区域管理数据。
+     *
+     * @param id 删除对象主键Id。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("restaurantAreaMenu.delete")
+    @OperationLog(type = SysOperationLogType.DELETE)
+    @PostMapping("/delete")
+    public ResponseResult<Void> delete(@MyRequestBody Long id) {
+        if (MyCommonUtil.existBlankArgument(id)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        return this.doDelete(id);
+    }
+
+    /**
+     * 批量删除餐馆区域管理数据。
+     *
+     * @param idList 待删除对象的主键Id列表。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("restaurantAreaMenu.delete")
+    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
+    @PostMapping("/deleteBatch")
+    public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> idList) {
+        if (MyCommonUtil.existBlankArgument(idList)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        for (Long id : idList) {
+            ResponseResult<Void> responseResult = this.doDelete(id);
+            if (!responseResult.isSuccess()) {
+                return responseResult;
+            }
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 列出符合过滤条件的餐馆区域管理列表。
+     *
+     * @param restaurantAreaMenuDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @param pageParam 分页参数。
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaCheckPermission("restaurantAreaMenu.view")
+    @PostMapping("/list")
+    public ResponseResult<MyPageData<RestaurantAreaMenuVo>> list(
+            @MyRequestBody RestaurantAreaMenuDto restaurantAreaMenuDtoFilter,
+            @MyRequestBody MyOrderParam orderParam,
+            @MyRequestBody MyPageParam pageParam) {
+        if (pageParam != null) {
+            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
+        }
+        RestaurantAreaMenu restaurantAreaMenuFilter = MyModelUtil.copyTo(restaurantAreaMenuDtoFilter, RestaurantAreaMenu.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, RestaurantAreaMenu.class);
+        List<RestaurantAreaMenu> restaurantAreaMenuList =
+                restaurantAreaMenuService.getRestaurantAreaMenuListWithRelation(restaurantAreaMenuFilter, orderBy);
+        return ResponseResult.success(MyPageUtil.makeResponseData(restaurantAreaMenuList, RestaurantAreaMenuVo.class));
+    }
+
+    /**
+     * 导入主表数据列表。
+     *
+     * @param importFile 上传的文件,目前仅仅支持xlsx和xls两种格式。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("restaurantAreaMenu.import")
+    @OperationLog(type = SysOperationLogType.IMPORT)
+    @PostMapping("/import")
+    public ResponseResult<Void> importBatch(
+            @RequestParam Boolean skipHeader,
+            @RequestParam("importFile") MultipartFile importFile) throws IOException {
+        String filename = ImportUtil.saveImportFile(appConfig.getUploadFileBaseDir(), null, importFile);
+        // 这里可以指定需要忽略导入的字段集合。如创建时间、创建人、更新时间、更新人、主键Id和逻辑删除,
+        // 以及一些存在缺省值且无需导入的字段。其中主键字段和逻辑删除字段不需要在这里设置,批量插入逻辑会自动处理的。
+        Set<String> ignoreFieldSet = new HashSet<>();
+        ignoreFieldSet.add("createUserId");
+        ignoreFieldSet.add("createTime");
+        ignoreFieldSet.add("updateUserId");
+        ignoreFieldSet.add("updateTime");
+        List<ImportUtil.ImportHeaderInfo> headerInfoList = ImportUtil.makeHeaderInfoList(RestaurantAreaMenu.class, ignoreFieldSet);
+        // 下面是导入时需要注意的地方,如果我们缺省生成的代码,与实际情况存在差异,请手动修改。
+        // 1. 头信息数据字段,我们只是根据当前的主表实体对象生成了缺省数组,开发者可根据实际情况,对headerInfoList进行修改。
+        ImportUtil.ImportHeaderInfo[] headerInfos = headerInfoList.toArray(new ImportUtil.ImportHeaderInfo[]{});
+        // 2. 这里需要根据实际情况决定,导入文件中第一行是否为中文头信息,如果是可以跳过。这里我们默认为true。
+        // 这里根据自己的实际需求,为doImport的最后一个参数,传递需要进行字典转换的字段集合。
+        // 注意,集合中包含需要翻译的Java字段名,如: gradeId。
+        Set<String> translatedDictFieldSet = new HashSet<>();
+        List<RestaurantAreaMenu> dataList =
+                ImportUtil.doImport(headerInfos, skipHeader, filename, RestaurantAreaMenu.class, translatedDictFieldSet);
+        CallResult result = restaurantAreaMenuService.verifyImportList(dataList, translatedDictFieldSet);
+        if (!result.isSuccess()) {
+            // result中返回了具体的验证失败对象,如果需要返回更加详细的错误,可根据实际情况手动修改。
+            return ResponseResult.errorFrom(result);
+        }
+        restaurantAreaMenuService.saveNewBatch(dataList, -1);
+        return ResponseResult.success();
+    }
+
+    /**
+     * 导出符合过滤条件的餐馆区域管理列表。
+     *
+     * @param restaurantAreaMenuDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @throws IOException 文件读写失败。
+     */
+    @SaCheckPermission("restaurantAreaMenu.export")
+    @OperationLog(type = SysOperationLogType.EXPORT, saveResponse = false)
+    @PostMapping("/export")
+    public void export(
+            @MyRequestBody RestaurantAreaMenuDto restaurantAreaMenuDtoFilter,
+            @MyRequestBody MyOrderParam orderParam) throws IOException {
+        RestaurantAreaMenu restaurantAreaMenuFilter = MyModelUtil.copyTo(restaurantAreaMenuDtoFilter, RestaurantAreaMenu.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, RestaurantAreaMenu.class);
+        List<RestaurantAreaMenu> resultList =
+                restaurantAreaMenuService.getRestaurantAreaMenuListWithRelation(restaurantAreaMenuFilter, orderBy);
+        // 导出文件的标题数组
+        // NOTE: 下面的代码中仅仅导出了主表数据,主表聚合计算数据和主表关联字典的数据。
+        // 一对一从表数据的导出,可根据需要自行添加。如:headerMap.put("slaveFieldName.xxxField", "标题名称")
+        Map<String, String> headerMap = new LinkedHashMap<>(13);
+        headerMap.put("id", "主键id");
+        headerMap.put("parentIdDictMap.name", "父级id");
+        headerMap.put("levelNum", "菜单等级");
+        headerMap.put("levelName", "菜单名称");
+        headerMap.put("showOrder", "显示顺序");
+        headerMap.put("enableDictMap.name", "是否启用,0禁用,1启用");
+        headerMap.put("isHotspotDictMap.name", "是否热点,0非热点,1热点");
+        headerMap.put("hotOrder", "热门排序");
+        headerMap.put("createUserId", "创建用户");
+        headerMap.put("createTime", "创建时间");
+        headerMap.put("updateUserId", "更新用户");
+        headerMap.put("updateTime", "更新时间");
+        headerMap.put("dataState", "删除标记(1: 正常 -1: 已删除)");
+        ExportUtil.doExport(resultList, headerMap, "restaurantAreaMenu.xlsx");
+    }
+
+    /**
+     * 查看指定餐馆区域管理对象详情。
+     *
+     * @param id 指定对象主键Id。
+     * @return 应答结果对象,包含对象详情。
+     */
+    @SaCheckPermission("restaurantAreaMenu.view")
+    @GetMapping("/view")
+    public ResponseResult<RestaurantAreaMenuVo> view(@RequestParam Long id) {
+        RestaurantAreaMenu restaurantAreaMenu = restaurantAreaMenuService.getByIdWithRelation(id, MyRelationParam.full());
+        if (restaurantAreaMenu == null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        RestaurantAreaMenuVo restaurantAreaMenuVo = MyModelUtil.copyTo(restaurantAreaMenu, RestaurantAreaMenuVo.class);
+        return ResponseResult.success(restaurantAreaMenuVo);
+    }
+
+    /**
+     * 以字典形式返回全部餐馆区域管理数据集合。字典的键值为[id, levelName]。
+     * 白名单接口,登录用户均可访问。
+     *
+     * @param filter 过滤对象。
+     * @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
+     */
+    @GetMapping("/listDict")
+    public ResponseResult<List<Map<String, Object>>> listDict(@ParameterObject RestaurantAreaMenuDto filter) {
+        List<RestaurantAreaMenu> resultList =
+                restaurantAreaMenuService.getListByFilter(MyModelUtil.copyTo(filter, RestaurantAreaMenu.class));
+        return ResponseResult.success(MyCommonUtil.toDictDataList(
+                resultList, RestaurantAreaMenu::getId, RestaurantAreaMenu::getLevelName, RestaurantAreaMenu::getParentId));
+    }
+
+    /**
+     * 根据字典Id集合,获取查询后的字典数据。
+     *
+     * @param dictIds 字典Id集合。
+     * @return 应答结果对象,包含字典形式的数据集合。
+     */
+    @GetMapping("/listDictByIds")
+    public ResponseResult<List<Map<String, Object>>> listDictByIds(@RequestParam List<Long> dictIds) {
+        List<RestaurantAreaMenu> resultList = restaurantAreaMenuService.getInList(new HashSet<>(dictIds));
+        return ResponseResult.success(MyCommonUtil.toDictDataList(
+                resultList, RestaurantAreaMenu::getId, RestaurantAreaMenu::getLevelName, RestaurantAreaMenu::getParentId));
+    }
+
+    /**
+     * 根据父主键Id,以字典的形式返回其下级数据列表。
+     * 白名单接口,登录用户均可访问。
+     *
+     * @param parentId 父主键Id。
+     * @return 按照字典的形式返回下级数据列表。
+     */
+    @GetMapping("/listDictByParentId")
+    public ResponseResult<List<Map<String, Object>>> listDictByParentId(@RequestParam(required = false) Long parentId) {
+        List<RestaurantAreaMenu> resultList = restaurantAreaMenuService.getListByParentId("parentId", parentId);
+        return ResponseResult.success(MyCommonUtil.toDictDataList(
+                resultList, RestaurantAreaMenu::getId, RestaurantAreaMenu::getLevelName, RestaurantAreaMenu::getParentId));
+    }
+
+    private ResponseResult<Void> doDelete(Long id) {
+        String errorMessage;
+        // 验证关联Id的数据合法性
+        RestaurantAreaMenu originalRestaurantAreaMenu = restaurantAreaMenuService.getById(id);
+        if (originalRestaurantAreaMenu == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (restaurantAreaMenuService.hasChildren(id)) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象存在子对象] ,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.HAS_CHILDREN_DATA, errorMessage);
+        }
+        if (!restaurantAreaMenuService.remove(id)) {
+            errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        return ResponseResult.success();
+    }
+}

+ 9 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/RestaurantTypeController.java

@@ -3,6 +3,7 @@ package com.tourism.webadmin.back.controller;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaIgnore;
 import cn.hutool.core.util.ReflectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.tourism.common.core.upload.BaseUpDownloader;
 import com.tourism.common.core.upload.UpDownloaderFactory;
 import com.tourism.common.core.upload.UploadResponseInfo;
@@ -68,6 +69,10 @@ public class RestaurantTypeController {
         if (errorMessage != null) {
             return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
         }
+        List<RestaurantType> list = restaurantTypeService.list(new LambdaQueryWrapper<RestaurantType>()
+                .eq(RestaurantType::getDataState, 1)
+                .eq(RestaurantType::getName, restaurantTypeDto.getName()));
+        if (!list.isEmpty()) return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "当前名称已存在,请修改后重试!");
         RestaurantType restaurantType = MyModelUtil.copyTo(restaurantTypeDto, RestaurantType.class);
         restaurantType = restaurantTypeService.saveNew(restaurantType);
         return ResponseResult.success(restaurantType.getId());
@@ -95,6 +100,10 @@ public class RestaurantTypeController {
             errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
             return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
         }
+        long count = restaurantTypeService.count(new LambdaQueryWrapper<RestaurantType>()
+                .eq(RestaurantType::getDataState, 1)
+                .eq(RestaurantType::getName, restaurantTypeDto.getName()));
+        if (count>1) return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "当前名称已存在,请修改后重试!");
         if (!restaurantTypeService.update(restaurantType, originalRestaurantType)) {
             return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
         }

+ 24 - 1
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourImComplaitController.java

@@ -1,7 +1,9 @@
 package com.tourism.webadmin.back.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ReflectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.tourism.common.core.upload.BaseUpDownloader;
 import com.tourism.common.core.upload.UpDownloaderFactory;
 import com.tourism.common.core.upload.UploadResponseInfo;
@@ -29,6 +31,7 @@ import org.springframework.web.multipart.MultipartFile;
 import jakarta.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 投诉内容管理操作控制器类。
@@ -50,6 +53,8 @@ public class TourImComplaitController {
     private UpDownloaderFactory upDownloaderFactory;
     @Autowired
     private TourImComplaitService tourImComplaitService;
+    @Autowired
+    private TourImGroupService tourImGroupService;
 
     /**
      * 新增投诉内容管理数据。
@@ -168,7 +173,25 @@ public class TourImComplaitController {
         String orderBy = MyOrderParam.buildOrderBy(orderParam, TourImComplait.class);
         List<TourImComplait> tourImComplaitList =
                 tourImComplaitService.getTourImComplaitListWithRelation(tourImComplaitFilter, orderBy);
-        return ResponseResult.success(MyPageUtil.makeResponseData(tourImComplaitList, TourImComplaitVo.class));
+        MyPageData<TourImComplaitVo> data = MyPageUtil.makeResponseData(tourImComplaitList, TourImComplaitVo.class);
+        List<TourImComplaitVo> dataList = data.getDataList();
+        if (dataList != null){
+            List<TourImComplaitVo> groupCollect = dataList.stream().filter(o -> o.getObjectType() == 2).collect(Collectors.toList());
+            if (!ObjectUtil.isEmpty(groupCollect)){
+                //取出groupId集合
+                List<String> groupIds = groupCollect.stream().map(TourImComplaitVo::getGroupId).toList();
+                List<TourImGroup> tourImGroupList = tourImGroupService.list(new LambdaQueryWrapper<TourImGroup>()
+                        .in(TourImGroup::getId, groupIds)
+                        .eq(TourImGroup::getDataState,1));
+                //将群组的封禁字段按照群id塞入集合中
+                Map<Long, Integer> groupStatusMap = tourImGroupList.stream().collect(Collectors.toMap(TourImGroup::getId, TourImGroup::getBannedStatus));
+                for (TourImComplaitVo tourImComplaitVo : groupCollect) {
+                    Integer groupStatus = groupStatusMap.get(Long.valueOf(tourImComplaitVo.getGroupId()));
+                    tourImComplaitVo.setGroupStatus(groupStatus);
+                }
+            }
+        }
+        return ResponseResult.success(data);
     }
 
     /**

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/RestaurantAreaMenuMapper.java

@@ -0,0 +1,33 @@
+package com.tourism.webadmin.back.dao;
+
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.back.model.RestaurantAreaMenu;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.*;
+
+/**
+ * 餐馆区域管理数据操作访问接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface RestaurantAreaMenuMapper extends BaseDaoMapper<RestaurantAreaMenu> {
+
+    /**
+     * 批量插入对象列表。
+     *
+     * @param restaurantAreaMenuList 新增对象列表。
+     */
+    void insertList(List<RestaurantAreaMenu> restaurantAreaMenuList);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param restaurantAreaMenuFilter 主表过滤对象。
+     * @param orderBy 排序字符串,order by从句的参数。
+     * @return 对象列表。
+     */
+    List<RestaurantAreaMenu> getRestaurantAreaMenuList(
+            @Param("restaurantAreaMenuFilter") RestaurantAreaMenu restaurantAreaMenuFilter, @Param("orderBy") String orderBy);
+}

+ 8 - 2
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/DeliveryOrderItemsMapper.xml

@@ -13,6 +13,7 @@
         <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
         <result column="data_state" jdbcType="TINYINT" property="dataState"/>
         <result column="image" jdbcType="VARCHAR" property="image"/>
+        <result column="price_unit" jdbcType="VARCHAR" property="priceUnit"/>
     </resultMap>
 
     <insert id="insertList">
@@ -27,7 +28,8 @@
             update_user_id,
             update_time,
             data_state,
-             image)
+             image,
+        price_unit)
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
             (#{item.id},
@@ -40,7 +42,8 @@
             #{item.updateUserId},
             #{item.updateTime},
             #{item.dataState},
-            #{item.image})
+            #{item.image},
+            #{item.priceUnit})
         </foreach>
     </insert>
 
@@ -59,6 +62,9 @@
             <if test="deliveryOrderItemsFilter.orderId != null">
                 AND tour_delivery_order_items.order_id = #{deliveryOrderItemsFilter.orderId}
             </if>
+            <if test="deliveryOrderItemsFilter.priceUnit != null and deliveryOrderItemsFilter.priceUnit != ''">
+                AND tour_delivery_order_items.price_unit = #{deliveryOrderItemsFilter.priceUnit}
+            </if>
         </if>
     </sql>
 

+ 100 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/RestaurantAreaMenuMapper.xml

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tourism.webadmin.back.dao.RestaurantAreaMenuMapper">
+    <resultMap id="BaseResultMap" type="com.tourism.webadmin.back.model.RestaurantAreaMenu">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="parent_id" jdbcType="BIGINT" property="parentId"/>
+        <result column="level_num" jdbcType="TINYINT" property="levelNum"/>
+        <result column="level_name" jdbcType="VARCHAR" property="levelName"/>
+        <result column="show_order" jdbcType="TINYINT" property="showOrder"/>
+        <result column="enable" jdbcType="TINYINT" property="enable"/>
+        <result column="is_hotspot" jdbcType="TINYINT" property="isHotspot"/>
+        <result column="hot_order" jdbcType="TINYINT" property="hotOrder"/>
+        <result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+        <result column="data_state" jdbcType="TINYINT" property="dataState"/>
+    </resultMap>
+
+    <insert id="insertList">
+        INSERT INTO tour_restaurant_area_menu
+            (id,
+            parent_id,
+            level_num,
+            level_name,
+            show_order,
+            enable,
+            is_hotspot,
+            hot_order,
+            create_user_id,
+            create_time,
+            update_user_id,
+            update_time,
+            data_state)
+        VALUES
+        <foreach collection="list" index="index" item="item" separator="," >
+            (#{item.id},
+            #{item.parentId},
+            #{item.levelNum},
+            #{item.levelName},
+            #{item.showOrder},
+            #{item.enable},
+            #{item.isHotspot},
+            #{item.hotOrder},
+            #{item.createUserId},
+            #{item.createTime},
+            #{item.updateUserId},
+            #{item.updateTime},
+            #{item.dataState})
+        </foreach>
+    </insert>
+
+    <!-- 如果有逻辑删除字段过滤,请写到这里 -->
+    <sql id="filterRef">
+        <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
+        <include refid="com.tourism.webadmin.back.dao.RestaurantAreaMenuMapper.inputFilterRef"/>
+        AND tour_restaurant_area_menu.data_state = ${@com.tourism.common.core.constant.GlobalDeletedFlag@NORMAL}
+    </sql>
+
+    <!-- 这里仅包含调用接口输入的主表过滤条件 -->
+    <sql id="inputFilterRef">
+        <if test="restaurantAreaMenuFilter != null">
+            <if test="restaurantAreaMenuFilter.id != null">
+                AND tour_restaurant_area_menu.id = #{restaurantAreaMenuFilter.id}
+            </if>
+            <if test="restaurantAreaMenuFilter.parentId != null">
+                AND tour_restaurant_area_menu.parent_id = #{restaurantAreaMenuFilter.parentId}
+            </if>
+            <if test="restaurantAreaMenuFilter.levelNum != null">
+                AND tour_restaurant_area_menu.level_num = #{restaurantAreaMenuFilter.levelNum}
+            </if>
+            <if test="restaurantAreaMenuFilter.levelName != null and restaurantAreaMenuFilter.levelName != ''">
+                <bind name = "safeRestaurantAreaMenuLevelName" value = "'%' + restaurantAreaMenuFilter.levelName + '%'" />
+                AND tour_restaurant_area_menu.level_name LIKE #{safeRestaurantAreaMenuLevelName}
+            </if>
+            <if test="restaurantAreaMenuFilter.showOrder != null">
+                AND tour_restaurant_area_menu.show_order = #{restaurantAreaMenuFilter.showOrder}
+            </if>
+            <if test="restaurantAreaMenuFilter.enable != null">
+                AND tour_restaurant_area_menu.enable = #{restaurantAreaMenuFilter.enable}
+            </if>
+            <if test="restaurantAreaMenuFilter.isHotspot != null">
+                AND tour_restaurant_area_menu.is_hotspot = #{restaurantAreaMenuFilter.isHotspot}
+            </if>
+            <if test="restaurantAreaMenuFilter.hotOrder != null">
+                AND tour_restaurant_area_menu.hot_order = #{restaurantAreaMenuFilter.hotOrder}
+            </if>
+        </if>
+    </sql>
+
+    <select id="getRestaurantAreaMenuList" resultMap="BaseResultMap" parameterType="com.tourism.webadmin.back.model.RestaurantAreaMenu">
+        SELECT * FROM tour_restaurant_area_menu
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
+</mapper>

+ 3 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/RestaurantFoodInfoMapper.xml

@@ -98,6 +98,9 @@
             <if test="restaurantFoodInfoFilter.foodTypeId != null and restaurantFoodInfoFilter.foodTypeId != '' ">
                 AND tour_restaurant_food_info.food_type_id = #{restaurantFoodInfoFilter.foodTypeId}
             </if>
+            <if test="restaurantFoodInfoFilter.priceUnit != null and restaurantFoodInfoFilter.priceUnit != ''">
+                AND tour_restaurant_food_info.price_unit = #{restaurantFoodInfoFilter.priceUnit}
+            </if>
         </if>
     </sql>
 

+ 16 - 4
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/RestaurantInfoMapper.xml

@@ -16,9 +16,9 @@
         <result column="longitude" jdbcType="DECIMAL" property="longitude"/>
         <result column="latitude" jdbcType="DECIMAL" property="latitude"/>
         <result column="total_sales" jdbcType="BIGINT" property="totalSales"/>
-        <result column="contry" jdbcType="VARCHAR" property="contry"/>
         <result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
-        <result column="city" jdbcType="VARCHAR" property="city"/>
+        <result column="contry" jdbcType="BIGINT" property="contry"/>
+        <result column="city" jdbcType="BIGINT" property="city"/>
         <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
         <result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
         <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
@@ -33,6 +33,7 @@
         <result column="restaurant_banner" jdbcType="VARCHAR" property="restaurantBanner"/>
         <result column="recommendation_rate" jdbcType="BIGINT" property="recommendationRate"/>
         <result column="delivery_time" jdbcType="INTEGER" property="deliveryTime"/>
+        <result column="price_unit" jdbcType="VARCHAR" property="priceUnit"/>
     </resultMap>
 
     <insert id="insertList">
@@ -67,7 +68,9 @@
             is_best_new_shop,
         restaurant_banner,
         recommendation_rate,
-        delivery_time)
+        delivery_time,
+        price_unit)
+
 
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
@@ -101,7 +104,9 @@
             #{item.isBestNewShop},
             #{item.restaurantBanner},
             #{item.recommendationRate},
-            #{item.deliveryTime})
+            #{item.deliveryTime},
+            #{item.priceUnit})
+
 
         </foreach>
     </insert>
@@ -120,6 +125,9 @@
                 <bind name = "safeRestaurantInfoName" value = "'%' + restaurantInfoFilter.name + '%'" />
                 AND tour_restaurant_info.name LIKE #{safeRestaurantInfoName}
             </if>
+            <if test="restaurantInfoFilter.priceUnit != null and restaurantInfoFilter.priceUnit != ''">
+                AND tour_restaurant_info.price_unit = #{restaurantInfoFilter.priceUnit}
+            </if>
             <if test="restaurantInfoFilter.id != null">
                 AND tour_restaurant_info.id = #{restaurantInfoFilter.id}
             </if>
@@ -161,6 +169,10 @@
                     #{id}
                 </foreach>
             </if>
+            <if test="restaurantInfoFilter.address != null and restaurantInfoFilter.address != ''">
+                <bind name = "safeRestaurantInfoAddress" value = "'%' + restaurantInfoFilter.address + '%'" />
+                AND tour_restaurant_info.address LIKE #{safeRestaurantInfoAddress}
+            </if>
         </if>
     </sql>
     <!-- 如果有逻辑删除字段过滤,请写到这里 -->

+ 7 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/DeliveryOrderItemsDto.java

@@ -62,4 +62,11 @@ public class DeliveryOrderItemsDto {
      */
     @Schema(description = "商品图片。")
     private String image;
+
+    /**
+     * 货币单位。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "货币单位。可支持等于操作符的列表数据过滤。")
+    private String priceUnit;
 }

+ 85 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/RestaurantAreaMenuDto.java

@@ -0,0 +1,85 @@
+package com.tourism.webadmin.back.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+import com.tourism.common.core.validator.ConstDictRef;
+import com.tourism.webadmin.back.model.constant.Enable;
+import com.tourism.webadmin.back.model.constant.IsTrue;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+
+/**
+ * 餐馆区域管理Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "餐馆区域管理Dto对象")
+@Data
+public class RestaurantAreaMenuDto {
+
+    /**
+     * 主键id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "主键id。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,主键id不能为空!", groups = {UpdateGroup.class})
+    private Long id;
+
+    /**
+     * 父级id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "父级id。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
+//    @NotNull(message = "数据验证失败,父级id不能为空!")
+    private Long parentId;
+
+    /**
+     * 菜单等级。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "菜单等级。可支持等于操作符的列表数据过滤。")
+    private Integer levelNum;
+
+    /**
+     * 菜单名称。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "菜单名称。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "数据验证失败,菜单名称不能为空!")
+    private String levelName;
+
+    /**
+     * 显示顺序。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "显示顺序。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
+//    @NotNull(message = "数据验证失败,显示顺序不能为空!")
+    private Integer showOrder;
+
+    /**
+     * 是否启用,0禁用,1启用。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "是否启用,0禁用,1启用。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,是否启用,0禁用,1启用不能为空!")
+    @ConstDictRef(constDictClass = Enable.class, message = "数据验证失败,是否启用,0禁用,1启用为无效值!")
+    private Integer enable;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "是否热点,0非热点,1热点。可支持等于操作符的列表数据过滤。")
+    @ConstDictRef(constDictClass = IsTrue.class, message = "数据验证失败,是否热点,0非热点,1热点为无效值!")
+    private Integer isHotspot;
+
+    /**
+     * 热门排序。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "热门排序。可支持等于操作符的列表数据过滤。")
+    private Integer hotOrder;
+}

+ 10 - 2
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/RestaurantInfoDto.java

@@ -116,14 +116,14 @@ public class RestaurantInfoDto {
      * NOTE: 可支持等于操作符的列表数据过滤。
      */
     @Schema(description = "所处国家。可支持等于操作符的列表数据过滤。")
-    private String contry;
+    private Long contry;
 
     /**
      * 所处城市。
      * NOTE: 可支持等于操作符的列表数据过滤。
      */
     @Schema(description = "所处城市。可支持等于操作符的列表数据过滤。")
-    private String city;
+    private Long city;
 
     /**
      * 配送费。
@@ -207,4 +207,12 @@ public class RestaurantInfoDto {
      */
     @Schema(description = "送餐时间/min。")
     private Integer deliveryTime;
+
+
+    /**
+     * 货币单位。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "货币单位。可支持等于操作符的列表数据过滤。")
+    private String priceUnit;
 }

+ 13 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/DeliveryOrderItems.java

@@ -8,6 +8,7 @@ import lombok.*;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 外卖订单明细管理实体对象。
@@ -71,4 +72,16 @@ public class DeliveryOrderItems extends BaseModel {
      */
     @TableField(exist = false)
     private List<Long> orderIds;
+
+    /**
+     * 货币单位。
+     */
+    @TableField(value = "price_unit")
+    private String priceUnit;
+
+    @RelationGlobalDict(
+            masterIdField = "priceUnit",
+            dictCode = "PriceUnit")
+    @TableField(exist = false)
+    private Map<String, Object> priceUnitDictMap;
 }

+ 98 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/RestaurantAreaMenu.java

@@ -0,0 +1,98 @@
+package com.tourism.webadmin.back.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.tourism.webadmin.back.model.constant.Enable;
+import com.tourism.webadmin.back.model.constant.IsTrue;
+import com.tourism.common.core.annotation.*;
+import com.tourism.common.core.base.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Map;
+
+/**
+ * 餐馆区域管理实体对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "tour_restaurant_area_menu")
+public class RestaurantAreaMenu extends BaseModel {
+
+    /**
+     * 主键id。
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 父级id。
+     */
+    @TableField(value = "parent_id")
+    private Long parentId;
+
+    /**
+     * 菜单等级。
+     */
+    @TableField(value = "level_num")
+    private Integer levelNum;
+
+    /**
+     * 菜单名称。
+     */
+    @TableField(value = "level_name")
+    private String levelName;
+
+    /**
+     * 显示顺序。
+     */
+    @TableField(value = "show_order")
+    private Integer showOrder;
+
+    /**
+     * 是否启用,0禁用,1启用。
+     */
+    @TableField(value = "enable")
+    private Integer enable;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     */
+    @TableField(value = "is_hotspot")
+    private Integer isHotspot;
+
+    /**
+     * 热门排序。
+     */
+    @TableField(value = "hot_order")
+    private Integer hotOrder;
+
+    /**
+     * 逻辑删除标记字段(1: 正常 -1: 已删除)。
+     */
+    @TableLogic
+    @TableField(value = "data_state")
+    private Integer dataState;
+
+    @RelationDict(
+            masterIdField = "parentId",
+            slaveModelClass = RestaurantAreaMenu.class,
+            slaveIdField = "id",
+            slaveNameField = "levelName")
+    @TableField(exist = false)
+    private Map<String, Object> parentIdDictMap;
+
+    @RelationConstDict(
+            masterIdField = "enable",
+            constantDictClass = Enable.class)
+    @TableField(exist = false)
+    private Map<String, Object> enableDictMap;
+
+    @RelationConstDict(
+            masterIdField = "isHotspot",
+            constantDictClass = IsTrue.class)
+    @TableField(exist = false)
+    private Map<String, Object> isHotspotDictMap;
+}

+ 6 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/RestaurantFoodInfo.java

@@ -144,4 +144,10 @@ public class RestaurantFoodInfo extends BaseModel {
             constantDictClass = IsHotFood.class)
     @TableField(exist = false)
     private Map<String, Object> isHotFoodDictMap;
+
+    @RelationGlobalDict(
+            masterIdField = "priceUnit",
+            dictCode = "PriceUnit")
+    @TableField(exist = false)
+    private Map<String, Object> priceUnitDictMap;
 }

+ 30 - 2
application-webadmin/src/main/java/com/tourism/webadmin/back/model/RestaurantInfo.java

@@ -116,13 +116,13 @@ public class RestaurantInfo extends BaseModel {
      * 所处国家。
      */
     @TableField(value = "contry")
-    private String contry;
+    private Long contry;
 
     /**
      * 所处城市。
      */
     @TableField(value = "city")
-    private String city;
+    private Long city;
 
     /**
      * 逻辑删除标记字段(1: 正常 -1: 已删除)。
@@ -204,6 +204,12 @@ public class RestaurantInfo extends BaseModel {
     private BigDecimal minCharge;
 
     /**
+     * 货币单位。
+     */
+    @TableField(value = "price_unit")
+    private String priceUnit;
+
+    /**
      * 餐馆idList。
      */
     @TableField(exist = false)
@@ -262,4 +268,26 @@ public class RestaurantInfo extends BaseModel {
     private Map<String, Object> isBestNewShopDictMap;
     @TableField(exist = false)
     private String foodName;
+
+    @RelationDict(
+            masterIdField = "contry",
+            slaveModelClass = RestaurantAreaMenu.class,
+            slaveIdField = "id",
+            slaveNameField = "levelName")
+    @TableField(exist = false)
+    private Map<String, Object> contryDictMap;
+
+    @RelationDict(
+            masterIdField = "city",
+            slaveModelClass = RestaurantAreaMenu.class,
+            slaveIdField = "id",
+            slaveNameField = "levelName")
+    @TableField(exist = false)
+    private Map<String, Object> cityDictMap;
+
+    @RelationGlobalDict(
+            masterIdField = "priceUnit",
+            dictCode = "PriceUnit")
+    @TableField(exist = false)
+    private Map<String, Object> priceUnitDictMap;
 }

+ 96 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/RestaurantAreaMenuService.java

@@ -0,0 +1,96 @@
+package com.tourism.webadmin.back.service;
+
+import com.tourism.webadmin.back.model.*;
+import com.tourism.common.core.object.CallResult;
+import com.tourism.common.core.base.service.IBaseService;
+
+import java.util.*;
+
+/**
+ * 餐馆区域管理数据操作服务接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface RestaurantAreaMenuService extends IBaseService<RestaurantAreaMenu, Long> {
+
+    /**
+     * 保存新增对象。
+     *
+     * @param restaurantAreaMenu 新增对象。
+     * @return 返回新增对象。
+     */
+    RestaurantAreaMenu saveNew(RestaurantAreaMenu restaurantAreaMenu);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。
+     *
+     * @param restaurantAreaMenuList 新增对象列表。
+     */
+    void saveNewBatch(List<RestaurantAreaMenu> restaurantAreaMenuList);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。通常适用于更大的插入数据量,如批量导入。
+     *
+     * @param restaurantAreaMenuList 新增对象列表。
+     * @param batchSize  每批插入的数量。如果该值小于等于0,则使用缺省值10000。
+     */
+    void saveNewBatch(List<RestaurantAreaMenu> restaurantAreaMenuList, int batchSize);
+
+    /**
+     * 更新数据对象。
+     *
+     * @param restaurantAreaMenu         更新的对象。
+     * @param originalRestaurantAreaMenu 原有数据对象。
+     * @return 成功返回true,否则false。
+     */
+    boolean update(RestaurantAreaMenu restaurantAreaMenu, RestaurantAreaMenu originalRestaurantAreaMenu);
+
+    /**
+     * 删除指定数据。
+     *
+     * @param id 主键Id。
+     * @return 成功返回true,否则false。
+     */
+    boolean remove(Long id);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getRestaurantAreaMenuListWithRelation)方法。
+     *
+     * @param filter  过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<RestaurantAreaMenu> getRestaurantAreaMenuList(RestaurantAreaMenu filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getRestaurantAreaMenuList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<RestaurantAreaMenu> getRestaurantAreaMenuListWithRelation(RestaurantAreaMenu filter, String orderBy);
+
+    /**
+     * 判断指定对象是否包含下级对象。
+     *
+     * @param id 主键Id。
+     * @return 存在返回true,否则false。
+     */
+    boolean hasChildren(Long id);
+
+    /**
+     * 对批量导入数据列表进行数据合法性验证。
+     * 验证逻辑主要覆盖主表的常量字典字段、字典表字典字段、数据源字段和一对一关联数据是否存在。
+     *
+     * @param dataList 主表的数据列表。
+     * @param ignoreFieldSet 需要忽略校验的字典字段集合。通常对于字典反向翻译过来的字段适用,
+     *                       避免了二次验证,以提升效率。
+     * @return 验证结果。如果失败,包含具体的错误信息和导致错误的数据对象。
+     */
+    CallResult verifyImportList(List<RestaurantAreaMenu> dataList, Set<String> ignoreFieldSet);
+}

+ 168 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/RestaurantAreaMenuServiceImpl.java

@@ -0,0 +1,168 @@
+package com.tourism.webadmin.back.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.dao.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.config.DataSourceType;
+import com.tourism.common.core.annotation.MyDataSource;
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.common.core.constant.GlobalDeletedFlag;
+import com.tourism.common.core.object.MyRelationParam;
+import com.tourism.common.core.object.CallResult;
+import com.tourism.common.core.base.service.BaseService;
+import com.tourism.common.core.util.MyModelUtil;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 餐馆区域管理数据操作服务类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Slf4j
+@MyDataSource(DataSourceType.MAIN)
+@Service("restaurantAreaMenuService")
+public class RestaurantAreaMenuServiceImpl extends BaseService<RestaurantAreaMenu, Long> implements RestaurantAreaMenuService {
+
+    @Autowired
+    private RestaurantAreaMenuMapper restaurantAreaMenuMapper;
+    @Autowired
+    private RestaurantAreaMenuService restaurantAreaMenuService;
+
+    /**
+     * 返回当前Service的主表Mapper对象。
+     *
+     * @return 主表Mapper对象。
+     */
+    @Override
+    protected BaseDaoMapper<RestaurantAreaMenu> mapper() {
+        return restaurantAreaMenuMapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public RestaurantAreaMenu saveNew(RestaurantAreaMenu restaurantAreaMenu) {
+        restaurantAreaMenuMapper.insert(this.buildDefaultValue(restaurantAreaMenu));
+        return restaurantAreaMenu;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<RestaurantAreaMenu> restaurantAreaMenuList) {
+        if (CollUtil.isNotEmpty(restaurantAreaMenuList)) {
+            restaurantAreaMenuList.forEach(this::buildDefaultValue);
+            restaurantAreaMenuMapper.insertList(restaurantAreaMenuList);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<RestaurantAreaMenu> restaurantAreaMenuList, int batchSize) {
+        if (CollUtil.isEmpty(restaurantAreaMenuList)) {
+            return;
+        }
+        if (batchSize <= 0) {
+            batchSize = 10000;
+        }
+        int start = 0;
+        do {
+            int end = Math.min(restaurantAreaMenuList.size(), start + batchSize);
+            List<RestaurantAreaMenu> subList = restaurantAreaMenuList.subList(start, end);
+            // 如果数据量过大,同时当前表中存在createTime或updateTime等字段,可以考虑在外部创建一次 new Date(),
+            // 然后传入buildDefaultValue,这样可以减少对象的创建次数,降低GC,提升效率。橙单之所以没有这样生成,是因为
+            // 有些业务场景下需要按照这两个日期字段排序,因此我们只是在这里给出优化建议。
+            subList.forEach(this::buildDefaultValue);
+            restaurantAreaMenuMapper.insertList(subList);
+            if (end == restaurantAreaMenuList.size()) {
+                break;
+            }
+            start += batchSize;
+        } while (true);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean update(RestaurantAreaMenu restaurantAreaMenu, RestaurantAreaMenu originalRestaurantAreaMenu) {
+        MyModelUtil.fillCommonsForUpdate(restaurantAreaMenu, originalRestaurantAreaMenu);
+        // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
+        UpdateWrapper<RestaurantAreaMenu> uw = this.createUpdateQueryForNullValue(restaurantAreaMenu, restaurantAreaMenu.getId());
+        return restaurantAreaMenuMapper.update(restaurantAreaMenu, uw) == 1;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean remove(Long id) {
+        return restaurantAreaMenuMapper.deleteById(id) == 1;
+    }
+
+    @Override
+    public List<RestaurantAreaMenu> getRestaurantAreaMenuList(RestaurantAreaMenu filter, String orderBy) {
+        return restaurantAreaMenuMapper.getRestaurantAreaMenuList(filter, orderBy);
+    }
+
+    @Override
+    public List<RestaurantAreaMenu> getRestaurantAreaMenuListWithRelation(RestaurantAreaMenu filter, String orderBy) {
+        List<RestaurantAreaMenu> resultList = restaurantAreaMenuMapper.getRestaurantAreaMenuList(filter, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+        int batchSize = resultList instanceof Page ? 0 : 1000;
+        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
+    @Override
+    public boolean hasChildren(Long id) {
+        RestaurantAreaMenu filter = new RestaurantAreaMenu();
+        filter.setParentId(id);
+        return getCountByFilter(filter) > 0;
+    }
+
+    @Override
+    public CallResult verifyImportList(List<RestaurantAreaMenu> dataList, Set<String> ignoreFieldSet) {
+        CallResult callResult;
+        if (!CollUtil.contains(ignoreFieldSet, "enable")) {
+            callResult = verifyImportForConstDict(dataList, "enableDictMap", RestaurantAreaMenu::getEnable);
+            if (!callResult.isSuccess()) {
+                return callResult;
+            }
+        }
+        if (!CollUtil.contains(ignoreFieldSet, "isHotspot")) {
+            callResult = verifyImportForConstDict(dataList, "isHotspotDictMap", RestaurantAreaMenu::getIsHotspot);
+            if (!callResult.isSuccess()) {
+                return callResult;
+            }
+        }
+        if (!CollUtil.contains(ignoreFieldSet, "parentId")) {
+            callResult = verifyImportForDatasourceDict(dataList, "parentIdDictMap", RestaurantAreaMenu::getParentId);
+            if (!callResult.isSuccess()) {
+                return callResult;
+            }
+        }
+        return CallResult.ok();
+    }
+
+    @Override
+    public CallResult verifyRelatedData(RestaurantAreaMenu restaurantAreaMenu, RestaurantAreaMenu originalRestaurantAreaMenu) {
+        String errorMessageFormat = "数据验证失败,关联的%s并不存在,请刷新后重试!";
+        //这里是基于字典的验证。
+        if (this.needToVerify(restaurantAreaMenu, originalRestaurantAreaMenu, RestaurantAreaMenu::getParentId)
+                && !restaurantAreaMenuService.existId(restaurantAreaMenu.getParentId())) {
+            return CallResult.error(String.format(errorMessageFormat, "父级id"));
+        }
+        return CallResult.ok();
+    }
+
+    private RestaurantAreaMenu buildDefaultValue(RestaurantAreaMenu restaurantAreaMenu) {
+        MyModelUtil.fillCommonsForInsert(restaurantAreaMenu);
+        restaurantAreaMenu.setDataState(GlobalDeletedFlag.NORMAL);
+        return restaurantAreaMenu;
+    }
+}

+ 14 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/DeliveryOrderItemsVo.java

@@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
 
 import java.math.BigDecimal;
 import java.util.Date;
+import java.util.Map;
 
 /**
  * 外卖订单明细管理VO视图对象。
@@ -60,4 +61,17 @@ public class DeliveryOrderItemsVo extends BaseVo {
      */
     @Schema(description = "商品图片")
     private String image;
+
+
+    /**
+     * 货币单位。
+     */
+    @Schema(description = "货币单位")
+    private String priceUnit;
+
+    /**
+     * priceUnit 全局字典关联数据。
+     */
+    @Schema(description = "priceUnit 全局字典关联数据")
+    private Map<String, Object> priceUnitDictMap;
 }

+ 86 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/RestaurantAreaMenuVo.java

@@ -0,0 +1,86 @@
+package com.tourism.webadmin.back.vo;
+
+import com.tourism.common.core.base.vo.BaseVo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Map;
+
+/**
+ * 餐馆区域管理VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "餐馆区域管理VO视图对象")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RestaurantAreaMenuVo extends BaseVo {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id")
+    private Long id;
+
+    /**
+     * 父级id。
+     */
+    @Schema(description = "父级id")
+    private Long parentId;
+
+    /**
+     * 菜单等级。
+     */
+    @Schema(description = "菜单等级")
+    private Integer levelNum;
+
+    /**
+     * 菜单名称。
+     */
+    @Schema(description = "菜单名称")
+    private String levelName;
+
+    /**
+     * 显示顺序。
+     */
+    @Schema(description = "显示顺序")
+    private Integer showOrder;
+
+    /**
+     * 是否启用,0禁用,1启用。
+     */
+    @Schema(description = "是否启用,0禁用,1启用")
+    private Integer enable;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     */
+    @Schema(description = "是否热点,0非热点,1热点")
+    private Integer isHotspot;
+
+    /**
+     * 热门排序。
+     */
+    @Schema(description = "热门排序")
+    private Integer hotOrder;
+
+    /**
+     * parentId 字典关联数据。
+     */
+    @Schema(description = "parentId 字典关联数据")
+    private Map<String, Object> parentIdDictMap;
+
+    /**
+     * enable 常量字典关联数据。
+     */
+    @Schema(description = "enable 常量字典关联数据")
+    private Map<String, Object> enableDictMap;
+
+    /**
+     * isHotspot 常量字典关联数据。
+     */
+    @Schema(description = "isHotspot 常量字典关联数据")
+    private Map<String, Object> isHotspotDictMap;
+}

+ 6 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/RestaurantFoodInfoVo.java

@@ -116,4 +116,10 @@ public class RestaurantFoodInfoVo extends BaseVo {
      */
     @Schema(description = "isHotFood 常量字典关联数据")
     private Map<String, Object> isHotFoodDictMap;
+
+    /**
+     * priceUnit 全局字典关联数据。
+     */
+    @Schema(description = "priceUnit 全局字典关联数据")
+    private Map<String, Object> priceUnitDictMap;
 }

+ 26 - 2
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/RestaurantInfoVo.java

@@ -120,13 +120,13 @@ public class RestaurantInfoVo extends BaseVo {
      * 所处国家。
      */
     @Schema(description = "所处国家")
-    private String contry;
+    private Long contry;
 
     /**
      * 所处城市。
      */
     @Schema(description = "所处城市")
-    private String city;
+    private Long city;
 
     /**
      * 用户所在部门Id。
@@ -238,6 +238,12 @@ public class RestaurantInfoVo extends BaseVo {
     private String typeName;
 
     /**
+     * 货币单位。
+     */
+    @Schema(description = "货币单位")
+    private String priceUnit;
+
+    /**
      * environmentImageAfterConvert environmentImage转换后的地址。
      */
     @Schema(description = "environmentImageAfterConvert url转换后的地址")
@@ -250,4 +256,22 @@ public class RestaurantInfoVo extends BaseVo {
     private List<String> restaurantBannerAfterConvert;
 
     private BannerInfoVo bannerInfoVo;
+
+    /**
+     * contry 字典关联数据。
+     */
+    @Schema(description = "contry 字典关联数据")
+    private Map<String, Object> contryDictMap;
+
+    /**
+     * city 字典关联数据。
+     */
+    @Schema(description = "city 字典关联数据")
+    private Map<String, Object> cityDictMap;
+
+    /**
+     * priceUnit 全局字典关联数据。
+     */
+    @Schema(description = "priceUnit 全局字典关联数据")
+    private Map<String, Object> priceUnitDictMap;
 }

+ 6 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourImComplaitVo.java

@@ -89,4 +89,10 @@ public class TourImComplaitVo extends BaseVo {
      */
     @Schema(description = "objectType 全局字典关联数据")
     private Map<String, Object> objectTypeDictMap;
+
+    /**
+     * 群组封禁状态
+     */
+    @Schema(description = "群组封禁状态")
+    private Integer groupStatus;
 }