Jelajahi Sumber

Merge branch 'master' of https://git.woshs.com/914769835/water_bus

shs 1 tahun lalu
induk
melakukan
40055c1964
25 mengubah file dengan 2484 tambahan dan 10 penghapusan
  1. 6 0
      aidex-common/src/main/java/com/aidex/common/utils/HardwareID.java
  2. 74 1
      aidex-controller/src/main/java/com/aidex/web/controller/app/AppController.java
  3. 129 0
      aidex-controller/src/main/java/com/aidex/web/controller/system/SysReservationConfigController.java
  4. 0 1
      aidex-quartz/src/main/java/com/aidex/quartz/task/RefreshMdsTask.java
  5. 12 0
      aidex-system/src/main/java/com/aidex/common/app/server/IAppService.java
  6. 117 7
      aidex-system/src/main/java/com/aidex/common/app/server/impl/AppService.java
  7. 147 0
      aidex-system/src/main/java/com/aidex/system/domain/SysReservationConfig.java
  8. 45 0
      aidex-system/src/main/java/com/aidex/system/domain/SysReservationData.java
  9. 62 0
      aidex-system/src/main/java/com/aidex/system/domain/vo/SysReservationDataHistoryVO.java
  10. 25 0
      aidex-system/src/main/java/com/aidex/system/domain/vo/SysReservationDataNumVO.java
  11. 33 0
      aidex-system/src/main/java/com/aidex/system/mapper/SysReservationConfigMapper.java
  12. 278 0
      aidex-system/src/main/java/com/aidex/system/mapper/SysReservationConfigMapper.xml
  13. 94 0
      aidex-system/src/main/java/com/aidex/system/mapper/SysReservationDataMapper.java
  14. 128 0
      aidex-system/src/main/java/com/aidex/system/mapper/SysReservationDataMapper.xml
  15. 52 0
      aidex-system/src/main/java/com/aidex/system/req/SysReservationConfigReq.java
  16. 55 0
      aidex-system/src/main/java/com/aidex/system/service/SysReservationConfigService.java
  17. 254 0
      aidex-system/src/main/java/com/aidex/system/service/impl/SysReservationConfigServiceImpl.java
  18. 4 1
      aidex-ui/package.json
  19. 85 0
      aidex-ui/src/api/system/sysReservationConfig.js
  20. 339 0
      aidex-ui/src/views/system/sysreservationconfig/index.vue
  21. 80 0
      aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigAddForm.vue
  22. 47 0
      aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigBatchAddForm.vue
  23. 84 0
      aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigEditForm.vue
  24. 158 0
      aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigForm.js
  25. 176 0
      aidex-ui/src/views/system/sysreservationconfig/statisc.vue

+ 6 - 0
aidex-common/src/main/java/com/aidex/common/utils/HardwareID.java

@@ -23,6 +23,12 @@ public class HardwareID {
     private static String a = null;
 
     public static void main(String[] args) {
+
+        int  i = 0;
+        while (i < 5){
+            i++;
+        }
+        System.out.println(i);
 //        System.out.println(HardwareID.getHardwareIDFromEthernetAddress()) ;//根据以太网地址生成HardwareID
 //        System.out.println(HardwareID.getHardwareIDFromHostName()) ;//根据主机名生成HardwareID
 //        System.out.println(HardwareID.getHardwareIDFromVolumeSerialNumber()) ;//根据卷序列号HardwareID

+ 74 - 1
aidex-controller/src/main/java/com/aidex/web/controller/app/AppController.java

@@ -1,28 +1,38 @@
 package com.aidex.web.controller.app;
 
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import com.aidex.common.app.domain.vo.LocationVO;
 import com.aidex.common.app.domain.vo.SysWharfVO;
 import com.aidex.common.app.server.IAppService;
+import com.aidex.common.core.domain.BaseEntity;
 import com.aidex.common.core.domain.R;
 import com.aidex.common.core.page.PageDomain;
 import com.aidex.common.gps.domain.LocationEntity;
 import com.aidex.common.plush.domain.vo.SysShipExtendVO;
 import com.aidex.common.plush.domain.vo.SysShipResVO;
+import com.aidex.common.utils.json.JSONObject;
 import com.aidex.quartz.task.RefreshAccessTokenTask;
 import com.aidex.system.domain.*;
+import com.aidex.system.domain.vo.SysReservationDataHistoryVO;
 import com.aidex.system.domain.vo.SysRouteVo;
 import com.aidex.system.service.*;
+import com.alibaba.fastjson2.JSONArray;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.service.WxService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.List;
@@ -49,7 +59,11 @@ public class AppController {
     @Autowired
     private SysNoticeService noticeService;
 
-    @GetMapping("/carousel")
+    @Resource
+    private WxMaService wxMaService;
+	private String code;
+
+	@GetMapping("/carousel")
     @ApiOperation(value = "获取轮播信息", notes = "获取轮播信息", produces = "application/json")
     public R<List<SysNotice>> carousel()
     {
@@ -117,6 +131,64 @@ public class AppController {
         return R.data(sysWharfService.getRouteList());
     }
 
+    @GetMapping("/openid")
+    @ApiOperation(value = "根据code获取openid", notes = "根据code获取openid", produces = "application/json")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "code", value = "临时code", required = true, dataType = "String")})
+    public R getOpenid(@RequestParam(name = "code") String code){
+        String openid = null;
+        String msg = null;
+		try {
+            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
+            openid = session.getOpenid();
+        } catch (WxErrorException e) {
+            e.printStackTrace();
+            msg = e.getMessage();
+            // 处理异常,例如返回错误信息给前端
+        }
+        return R.data(openid, msg);
+	}
+
+    @GetMapping("/reservation/config")
+    @ApiOperation(value = "获取预约配置", notes = "获取预约配置", produces = "application/json")
+    public R<JSONArray> getReservationConfig()
+    {
+        return R.data(iAppService.getEnableReservationConfig());
+    }
+
+
+
+    @PostMapping("/reservation/data")
+    @ApiOperation(value = "预约提交", notes = "预约提交", produces = "application/json")
+    public R saveReservation(@RequestBody @Validated SysReservationData sysReservationData)
+    {
+        return iAppService.saveReservationData(sysReservationData);
+    }
+
+
+
+    @PostMapping("/reservation/cancel")
+    @ApiOperation(value = "取消预约", notes = "取消预约", produces = "application/json")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "预约记录id", required = true, dataType = "String")})
+    public R cancelReservation(@RequestParam(name = "id") String id)
+    {
+        return R.status(iAppService.cancelReservation(id));
+    }
+
+    @GetMapping("/reservation/history")
+    @ApiOperation(value = "获取历史预约", notes = "获取历史预约", produces = "application/json")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "openid", value = "小程序id", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "type", value = "类型 0为 未使用 1为 已过期", required = true, dataType = "String"),
+    })
+    public R<List<SysReservationDataHistoryVO>> getHistoryReservationList(@RequestParam(name = "openid") String openid,
+                                                                          @RequestParam(defaultValue = "0" ,name = "type") String type)
+    {
+        List<SysReservationDataHistoryVO> list = iAppService.getHistoryReservationList(openid, type);
+        return R.data(list);
+    }
+
     @GetMapping("/notice/type")
     @ApiOperation(value = "获取信息类型", notes = "获取信息类型", produces = "application/json")
     public R<List<SysDictData>> getNoticeType()
@@ -139,6 +211,7 @@ public class AppController {
     {
         SysNotice sysNotice = new SysNotice();
         sysNotice.setNoticeType(dictValue);
+        sysNotice.setStatus(BaseEntity.STATUS_NORMAL);
         PageDomain pageDomain = new PageDomain();
         pageDomain.setPageNum(pageNum);
         pageDomain.setPageSize(pageSize);

+ 129 - 0
aidex-controller/src/main/java/com/aidex/web/controller/system/SysReservationConfigController.java

@@ -0,0 +1,129 @@
+package com.aidex.web.controller.system;
+
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import com.aidex.common.annotation.Log;
+import com.aidex.common.core.domain.R;
+import com.aidex.system.req.SysReservationConfigReq;
+import com.github.pagehelper.PageInfo;
+import com.aidex.common.core.page.PageDomain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import com.aidex.common.enums.BusinessType;
+import com.aidex.common.utils.poi.ExcelUtil;
+import com.aidex.framework.cache.DictUtils;
+import javax.validation.constraints.*;
+import org.springframework.web.bind.annotation.*;
+import com.aidex.common.core.controller.BaseController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.aidex.system.domain.SysReservationConfig;
+import com.aidex.system.service.SysReservationConfigService;
+
+/**
+ * 预约配置Controller
+ * @author Chensir
+ * @email 914769835
+ * @date 2024-03-28
+ */
+@RestController
+@RequestMapping("/system/sysReservationConfig")
+public class SysReservationConfigController extends BaseController {
+
+    @Autowired
+    private SysReservationConfigService sysReservationConfigService;
+
+    /**
+     * 查询预约配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:list')")
+    @GetMapping("/list")
+    public R<PageInfo> list(SysReservationConfig sysReservationConfig, HttpServletRequest request, HttpServletResponse response) {
+        sysReservationConfig.setPage(new PageDomain(request, response));
+        return R.data(sysReservationConfigService.findPage(sysReservationConfig));
+    }
+
+    /**
+     * 获取预约配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:query')")
+    @GetMapping(value = "/{id}")
+    public R<SysReservationConfig> detail(@PathVariable("id") String id) {
+        return R.data(sysReservationConfigService.get(id));
+    }
+
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:add')")
+    @Log(title = "预约配置", businessType = BusinessType.INSERT)
+    @PostMapping("/batchAdd")
+    public R addBySysReservationConfigReq(@RequestBody @Validated SysReservationConfigReq sysReservationConfigReq) {
+        return R.status(sysReservationConfigService.addBySysReservationConfigReq(sysReservationConfigReq));
+    }
+
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:list')")
+    @GetMapping("/statisc")
+    public R<List<Map<String, String>>> statisc(@RequestParam(value = "date", required = true) String date) {
+        List<Map<String, String>> statiscDataBydate = sysReservationConfigService.getStatiscDataBydate(date);
+        return R.data(statiscDataBydate);
+    }
+
+    @GetMapping("/statisc/columns")
+    public R<List<String>> statisColumns(@RequestParam(value = "date", required = true) String date) {
+        return R.data(sysReservationConfigService.getStatiscColumns(date));
+    }
+
+    /**
+     * 新增预约配置
+     */
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:add')")
+    @Log(title = "预约配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R add(@RequestBody @Validated  SysReservationConfig sysReservationConfig) {
+        return R.status(sysReservationConfigService.save(sysReservationConfig));
+    }
+
+    /**
+     * 修改预约配置
+     */
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:edit')")
+    @Log(title = "预约配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody @Validated SysReservationConfig sysReservationConfig) {
+        return R.status(sysReservationConfigService.save(sysReservationConfig));
+    }
+
+    /**
+     * 删除预约配置
+     */
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:remove')")
+    @Log(title = "预约配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R remove(@PathVariable String[] ids) {
+        return R.status(sysReservationConfigService.deleteSysReservationConfigByIds(ids));
+    }
+
+
+    /**
+     * 导出预约配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:sysReservationConfig:export')")
+    @Log(title = "预约配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public R export(SysReservationConfig sysReservationConfig) {
+        List<SysReservationConfig> list = sysReservationConfigService.findList(sysReservationConfig);
+        ExcelUtil<SysReservationConfig> util = new ExcelUtil<SysReservationConfig>(SysReservationConfig.class);
+        return util.exportExcel(list, "预约配置数据");
+    }
+
+    /**
+     * 根据字典类型查询字典数据信息等其他自定义信息
+     */
+    @GetMapping(value = "/getInitData/{dictTypes}")
+    public R getInitData(@PathVariable String dictTypes) {
+        Map<String, Object> dataMap = new HashMap<String, Object>();
+        dataMap.putAll(DictUtils.getMultiDictList(dictTypes));
+        return R.data(dataMap);
+    }
+
+}

+ 0 - 1
aidex-quartz/src/main/java/com/aidex/quartz/task/RefreshMdsTask.java

@@ -141,7 +141,6 @@ public class RefreshMdsTask {
 			SysShip sysShip = new SysShip();
 			sysShip.setDelFlag(BaseEntity.DEL_FLAG_NORMAL);
 			List<SysShip> list = sysShipService.findList(sysShip);
-
 			String mds = redisCache.getStringValue(Constants.GPS_TOKEN_PREFIX);
 			SysConfig configUrl = ConfigUtils.getConfigByKey("sys.gps.api.url");
 			String url = configUrl.getConfigValue();

+ 12 - 0
aidex-system/src/main/java/com/aidex/common/app/server/IAppService.java

@@ -2,11 +2,15 @@ package com.aidex.common.app.server;
 
 import com.aidex.common.app.domain.vo.LocationVO;
 import com.aidex.common.app.domain.vo.SysWharfVO;
+import com.aidex.common.core.domain.R;
 import com.aidex.common.gps.domain.LocationEntity;
 import com.aidex.common.plush.domain.vo.SysShipExtendVO;
 import com.aidex.common.plush.domain.vo.SysShipResVO;
 import com.aidex.system.domain.SysNotice;
+import com.aidex.system.domain.SysReservationData;
 import com.aidex.system.domain.SysWharf;
+import com.aidex.system.domain.vo.SysReservationDataHistoryVO;
+import com.alibaba.fastjson2.JSONArray;
 
 import java.util.List;
 
@@ -25,4 +29,12 @@ public interface IAppService {
     SysShipResVO findAllLocationByNext(Boolean direction, String lat, String lon);
 
     SysWharfVO findNearestStation(String lat, String lng);
+
+    JSONArray getEnableReservationConfig();
+
+    R saveReservationData(SysReservationData sysReservationData);
+
+    int cancelReservation(String id);
+
+    List<SysReservationDataHistoryVO> getHistoryReservationList(String openid, String type);
 }

+ 117 - 7
aidex-system/src/main/java/com/aidex/common/app/server/impl/AppService.java

@@ -1,7 +1,13 @@
 package com.aidex.common.app.server.impl;
 
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import com.aidex.common.app.domain.vo.SysWharfVO;
 import com.aidex.common.app.server.IAppService;
+import com.aidex.common.constant.Constants;
+import com.aidex.common.core.domain.BaseEntity;
+import com.aidex.common.core.domain.R;
 import com.aidex.common.exception.SysException;
 import com.aidex.common.gps.server.IGpsService;
 import com.aidex.common.plush.domain.vo.SysShipExtendVO;
@@ -9,19 +15,23 @@ import com.aidex.common.plush.domain.vo.SysShipResVO;
 import com.aidex.common.plush.service.SysShipExtendService;
 import com.aidex.common.utils.StringUtils;
 import com.aidex.common.utils.dist.CalcDist;
+import com.aidex.common.utils.uuid.IdUtils;
 import com.aidex.framework.cache.ConfigUtils;
-import com.aidex.system.domain.SysNotice;
-import com.aidex.system.domain.SysWharf;
+import com.aidex.system.domain.*;
+import com.aidex.system.domain.vo.SysReservationDataHistoryVO;
+import com.aidex.system.domain.vo.SysReservationDataNumVO;
+import com.aidex.system.mapper.SysReservationDataMapper;
 import com.aidex.system.service.SysNoticeService;
+import com.aidex.system.service.SysReservationConfigService;
 import com.aidex.system.service.SysShipService;
 import com.aidex.system.service.SysWharfService;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
@@ -29,25 +39,34 @@ public class AppService implements IAppService {
 
     @Autowired
     private SysNoticeService sysNoticeService;
+
     @Autowired
     private SysWharfService sysWharfService;
+
     @Autowired
     private IGpsService iGpsService;
 
     @Autowired
     private SysShipService sysShipService;
+
     @Autowired
     private SysShipExtendService sysShipExtendService;
 
+    @Autowired
+    private SysReservationConfigService sysReservationConfigService;
+
+    @Autowired
+    private SysReservationDataMapper sysReservationDataMapper;
+
 
     public List<SysNotice> getCarouselList(){
 
-        List<SysNotice> carouselList = sysNoticeService.findList(new SysNotice(){{setCarousel("1");}});
+        List<SysNotice> carouselList = sysNoticeService.findList(new SysNotice(){{setCarousel("1"); setStatus(BaseEntity.STATUS_NORMAL);}});
         return carouselList;
     }
 
     public List<SysNotice> getNoticeList(){
-        List<SysNotice> noticeList = sysNoticeService.findList(new SysNotice(){{setCarousel("0");setNoticeType("1");}});
+        List<SysNotice> noticeList = sysNoticeService.findList(new SysNotice(){{setCarousel("0");setNoticeType("1");setStatus(BaseEntity.STATUS_NORMAL);}});
         return noticeList;
     }
 
@@ -203,4 +222,95 @@ public class AppService implements IAppService {
         return  vos.stream().sorted(Comparator.comparing(SysWharfVO::getDistance)).findFirst().orElse(null);
     }
 
+    @Override
+    public JSONArray getEnableReservationConfig() {
+        JSONArray jsonArray = new JSONArray();
+        SysConfig beforeDaysConfig =  ConfigUtils.getConfigByKey("sys.reservation.before");
+        SysConfig betweenDayConfig = ConfigUtils.getConfigByKey("sys.reservation.days");
+        if(beforeDaysConfig != null && betweenDayConfig != null){
+            Integer beforeDays = Integer.valueOf(beforeDaysConfig.getConfigValue());
+            Integer betweenDay = Integer.valueOf(betweenDayConfig.getConfigValue());
+            if (beforeDays > 0){
+                DateTime startDate = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, beforeDays);
+                DateTime endDate =  DateUtil.offset(startDate, DateField.DAY_OF_YEAR, betweenDay);
+                SysReservationConfig sysReservationConfig = new SysReservationConfig();
+                sysReservationConfig.setBeginReservationDate(DateUtil.formatDate(startDate));
+                sysReservationConfig.setEndReservationDate(DateUtil.formatDate(endDate));
+                sysReservationConfig.setStatus("1");
+                List<SysReservationConfig> list = sysReservationConfigService.findList(sysReservationConfig);
+                List<String> sysReservationConfigIds = list.stream().map(SysReservationConfig::getId).collect(Collectors.toList());
+                List<SysReservationDataNumVO> numByReservationConfigIds = sysReservationDataMapper.getNumByReservationConfigIds(sysReservationConfigIds.toArray(new String[]{}));
+                SysReservationDataNumVO defaultMap = new SysReservationDataNumVO();
+                defaultMap.setNum(0L);
+                list.stream().forEach(item -> item.setEnableNum(item.getEnableNum() - numByReservationConfigIds.stream().filter(item1 -> item1.getReservationConfigId().equals(item.getId())).findFirst().orElse(defaultMap).getNum()));
+                Map<Date, List<SysReservationConfig>> collect = list.stream().collect(Collectors.groupingBy(SysReservationConfig::getReservationDate, Collectors.mapping(value -> value, Collectors.toList())));
+                collect.forEach((k,v)->{
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("date",DateUtil.formatDate(k));
+                    // 计算可预约人数
+                    jsonObject.put("list",v.stream().sorted(Comparator.comparing(SysReservationConfig::getReservationStartTime)).collect(Collectors.toList()));
+                    jsonArray.add(jsonObject);
+                });
+            } else {
+                DateTime startDate = DateUtil.date();
+                DateTime endDate =  DateUtil.offset(startDate, DateField.DAY_OF_YEAR, betweenDay);
+                SysReservationConfig sysReservationConfig = new SysReservationConfig();
+                sysReservationConfig.setBeginReservationDate(DateUtil.formatDate(startDate));
+                sysReservationConfig.setEndReservationDate(DateUtil.formatDate(endDate));
+                sysReservationConfig.setBeginReservationStartTime(DateUtil.formatDateTime(DateUtil.date()));
+                sysReservationConfig.setStatus("1");
+                List<SysReservationConfig> list = sysReservationConfigService.findList(sysReservationConfig);
+                List<String> sysReservationConfigIds = list.stream().map(SysReservationConfig::getId).collect(Collectors.toList());
+                List<SysReservationDataNumVO> numByReservationConfigIds = sysReservationDataMapper.getNumByReservationConfigIds(sysReservationConfigIds.toArray(new String[]{}));
+                SysReservationDataNumVO defaultMap = new SysReservationDataNumVO();
+                defaultMap.setNum(0L);
+                list.stream().forEach(item -> item.setEnableNum(item.getEnableNum() - numByReservationConfigIds.stream().filter(item1 -> item1.getReservationConfigId().equals(item.getId())).findFirst().orElse(defaultMap).getNum()));
+                Map<Date, List<SysReservationConfig>> collect = list.stream().collect(Collectors.groupingBy(SysReservationConfig::getReservationDate, Collectors.mapping(value -> value, Collectors.toList())));
+                collect.forEach((k,v)->{
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("date",DateUtil.formatDate(k));
+                    // 计算可预约人数
+                    jsonObject.put("list",v.stream().sorted(Comparator.comparing(SysReservationConfig::getReservationStartTime)).collect(Collectors.toList()));
+                    jsonArray.add(jsonObject);
+                });
+            }
+        }
+        jsonArray.sort(Comparator.comparing(obj -> ((JSONObject) obj).getDate("date")));
+        return jsonArray;
+    }
+
+    @Override
+    public R saveReservationData(SysReservationData sysReservationData) {
+        if (sysReservationDataMapper.getNumByOpenid(sysReservationData) > 0){
+            return R.fail("当前预约日期已存在预约记录!");
+        }
+        int numByReservationConfigId = sysReservationDataMapper.getNumByReservationConfigId(sysReservationData);
+        SysReservationConfig sysReservationConfig = sysReservationConfigService.get(sysReservationData.getReservationConfigId());
+        if (sysReservationConfig!=null && numByReservationConfigId >= sysReservationConfig.getEnableNum()){
+            return R.fail("已超出可预约人数!");
+        }
+        sysReservationData.setReservationTime(DateUtil.date());
+        sysReservationData.setId(IdUtils.simpleUUID());
+        // 判断预约记录
+        return R.status(sysReservationDataMapper.addReservationData(sysReservationData));
+    }
+
+    @Override
+    public int cancelReservation(String id) {
+        return sysReservationDataMapper.deleteById(id);
+    }
+
+    @Override
+    public List<SysReservationDataHistoryVO> getHistoryReservationList(String openid, String type) {
+        List<SysReservationDataHistoryVO> historyData = sysReservationDataMapper.getHistoryData(openid, type);
+        SysConfig configByKey = ConfigUtils.getConfigByKey("sys.before.open.minte");
+        if (configByKey != null){
+            String value = configByKey.getConfigValue();
+            if (!Constants.SUCCESS.equals(value)){
+                historyData.stream().forEach(item -> item.setBeforeOpenTime(DateUtil.offsetDay(item.getReservationTime(), -1)));
+            }
+        }
+        return historyData;
+    }
+
 }

+ 147 - 0
aidex-system/src/main/java/com/aidex/system/domain/SysReservationConfig.java

@@ -0,0 +1,147 @@
+package com.aidex.system.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.aidex.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.aidex.common.utils.log.annotation.FieldRemark;
+import com.aidex.common.utils.log.annotation.LogField;
+import com.aidex.common.annotation.Excel;
+
+/**
+ * 预约配置对象 sys_reservation_config
+ * @author Chensir
+ * @email 914769835
+ * @date 2024-03-28
+ */
+@Data
+public class SysReservationConfig extends BaseEntity<SysReservationConfig>
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 预约日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @Excel(name = "预约日期", width = 30, dateFormat = "yyyy-MM-dd")
+    @LogField
+    @FieldRemark(name = "预约日期",field = "reservationDate")
+    private Date reservationDate;
+
+    /** 预约日期开始 */
+    private String beginReservationDate;
+
+    /** 预约日期结束 */
+    private String endReservationDate;
+
+    /** 预约开始时段 */
+    @JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
+    @Excel(name = "预约开始时段", width = 30, dateFormat = "HH:mm")
+    @LogField
+    @FieldRemark(name = "预约开始时段",field = "reservationStartTime")
+    private Date reservationStartTime;
+
+    /** 预约开始时段开始 */
+    private String beginReservationStartTime;
+
+    /** 预约开始时段结束 */
+    private String endReservationStartTime;
+
+    /** 预约结束时段 */
+    @JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
+    @Excel(name = "预约结束时段", width = 30, dateFormat = "HH:mm")
+    @LogField
+    @FieldRemark(name = "预约结束时段",field = "reservationEndTime")
+    private Date reservationEndTime;
+
+    /** 预约结束时段开始 */
+    private String beginReservationEndTime;
+
+    /** 预约结束时段结束 */
+    private String endReservationEndTime;
+
+    /** 可预约人数 */
+    @Excel(name = "可预约人数")
+    @LogField
+    @FieldRemark(name = "可预约人数",field = "enableNum")
+    private Long enableNum;
+
+    /** 配置状态 0 保存 1 发布 */
+    @Excel(name = "配置状态", dictType = "sys_normal_disable")
+    @LogField
+    @FieldRemark(name = "配置状态",field = "status")
+    private String status;
+
+    public void setReservationDate(Date reservationDate)
+    {
+        this.reservationDate = reservationDate;
+    }
+
+    public Date getReservationDate()
+    {
+        return reservationDate;
+    }
+
+    public void setReservationStartTime(Date reservationStartTime)
+    {
+        this.reservationStartTime = reservationStartTime;
+    }
+
+    public Date getReservationStartTime()
+    {
+        return reservationStartTime;
+    }
+
+    public void setReservationEndTime(Date reservationEndTime)
+    {
+        this.reservationEndTime = reservationEndTime;
+    }
+
+    public Date getReservationEndTime()
+    {
+        return reservationEndTime;
+    }
+
+    public void setEnableNum(Long enableNum)
+    {
+        this.enableNum = enableNum;
+    }
+
+    public Long getEnableNum()
+    {
+        return enableNum;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("reservationDate", getReservationDate())
+            .append("reservationStartTime", getReservationStartTime())
+            .append("reservationEndTime", getReservationEndTime())
+            .append("enableNum", getEnableNum())
+            .append("status", getStatus())
+            .append("remark", getRemark())
+            .append("id", getId())
+            .append("createBy", getCreateBy())
+            .append("createDept", getCreateDept())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("updateIp", getUpdateIp())
+            .append("version", getVersion())
+            .append("delFlag", getDelFlag())
+            .toString();
+    }
+}

+ 45 - 0
aidex-system/src/main/java/com/aidex/system/domain/SysReservationData.java

@@ -0,0 +1,45 @@
+package com.aidex.system.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Date;
+
+/**
+ * @author :ChenSir
+ * @date :Created in 2024/3/29 9:24
+ * @description:预约记录
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor()
+public class SysReservationData {
+
+	@ApiModelProperty(value = "预约记录id")
+	private String id;
+
+	@ApiModelProperty(value = "小程序用户openid")
+	@NotBlank(message = "小程序用户openid不能为空")
+	private String openid;
+
+	@ApiModelProperty(value = "预约配置id")
+	@NotBlank(message = "预约配置不能为空")
+	private String reservationConfigId;
+
+	@ApiModelProperty(value = "预约日期")
+	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+	private Date reservationTime;
+
+	@ApiModelProperty(value = "起始码头id")
+	@NotBlank(message = "起始码头不能为空")
+	private String startWharfId;
+
+	@ApiModelProperty(value = "终止码头id")
+	@NotBlank(message = "终止码头不能为空")
+	private String endWharfId;
+
+}

+ 62 - 0
aidex-system/src/main/java/com/aidex/system/domain/vo/SysReservationDataHistoryVO.java

@@ -0,0 +1,62 @@
+package com.aidex.system.domain.vo;
+
+import com.aidex.common.annotation.Excel;
+import com.aidex.common.utils.log.annotation.FieldRemark;
+import com.aidex.common.utils.log.annotation.LogField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @author :ChenSir
+ * @date :Created in 2024/3/29 9:24
+ * @description:预约记录
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor()
+public class SysReservationDataHistoryVO {
+
+	@ApiModelProperty(name = "预约id")
+	private String id;
+
+	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+	@ApiModelProperty(value = "预约配置日期")
+	private Date reservationDate;
+
+	/** 预约开始时段 */
+	@JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
+	@ApiModelProperty(name = "预约配置开始时段")
+	private Date reservationStartTime;
+
+	/** 预约结束时段 */
+	@JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
+	@ApiModelProperty(name = "预约配置结束时段")
+	private Date reservationEndTime;
+
+	@ApiModelProperty(name = "小程序用户id")
+	private String openid;
+
+
+	@ApiModelProperty(value = "预约日期")
+	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+	private Date reservationTime;
+
+
+	@ApiModelProperty(name = "起始码头")
+	private String startWharfName;
+
+	@ApiModelProperty(name = "终止码头")
+	private String endWharfName;
+
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+	@ApiModelProperty(name = "前置时间")
+	private Date beforeOpenTime;
+
+
+}

+ 25 - 0
aidex-system/src/main/java/com/aidex/system/domain/vo/SysReservationDataNumVO.java

@@ -0,0 +1,25 @@
+package com.aidex.system.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Date;
+
+/**
+ * @author :ChenSir
+ * @date :Created in 2024/3/29 9:24
+ * @description:预约记录
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor()
+public class SysReservationDataNumVO {
+
+	private String reservationConfigId;
+
+	private long num;
+
+}

+ 33 - 0
aidex-system/src/main/java/com/aidex/system/mapper/SysReservationConfigMapper.java

@@ -0,0 +1,33 @@
+package com.aidex.system.mapper;
+
+import com.aidex.common.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import com.aidex.system.domain.SysReservationConfig;
+
+import java.util.List;
+
+/**
+ * 预约配置Mapper接口
+ * @author Chensir
+ * @email 914769835
+ * @date 2024-03-28
+ */
+public interface SysReservationConfigMapper extends BaseMapper<SysReservationConfig>
+{
+
+    /**
+     * 批量删除预约配置
+     * @param ids 需要删除的预约配置ID集合
+     * @return
+     */
+    public int deleteSysReservationConfigByIds(@Param("ids") String[] ids, @Param("DEL_FLAG_DELETE") String DEL_FLAG_DELETE);
+
+    /**
+     * 批量添加
+     * @param list 需要添加的预约配置集合
+     * @return
+     */
+    public int batchInsert(List<SysReservationConfig> list);
+
+
+}

+ 278 - 0
aidex-system/src/main/java/com/aidex/system/mapper/SysReservationConfigMapper.xml

@@ -0,0 +1,278 @@
+<?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.aidex.system.mapper.SysReservationConfigMapper">
+
+    <sql id="sysReservationConfigColumns">
+        a.reservation_date as "reservationDate",
+
+        a.reservation_start_time as "reservationStartTime",
+
+        a.reservation_end_time as "reservationEndTime",
+
+        a.enable_num as "enableNum",
+
+        a.status as "status",
+
+        a.remark as "remark",
+
+        a.id as "id",
+
+        a.create_by as "createBy",
+
+        a.create_dept as "createDept",
+
+        a.create_time as "createTime",
+
+        a.update_by as "updateBy",
+
+        a.update_time as "updateTime",
+
+        a.update_ip as "updateIp",
+
+        a.version as "version",
+
+        a.del_flag as "delFlag"
+
+    </sql>
+
+    <sql id="sysReservationConfigJoins">
+    </sql>
+
+    <select id="get" resultType="SysReservationConfig">
+        SELECT
+            <include refid="sysReservationConfigColumns"/>
+        FROM sys_reservation_config a
+        <include refid="sysReservationConfigJoins"/>
+        WHERE a.id = #{id}
+    </select>
+
+    <select id="findList" resultType="SysReservationConfig">
+        SELECT
+            <include refid="sysReservationConfigColumns"/>
+        FROM sys_reservation_config a
+        <include refid="sysReservationConfigJoins"/>
+        <where>
+            a.del_flag = #{DEL_FLAG_NORMAL}
+            <if test="status != null and status != ''">
+                AND  a.status = #{status}
+            </if>
+            <if test="beginReservationDate != null and beginReservationDate != ''">
+                AND date_format(a.reservation_date,'%Y%m%d') &gt;= date_format(#{beginReservationDate},'%Y%m%d')
+            </if>
+            <if test="endReservationDate != null and endReservationDate != ''">
+                AND date_format(a.reservation_date,'%Y%m%d') &lt;= date_format(#{endReservationDate},'%Y%m%d')
+            </if>
+
+            <if test="beginReservationStartTime != null and beginReservationStartTime != ''">
+                AND date_format(a.reservation_start_time,'%Y-%m-%d %H:%i:%s') &gt;=  date_format(#{beginReservationStartTime},'%Y-%m-%d %H:%i:%s')
+            </if>
+
+            <if test="endReservationStartTime != null and endReservationStartTime != ''">
+                AND date_format(a.reservation_start_time,'%Y-%m-%d %H:%i:%s') &lt;= date_format(#{endReservationStartTime},'%Y-%m-%d %H:%i:%s')
+            </if>
+
+            <if test="beginReservationEndTime != null and beginReservationEndTime != ''">
+                AND date_format(a.reservation_end_time,'%Y-%m-%d %H:%i:%s') &gt;= date_format(#{beginReservationEndTime},'%Y-%m-%d %H:%i:%s')
+            </if>
+
+            <if test="endReservationEndTime != null and endReservationEndTime != ''">
+                AND date_format(a.reservation_end_time,'%Y-%m-%d %H:%i:%s') &lt;= date_format(#{endReservationEndTime},'%Y-%m-%d %H:%i:%s')
+            </if>
+
+            <if test="enableNum != null ">
+                AND a.enable_num = #{enableNum}
+            </if>
+        </where>
+        <choose>
+            <when test="page !=null and page.orderBy != null and page.orderBy != ''">
+                ORDER BY ${page.orderBy}
+            </when>
+            <otherwise>
+            </otherwise>
+        </choose>
+    </select>
+
+    <select id="findListWithUnique" resultType="SysReservationConfig">
+        SELECT
+            a.id
+        FROM sys_reservation_config a
+        <include refid="sysReservationConfigJoins"/>
+        <where>
+            a.del_flag = #{DEL_FLAG_NORMAL}
+            <if test="notEqualId != null and notEqualId != ''">
+                AND id != #{notEqualId}
+            </if>
+        </where>
+    </select>
+
+
+    <insert id="insert">
+        INSERT INTO sys_reservation_config(
+            reservation_date,
+
+            reservation_start_time,
+
+            reservation_end_time,
+
+            enable_num,
+
+            status,
+
+            remark,
+
+            id,
+
+            create_by,
+
+            create_dept,
+
+            create_time,
+
+            update_by,
+
+            update_time,
+
+            update_ip,
+
+            version,
+
+            del_flag
+
+        ) VALUES (
+            #{reservationDate},
+
+            #{reservationStartTime},
+
+            #{reservationEndTime},
+
+            #{enableNum},
+
+            #{status},
+
+            #{remark},
+
+            #{id},
+
+            #{createBy},
+
+            #{createDept},
+
+            #{createTime},
+
+            #{updateBy},
+
+            #{updateTime},
+
+            #{updateIp},
+
+            #{version},
+
+            #{delFlag}
+
+        )
+    </insert>
+    <insert id="batchInsert" parameterType="java.util.List">
+        INSERT INTO sys_reservation_config(
+            reservation_date,
+
+            reservation_start_time,
+
+            reservation_end_time,
+
+            enable_num,
+
+            status,
+
+            remark,
+
+            id,
+
+            create_by,
+
+            create_dept,
+
+            create_time,
+
+            update_by,
+
+            update_time,
+
+            update_ip,
+
+            version,
+
+            del_flag
+
+        ) VALUES
+        <foreach collection="list" item="item" index="index" separator=",">
+          (  #{item.reservationDate},
+
+            #{item.reservationStartTime},
+
+            #{item.reservationEndTime},
+
+            #{item.enableNum},
+
+            #{item.status},
+
+            #{item.remark},
+
+            #{item.id},
+
+            #{item.createBy},
+
+            #{item.createDept},
+
+            #{item.createTime},
+
+            #{item.updateBy},
+
+            #{item.updateTime},
+
+            #{item.updateIp},
+
+            #{item.version},
+
+            #{item.delFlag}
+            )
+        </foreach>
+    </insert>
+
+    <update id="update">
+        UPDATE sys_reservation_config SET
+            reservation_date = #{reservationDate},
+            reservation_start_time = #{reservationStartTime},
+            reservation_end_time = #{reservationEndTime},
+            enable_num = #{enableNum},
+            status = #{status},
+            remark = #{remark},
+            update_by = #{updateBy},
+            update_time = #{updateTime},
+            update_ip = #{updateIp},
+            version = version + 1
+        WHERE id = #{id} and version = #{version}
+    </update>
+
+    <update id="updateStatus">
+        UPDATE sys_reservation_config SET
+            status = #{status},
+            version = version + 1
+        WHERE id = #{id}
+    </update>
+
+    <update id="delete">
+        UPDATE sys_reservation_config SET
+            del_flag = #{DEL_FLAG_DELETE}
+        WHERE id = #{id}
+    </update>
+
+    <delete id="deleteSysReservationConfigByIds">
+        UPDATE sys_reservation_config SET
+            del_flag = #{DEL_FLAG_DELETE}
+        WHERE id in
+        <foreach item="id" collection="ids" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>

+ 94 - 0
aidex-system/src/main/java/com/aidex/system/mapper/SysReservationDataMapper.java

@@ -0,0 +1,94 @@
+package com.aidex.system.mapper;
+
+import com.aidex.system.domain.SysReservationData;
+import com.aidex.system.domain.SysRoleMenu;
+import com.aidex.system.domain.vo.SysReservationDataHistoryVO;
+import com.aidex.system.domain.vo.SysReservationDataNumVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 角色与菜单关联表 数据层
+ *
+ * @author ruoyi
+ */
+public interface SysReservationDataMapper
+{
+    /**
+     * 根据配置获取当前预约人数
+     *
+     * @param ids 需要删除的数据ID
+     * @return 结果
+     */
+    public List<SysReservationDataNumVO> getNumByReservationConfigIds(String[] ids);
+
+    /**
+     * 新增预约数据
+     *
+     * @param sysReservationData 预约数据
+     * @return 结果
+     */
+    public int addReservationData(SysReservationData sysReservationData);
+
+
+    /**
+     * 获取数据
+     *
+     * @param sysReservationData 预约数据
+     * @return 结果
+     */
+    public List<SysReservationData> getData(SysReservationData sysReservationData);
+
+    /**
+     * 判断小程序当日有无预约
+     *
+     * @param sysReservationData 预约数据
+     * @return 结果
+     */
+    public int getNumByOpenid(SysReservationData sysReservationData);
+
+    /**
+     * 判断小程序当日有无预约
+     *
+     * @param sysReservationData 预约数据
+     * @return 结果
+     */
+    public int getNumByReservationConfigId(SysReservationData sysReservationData);
+
+    /**
+     * 判断小程序当日有无预约
+     *
+     * @param id 预约数据id
+     * @return 结果
+     */
+    public int deleteById(String id);
+
+    /**
+     * 获取小程序历史数据
+     *
+     * @param openid 小程序用户名
+     *
+     * @return 结果
+     */
+    public List<SysReservationDataHistoryVO> getHistoryData(@Param("openid") String openid, @Param("type") String type);
+
+    /**
+     * 根据日期获取预约时间点
+     *
+     * @param date 预约数据
+     * @return 结果
+     */
+    public List<String> getDurationByDate(String date);
+
+    /**
+     * 根据日期获取预约时间点
+     *
+     * @param date 预约数据
+     * @return 结果
+     */
+    public List<Map<String, String>> getReservationDataByDate(String date);
+
+
+}

+ 128 - 0
aidex-system/src/main/java/com/aidex/system/mapper/SysReservationDataMapper.xml

@@ -0,0 +1,128 @@
+<?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.aidex.system.mapper.SysReservationDataMapper">
+
+	<resultMap type="SysReservationData" id="SysReservationDataResult">
+		<result property="id"     column="id"      />
+		<result property="openid"     column="openid"      />
+		<result property="reservationConfigId"     column="reservation_config_id"      />
+		<result property="reservationTime"     column="reservation_time"      />
+		<result property="startWharfId"     column="start_wharf_id"      />
+		<result property="endWharfId"     column="end_wharf_id"      />
+	</resultMap>
+
+	<delete id="deleteById">
+		delete from sys_reservation_data where id = #{id}
+	</delete>
+
+	<select id="getNumByReservationConfigIds" parameterType="String" resultType="com.aidex.system.domain.vo.SysReservationDataNumVO">
+		SELECT
+			a.reservation_config_id as reservationConfigId,
+			SUM(1) AS num
+		FROM
+			sys_reservation_data a
+		WHERE
+			a.reservation_config_id IN
+ 		<foreach collection="array" item="rervationConfigId" open="(" separator="," close=")">
+ 			#{rervationConfigId}
+        </foreach>
+		GROUP BY
+			a.reservation_config_id
+ 	</select>
+
+	<insert id="addReservationData">
+		insert into sys_reservation_data(id, openid, reservation_config_id, start_wharf_id, end_wharf_id, reservation_time) VALUES( #{id}, #{openid}, #{reservationConfigId}, #{startWharfId}, #{endWharfId},NOW())
+	</insert>
+
+	<select id="getData" resultType="com.aidex.system.domain.SysReservationData">
+		SELECT
+			a.id,
+			a.openid,
+			a.reservation_config_id,
+			a.reservation_time,
+			a.start_wharf_id,
+			a.end_wharf_id
+		FROM sys_reservation_data a
+		where a.openid = #{openid}
+	</select>
+
+	<select id="getNumByOpenid" resultType="java.lang.Integer">
+		SELECT
+			COUNT(1)
+		FROM
+			sys_reservation_data a
+		WHERE
+			a.openid = #{openid}
+		  AND a.reservation_config_id IN (
+			SELECT
+				z.id
+			FROM
+				sys_reservation_config z
+			WHERE
+				z.reservation_date = ( SELECT a.reservation_date FROM sys_reservation_config a WHERE a.id = #{reservationConfigId} )
+		)
+	</select>
+
+	<select id="getNumByReservationConfigId" resultType="java.lang.Integer">
+		SELECT
+			COUNT(1)
+		FROM
+			sys_reservation_data a
+		WHERE
+			a.reservation_config_id = #{reservationConfigId}
+	</select>
+
+	<select id="getHistoryData" resultType="com.aidex.system.domain.vo.SysReservationDataHistoryVO">
+		SELECT
+			c.reservation_date as reservationDate,
+			c.reservation_start_time as reservationStartTime,
+			c.reservation_end_time as reservationEndTime,
+			a.openid,
+        	a.id,
+			a.reservation_time as reservationTime,
+			sw_s.wharf_nanme as startWharfName,
+			sw_e.wharf_nanme as endWharfName
+		FROM
+			sys_reservation_data a
+				LEFT JOIN sys_reservation_config c ON a.reservation_config_id = c.id
+				LEFT JOIN sys_wharf sw_s ON a.start_wharf_id = sw_s.id
+				LEFT JOIN sys_wharf sw_e ON a.end_wharf_id = sw_e.id
+		WHERE
+			a.openid = #{openid}
+		<choose>
+			<when test="type != 1">
+				and  c.reservation_start_time &gt;= NOW()
+			</when>
+			<otherwise>
+				and  c.reservation_start_time &lt; now()
+			</otherwise>
+		</choose>
+	</select>
+
+	<select id="getDurationByDate" resultType="java.lang.String">
+		SELECT
+			CONCAT(date_format(a.reservation_start_time,'%H:%i'),'~',date_format(a.reservation_end_time,'%H:%i')) as duration
+		FROM
+			sys_reservation_config a
+		WHERE
+			a.reservation_date = #{date}
+		ORDER BY a.reservation_start_time
+
+	</select>
+
+	<select id="getReservationDataByDate" resultType="java.util.Map">
+		SELECT
+			CONCAT(date_format(c.reservation_start_time,'%H:%i'),'~',date_format(c.reservation_end_time,'%H:%i')) as duration,
+			sw_s.wharf_nanme as startWharfName,
+			sw_s.id as startWharfId
+		FROM
+			sys_reservation_data a
+				LEFT JOIN sys_reservation_config c ON a.reservation_config_id = c.id
+				LEFT JOIN sys_wharf sw_s ON a.start_wharf_id = sw_s.id
+		WHERE
+			c.reservation_date = #{date}
+	</select>
+
+</mapper>

+ 52 - 0
aidex-system/src/main/java/com/aidex/system/req/SysReservationConfigReq.java

@@ -0,0 +1,52 @@
+package com.aidex.system.req;
+
+import com.aidex.common.annotation.Excel;
+import com.aidex.common.utils.log.annotation.FieldRemark;
+import com.aidex.common.utils.log.annotation.LogField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.FutureOrPresent;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author :ChenSir
+ * @date :Created in 2024/3/28 11:32
+ * @description:
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysReservationConfigReq implements Serializable {
+
+	private static final long serialVersionUID = 4854884754912549447L;
+
+	/** 开始日期 */
+	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+	@NotNull(message = "开始日期不允许为空")
+	private Date startDate;
+
+	/** 结束日期 */
+	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+	@NotNull(message = "结束日期不允许为空")
+	private Date endDate;
+
+	/** 班次时常-分钟 */
+	@NotNull(message = "班次时常不允许为空")
+	private int duration;
+
+	/** 班次可预约人数 */
+	@NotNull(message = "可预约人数不允许为空")
+	private long enableNum;
+
+	/** 班次可预约人数 */
+	@NotNull(message = "发布状态不可为空")
+	private String status;
+
+}

+ 55 - 0
aidex-system/src/main/java/com/aidex/system/service/SysReservationConfigService.java

@@ -0,0 +1,55 @@
+package com.aidex.system.service;
+
+import com.aidex.common.core.service.BaseService;
+import com.aidex.system.domain.SysReservationConfig;
+import com.aidex.system.req.SysReservationConfigReq;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 预约配置Service接口
+ * @author Chensir
+ * @email 914769835
+ * @date 2024-03-28
+ */
+public interface SysReservationConfigService extends BaseService<SysReservationConfig> {
+
+    /**
+     * 批量删除预约配置
+     * @param ids 需要删除的预约配置ID集合
+     * @return 结果
+     */
+    public int deleteSysReservationConfigByIds(String[] ids);
+
+
+    /**
+     * 批量添加预约配置
+     * @param list 需要删除的预约配置ID集合
+     * @return 结果
+     */
+    public int batchInsert(List<SysReservationConfig> list);
+
+    /**
+     * 预约配置
+     * @param sysReservationConfigReq 新增预约配置对象
+     * @return 结果
+     */
+    public int addBySysReservationConfigReq(SysReservationConfigReq sysReservationConfigReq);
+
+
+    /**
+     * 根据日期获取统计数据
+     * @param date 根据日期获取统计数据
+     * @return 结果
+     */
+    public List<Map<String, String>> getStatiscDataBydate(String date);
+
+    /**
+     * 根据日期获取统计数据-行数据
+     * @param date 根据日期获取统计数据
+     * @return 结果
+     */
+    public List<String> getStatiscColumns(String date);
+
+}

+ 254 - 0
aidex-system/src/main/java/com/aidex/system/service/impl/SysReservationConfigServiceImpl.java

@@ -0,0 +1,254 @@
+package com.aidex.system.service.impl;
+
+import java.util.*;
+
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.IdUtil;
+import com.aidex.framework.cache.ConfigUtils;
+import com.aidex.system.domain.SysConfig;
+import com.aidex.system.domain.SysWharf;
+import com.aidex.system.mapper.SysReservationDataMapper;
+import com.aidex.system.req.SysReservationConfigReq;
+import com.aidex.system.service.SysWharfService;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.github.pagehelper.PageInfo;
+import com.aidex.common.core.domain.BaseEntity;
+import com.aidex.common.core.service.BaseServiceImpl;
+import com.aidex.system.mapper.SysReservationConfigMapper;
+import com.aidex.system.domain.SysReservationConfig;
+import com.aidex.system.service.SysReservationConfigService;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 预约配置Service业务层处理
+ * @author Chensir
+ * @email 914769835
+ * @date 2024-03-28
+ */
+@Service
+@Transactional(readOnly = true)
+public class SysReservationConfigServiceImpl extends BaseServiceImpl<SysReservationConfigMapper, SysReservationConfig> implements SysReservationConfigService {
+
+    private static final Logger log = LoggerFactory.getLogger(SysReservationConfigServiceImpl.class);
+
+
+    @Autowired
+    private SysReservationDataMapper sysReservationDataMapper;
+
+    @Autowired
+    private SysWharfService sysWharfService;
+
+
+    /**
+     * 获取单条数据
+     * @param sysReservationConfig 预约配置
+     * @return 预约配置
+     */
+    @Override
+    public SysReservationConfig get(SysReservationConfig sysReservationConfig) {
+        SysReservationConfig dto = super.get(sysReservationConfig);
+        return dto;
+    }
+
+    /**
+     * 获取单条数据
+     * @param id 预约配置id
+     * @return 预约配置
+     */
+    @Override
+    public SysReservationConfig get(String id) {
+        SysReservationConfig dto = super.get(id);
+        return dto;
+    }
+
+    /**
+     * 查询预约配置列表
+     * @param sysReservationConfig 预约配置
+     * @return 预约配置
+     */
+    @Override
+    public List<SysReservationConfig> findList(SysReservationConfig sysReservationConfig) {
+		List<SysReservationConfig> sysReservationConfigList = super.findList(sysReservationConfig);
+        return sysReservationConfigList;
+    }
+
+    /**
+     * 分页查询预约配置列表
+     * @param sysReservationConfig 预约配置
+     * @return 预约配置
+     */
+    @Override
+    public PageInfo<SysReservationConfig> findPage(SysReservationConfig sysReservationConfig) {
+		PageInfo<SysReservationConfig> page = super.findPage(sysReservationConfig);
+        return page;
+    }
+
+    /**
+     * 保存预约配置
+     * @param sysReservationConfig
+     * @return 结果
+     */
+    @Override
+    public boolean save(SysReservationConfig sysReservationConfig) {
+        return super.save(sysReservationConfig);
+    }
+
+    /**
+     * 删除预约配置信息
+     * @param sysReservationConfig
+     * @return 结果
+     */
+    @Override
+    public boolean remove(SysReservationConfig sysReservationConfig) {
+        return super.remove(sysReservationConfig);
+    }
+
+    /**
+     * 批量删除预约配置
+     * @param ids 需要删除的预约配置ID
+     * @return 结果
+     */
+    @Transactional(readOnly = false)
+    @Override
+    public int deleteSysReservationConfigByIds(String[] ids) {
+        return mapper.deleteSysReservationConfigByIds(ids, BaseEntity.DEL_FLAG_DELETE);
+    }
+    @Transactional(readOnly = false)
+    @Override
+    public int batchInsert(List<SysReservationConfig> list) {
+        return mapper.batchInsert(list);
+    }
+    @Transactional(readOnly = false)
+    @Override
+    public int addBySysReservationConfigReq(SysReservationConfigReq sysReservationConfigReq) {
+        SysConfig routeStartConfig =  ConfigUtils.getConfigByKey("sys.route.start");
+        SysConfig routeEndConfig = ConfigUtils.getConfigByKey("sys.route.end");
+        List<SysReservationConfig> list = new ArrayList<>();
+        if(routeStartConfig != null && routeEndConfig != null){
+            String routeStart = routeStartConfig.getConfigValue();
+            String routeEnd = routeEndConfig.getConfigValue();
+            Date startDate = sysReservationConfigReq.getStartDate();
+            Date endDate = sysReservationConfigReq.getEndDate();
+            long days = DateUtil.between(startDate,endDate, DateUnit.DAY);
+            if(days > 0){
+                for(int i = 0; i < days; i++){
+                    DateTime date = DateUtil.offsetDay(startDate, i);
+                    DateTime dateTime = DateUtil.offsetDay(startDate, i);
+                    String[] split = routeStart.split(":");
+                    dateTime.setField(DateField.HOUR, Integer.valueOf(split[0]));
+                    dateTime.setField(DateField.MINUTE, Integer.valueOf(split[1]));
+                    dateTime.setField(DateField.SECOND, 0);
+                    DateTime end = DateUtil.offsetDay(startDate, i);
+                    String[] endSplit = routeEnd.split(":");
+                    end.setField(DateField.HOUR, Integer.valueOf(endSplit[0]));
+                    end.setField(DateField.MINUTE, Integer.valueOf(endSplit[1]));
+                    end.setField(DateField.SECOND, 0);
+                    DateTime last = DateUtil.date();
+                    DateTime endTime = DateUtil.offset(dateTime, DateField.MINUTE, sysReservationConfigReq.getDuration());
+                    while (endTime.getTime() <= end.getTime()) {
+                        SysReservationConfig sysReservationConfig = new SysReservationConfig();
+                        sysReservationConfig.setReservationDate(date);
+                        sysReservationConfig.setEnableNum(sysReservationConfigReq.getEnableNum());
+                        sysReservationConfig.setReservationStartTime(dateTime);
+                        sysReservationConfig.setReservationEndTime(endTime);
+                        sysReservationConfig.setId(IdUtil.simpleUUID());
+                        sysReservationConfig.setStatus(sysReservationConfigReq.getStatus());
+                        last = endTime;
+                        list.add(sysReservationConfig);
+                        endTime = DateUtil.offset(endTime, DateField.MINUTE, sysReservationConfigReq.getDuration());
+                        dateTime  = DateUtil.offset(dateTime, DateField.MINUTE, sysReservationConfigReq.getDuration());
+                    }
+                    if (endTime.getTime() > end.getTime()){
+                        SysReservationConfig lastConfig = new SysReservationConfig();
+                        lastConfig.setReservationDate(date);
+                        lastConfig.setReservationStartTime(last);
+                        lastConfig.setReservationEndTime(end);
+                        lastConfig.setEnableNum(sysReservationConfigReq.getEnableNum());
+                        lastConfig.setId(IdUtil.simpleUUID());
+                        lastConfig.setStatus(sysReservationConfigReq.getStatus());
+                        list.add(lastConfig);
+                    }
+                }
+                return mapper.batchInsert(list);
+            } else {
+                DateTime date = DateUtil.offsetDay(startDate, 0);
+                DateTime dateTime = DateUtil.offsetDay(startDate, 0);
+                String[] split = routeStart.split(":");
+                dateTime.setField(DateField.HOUR, Integer.valueOf(split[0]));
+                dateTime.setField(DateField.MINUTE, Integer.valueOf(split[1]));
+                dateTime.setField(DateField.SECOND, 0);
+                DateTime end = DateUtil.offsetDay(startDate, 0);
+                String[] endSplit = routeEnd.split(":");
+                end.setField(DateField.HOUR, Integer.valueOf(endSplit[0]));
+                end.setField(DateField.MINUTE, Integer.valueOf(endSplit[1]));
+                end.setField(DateField.SECOND, 0);
+                DateTime last = DateUtil.date();
+                DateTime endTime = DateUtil.offset(dateTime, DateField.MINUTE, sysReservationConfigReq.getDuration());
+                while (endTime.getTime() <= end.getTime()) {
+                    SysReservationConfig sysReservationConfig = new SysReservationConfig();
+                    sysReservationConfig.setReservationDate(date);
+                    sysReservationConfig.setEnableNum(sysReservationConfigReq.getEnableNum());
+                    sysReservationConfig.setReservationStartTime(dateTime);
+                    sysReservationConfig.setReservationEndTime(endTime);
+                    sysReservationConfig.setId(IdUtil.simpleUUID());
+                    sysReservationConfig.setStatus(sysReservationConfigReq.getStatus());
+                    last = endTime;
+                    list.add(sysReservationConfig);
+                    endTime = DateUtil.offset(endTime, DateField.MINUTE, sysReservationConfigReq.getDuration());
+                    dateTime  = DateUtil.offset(dateTime, DateField.MINUTE, sysReservationConfigReq.getDuration());
+                }
+                if (endTime.getTime() > end.getTime()){
+                    SysReservationConfig lastConfig = new SysReservationConfig();
+                    lastConfig.setReservationDate(date);
+                    lastConfig.setReservationStartTime(last);
+                    lastConfig.setReservationEndTime(end);
+                    lastConfig.setEnableNum(sysReservationConfigReq.getEnableNum());
+                    lastConfig.setId(IdUtil.simpleUUID());
+                    lastConfig.setStatus(sysReservationConfigReq.getStatus());
+                    list.add(lastConfig);
+                }
+                return mapper.batchInsert(list);
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public List<Map<String, String>> getStatiscDataBydate(String date) {
+        List<String> durationByDate = sysReservationDataMapper.getDurationByDate(date);
+        List<Map<String, String>> reservationDataByDate = sysReservationDataMapper.getReservationDataByDate(date);
+        SysWharf sysWharf = new SysWharf();
+        sysWharf.setStatus(BaseEntity.STATUS_NORMAL);
+        List<SysWharf> list = sysWharfService.findList(sysWharf);
+        List<Map<String, String>> data = new ArrayList<>();
+        if (reservationDataByDate != null){
+            for (SysWharf item : list) {
+                Map<String, String> map = new HashMap<>();
+                map.put("wharfName", item.getWharfNanme());
+                map.put("date", date);
+                String wharfName = item.getWharfNanme();
+                for (int i = 0; i < durationByDate.size(); i++) {
+                    String duration = durationByDate.get(i);
+                    long count = reservationDataByDate.stream().filter(reservationData -> reservationData.get("startWharfName").equals(wharfName) && reservationData.get("duration").equals(duration)).count();
+                    map.put(duration, String.valueOf(count));
+                }
+                data.add(map);
+            }
+        }
+        return data;
+    }
+
+    @Override
+    public List<String> getStatiscColumns(String date) {
+        return sysReservationDataMapper.getDurationByDate(date);
+    }
+
+}

+ 4 - 1
aidex-ui/package.json

@@ -16,6 +16,7 @@
     "core-js": "^3.1.2",
     "echarts": "^5.0.0",
     "enquire.js": "^2.1.6",
+    "file-saver": "^2.0.5",
     "highlight.js": "^10.5.0",
     "lodash.clonedeep": "^4.5.0",
     "lodash.get": "^4.4.2",
@@ -24,6 +25,7 @@
     "mockjs2": "1.0.8",
     "moment": "^2.24.0",
     "nprogress": "^0.2.0",
+    "print-js": "^1.6.0",
     "qq": "^0.3.5",
     "sortablejs": "^1.10.2",
     "store": "^2.0.12",
@@ -42,7 +44,8 @@
     "vuex": "^3.1.1",
     "xgplayer": "^3.0.10",
     "xgplayer-flv": "^3.0.10",
-    "xgplayer-hls": "^3.0.10"
+    "xgplayer-hls": "^3.0.10",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "@ant-design/colors": "^3.2.1",

+ 85 - 0
aidex-ui/src/api/system/sysReservationConfig.js

@@ -0,0 +1,85 @@
+import request from '@/utils/request'
+
+// 查询预约配置列表
+export function listSysReservationConfig (query) {
+  return request({
+    url: '/system/sysReservationConfig/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询预约配置详细
+export function getSysReservationConfig (id) {
+  return request({
+    url: '/system/sysReservationConfig/' + id,
+    method: 'get'
+  })
+}
+
+// 新增预约配置
+export function addSysReservationConfig (data) {
+  return request({
+    url: '/system/sysReservationConfig',
+    method: 'post',
+    data: data
+  })
+}
+
+export function batchAddSysReservationConfig (data) {
+  return request({
+    url: '/system/sysReservationConfig/batchAdd',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改预约配置
+export function updateSysReservationConfig (data) {
+  return request({
+    url: '/system/sysReservationConfig',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除预约配置
+export function delSysReservationConfig (id) {
+  return request({
+    url: '/system/sysReservationConfig/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出预约配置
+export function exportSysReservationConfig (query) {
+  return request({
+    url: '/system/sysReservationConfig/export',
+    method: 'get',
+    params: query
+  })
+}
+
+// 获取初始化数据
+export function getInitData (dictTypes) {
+  return request({
+    url: '/system/sysReservationConfig/getInitData/' + dictTypes,
+    method: 'get'
+  })
+}
+
+export function statiscData (query) {
+  return request({
+    url: '/system/sysReservationConfig/statisc',
+    method: 'get',
+    params: query
+  })
+}
+
+export function statiscColumns (query) {
+  return request({
+    url: '/system/sysReservationConfig/statisc/columns',
+    method: 'get',
+    params: query
+  })
+}

+ 339 - 0
aidex-ui/src/views/system/sysreservationconfig/index.vue

@@ -0,0 +1,339 @@
+<template>
+  <div>
+    <a-card :bordered="false" style="margin-bottom: 10px;">
+      <!-- 条件搜索 -->
+      <div class="table-page-search-wrapper">
+        <a-form :labelCol="labelCol" :wrapperCol="wrapperCol" ref="queryForm">
+          <a-row :gutter="32">
+            <a-col :span="6" >
+              <a-form-item label="预约日期">
+                <a-date-picker
+                  v-model="queryParam.beginReservationDate"
+                  valueFormat="YYYY-MM-DD"
+                  :show-today="true"
+                  placeholder="选择日期"
+                  style="width: 100%"
+                />
+              </a-form-item>
+            </a-col>
+            <a-col>
+              <span class="table-page-search-submitButtons" style="float: right;">
+                <a-button type="primary" @click="handleQuery"><a-icon type="search" />查询</a-button>
+                <a-button style="margin-left: 8px" @click="resetQuery"><a-icon type="redo" />重置</a-button>
+                <a @click="toggleAdvanced" style="margin-left: 8px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'"/>
+                </a>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+    </a-card>
+    <a-card :bordered="false" class="table-card">
+      <!-- 增加 -->
+      <sys-reservation-config-add-form
+        v-if="showAddModal"
+        ref="sysReservationConfigAddForm"
+        :statusOptions="statusOptions"
+        @ok="getList"
+        @close="showAddModal = false"
+      />
+      <!-- 增加 -->
+      <sys-reservation-config-batch-add-form
+        v-if="showBatchAddModal"
+        ref="sysReservationConfigBatchAddForm"
+        :statusOptions="statusOptions"
+        @ok="getList"
+        @close="showBatchAddModal = false"
+      />
+      <!-- 编辑 -->
+      <sys-reservation-config-edit-form
+        v-if="showEditModal"
+        ref="sysReservationConfigEditForm"
+        :statusOptions="statusOptions"
+        @ok="getList"
+        @close="showEditModal = false"
+      />
+      <advance-table
+        title="预约配置"
+        :pagination="{
+          current: queryParam.pageNum,
+          pageSize: queryParam.pageSize,
+          total: total,
+          showSizeChanger: true,
+          showLessItems: true,
+          showQuickJumper: true,
+          showTotal: (total, range) => `第 ${range[0]}-${range[1]} 条,总计 ${total} 条`,
+          onChange: changeSize,
+          onShowSizeChange: onShowSizeChange
+        }"
+        tableKey="base-sysReservationConfig-index-table"
+        @change="handleTableChange"
+        rowKey="id"
+        size="middle"
+        @refresh="getList"
+        :columns="columns"
+        :data-source="sysReservationConfigList"
+        :loading="loading"
+        :format-conditions="true"
+        :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+      >
+        <div class="table-operations" slot="button">
+          <a-button type="primary" @click="handleBatchAdd" v-hasPermi="['system:sysReservationConfig:add']">
+            <a-icon type="plus" />预约配置
+          </a-button>
+          <a-button type="primary" @click="handleAdd" v-hasPermi="['system:sysReservationConfig:add']">
+            <a-icon type="plus" />新增
+          </a-button>
+          <a-button type="danger" v-if="!multiple" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:sysReservationConfig:remove']">
+            <a-icon type="delete" />删除
+          </a-button>
+          <a-button type="" @click="handleExport" v-hasPermi="['system:sysReservationConfig:export']">
+            <a-icon type="download" />导出
+          </a-button>
+        </div>
+<!--        <span slot="statusRender" slot-scope="{record}">
+          <a-badge :status="record.status === '0' ? 'processing' : 'error'" :text=" statusFormat(record) " />
+        </span>-->
+        <span slot="statusRender" slot-scope="{record}">
+          <a-switch
+            :checkedValue="1"
+            :unCheckedValue="0"
+            checkedChildren="已发布"
+            unCheckedChildren="未发布"
+            :checked="record.status === '1'"/>
+        </span>
+        <span slot="operation" slot-scope="{text, record}">
+          <a v-if="record.status === '0'" @click="handleUpdate(record)" v-hasPermi="['system:sysReservationConfig:edit']">
+            修改
+          </a>
+          <a-divider type="vertical" v-hasPermi="['system:sysReservationConfig:remove']"/>
+          <a v-if="record.status === '0'" @click="handleDelete(record)" v-hasPermi="['system:sysReservationConfig:remove']">
+            删除
+          </a>
+        </span>
+      </advance-table>
+    </a-card>
+  </div>
+</template>
+<script>
+import { listSysReservationConfig, delSysReservationConfig, exportSysReservationConfig, getInitData } from '@/api/system/sysReservationConfig'
+import AdvanceTable from '@/components/pt/table/AdvanceTable'
+import SysReservationConfigAddForm from '@/views/system/sysreservationconfig/modules/SysReservationConfigAddForm'
+import SysReservationConfigEditForm from '@/views/system/sysreservationconfig/modules/SysReservationConfigEditForm'
+import SysReservationConfigBatchAddForm from '@/views/system/sysreservationconfig/modules/SysReservationConfigBatchAddForm'
+export default {
+  name: 'SysReservationConfig',
+  components: {
+    AdvanceTable,
+    SysReservationConfigAddForm,
+    SysReservationConfigEditForm,
+    SysReservationConfigBatchAddForm
+  },
+  data () {
+    return {
+      showBatchAddModal: false,
+      showAddModal: false,
+      showEditModal: false,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 选中的主键集合
+      selectedRowKeys: [],
+      // 选中的数据集合
+      selectedRows: [],
+      // 高级搜索 展开/关闭
+      advanced: false,
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 总条数
+      total: 0,
+      // label的百分比
+      labelCol: { span: 6 },
+      // 内容区域的百分比
+      wrapperCol: { span: 18 },
+      // 预约配置表格数据
+      sysReservationConfigList: [],
+      // 配置状态 0 保存 1 发布字典
+      statusOptions: [],
+      // 查询参数
+      queryParam: {
+        pageNum: 1,
+        pageSize: 10,
+        orderByColumn: 'reservation_start_time'
+      },
+      columns: [
+        {
+          title: '预约日期',
+          dataIndex: 'reservationDate',
+          align: 'center',
+          width: '18%'
+        },
+        {
+          title: '预约开始时段',
+          dataIndex: 'reservationStartTime',
+          align: 'center',
+          width: '18%'
+        },
+        {
+          title: '预约结束时段',
+          dataIndex: 'reservationEndTime',
+          align: 'center',
+          width: '18%'
+        },
+        {
+          title: '可预约人数',
+          dataIndex: 'enableNum',
+          align: 'center',
+          width: '18%'
+        },
+        {
+          title: '配置状态',
+          dataIndex: 'status',
+          scopedSlots: { customRender: 'statusRender' },
+          align: 'center',
+          width: '18%'
+        },
+        {
+          title: '操作',
+          dataIndex: 'operation',
+          align: 'center',
+          width: '10%',
+          scopedSlots: { customRender: 'operation' }
+        }
+      ]
+    }
+  },
+  created () {
+    this.getList()
+    getInitData('sys_reservation_status').then(response => {
+      this.statusOptions = response.data.sys_normal_disable
+    })
+  },
+  methods: {
+    /** 查询预约配置列表 */
+    getList () {
+      this.loading = true
+      listSysReservationConfig(this.queryParam).then(response => {
+        this.sysReservationConfigList = response.data.list
+        this.total = response.data.total
+        this.loading = false
+      })
+    },
+    // 配置状态 0 保存 1 发布字典翻译
+    statusFormat (row) {
+      return this.selectDictLabel(this.statusOptions, row.status)
+    },
+    /** 搜索按钮操作 */
+    handleQuery () {
+      this.queryParam.pageNum = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery () {
+      this.queryParam = {
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.handleQuery()
+    },
+    /** 翻页操作 */
+    onShowSizeChange (current, pageSize) {
+      this.queryParam.pageSize = pageSize
+      this.getList()
+    },
+    /** 翻页操作 */
+    onSizeChange (current, size) {
+      this.queryParam.pageNum = 1
+      this.queryParam.pageSize = size
+      this.getList()
+    },
+    /** 翻页操作 */
+    changeSize (current, pageSize) {
+      this.queryParam.pageNum = current
+      this.queryParam.pageSize = pageSize
+      this.getList()
+    },
+    /** 翻页操作 */
+    onSelectChange (selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRows = selectedRows
+      this.ids = this.selectedRows.map(item => item.id)
+      this.single = selectedRowKeys.length !== 1
+      this.multiple = !selectedRowKeys.length
+    },
+    /** 查询折叠和展开操作 */
+    toggleAdvanced () {
+      this.advanced = !this.advanced
+    },
+    handleAdd () {
+      this.showAddModal = true
+      this.$nextTick(() => (
+        this.$refs.sysReservationConfigAddForm.handleAdd()
+      ))
+    },
+    handleBatchAdd() {
+      this.showBatchAddModal = true
+      this.$nextTick(() => (
+        this.$refs.sysReservationConfigBatchAddForm.handleAdd()
+      ))
+    },
+    handleUpdate (record, ids) {
+      this.showEditModal = true
+      this.$nextTick(() => (
+        this.$refs.sysReservationConfigEditForm.handleUpdate(record, ids)
+      ))
+    },
+    /** 删除按钮操作 */
+    handleDelete (row) {
+      var that = this
+      const sysReservationConfigIds = row.id || this.ids
+      this.$confirm({
+        title: '确认删除所选中数据?',
+        onOk () {
+          return delSysReservationConfig(sysReservationConfigIds)
+            .then(() => {
+              that.onSelectChange([], [])
+              that.getList()
+              that.$message.success(
+                '删除成功',
+                3
+              )
+          })
+        },
+        onCancel () {}
+      })
+    },
+    /** 导出按钮操作 */
+    handleExport () {
+      var that = this
+      this.$confirm({
+        title: '是否确认导出?',
+        content: '此操作将导出当前条件下所有数据而非选中数据',
+        onOk () {
+          return exportSysReservationConfig(that.queryParam)
+            .then(response => {
+              that.download(response.msg)
+              that.$message.success(
+                '导出成功',
+                3
+              )
+          })
+        },
+        onCancel () {}
+      })
+    },
+    handleTableChange (pagination, filters, sorter) {
+      if (sorter.field !== undefined && sorter.field !== null && sorter.field !== '') {
+        this.queryParam.orderByColumn = 'a.' + sorter.field
+        this.queryParam.isAsc = sorter.order
+      }
+      this.getList()
+    }
+  }
+}
+</script>

+ 80 - 0
aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigAddForm.vue

@@ -0,0 +1,80 @@
+<template>
+  <ant-modal
+    modalWidth="576"
+    modalHeight="500"
+    :visible="open"
+    :modal-title="formTitle"
+    :adjust-size="true"
+    @cancel="cancel"
+  >
+    <a-form-model ref="form" :model="form" :rules="rules" slot="content" layout="vertical">
+      <a-row :gutter="32">
+        <a-col :span="12">
+          <a-form-model-item label="预约日期" prop="reservationDate">
+            <a-date-picker
+              v-model="form.reservationDate"
+              valueFormat="YYYY-MM-DD"
+              :show-today="true"
+              placeholder="选择日期"
+              style="width: 100%"
+            />
+          </a-form-model-item>
+        </a-col>
+        <a-col :span="12">
+          <a-form-model-item label="预约开始时段" prop="reservationStartTime">
+            <a-date-picker
+              v-model="form.reservationStartTime"
+              valueFormat="YYYY-MM-DD"
+              :show-today="true"
+              placeholder="选择日期"
+              style="width: 100%"
+            />
+          </a-form-model-item>
+        </a-col>
+        <a-col :span="12">
+          <a-form-model-item label="预约结束时段" prop="reservationEndTime">
+            <a-date-picker
+              v-model="form.reservationEndTime"
+              valueFormat="YYYY-MM-DD"
+              :show-today="true"
+              placeholder="选择日期"
+              style="width: 100%"
+            />
+          </a-form-model-item>
+        </a-col>
+        <a-col :span="12">
+          <a-form-model-item label="可预约人数" prop="enableNum">
+            <a-input-number v-model="form.enableNum" :min="0" style="width: 100%"/>
+          </a-form-model-item>
+        </a-col>
+        <a-col :span="12" >
+          <a-form-model-item label="配置状态 0 保存 1 发布" prop="status">
+            <a-radio-group v-model="form.status">
+              <a-radio
+                v-for="(dict, index) in statusOptions"
+                :key="index"
+                :value="dict.dictValue"
+              >
+                {{ dict.dictLabel }}
+              </a-radio>
+            </a-radio-group>
+          </a-form-model-item>
+        </a-col>
+      </a-row>
+    </a-form-model>
+    <template slot="footer">
+      <a-button :disabled="disabled" @click="cancel">
+        取消
+      </a-button>
+      <a-button type="primary" :disabled="disabled" @click="submitForm(true)">
+        保存
+      </a-button>
+    </template>
+  </ant-modal>
+</template>
+<script>
+import SysReservationConfigAddForm from './SysReservationConfigForm'
+export default {
+  ...SysReservationConfigAddForm
+}
+</script>

+ 47 - 0
aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigBatchAddForm.vue

@@ -0,0 +1,47 @@
+<template>
+  <ant-modal
+    modalWidth="576"
+    modalHeight="500"
+    :visible="open"
+    :modal-title="formTitle"
+    :adjust-size="true"
+    @cancel="cancel"
+  >
+    <a-form-model ref="batchForm" :model="batchForm" :rules="batchAddRules" slot="content" layout="vertical">
+      <a-row :gutter="32">
+        <a-col :span="24">
+          <a-form-model-item label="预约日期" prop="dateRange">
+            <a-range-picker style="width: 100%" v-model="batchForm.dateRange" valueFormat="YYYY-MM-DD" format="YYYY-MM-DD" allow-clear/>
+          </a-form-model-item>
+        </a-col>
+        <a-col :span="12">
+          <a-form-model-item label="班次时长" prop="duration">
+            <a-input-number placeholder="请输入班次时长(分钟)" v-model="batchForm.duration" :min="0" style="width: 100%"/>
+          </a-form-model-item>
+        </a-col>
+        <a-col :span="12">
+          <a-form-model-item label="可预约人数" prop="enableNum">
+            <a-input-number placeholder="请输入可预约人数" v-model="batchForm.enableNum" :min="0" style="width: 100%"/>
+          </a-form-model-item>
+        </a-col>
+      </a-row>
+    </a-form-model>
+    <template slot="footer">
+      <a-button :disabled="disabled" @click="cancel">
+        取消
+      </a-button>
+      <a-button type="primary" :disabled="disabled" @click="batchSave(true, 0)">
+        保存
+      </a-button>
+      <a-button type="primary" :disabled="disabled" @click="batchSave(true, 1)">
+        保存并发布
+      </a-button>
+    </template>
+  </ant-modal>
+</template>
+<script>
+import SysReservationConfigAddForm from './SysReservationConfigForm'
+export default {
+  ...SysReservationConfigAddForm
+}
+</script>

+ 84 - 0
aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigEditForm.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    width="576"
+    :title="formTitle"
+    :label-col="4"
+    :wrapper-col="14"
+    :visible="open"
+    :body-style="{height:'calc(100vh - 100px)',overflow:'auto'}"
+    @close="cancel">
+    <a-form-model ref="form" :model="form" :rules="rules" layout="vertical">
+      <a-spin :spinning="spinning" :delay="delayTime" tip="Loading...">
+        <a-row :gutter="32">
+          <a-col :span="12">
+            <a-form-model-item label="预约日期" prop="reservationDate">
+              <a-date-picker
+                v-model="form.reservationDate"
+                valueFormat="YYYY-MM-DD"
+                :show-today="true"
+                placeholder="选择日期"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="预约开始时段" prop="reservationStartTime">
+              <a-date-picker
+                v-model="form.reservationStartTime"
+                valueFormat="YYYY-MM-DD"
+                :show-today="true"
+                placeholder="选择日期"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="预约结束时段" prop="reservationEndTime">
+              <a-date-picker
+                v-model="form.reservationEndTime"
+                valueFormat="YYYY-MM-DD"
+                :show-today="true"
+                placeholder="选择日期"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="可预约人数" prop="enableNum">
+              <a-input-number v-model="form.enableNum" :min="0" style="width: 100%"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12" >
+            <a-form-model-item label="配置状态 0 保存 1 发布" prop="status">
+              <a-radio-group v-model="form.status">
+                <a-radio
+                  v-for="(dict, index) in statusOptions"
+                  :key="index"
+                  :value="dict.dictValue"
+                >
+                  {{ dict.dictLabel }}
+                </a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-spin>
+      <div class="bottom-control">
+        <a-space>
+          <a-button :disabled="disabled" @click="cancel">
+            取消
+          </a-button>
+          <a-button type="primary" :disabled="disabled" @click="submitForm(true)">
+            保存
+          </a-button>
+        </a-space>
+      </div>
+    </a-form-model>
+  </a-drawer>
+</template>
+<script>
+import SysReservationConfigEditForm from './SysReservationConfigForm'
+export default {
+  ...SysReservationConfigEditForm
+}
+</script>

+ 158 - 0
aidex-ui/src/views/system/sysreservationconfig/modules/SysReservationConfigForm.js

@@ -0,0 +1,158 @@
+import AntModal from '@/components/pt/dialog/AntModal'
+import { getSysReservationConfig, addSysReservationConfig, updateSysReservationConfig, batchAddSysReservationConfig } from '@/api/system/sysReservationConfig'
+
+export default {
+  name: 'CreateForm',
+  props: {
+    statusOptions: {
+      type: Array,
+      required: true
+    }
+  },
+  components: {
+    AntModal
+  },
+  data () {
+    return {
+      open: false,
+      closeDialog: true,
+      spinning: false,
+      delayTime: 100,
+      labelCol: { span: 4 },
+      wrapperCol: { span: 14 },
+      loading: false,
+      disabled: false,
+      total: 0,
+      id: undefined,
+      formTitle: '预约配置',
+      // 表单参数
+      form: {},
+      batchForm: {
+        dateRange: []
+      },
+      rules: {
+        reservationDate: [{ required: true, message: '预约日期不能为空', trigger: 'blur' }],
+        reservationStartTime: [{ required: true, message: '预约开始时段不能为空', trigger: 'blur' }],
+        reservationEndTime: [{ required: true, message: '预约结束时段不能为空', trigger: 'blur' }],
+        enableNum: [{ required: true, message: '可预约人数不能为空', trigger: 'blur' }]
+      },
+      batchAddRules: {
+        dateRange: [{ required: true, message: '预约日期不能为空', trigger: 'blur' }],
+        duration: [{ required: true, message: '班次时长不能为空', trigger: 'blur' }],
+        enableNum: [{ required: true, message: '可预约人数不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  filters: {},
+  created () {},
+  computed: {},
+  watch: {},
+  mounted () {},
+  methods: {
+    onClose () {
+      this.open = false
+      this.reset()
+      this.$emit('close')
+    },
+    // 取消按钮
+    cancel () {
+      this.open = false
+      this.reset()
+      this.$emit('close')
+    },
+    // 表单重置
+    reset () {
+      this.form = {
+        id: undefined,
+        reservationDate: undefined,
+
+        reservationStartTime: undefined,
+
+        reservationEndTime: undefined,
+
+        enableNum: undefined,
+
+        status: '0'
+
+      }
+    },
+    /** 新增按钮操作 */
+    handleAdd () {
+      this.reset()
+      this.open = true
+      this.formTitle = '预约配置'
+    },
+    /** 修改按钮操作 */
+    handleUpdate (row) {
+      this.reset()
+      this.open = true
+      this.spinning = !this.spinning
+      const sysReservationConfigId = row.id
+      getSysReservationConfig(sysReservationConfigId).then(response => {
+        this.form = response.data
+        this.formTitle = '修改预约配置'
+        this.spinning = !this.spinning
+      })
+    },
+    batchSave: function (closeDialog, status) {
+      this.closeDialog = closeDialog
+      this.disabled = true
+      this.$refs.batchForm.validate(valid => {
+        if (valid) {
+          const saveForm = {
+            startDate: this.batchForm.dateRange[0],
+            endDate: this.batchForm.dateRange[1],
+            duration: this.batchForm.duration,
+            enableNum: this.batchForm.enableNum,
+            status: status
+          }
+          batchAddSysReservationConfig(saveForm).then(response => {
+            this.$message.success('配置成功', 3)
+            this.open = false
+            this.$emit('ok')
+            this.$emit('close')
+            this.disabled = false
+          })
+        } else {
+          this.disabled = false
+          return false
+        }
+      })
+    },
+    /** 提交按钮 */
+    submitForm: function (closeDialog) {
+      this.closeDialog = closeDialog
+      this.disabled = true
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          const saveForm = JSON.parse(JSON.stringify(this.form))
+          if (this.form.id !== undefined) {
+            updateSysReservationConfig(saveForm).then(response => {
+              this.$message.success('更新成功', 3)
+              this.open = false
+              this.$emit('ok')
+              this.$emit('close')
+              this.disabled = false
+            })
+          } else {
+            addSysReservationConfig(saveForm).then(response => {
+              this.$message.success('新增成功', 3)
+              this.open = false
+              this.$emit('ok')
+              this.$emit('close')
+              this.disabled = false
+            })
+          }
+        } else {
+          this.disabled = false
+          return false
+        }
+      })
+    },
+    back () {
+      const index = '/system/sysreservationconfig/index'
+      this.$router.push(index)
+    }
+
+  }
+}

+ 176 - 0
aidex-ui/src/views/system/sysreservationconfig/statisc.vue

@@ -0,0 +1,176 @@
+<template>
+  <div>
+    <a-card :bordered="false" style="margin-bottom: 10px;">
+      <!-- 条件搜索 -->
+      <div class="table-page-search-wrapper">
+        <a-form :labelCol="labelCol" :wrapperCol="wrapperCol" ref="queryForm">
+          <a-row :gutter="32">
+            <a-col :span="6" >
+              <a-form-item label="日期">
+                <a-date-picker
+                  v-model="queryParam.date"
+                  valueFormat="YYYY-MM-DD"
+                  :show-today="true"
+                  placeholder="选择日期"
+                  style="width: 100%"
+                />
+              </a-form-item>
+            </a-col>
+            <a-col>
+              <span class="table-page-search-submitButtons" style="float: right;">
+                <a-button type="primary" @click="queryData()"><a-icon type="search" />查询</a-button>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+    </a-card>
+    <a-card :bordered="false" class="table-card" v-if="tableShow">
+      <advance-table
+        id="table-1"
+        title="预约统计"
+        tableKey="base-sysReservationConfig-statisc-table"
+        rowKey="wharfName"
+        size="middle"
+        @refresh="getList"
+        :columns="columns"
+        :data-source="listData"
+        :loading="loading"
+        :format-conditions="true"
+      >
+        <div class="table-operations" slot="button">
+          <a-button type="danger" @click="printData()">
+            <a-icon type="delete" />打印
+          </a-button>
+          <a-button type="" @click="doExport()" >
+            <a-icon type="download" />导出
+          </a-button>
+        </div>
+      </advance-table>
+    </a-card>
+  </div>
+</template>
+
+<script>
+/* eslint-disable */
+import {  statiscData, statiscColumns } from '@/api/system/sysReservationConfig'
+import AdvanceTable from '@/components/pt/table/AdvanceTable.vue'
+import { parseTime } from '@/utils/aidex'
+import printJS from 'print-js'
+import * as XLSX from "xlsx";
+import FileSaver from 'file-saver';
+
+export default {
+  name: 'RouterLine',
+  components: {
+    AdvanceTable
+  },
+  data() {
+    return {
+      // label的百分比
+      labelCol: { span: 6 },
+      // 内容区域的百分比
+      wrapperCol: { span: 18 },
+      columns: [
+        {
+          title: '日期',
+          dataIndex: 'date',
+          align: 'center',
+          width: '120px'
+        },
+        {
+          title: '码头',
+          dataIndex: 'wharfName',
+          align: 'center',
+          width: '180px'
+        }
+      ],
+      listData: [],
+      loading: false,
+      tableShow: false,
+      queryParam: {
+        date:  parseTime(new Date(), '{y}-{m}-{d}')
+      }
+    }
+  },
+  filters: {
+  },
+  mounted() {
+    this.getColumn()
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    getList () {
+      this.loading = true
+      this.tableShow = false
+      statiscData(this.queryParam).then(response => {
+        this.listData = response.data
+        this.loading = false
+        this.$nextTick(() => {
+          this.tableShow = true
+        })
+      })
+    },
+     getColumn() {
+        statiscColumns(this.queryParam).then(response => {
+         response.data.forEach(item => {
+           this.columns.push({
+             title: item,
+             dataIndex: item,
+             align: 'center',
+             visible: true
+           })
+         })
+         console.log(this.columns)
+       })
+     },
+     queryData() {
+      this.columns = [{
+        title: '日期',
+        dataIndex: 'date',
+        align: 'center',
+        width: '120px'
+      }, {
+        title: '码头',
+        dataIndex: 'wharfName',
+        align: 'center',
+        width: '180px'
+      }]
+       this.getColumn()
+       this.getList()
+     },
+      printData(){
+        const pro = [ { field: 'date', displayName: '日期' },{ field: 'wharfName', displayName: '码头' }]
+        this.columns.forEach(item =>{
+          if (item.dataIndex !== 'date' && item.dataIndex !== 'wharfName'){
+            pro.push({ field: item.dataIndex, displayName: item.dataIndex })
+          }
+        })
+        printJS({
+          printable: this.listData,
+          properties: pro,
+          type: 'json',
+          maxWidth: 1150,
+          gridHeaderStyle: 'border: 1px solid #000;text-align:center',
+          gridStyle: 'border: 1px solid #000;text-align:center'
+      })
+    },
+    doExport() {
+      console.log(this.listData)
+      let header = { }
+      this.columns.forEach(item =>{
+        header[item.dataIndex] = item.title
+      })
+      const alldata = [header, ...this.listData]
+      const fileName = '预约统计数据_' + new Date().getTime()
+      const worksheet = XLSX.utils.json_to_sheet(alldata, { header: ["date", "wharfName"], skipHeader: true})
+      const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] }
+      const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' })
+      const datas = new Blob([excelBuffer], { type: 'application/octet-stream;charset=utf-8' })
+      FileSaver.saveAs(datas, `${fileName}.xlsx`)
+    }
+ }
+}
+</script>