ソースを参照

feat: 打卡频次支持 多周期

shc 2 年 前
コミット
95288681b4

+ 50 - 29
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmUserSignServiceImpl.java

@@ -1,19 +1,3 @@
-/*
- *    Copyright (c) 2018-2025, hnqz All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: hnqz
- */
 package com.qunzhixinxi.hnqz.admin.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
@@ -23,7 +7,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qunzhixinxi.hnqz.admin.api.entity.WmTaskSubmissionRule;
-import com.qunzhixinxi.hnqz.admin.api.entity.WmTaskTypeSubCategory;
 import com.qunzhixinxi.hnqz.admin.api.vo.UserVO;
 import com.qunzhixinxi.hnqz.admin.config.UpmsConfig;
 import com.qunzhixinxi.hnqz.admin.entity.*;
@@ -39,11 +22,9 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.time.Duration;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalAdjusters;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -124,11 +105,11 @@ public class WmUserSignServiceImpl extends ServiceImpl<WmUserSignMapper, WmUserS
 		}
 		wmUserSign.setTaskTypeId(taskTypeId);
 
-		int dailyLimit = 0;
-		int eachLimit = 0;
-
 		List<WmTaskSubmissionRule.SubmissionRule> rules = wmTaskContentService.getTaskSubmissionRule(taskTypeId, tWmScorePackage.getRelatedService());
 
+		int dailyLimit = 0;
+		Map<String, Integer> eachLimitMap = new HashMap<>(2);
+
 		if (CollUtil.isNotEmpty(rules)) {
 			// 获取限制
 			for (int i = 0, size = rules.size(); i < size; i++) {
@@ -141,25 +122,65 @@ public class WmUserSignServiceImpl extends ServiceImpl<WmUserSignMapper, WmUserS
 
 				}
 				if (r.getManual().startsWith("同一个人")) {
-					Object o = r.getFrequency().get(0).get("quantity");
-					eachLimit = o instanceof String ? Integer.parseInt((String) o) : (int) o;
+
+					r.getFrequency().forEach(f -> {
+
+						// 获取数量
+						Object o = f.get("quantity");
+						int limit = o instanceof String ? Integer.parseInt((String) o) : (int) o;
+
+						// 获取单位
+						String timeUnit = (String) f.get("timeUnit");
+
+						// 同一个单位只记录最小的
+						Integer l1 = eachLimitMap.get(timeUnit);
+						if (l1 != null && l1 > limit) {
+							eachLimitMap.put(timeUnit, limit);
+						}
+					});
+
 				}
 			}
 		}
 
-		// 查询当天所有的记录
+		// 按照最大周期进行查询
 		LocalDateTime now = LocalDateTime.now();
+		LocalDateTime start;
+		boolean isMonth = false;
+		if (eachLimitMap.containsKey("MONTH")) {
+			start = now.minusDays(30L);
+			isMonth = true;
+		} else {
+			start = LocalDateTime.of(now.toLocalDate(), LocalTime.MIN);
+		}
+
 		List<WmUserSign> signs = this.list(Wrappers.<WmUserSign>lambdaQuery()
 				.eq(WmUserSign::getSignUserid, wmUserSign.getSignUserid())
 				.eq(WmUserSign::getTaskTypeId, taskTypeId)
-				.between(WmUserSign::getSignDate, LocalDateTime.of(now.toLocalDate(), LocalTime.MIN), LocalDateTime.of(now.toLocalDate(), LocalTime.MAX)));
+				.between(WmUserSign::getSignDate, start, now));
+
+
+		// 月度限制
+		if (isMonth) {
+			int monthLimit = eachLimitMap.get("MONTH");
+			if (monthLimit < signs.size()) {
+				log.warn("超过打卡每月限制:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
+				return R.failed("超过打卡每月限制");
+			}
+		}
+
+		// 获取当日的打卡记录
+		LocalDateTime begin = LocalDateTime.of(now.toLocalDate(), LocalTime.MIN);
+		List<WmUserSign> todaySign = signs.stream().filter(s -> s.getSignDate().isAfter(begin)).collect(Collectors.toList());
 
 		// 没有超过日打卡限制
-		if (dailyLimit > signs.size()) {
+		int todaySignQty = CollUtil.isNotEmpty(todaySign) ? todaySign.size() : 0;
+		if (dailyLimit > todaySignQty) {
 
-			Map<String, List<WmUserSign>> collect = signs.stream().collect(Collectors.groupingBy(WmUserSign::getSignEntId));
+			Map<String, List<WmUserSign>> collect = todaySign.stream().collect(Collectors.groupingBy(WmUserSign::getSignEntId));
 			List<WmUserSign> wmUserSigns = collect.get(wmUserSign.getSignEntId());
 			if (CollUtil.isNotEmpty(wmUserSigns)) {
+				int eachLimit = eachLimitMap.get("DAY");
 				if (wmUserSigns.size() < eachLimit) {
 
 					// 一个用户,在同一打卡地点,4小时内只能打卡一次