Эх сурвалжийг харах

feat: 打卡任务限制规则

shc 2 жил өмнө
parent
commit
4a59902ac2

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

@@ -106,18 +106,139 @@ public class WmUserSignServiceImpl extends ServiceImpl<WmUserSignMapper, WmUserS
 		}
 		wmUserSign.setTaskTypeId(taskTypeId);
 
-		// 一个用户,在同一打卡地点,4小时内只能打卡一次
-		int total = this.count(Wrappers.<WmUserSign>lambdaQuery()
-				.eq(WmUserSign::getSignUserid, wmUserSign.getSignUserid())
-				.eq(WmUserSign::getSignEntId, wmUserSign.getSignEntId())
-				.gt(WmUserSign::getSignDate, LocalDateTime.now().minus(4, ChronoUnit.HOURS)));
-		// 一个用户,半小时内只能打卡一次
-		int halfHourTotal = this.count(Wrappers.<WmUserSign>lambdaQuery()
-				.eq(WmUserSign::getSignUserid, wmUserSign.getSignUserid())
-				.gt(WmUserSign::getSignDate, LocalDateTime.now().minus(30, ChronoUnit.MINUTES)));
-		if (total != 0 || halfHourTotal != 0) {
-			log.warn("打卡间隔过短:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
-			return R.failed("打卡间隔过短");
+
+		if ("33".equals(taskTypeId)) {
+			// 一个用户,在同一打卡地点,4小时内只能打卡一次
+			int total = this.count(Wrappers.<WmUserSign>lambdaQuery()
+					.eq(WmUserSign::getSignUserid, wmUserSign.getSignUserid())
+					.eq(WmUserSign::getSignEntId, wmUserSign.getSignEntId())
+					.gt(WmUserSign::getSignDate, LocalDateTime.now().minus(4, ChronoUnit.HOURS)));
+			// 一个用户,半小时内只能打卡一次
+			int halfHourTotal = this.count(Wrappers.<WmUserSign>lambdaQuery()
+					.eq(WmUserSign::getSignUserid, wmUserSign.getSignUserid())
+					.gt(WmUserSign::getSignDate, LocalDateTime.now().minus(30, ChronoUnit.MINUTES)));
+			if (total != 0 || halfHourTotal != 0) {
+				log.warn("打卡间隔过短:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
+				return R.failed("打卡间隔过短");
+			}
+		} else {
+
+			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++) {
+					Map<String, Object> map = (Map<String, Object>) rules.get(i);
+					WmTaskSubmissionRule.SubmissionRule r = BeanUtil.mapToBean(map, WmTaskSubmissionRule.SubmissionRule.class, true, new CopyOptions());
+
+					if ("拜访次数上限".equals(r.getManual())) {
+						Object o = r.getFrequency().get(0).get("quantity");
+						dailyLimit = o instanceof String ? Integer.parseInt((String) o) : (int) o;
+
+					}
+					if (r.getManual().startsWith("同一个人")) {
+
+						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");
+
+							// 同一个单位只记录最小的
+							if (eachLimitMap.containsKey(timeUnit)) {
+								Integer l1 = eachLimitMap.get(timeUnit);
+								if (l1 != null && l1 > limit) {
+									eachLimitMap.put(timeUnit, limit);
+								}
+							} else {
+								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, start, now));
+
+
+			// 月度限制
+			if (isMonth) {
+
+				Map<String, List<WmUserSign>> collect = signs.stream().collect(Collectors.groupingBy(WmUserSign::getSignEntId));
+				List<WmUserSign> wmUserSigns = collect.get(wmUserSign.getSignEntId());
+				if (CollUtil.isNotEmpty(wmUserSigns)) {
+					int monthLimit = eachLimitMap.get("MONTH");
+					if (monthLimit <= wmUserSigns.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());
+
+			// 没有超过日打卡限制
+			int todaySignQty = CollUtil.isNotEmpty(todaySign) ? todaySign.size() : 0;
+			if (dailyLimit > todaySignQty) {
+
+				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小时内只能打卡一次
+						Optional<LocalDateTime> first = wmUserSigns.stream().map(WmUserSign::getSignDate).filter(sd -> Duration.between(sd, now).toMinutes() <= upmsConfig.getDurationLimit()).findFirst();
+
+						if (first.isPresent()) {
+							log.warn("打卡间隔过短:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
+							return R.failed("打卡间隔过短");
+						}
+
+						// 一个用户,半小时内只能打卡一次
+						Optional<LocalDateTime> first1 = signs.stream().map(WmUserSign::getSignDate).filter(sd -> Duration.between(sd, now).toMinutes() <= upmsConfig.getEachDurationLimit()).findFirst();
+
+						if (first1.isPresent()) {
+							log.warn("打卡间隔过短:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
+							return R.failed("打卡间隔过短");
+						}
+
+
+					} else {
+						log.warn("超过每个地点打卡每日限制:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
+						return R.failed("超过每个地点打卡每日限制");
+					}
+				}
+
+			} else {
+				log.warn("超过打卡每日总限制:{} {}", wmUserSign.getSignUserid(), wmUserSign.getSignEntName());
+				return R.failed("超过打卡每日总限制");
+			}
+
 		}
 
 		/**