Ver Fonte

feat(system): 添加首页金刚区管理功能

- 新增 AppKongfuZone 实体类
- 创建 AppKongfuZoneController 控制器
- 添加 AppKongfuZoneMapper 映射接口
- 实现 AppKongfuZoneServiceImpl 服务类
- 增加 IAppKongfuZoneService 服务接口
- 在 AppOrderMapper 中添加查询已预订数量的方法
- 更新 AppOrderMapper.xml,添加查询已预订数量的 SQL语句
- 修改 AppSitePriceRulesMapper.xml,调整时间规则查询结果
- 更新 OrderServiceImpl,增加教学日和非教学日的解析逻辑
- 修改 OrderVO,增加时间段相关字段和解析类
SheepHy há 5 dias atrás
pai
commit
5cce97988d

+ 50 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -8,6 +8,8 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -33,6 +35,7 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.LocalTime;
 import java.time.ZoneId;
 import java.util.*;
 import java.util.concurrent.ThreadLocalRandom;
@@ -128,12 +131,59 @@ public class OrderServiceImpl implements IOrderService {
         return appCoursesMapper.selectById(courseId).getLimitNum() >= limitNum;
     }
 
+    private List<OrderVO.TimeSlotData> parseTimeSlotData(String timeSlot) {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            JsonNode teachingDays = objectMapper.readTree(timeSlot);
+            List<OrderVO.TimeSlotData> teachingList = new ArrayList<>();
+            for (JsonNode node : teachingDays.get("data")) {
+                OrderVO.TimeSlotData data = objectMapper.treeToValue(node, OrderVO.TimeSlotData.class);
+                teachingList.add(data);
+            }
+            return teachingList;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     @Override
     public OrderVO.PreviewOrderPlaceSchool previewOrderPlaceSchool(String placeId, Date startTime) {
         LocalDate localDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
         Date dateOnly = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
         OrderVO.PreviewOrderPlaceSchool previewOrderPlaceSchool = new OrderVO.PreviewOrderPlaceSchool();
+        AppSite appSite = appSiteMapper.selectOne(Wrappers.<AppSite>lambdaQuery().eq(AppSite::getId, appSitePlaceMapper.selectById(placeId).getSiteId()));
         List<OrderVO.PreviewOrderPlaceSchoolChild> timeSlot = appSitePriceRulesMapper.timeSlot(placeId, dateOnly);
+        // 解析教学日和非教学日数据
+        List<OrderVO.TimeSlotData> teachingList = parseTimeSlotData(appSite.getTeachingDay());
+        List<OrderVO.TimeSlotData> nonTeachingList = parseTimeSlotData(appSite.getNoTeachingDay());
+
+        timeSlot.forEach(a -> {
+            LocalTime slotStart = LocalTime.parse(DateUtil.format(a.getStartTime(), "HH:mm"));
+            LocalTime slotEnd = LocalTime.parse(DateUtil.format(a.getEndTime(), "HH:mm"));
+            boolean isTeaching = a.getIsTeaching() == 0;
+
+            List<OrderVO.TimeSlotData> targetList = isTeaching ? teachingList : nonTeachingList;
+
+            Optional<OrderVO.TimeSlotData> matchedSlot = targetList.stream()
+                    .filter(t -> {
+                        LocalTime invStart = LocalTime.parse(t.getStartTime());
+                        LocalTime invEnd = LocalTime.parse(t.getEndTime());
+                        return !slotStart.isAfter(invEnd) && !slotEnd.isBefore(invStart);
+                    })
+                    .findFirst();
+
+            matchedSlot.ifPresent(timeSlotData -> {
+                int totalInventory = Integer.parseInt(timeSlotData.getTicketNum());
+                int bookedCount = appOrderMapper.queryBookedCount(
+                        placeId,
+                        DateUtil.format(startTime, "yyyy-MM-dd"),
+                        timeSlotData.getStartTime(),
+                        timeSlotData.getEndTime()
+                );
+                int availableInventory = totalInventory - bookedCount;
+                a.setInventory(availableInventory);
+            });
+        });
         AppSitePlace appSitePlace = appSitePlaceMapper.selectById(placeId);
         previewOrderPlaceSchool.setName(appSitePlace.getName())
                 .setId(appSitePlace.getId())

+ 28 - 3
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/vo/OrderVO.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import org.jeecg.modules.system.app.entity.AppInsure;
+import org.jeecgframework.poi.excel.annotation.Excel;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
@@ -45,10 +46,34 @@ public class OrderVO {
         private String id;
         @Schema(description = "时间段名称")
         private String name;
+        /**开始时间*/
+        @Excel(name = "开始时间", width = 20, format = "HH:mm:ss")
+        @JsonFormat(timezone = "GMT+8",pattern = "HH:mm:ss")
+        @DateTimeFormat(pattern="HH:mm:ss")
+        @Schema(description = "开始时间")
+        private Date startTime;
+        /**结束时间*/
+        @Excel(name = "结束时间", width = 20, format = "HH:mm:ss")
+        @JsonFormat(timezone = "GMT+8",pattern = "HH:mm:ss")
+        @DateTimeFormat(pattern="HH:mm:ss")
+        @Schema(description = "结束时间")
+        private Date endTime;
         @Schema(description = "库存")
         private int inventory;
+        private int isTeaching;
         @Schema(description = "价格")
-        private BigDecimal price;
+        private BigDecimal price = BigDecimal.ZERO;
+
+    }
+
+    @Data
+    @Accessors(chain = true)
+    @EqualsAndHashCode(callSuper = false)
+    @Schema(description="教学日非教学日解析")
+    public static class TimeSlotData {
+        private String ticketNum;
+        private String startTime;
+        private String endTime;
 
     }
 
@@ -120,9 +145,9 @@ public class OrderVO {
         @Schema(description = "场地名称")
         private String name;
         @Schema(description = "原价")
-        private BigDecimal originalPrice;
+        private BigDecimal originalPrice = BigDecimal.ZERO;
         @Schema(description = "售价")
-        private BigDecimal sellingPrice;
+        private BigDecimal sellingPrice = BigDecimal.ZERO;
         @Schema(description = "购买须知")
         private String reminder;
         @Schema(description = "有效期")

+ 158 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/controller/AppKongfuZoneController.java

@@ -0,0 +1,158 @@
+package org.jeecg.modules.system.app.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.system.app.entity.AppKongfuZone;
+import org.jeecg.modules.system.app.service.IAppKongfuZoneService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Arrays;
+
+/**
+ * @Description: 首页金刚区管理
+ * @Author: jeecg-boot
+ * @Date:   2023-08-14
+ * @Version: V1.0
+ */
+@Tag(name="首页金刚区管理")
+@RestController
+@RequestMapping("/app/appKongfuZone")
+@Slf4j
+public class AppKongfuZoneController extends JeecgController<AppKongfuZone, IAppKongfuZoneService> {
+	@Autowired
+	private IAppKongfuZoneService appKongfuZoneService;
+	
+	/**
+	 * 分页列表查询
+	 *
+	 * @param appKongfuZone
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	//@AutoLog(value = "首页金刚区管理-分页列表查询")
+	@Operation(summary="首页金刚区管理-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<AppKongfuZone>> queryPageList(AppKongfuZone appKongfuZone,
+								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+								   HttpServletRequest req) {
+		QueryWrapper<AppKongfuZone> queryWrapper = QueryGenerator.initQueryWrapper(appKongfuZone, req.getParameterMap());
+		Page<AppKongfuZone> page = new Page<AppKongfuZone>(pageNo, pageSize);
+		IPage<AppKongfuZone> pageList = appKongfuZoneService.page(page, queryWrapper);
+		return Result.OK(pageList);
+	}
+	
+	/**
+	 *   添加
+	 *
+	 * @param appKongfuZone
+	 * @return
+	 */
+	@AutoLog(value = "首页金刚区管理-添加")
+	@Operation(summary="首页金刚区管理-添加")
+	@PostMapping(value = "/add")
+	public Result<String> add(@RequestBody AppKongfuZone appKongfuZone) {
+		appKongfuZoneService.save(appKongfuZone);
+		return Result.OK("添加成功!");
+	}
+	
+	/**
+	 *  编辑
+	 *
+	 * @param appKongfuZone
+	 * @return
+	 */
+	@AutoLog(value = "首页金刚区管理-编辑")
+	@Operation(summary="首页金刚区管理-编辑")
+	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
+	public Result<String> edit(@RequestBody AppKongfuZone appKongfuZone) {
+		appKongfuZoneService.updateById(appKongfuZone);
+		return Result.OK("编辑成功!");
+	}
+	
+	/**
+	 *   通过id删除
+	 *
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "首页金刚区管理-通过id删除")
+	@Operation(summary="首页金刚区管理-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
+		appKongfuZoneService.removeById(id);
+		return Result.OK("删除成功!");
+	}
+	
+	/**
+	 *  批量删除
+	 *
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "首页金刚区管理-批量删除")
+	@Operation(summary="首页金刚区管理-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		this.appKongfuZoneService.removeByIds(Arrays.asList(ids.split(",")));
+		return Result.OK("批量删除成功!");
+	}
+	
+	/**
+	 * 通过id查询
+	 *
+	 * @param id
+	 * @return
+	 */
+	//@AutoLog(value = "首页金刚区管理-通过id查询")
+	@Operation(summary="首页金刚区管理-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<AppKongfuZone> queryById(@RequestParam(name="id",required=true) String id) {
+		AppKongfuZone appKongfuZone = appKongfuZoneService.getById(id);
+		if(appKongfuZone==null) {
+			return Result.error("未找到对应数据");
+		}
+		return Result.OK(appKongfuZone);
+	}
+
+    /**
+    * 导出excel
+    *
+    * @param request
+    * @param appKongfuZone
+    */
+    @RequiresPermissions("app:app_kongfu_zone:exportXls")
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, AppKongfuZone appKongfuZone) {
+        return super.exportXls(request, appKongfuZone, AppKongfuZone.class, "首页金刚区管理");
+    }
+
+    /**
+      * 通过excel导入数据
+    *
+    * @param request
+    * @param response
+    * @return
+    */
+    @RequiresPermissions("app:app_kongfu_zone:importExcel")
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        return super.importExcel(request, response, AppKongfuZone.class);
+    }
+
+}

+ 66 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/entity/AppKongfuZone.java

@@ -0,0 +1,66 @@
+package org.jeecg.modules.system.app.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+@Data
+@TableName("nm_kongfu_zone")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Schema(description="nm_kongfu_zone")
+public class AppKongfuZone {
+    /**主键id*/
+    @TableId(type = IdType.ASSIGN_ID)
+    @Schema(description = "主键id")
+    private String id;
+    /**名称*/
+    @Excel(name = "名称", width = 15)
+    @Schema(description = "名称")
+    private String name;
+    /**图标URL*/
+    @Excel(name = "图标URL", width = 15)
+    @Schema(description = "图标URL")
+    private String iconUrl;
+    /**跳转路由*/
+    @Excel(name = "跳转路由", width = 15)
+    @Schema(description = "跳转路由")
+    private String route;
+    /**金刚区显示顺序*/
+    @Excel(name = "金刚区显示顺序", width = 15)
+    @Schema(description = "金刚区显示顺序")
+    private Integer orderNumber;
+    /**是否展示,1表示展示,0表示不展示*/
+    @Excel(name = "是否展示,1表示展示,0表示不展示", width = 15)
+    @Schema(description = "是否展示,1表示展示,0表示不展示")
+    private String izShow;
+    /**创建时间*/
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "创建时间")
+    private java.util.Date createTime;
+    /**修改人*/
+    @Schema(description = "修改人")
+    private String updateBy;
+    /**修改时间*/
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "修改时间")
+    private java.util.Date updateTime;
+    /**删除状态(0-正常,1-已删除)*/
+    @Excel(name = "删除状态(0-正常,1-已删除)", width = 15)
+    @Schema(description = "删除状态(0-正常,1-已删除)")
+    @TableLogic
+    private Integer delFlag;
+    @Excel(name = "角色权限", width = 15)
+    @Schema(description = "角色权限")
+    private String roleCode;
+}

+ 14 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/AppKongfuZoneMapper.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.system.app.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.system.app.entity.AppKongfuZone;
+
+/**
+ * @Description: 首页金刚区管理
+ * @Author: jeecg-boot
+ * @Date:   2023-08-14
+ * @Version: V1.0
+ */
+public interface AppKongfuZoneMapper extends BaseMapper<AppKongfuZone> {
+
+}

+ 5 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/AppOrderMapper.java

@@ -33,4 +33,9 @@ public interface AppOrderMapper extends BaseMapper<AppOrder> {
     Long findByTeachingCount(@Param("productIds") List<String> productIds);
 
     Long findByOrderNumCount(@Param("productIds") List<String> productIds);
+
+    int queryBookedCount(@Param("placeId") String placeId,
+                         @Param("date") String date,
+                         @Param("startTime") String startTime,
+                         @Param("endTime") String endTime);
 }

+ 11 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppOrderMapper.xml

@@ -70,4 +70,15 @@
             #{productId}
         </foreach>
     </select>
+    <select id="queryBookedCount" resultType="java.lang.Integer">
+        SELECT
+            COUNT(a.id)
+        FROM
+            nm_order a LEFT JOIN nm_site_price_rules b ON a.product_ids = b.id
+        WHERE
+            b.site_place_id = #{placeId}
+          AND b.date_of_sale = #{date}
+          AND b.start_time = #{startTime}
+          AND b.end_time = #{endTime}
+    </select>
 </mapper>

+ 3 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppSitePriceRulesMapper.xml

@@ -60,6 +60,9 @@
             id,
             inventory,
             selling_price AS price,
+            is_teaching,
+            start_time,
+            end_time,
             CONCAT( DATE_FORMAT( start_time, '%H:%i' ), '-', DATE_FORMAT( end_time, '%H:%i' ) ) AS NAME
         FROM
             `nm_site_price_rules`

+ 10 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/IAppKongfuZoneService.java

@@ -0,0 +1,10 @@
+package org.jeecg.modules.system.app.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.system.app.entity.AppKongfuZone;
+
+/**
+ * @Description: 首页金刚区管理
+ */
+public interface IAppKongfuZoneService extends IService<AppKongfuZone> {
+}

+ 18 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppKongfuZoneServiceImpl.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.system.app.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.system.app.entity.AppKongfuZone;
+import org.jeecg.modules.system.app.mapper.AppKongfuZoneMapper;
+import org.jeecg.modules.system.app.service.IAppKongfuZoneService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Description: 首页金刚区管理
+ * @Author: jeecg-boot
+ * @Date: 2023-08-14
+ * @Version: V1.0
+ */
+@Service
+public class AppKongfuZoneServiceImpl extends ServiceImpl<AppKongfuZoneMapper, AppKongfuZone> implements IAppKongfuZoneService {
+
+}