liangwenxuan 1 ay önce
ebeveyn
işleme
aa0147afc6
13 değiştirilmiş dosya ile 98 ekleme ve 84 silme
  1. 11 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/JiashuVisitAppointmentController.java
  2. 9 7
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/AppAppointmentQuotaController.java
  3. 4 4
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaOccupyReqVO.java
  4. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaOccupyRespVO.java
  5. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaQueryReqVO.java
  6. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaQueryRespVO.java
  7. 6 6
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/miniapp/JiashuVisitAppointmentMapper.java
  8. 12 12
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/appointment/AppointmentQuotaRedisDAO.java
  9. 5 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/appointment/AppAppointmentQuotaService.java
  10. 22 22
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/appointment/AppAppointmentQuotaServiceImpl.java
  11. 6 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/miniapp/JiashuVisitAppointmentService.java
  12. 19 20
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/miniapp/JiashuVisitAppointmentServiceImpl.java
  13. 1 0
      yudao-server/src/main/resources/application.yaml

+ 11 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/JiashuVisitAppointmentController.java

@@ -1,16 +1,21 @@
 package cn.iocoder.yudao.module.system.controller.admin.biz;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.date.DateUtils;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.VisitAppointmentCountRespVO;
 import cn.iocoder.yudao.module.system.service.miniapp.JiashuVisitAppointmentService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
+import java.time.LocalDate;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -28,9 +33,12 @@ public class JiashuVisitAppointmentController {
     private JiashuVisitAppointmentService jiashuVisitAppointmentService;
 
     @GetMapping("/count")
-    @Operation(summary = "获取当日、当周、当月的预约参观数量")
-    public CommonResult<VisitAppointmentCountRespVO> count(@RequestParam(name = "tenantId") Long tenantId) {
-        return success(jiashuVisitAppointmentService.getVisitCount(tenantId));
+    @Operation(summary = "获取指定日期的当日、当周、当月的预约参观数量")
+    @PermitAll
+    @TenantIgnore
+    public CommonResult<VisitAppointmentCountRespVO> count(@RequestParam(name = "tenantId") Long tenantId,
+                                                          @RequestParam(name = "date") @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY) LocalDate date) {
+        return success(jiashuVisitAppointmentService.getVisitCount(tenantId, date));
     }
 
 }

+ 9 - 7
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/appointment/AppAppointmentQuotaController.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/AppAppointmentQuotaController.java

@@ -1,11 +1,13 @@
-package cn.iocoder.yudao.module.system.controller.app.appointment;
+package cn.iocoder.yudao.module.system.controller.admin.biz.appointment;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import javax.annotation.security.PermitAll;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaOccupyReqVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaOccupyRespVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaQueryReqVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaQueryRespVO;
+
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaOccupyReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaOccupyRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaQueryReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaQueryRespVO;
 import cn.iocoder.yudao.module.system.service.appointment.AppAppointmentQuotaService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,14 +25,14 @@ import java.util.List;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 /**
- * 用户 App - 预约名额预占
+ * 管理后台 - 预约名额预占
  *
  * <p>前端在真正调用预约接口前,先调用 {@code /occupy} 校验名额并占用,避免并发超卖;
  * 校验通过后前端再调用实际预约接口完成入库。</p>
  *
  * @author system
  */
-@Tag(name = "用户 App - 预约名额预占")
+@Tag(name = "管理后台 - 预约名额预占")
 @RestController
 @RequestMapping("/system/appointment-quota")
 @Validated

+ 4 - 4
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/appointment/vo/AppointmentQuotaOccupyReqVO.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaOccupyReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.controller.app.appointment.vo;
+package cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -34,9 +34,9 @@ public class AppointmentQuotaOccupyReqVO {
     @NotEmpty(message = "预约结束时间不能为空")
     private String visitEndTime;
 
-    @Schema(description = "访客微信 openId(用于单人名额限制)", requiredMode = Schema.RequiredMode.REQUIRED, example = "oUpF8uxxxx")
-    @NotEmpty(message = "访客 openId 不能为空")
-    private String visitorOpenId;
+    @Schema(description = "预约人手机号(用于单人名额限制)", requiredMode = Schema.RequiredMode.REQUIRED, example = "13800138000")
+    @NotEmpty(message = "预约人手机号不能为空")
+    private String phone;
 
     @Schema(description = "随行人数", example = "0")
     private Integer accompanyNum;

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/appointment/vo/AppointmentQuotaOccupyRespVO.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaOccupyRespVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.controller.app.appointment.vo;
+package cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/appointment/vo/AppointmentQuotaQueryReqVO.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaQueryReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.controller.app.appointment.vo;
+package cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/appointment/vo/AppointmentQuotaQueryRespVO.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/appointment/vo/AppointmentQuotaQueryRespVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.controller.app.appointment.vo;
+package cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;

+ 6 - 6
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/miniapp/JiashuVisitAppointmentMapper.java

@@ -42,18 +42,18 @@ public interface JiashuVisitAppointmentMapper extends BaseMapperX<JiashuVisitApp
     }
 
     /**
-     * 统计指定访客在指定日期范围内的预约数量(status in 1,3)
+     * 统计指定预约人手机号在指定日期范围内的预约数量(status in 1,3)
      * <p>
      * 注意:visit_appointment 位于 yanglao-jiashu 数据源,调用方需自行切换 @DS("miniapp")
      *
-     * @param visitorOpenId 访客微信 openId
-     * @param startDate     开始日期(含)
-     * @param endDate       结束日期(含)
+     * @param phone      预约人手机号
+     * @param startDate  开始日期(含)
+     * @param endDate    结束日期(含)
      * @return 预约数量
      */
-    default Long countByOpenIdAndDateRange(String visitorOpenId, LocalDate startDate, LocalDate endDate) {
+    default Long countByPhoneAndDateRange(String phone, LocalDate startDate, LocalDate endDate) {
         return selectCount(new LambdaQueryWrapperX<JiashuVisitAppointmentDO>()
-                .eq(JiashuVisitAppointmentDO::getVisitorOpenId, visitorOpenId)
+                .eq(JiashuVisitAppointmentDO::getVisitorPhone, phone)
                 .between(JiashuVisitAppointmentDO::getVisitDate, startDate, endDate)
                 .in(JiashuVisitAppointmentDO::getStatus, 1, 3));
     }

+ 12 - 12
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/appointment/AppointmentQuotaRedisDAO.java

@@ -45,16 +45,16 @@ public class AppointmentQuotaRedisDAO {
         return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_TOTAL_MONTHLY, tenantId, fmtMonth(date));
     }
 
-    public String formatPersonDailyKey(Long tenantId, String openId, LocalDate date) {
-        return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_PERSON_DAILY, tenantId, openId, fmtDate(date));
+    public String formatPersonDailyKey(Long tenantId, String phone, LocalDate date) {
+        return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_PERSON_DAILY, tenantId, phone, fmtDate(date));
     }
 
-    public String formatPersonWeeklyKey(Long tenantId, String openId, LocalDate date) {
-        return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_PERSON_WEEKLY, tenantId, openId, fmtWeek(date));
+    public String formatPersonWeeklyKey(Long tenantId, String phone, LocalDate date) {
+        return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_PERSON_WEEKLY, tenantId, phone, fmtWeek(date));
     }
 
-    public String formatPersonMonthlyKey(Long tenantId, String openId, LocalDate date) {
-        return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_PERSON_MONTHLY, tenantId, openId, fmtMonth(date));
+    public String formatPersonMonthlyKey(Long tenantId, String phone, LocalDate date) {
+        return String.format(RedisKeyConstants.APPOINTMENT_QUOTA_PERSON_MONTHLY, tenantId, phone, fmtMonth(date));
     }
 
     public String formatGroupDailyKey(Long groupId, LocalDate date) {
@@ -75,16 +75,16 @@ public class AppointmentQuotaRedisDAO {
         return incr(formatTotalMonthlyKey(tenantId, date), date.withDayOfMonth(date.lengthOfMonth()).plusDays(1), delta);
     }
 
-    public long incrPersonDaily(Long tenantId, String openId, LocalDate date, int delta) {
-        return incr(formatPersonDailyKey(tenantId, openId, date), date.plusDays(1), delta);
+    public long incrPersonDaily(Long tenantId, String phone, LocalDate date, int delta) {
+        return incr(formatPersonDailyKey(tenantId, phone, date), date.plusDays(1), delta);
     }
 
-    public long incrPersonWeekly(Long tenantId, String openId, LocalDate date, int delta) {
-        return incr(formatPersonWeeklyKey(tenantId, openId, date), date.with(DayOfWeek.SUNDAY).plusDays(1), delta);
+    public long incrPersonWeekly(Long tenantId, String phone, LocalDate date, int delta) {
+        return incr(formatPersonWeeklyKey(tenantId, phone, date), date.with(DayOfWeek.SUNDAY).plusDays(1), delta);
     }
 
-    public long incrPersonMonthly(Long tenantId, String openId, LocalDate date, int delta) {
-        return incr(formatPersonMonthlyKey(tenantId, openId, date), date.withDayOfMonth(date.lengthOfMonth()).plusDays(1), delta);
+    public long incrPersonMonthly(Long tenantId, String phone, LocalDate date, int delta) {
+        return incr(formatPersonMonthlyKey(tenantId, phone, date), date.withDayOfMonth(date.lengthOfMonth()).plusDays(1), delta);
     }
 
     public long incrGroupDaily(Long groupId, LocalDate date, int delta) {

+ 5 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/appointment/AppAppointmentQuotaService.java

@@ -1,9 +1,9 @@
 package cn.iocoder.yudao.module.system.service.appointment;
 
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaOccupyReqVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaOccupyRespVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaQueryReqVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaQueryRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaOccupyReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaOccupyRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaQueryReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaQueryRespVO;
 
 /**
  * 预约名额预占 Service
@@ -17,7 +17,7 @@ public interface AppAppointmentQuotaService {
     /**
      * 校验预约名额并预占:结合预约配置与预约组进行校验,全部通过后各维度 Redis +1(预占),返回命中的预约组
      *
-     * @param reqVO 预占请求(机构、预约日期、开始/结束时间、访客 openId
+     * @param reqVO 预占请求(机构、预约日期、开始/结束时间、预约人手机号
      * @return 预占结果(含命中的预约组 id),成功方可继续调实际预约接口
      */
     AppointmentQuotaOccupyRespVO occupy(AppointmentQuotaOccupyReqVO reqVO);

+ 22 - 22
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/appointment/AppAppointmentQuotaServiceImpl.java

@@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.system.service.appointment;
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.AppointmentConfigRespVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaOccupyReqVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaOccupyRespVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaQueryReqVO;
-import cn.iocoder.yudao.module.system.controller.app.appointment.vo.AppointmentQuotaQueryRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaOccupyReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaOccupyRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaQueryReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.appointment.vo.AppointmentQuotaQueryRespVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.biz.AppointmentConfigDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.biz.AppointmentGroupDO;
 import cn.iocoder.yudao.module.system.dal.mysql.miniapp.JiashuVisitAppointmentMapper;
@@ -68,7 +68,7 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
     public AppointmentQuotaOccupyRespVO occupy(AppointmentQuotaOccupyReqVO reqVO) {
         Long tenantId = reqVO.getOrgId();
         LocalDate visitDate = reqVO.getVisitDate();
-        String openId = reqVO.getVisitorOpenId();
+        String phone = reqVO.getPhone();
 
         // 1. 配置存在 & 开关
         AppointmentConfigRespVO configResp = appointmentConfigService.getByTenant(tenantId);
@@ -106,7 +106,7 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
         // 4. 总名额(daily / weekly / monthly)
         checkTotalLimit(config, tenantId, visitDate);
         // 5. 单人名额(daily / weekly / monthly)
-        checkPersonLimit(config, tenantId, openId, visitDate);
+        checkPersonLimit(config, tenantId, phone, visitDate);
         // 6. 组名额(每组每天 limitCount)
         checkGroupLimit(matchedGroup, visitDate);
 
@@ -114,9 +114,9 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
         appointmentQuotaRedisDAO.incrTotalDaily(tenantId, visitDate, OCCUPY_COUNT);
         appointmentQuotaRedisDAO.incrTotalWeekly(tenantId, visitDate, OCCUPY_COUNT);
         appointmentQuotaRedisDAO.incrTotalMonthly(tenantId, visitDate, OCCUPY_COUNT);
-        appointmentQuotaRedisDAO.incrPersonDaily(tenantId, openId, visitDate, OCCUPY_COUNT);
-        appointmentQuotaRedisDAO.incrPersonWeekly(tenantId, openId, visitDate, OCCUPY_COUNT);
-        appointmentQuotaRedisDAO.incrPersonMonthly(tenantId, openId, visitDate, OCCUPY_COUNT);
+        appointmentQuotaRedisDAO.incrPersonDaily(tenantId, phone, visitDate, OCCUPY_COUNT);
+        appointmentQuotaRedisDAO.incrPersonWeekly(tenantId, phone, visitDate, OCCUPY_COUNT);
+        appointmentQuotaRedisDAO.incrPersonMonthly(tenantId, phone, visitDate, OCCUPY_COUNT);
         appointmentQuotaRedisDAO.incrGroupDaily(matchedGroup.getId(), visitDate, OCCUPY_COUNT);
 
         return AppointmentQuotaOccupyRespVO.success(matchedGroup.getId());
@@ -126,7 +126,7 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
     public void release(AppointmentQuotaOccupyReqVO reqVO) {
         Long tenantId = reqVO.getOrgId();
         LocalDate visitDate = reqVO.getVisitDate();
-        String openId = reqVO.getVisitorOpenId();
+        String phone = reqVO.getPhone();
 
         /*
          * release 调用时机:前端调 occupy 通过 → 调实际预约接口落库 → 立即调 release
@@ -141,9 +141,9 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
         appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatTotalDailyKey(tenantId, visitDate), OCCUPY_COUNT);
         appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatTotalWeeklyKey(tenantId, visitDate), OCCUPY_COUNT);
         appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatTotalMonthlyKey(tenantId, visitDate), OCCUPY_COUNT);
-        appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatPersonDailyKey(tenantId, openId, visitDate), OCCUPY_COUNT);
-        appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatPersonWeeklyKey(tenantId, openId, visitDate), OCCUPY_COUNT);
-        appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatPersonMonthlyKey(tenantId, openId, visitDate), OCCUPY_COUNT);
+        appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatPersonDailyKey(tenantId, phone, visitDate), OCCUPY_COUNT);
+        appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatPersonWeeklyKey(tenantId, phone, visitDate), OCCUPY_COUNT);
+        appointmentQuotaRedisDAO.decr(appointmentQuotaRedisDAO.formatPersonMonthlyKey(tenantId, phone, visitDate), OCCUPY_COUNT);
         // 注意:组维度不递减——visit_appointment 缺 groupId 无法从 DB 按组统计,Redis 即正式计数,到期自动释放
     }
 
@@ -220,24 +220,24 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
         }
     }
 
-    private void checkPersonLimit(AppointmentConfigDO config, Long tenantId, String openId, LocalDate date) {
+    private void checkPersonLimit(AppointmentConfigDO config, Long tenantId, String phone, LocalDate date) {
         if (config.getPersonDailyLimit() != null) {
-            Long db = countByOpenIdInMiniapp(openId, date, date);
-            Long redis = appointmentQuotaRedisDAO.getCount(appointmentQuotaRedisDAO.formatPersonDailyKey(tenantId, openId, date));
+            Long db = countByPhoneInMiniapp(phone, date, date);
+            Long redis = appointmentQuotaRedisDAO.getCount(appointmentQuotaRedisDAO.formatPersonDailyKey(tenantId, phone, date));
             if (db + redis >= config.getPersonDailyLimit()) {
                 throw exception(ErrorCodeConstants.APPOINTMENT_PERSON_LIMIT);
             }
         }
         if (config.getPersonWeeklyLimit() != null) {
-            Long db = countByOpenIdInMiniapp(openId, date.with(DayOfWeek.MONDAY), date.with(DayOfWeek.SUNDAY));
-            Long redis = appointmentQuotaRedisDAO.getCount(appointmentQuotaRedisDAO.formatPersonWeeklyKey(tenantId, openId, date));
+            Long db = countByPhoneInMiniapp(phone, date.with(DayOfWeek.MONDAY), date.with(DayOfWeek.SUNDAY));
+            Long redis = appointmentQuotaRedisDAO.getCount(appointmentQuotaRedisDAO.formatPersonWeeklyKey(tenantId, phone, date));
             if (db + redis >= config.getPersonWeeklyLimit()) {
                 throw exception(ErrorCodeConstants.APPOINTMENT_PERSON_LIMIT);
             }
         }
         if (config.getPersonMonthlyLimit() != null) {
-            Long db = countByOpenIdInMiniapp(openId, date.withDayOfMonth(1), date.withDayOfMonth(date.lengthOfMonth()));
-            Long redis = appointmentQuotaRedisDAO.getCount(appointmentQuotaRedisDAO.formatPersonMonthlyKey(tenantId, openId, date));
+            Long db = countByPhoneInMiniapp(phone, date.withDayOfMonth(1), date.withDayOfMonth(date.lengthOfMonth()));
+            Long redis = appointmentQuotaRedisDAO.getCount(appointmentQuotaRedisDAO.formatPersonMonthlyKey(tenantId, phone, date));
             if (db + redis >= config.getPersonMonthlyLimit()) {
                 throw exception(ErrorCodeConstants.APPOINTMENT_PERSON_LIMIT);
             }
@@ -267,10 +267,10 @@ public class AppAppointmentQuotaServiceImpl implements AppAppointmentQuotaServic
         }
     }
 
-    private Long countByOpenIdInMiniapp(String openId, LocalDate start, LocalDate end) {
+    private Long countByPhoneInMiniapp(String phone, LocalDate start, LocalDate end) {
         DynamicDataSourceContextHolder.push("miniapp");
         try {
-            return jiashuVisitAppointmentMapper.countByOpenIdAndDateRange(openId, start, end);
+            return jiashuVisitAppointmentMapper.countByPhoneAndDateRange(phone, start, end);
         } finally {
             DynamicDataSourceContextHolder.poll();
         }

+ 6 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/miniapp/JiashuVisitAppointmentService.java

@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.service.miniapp;
 
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.VisitAppointmentCountRespVO;
 
+import java.time.LocalDate;
+
 /**
  * 探访预约 Service(yanglao-jiashu 数据源)
  *
@@ -10,10 +12,12 @@ import cn.iocoder.yudao.module.system.controller.admin.biz.vo.VisitAppointmentCo
 public interface JiashuVisitAppointmentService {
 
     /**
-     * 获取当日、当周、当月的预约参观数量
+     * 获取指定日期的当日、当周、当月的预约参观数量
      *
+     * @param tenantId 租户/机构 id
+     * @param date     基准日期(前端传入),据此计算当日 / 当周 / 当月的预约数量
      * @return 当日 / 当周 / 当月的预约数量
      */
-    VisitAppointmentCountRespVO getVisitCount(Long tenantId);
+    VisitAppointmentCountRespVO getVisitCount(Long tenantId, LocalDate date);
 
 }

+ 19 - 20
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/miniapp/JiashuVisitAppointmentServiceImpl.java

@@ -23,40 +23,39 @@ public class JiashuVisitAppointmentServiceImpl implements JiashuVisitAppointment
     private JiashuVisitAppointmentMapper jiashuVisitAppointmentMapper;
 
     @Override
-    public VisitAppointmentCountRespVO getVisitCount(Long tenantId) {
+    public VisitAppointmentCountRespVO getVisitCount(Long tenantId, LocalDate date) {
+        // 前端未传日期时,默认以当天作为基准日期
+        LocalDate baseDate = date != null ? date : LocalDate.now();
         VisitAppointmentCountRespVO respVO = new VisitAppointmentCountRespVO();
-        respVO.setTodayCount(getTodayCount(tenantId));
-        respVO.setWeekCount(getWeekCount(tenantId));
-        respVO.setMonthCount(getMonthCount(tenantId));
+        respVO.setTodayCount(getTodayCount(tenantId, baseDate));
+        respVO.setWeekCount(getWeekCount(tenantId, baseDate));
+        respVO.setMonthCount(getMonthCount(tenantId, baseDate));
         return respVO;
     }
 
     /**
-     * 当日预约参观数量
+     * 当日预约参观数量(以传入的基准日期为准)
      */
-    private Long getTodayCount(Long tenantId) {
-        LocalDate today = LocalDate.now();
-        return jiashuVisitAppointmentMapper.countByVisitDateRange(today, today,tenantId);
+    private Long getTodayCount(Long tenantId, LocalDate baseDate) {
+        return jiashuVisitAppointmentMapper.countByVisitDateRange(baseDate, baseDate, tenantId);
     }
 
     /**
-     * 当周(周一至周日)预约参观数量
+     * 当周(周一至周日)预约参观数量(以传入的基准日期所在周为准)
      */
-    private Long getWeekCount(Long tenantId) {
-        LocalDate now = LocalDate.now();
-        LocalDate monday = now.with(DayOfWeek.MONDAY);
-        LocalDate sunday = now.with(DayOfWeek.SUNDAY);
-        return jiashuVisitAppointmentMapper.countByVisitDateRange(monday, sunday,tenantId);
+    private Long getWeekCount(Long tenantId, LocalDate baseDate) {
+        LocalDate monday = baseDate.with(DayOfWeek.MONDAY);
+        LocalDate sunday = baseDate.with(DayOfWeek.SUNDAY);
+        return jiashuVisitAppointmentMapper.countByVisitDateRange(monday, sunday, tenantId);
     }
 
     /**
-     * 当月(1号至月末)预约参观数量
+     * 当月(1号至月末)预约参观数量(以传入的基准日期所在月为准)
      */
-    private Long getMonthCount(Long tenantId) {
-        LocalDate now = LocalDate.now();
-        LocalDate firstDay = now.withDayOfMonth(1);
-        LocalDate lastDay = now.withDayOfMonth(now.lengthOfMonth());
-        return jiashuVisitAppointmentMapper.countByVisitDateRange(firstDay, lastDay,tenantId);
+    private Long getMonthCount(Long tenantId, LocalDate baseDate) {
+        LocalDate firstDay = baseDate.withDayOfMonth(1);
+        LocalDate lastDay = baseDate.withDayOfMonth(baseDate.lengthOfMonth());
+        return jiashuVisitAppointmentMapper.countByVisitDateRange(firstDay, lastDay, tenantId);
     }
 
 }

+ 1 - 0
yudao-server/src/main/resources/application.yaml

@@ -255,6 +255,7 @@ yudao:
       - /admin-api/elderly/askLeave/scanOut
       - /admin-api/elderly/askLeave/scanReturn
       - /admin-api/system/appointment-quota/query
+      - /admin-api/jiashu/visitAppointment/count
 #      - /admin-api/bpm/check-in-wait/create
     ignore-tables:
       - system_tenant