소스 검색

feat(hr): 生成优秀生评价问卷功能

- 新增 CreateEvalQuestService 类实现评价问卷生成逻辑
- 添加 EvalQuestHelper 类作为评价问卷辅助类
- 在 AdminOrgHelper 中增加 getParentOrg 方法获取上级组织
- 新增 PersonHelper 类提供人员相关辅助方法
- 修改 QFilterCommonHelper 类,将 ID 比较条件改为等于
wyc 1 주 전
부모
커밋
e96728387d
21개의 변경된 파일1310개의 추가작업 그리고 75개의 파일을 삭제
  1. 441 69
      code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/utils/DateUtil.java
  2. 8 5
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/org/helper/AdminOrgHelper.java
  3. 58 0
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/org/helper/PersonHelper.java
  4. 1 1
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterCommonHelper.java
  5. 1 0
      code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterPersonHelper.java
  6. 188 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/business/CreateEvalQuestService.java
  7. 11 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/business/helper/EvalQuestHelper.java
  8. 106 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/common/HonorStudentConstant.java
  9. 0 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/mservice/.gitkeep
  10. 112 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/CreateEvalQuestFormPlugin.java
  11. 112 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/EvalQuestTplListPlugin.java
  12. 43 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/EvaluationRuleFormPlugin.java
  13. 114 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/EvaluationRuleListPlugin.java
  14. 41 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/OrgDifferenceFormPlugin.java
  15. 0 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/operate/.gitkeep
  16. 0 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/other/.gitkeep
  17. 0 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/report/.gitkeep
  18. 0 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/workflow/.gitkeep
  19. 44 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/task/CreateEvalQuestTask.java
  20. 30 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/task/CreateEvalQuestTaskClick.java
  21. 0 0
      code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/webapi/.gitkeep

+ 441 - 69
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/utils/DateUtil.java

@@ -8,7 +8,9 @@ import java.time.LocalTime;
 import java.time.Month;
 import java.time.Period;
 import java.time.ZoneId;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
 import java.util.ArrayList;
@@ -18,9 +20,15 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+/**
+* 日期时间工具类
+* 提供日期时间常用操作,包括转换、格式化、计算、范围处理等功能
+* @author W.Y.C
+* @date 2025/7/8 14:53
+* @version 1.0
+*/
 public class DateUtil {
 
-    // 常用日期格式
     public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
     public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
     public static final String NORM_TIME_PATTERN = "HH:mm:ss";
@@ -28,8 +36,12 @@ public class DateUtil {
     private static final DateTimeFormatter NORM_DATE_FORMAT = DateTimeFormatter.ofPattern(NORM_DATE_PATTERN);
     private static final DateTimeFormatter NORM_TIME_FORMAT = DateTimeFormatter.ofPattern(NORM_TIME_PATTERN);
 
+    // ==================== 基础方法 ====================
+
     /**
      * 获取当前日期时间
+     *
+     * @return 当前日期时间
      */
     public static LocalDateTime now() {
         return LocalDateTime.now();
@@ -37,6 +49,9 @@ public class DateUtil {
 
     /**
      * 转换为Date对象
+     *
+     * @param dateTime LocalDateTime对象
+     * @return 对应的Date对象
      */
     public static Date toDate(LocalDateTime dateTime) {
         return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
@@ -44,158 +59,451 @@ public class DateUtil {
 
     /**
      * 转换为LocalDateTime对象
+     *
+     * @param date Date对象
+     * @return 对应的LocalDateTime对象
      */
     public static LocalDateTime toLocalDateTime(Date date) {
         return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
     }
 
+    // ==================== 格式化与解析 ====================
+
     /**
-     * 格式化日期时间
-     */
-    public static String format(Date dateTime, String pattern) {
-        return format(toLocalDateTime(dateTime),pattern);
-    }
-    /**
-     * 格式化日期时间
+     * 格式化日期时间(指定模式)
+     *
+     * @param dateTime 日期时间对象
+     * @param pattern  日期格式模式
+     * @return 格式化后的字符串
      */
     public static String format(LocalDateTime dateTime, String pattern) {
         return dateTime.format(DateTimeFormatter.ofPattern(pattern));
     }
 
+    /**
+     * 格式化日期时间(默认格式:yyyy-MM-dd HH:mm:ss)
+     *
+     * @param dateTime 日期时间对象
+     * @return 格式化后的字符串
+     */
     public static String format(LocalDateTime dateTime) {
         return dateTime.format(NORM_DATETIME_FORMAT);
     }
 
     /**
-     * 解析日期时间
+     * 格式化日期时间(Date对象版本)
+     *
+     * @param date    Date对象
+     * @param pattern 日期格式模式
+     * @return 格式化后的字符串
+     */
+    public static String format(Date date, String pattern) {
+        return format(toLocalDateTime(date), pattern);
+    }
+
+    /**
+     * 解析日期时间(指定模式)
+     *
+     * @param dateStr 日期时间字符串
+     * @param pattern 日期格式模式
+     * @return 解析后的LocalDateTime对象
+     * @throws DateTimeParseException 如果解析失败
      */
     public static LocalDateTime parse(String dateStr, String pattern) {
         return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
     }
 
+    /**
+     * 解析日期时间(默认格式:yyyy-MM-dd HH:mm:ss)
+     *
+     * @param dateStr 日期时间字符串
+     * @return 解析后的LocalDateTime对象
+     * @throws DateTimeParseException 如果解析失败
+     */
     public static LocalDateTime parse(String dateStr) {
         return parse(dateStr, NORM_DATETIME_PATTERN);
     }
 
+    // ==================== 日期加减操作 ====================
+
     /**
-     * 日期加减
+     * 加年
+     *
+     * @param dateTime 原始日期时间
+     * @param years    要加的年数(可为负数)
+     * @return 计算后的日期时间
      */
     public static LocalDateTime addYears(LocalDateTime dateTime, int years) {
         return dateTime.plusYears(years);
     }
 
+    /**
+     * 减年
+     *
+     * @param dateTime 原始日期时间
+     * @param years    要减的年数
+     * @return 计算后的日期时间
+     */
+    public static LocalDateTime minusYears(LocalDateTime dateTime, int years) {
+        return dateTime.minusYears(years);
+    }
+
+    /**
+     * 加月
+     *
+     * @param dateTime 原始日期时间
+     * @param months   要加的月数(可为负数)
+     * @return 计算后的日期时间
+     */
     public static LocalDateTime addMonths(LocalDateTime dateTime, int months) {
         return dateTime.plusMonths(months);
     }
 
+    /**
+     * 减月
+     *
+     * @param dateTime 原始日期时间
+     * @param months   要减的月数
+     * @return 计算后的日期时间
+     */
+    public static LocalDateTime minusMonths(LocalDateTime dateTime, int months) {
+        return dateTime.minusMonths(months);
+    }
+
+    /**
+     * 加日
+     *
+     * @param dateTime 原始日期时间
+     * @param days     要加的天数(可为负数)
+     * @return 计算后的日期时间
+     */
     public static LocalDateTime addDays(LocalDateTime dateTime, int days) {
         return dateTime.plusDays(days);
     }
 
+    /**
+     * 减日
+     *
+     * @param dateTime 原始日期时间
+     * @param days     要减的天数
+     * @return 计算后的日期时间
+     */
+    public static LocalDateTime minusDays(LocalDateTime dateTime, int days) {
+        return dateTime.minusDays(days);
+    }
+
+    /**
+     * 加小时
+     *
+     * @param dateTime 原始日期时间
+     * @param hours    要加的小时数(可为负数)
+     * @return 计算后的日期时间
+     */
     public static LocalDateTime addHours(LocalDateTime dateTime, int hours) {
         return dateTime.plusHours(hours);
     }
 
+    /**
+     * 减小时
+     *
+     * @param dateTime 原始日期时间
+     * @param hours    要减的小时数
+     * @return 计算后的日期时间
+     */
+    public static LocalDateTime minusHours(LocalDateTime dateTime, int hours) {
+        return dateTime.minusHours(hours);
+    }
+
+    /**
+     * 加分钟
+     *
+     * @param dateTime 原始日期时间
+     * @param minutes  要加的分钟数(可为负数)
+     * @return 计算后的日期时间
+     */
     public static LocalDateTime addMinutes(LocalDateTime dateTime, int minutes) {
         return dateTime.plusMinutes(minutes);
     }
 
+    /**
+     * 减分钟
+     *
+     * @param dateTime 原始日期时间
+     * @param minutes  要减的分钟数
+     * @return 计算后的日期时间
+     */
+    public static LocalDateTime minusMinutes(LocalDateTime dateTime, int minutes) {
+        return dateTime.minusMinutes(minutes);
+    }
+
+    /**
+     * 加秒
+     *
+     * @param dateTime 原始日期时间
+     * @param seconds  要加的秒数(可为负数)
+     * @return 计算后的日期时间
+     */
     public static LocalDateTime addSeconds(LocalDateTime dateTime, int seconds) {
         return dateTime.plusSeconds(seconds);
     }
 
     /**
-     * 获取日期部分
+     * 减秒
+     *
+     * @param dateTime 原始日期时间
+     * @param seconds  要减的秒数
+     * @return 计算后的日期时间
      */
+    public static LocalDateTime minusSeconds(LocalDateTime dateTime, int seconds) {
+        return dateTime.minusSeconds(seconds);
+    }
+
+    // ==================== 日期部分获取 ====================
 
+    /**
+     * 获取年份
+     *
+     * @param date 日期时间对象
+     * @return 年份
+     */
     public static int getYear(Date date) {
         return getYear(toLocalDateTime(date));
     }
+
+    /**
+     * 获取年份
+     *
+     * @param dateTime 日期时间对象
+     * @return 年份
+     */
     public static int getYear(LocalDateTime dateTime) {
         return dateTime.getYear();
     }
 
+    /**
+     * 获取月份枚举
+     *
+     * @param dateTime 日期时间对象
+     * @return 月份枚举值
+     */
     public static Month getMonth(LocalDateTime dateTime) {
         return dateTime.getMonth();
     }
 
+    /**
+     * 获取月份数字(1-12)
+     *
+     * @param dateTime 日期时间对象
+     * @return 月份数字
+     */
+    public static int getMonthValue(LocalDateTime dateTime) {
+        return dateTime.getMonthValue();
+    }
+
+    /**
+     * 获取当月天数
+     *
+     * @param dateTime 日期时间对象
+     * @return 当月天数(1-31)
+     */
     public static int getDayOfMonth(LocalDateTime dateTime) {
         return dateTime.getDayOfMonth();
     }
 
+    /**
+     * 获取星期枚举
+     *
+     * @param dateTime 日期时间对象
+     * @return 星期枚举值
+     */
     public static DayOfWeek getDayOfWeek(LocalDateTime dateTime) {
         return dateTime.getDayOfWeek();
     }
 
+    /**
+     * 获取小时(24小时制)
+     *
+     * @param dateTime 日期时间对象
+     * @return 小时(0-23)
+     */
     public static int getHour(LocalDateTime dateTime) {
         return dateTime.getHour();
     }
 
+    /**
+     * 获取分钟
+     *
+     * @param dateTime 日期时间对象
+     * @return 分钟(0-59)
+     */
     public static int getMinute(LocalDateTime dateTime) {
         return dateTime.getMinute();
     }
 
+    /**
+     * 获取秒
+     *
+     * @param dateTime 日期时间对象
+     * @return 秒(0-59)
+     */
     public static int getSecond(LocalDateTime dateTime) {
         return dateTime.getSecond();
     }
 
+    // ==================== 日期计算 ====================
+
     /**
-     * 计算日期差
+     * 计算两个日期时间之间的差值
+     *
+     * @param start 开始时间
+     * @param end   结束时间
+     * @param unit  时间单位(ChronoUnit)
+     * @return 时间差值
      */
     public static long between(LocalDateTime start, LocalDateTime end, ChronoUnit unit) {
         return unit.between(start, end);
     }
 
     /**
-     * 判断日期是否在范围内
-     */
-    public static boolean isInRange(Date date, Date start, Date end){
-        return isInRange(toLocalDateTime(date), toLocalDateTime(start), toLocalDateTime(end));
-    }
-    /**
-     * 判断日期是否在范围内
+     * 判断日期是否在指定范围内
+     *
+     * @param date  待判断日期
+     * @param start 范围开始时间(包含)
+     * @param end   范围结束时间(包含)
+     * @return 是否在范围内
      */
     public static boolean isInRange(LocalDateTime date, LocalDateTime start, LocalDateTime end) {
         return !date.isBefore(start) && !date.isAfter(end);
     }
 
+    // ==================== 时间范围处理 ====================
+
     /**
-     * 获取开始时间
+     * 获取日期的开始时间(00:00:00)
+     *
+     * @param dateTime 日期时间
+     * @return 当天的开始时间
      */
     public static LocalDateTime beginOfDay(LocalDateTime dateTime) {
         return dateTime.toLocalDate().atStartOfDay();
     }
 
+    /**
+     * 获取月份的开始时间
+     *
+     * @param dateTime 日期时间
+     * @return 当月第一天 00:00:00
+     */
     public static LocalDateTime beginOfMonth(LocalDateTime dateTime) {
         return dateTime.withDayOfMonth(1).toLocalDate().atStartOfDay();
     }
 
+    /**
+     * 获取季度的开始时间
+     *
+     * @param dateTime 日期时间
+     * @return 当季度第一天 00:00:00
+     */
+    public static LocalDateTime beginOfQuarter(LocalDateTime dateTime) {
+        int month = dateTime.getMonthValue();
+        int quarterStartMonth = ((month - 1) / 3) * 3 + 1;
+        return dateTime.withMonth(quarterStartMonth).withDayOfMonth(1).toLocalDate().atStartOfDay();
+    }
+
+    /**
+     * 获取年份的开始时间
+     *
+     * @param dateTime 日期时间
+     * @return 当年第一天 00:00:00
+     */
     public static LocalDateTime beginOfYear(LocalDateTime dateTime) {
         return dateTime.withDayOfYear(1).toLocalDate().atStartOfDay();
     }
 
     /**
-     * 获取结束时间
+     * 获取日期当天的结束时间(23:59:59.999999999)
+     *
+     * @param dateTime 日期时间
+     * @return 当天的结束时间
      */
     public static LocalDateTime endOfDay(LocalDateTime dateTime) {
         return dateTime.toLocalDate().atTime(LocalTime.MAX);
     }
 
+    /**
+     * 获取月份结束时间
+     *
+     * @param dateTime 日期时间
+     * @return 当月最后一天 23:59:59.999999999
+     */
     public static LocalDateTime endOfMonth(LocalDateTime dateTime) {
         return dateTime.with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().atTime(LocalTime.MAX);
     }
 
+    /**
+     * 获取季度结束时间
+     *
+     * @param dateTime 日期时间
+     * @return 当季度最后一天 23:59:59.999999999
+     */
+    public static LocalDateTime endOfQuarter(LocalDateTime dateTime) {
+        int month = dateTime.getMonthValue();
+        int quarterEndMonth = ((month - 1) / 3 + 1) * 3;
+        return dateTime.withMonth(quarterEndMonth)
+                .with(TemporalAdjusters.lastDayOfMonth())
+                .toLocalDate().atTime(LocalTime.MAX);
+    }
+
+    /**
+     * 获取年份结束时间
+     *
+     * @param dateTime 日期时间
+     * @return 当年最后一天 23:59:59.999999999
+     */
     public static LocalDateTime endOfYear(LocalDateTime dateTime) {
         return dateTime.with(TemporalAdjusters.lastDayOfYear()).toLocalDate().atTime(LocalTime.MAX);
     }
 
     /**
-     * 生成日期范围
+     * 获取周的开始时间(周一)
+     *
+     * @param dateTime 日期时间
+     * @return 当周周一 00:00:00
+     */
+    public static LocalDateTime beginOfWeek(LocalDateTime dateTime) {
+        return dateTime.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
+                .toLocalDate().atStartOfDay();
+    }
+
+    /**
+     * 获取周的结束时间(周日)
+     *
+     * @param dateTime 日期时间
+     * @return 当周周日 23:59:59.999999999
+     */
+    public static LocalDateTime endOfWeek(LocalDateTime dateTime) {
+        return dateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY))
+                .toLocalDate().atTime(LocalTime.MAX);
+    }
+
+    // ==================== 日期范围生成 ====================
+
+    /**
+     * 生成日期范围列表
+     *
+     * @param start 开始时间(包含)
+     * @param end   结束时间(包含)
+     * @param unit  时间单位
+     * @return 日期时间列表
      */
     public static List<LocalDateTime> range(LocalDateTime start, LocalDateTime end, ChronoUnit unit) {
+        if (start.isAfter(end)) {
+            throw new IllegalArgumentException("Start must be before end");
+        }
+
         List<LocalDateTime> result = new ArrayList<>();
         long distance = unit.between(start, end);
-        
+
         for (long i = 0; i <= distance; i++) {
             result.add(start.plus(i, unit));
         }
@@ -203,120 +511,184 @@ public class DateUtil {
     }
 
     /**
-     * 日期范围处理
+     * 日期范围转换处理
+     *
+     * @param <T>   返回类型
+     * @param start 开始时间
+     * @param end   结束时间
+     * @param unit  时间单位
+     * @param func  转换函数
+     * @return 转换后的结果列表
      */
     public static <T> List<T> rangeFunc(LocalDateTime start, LocalDateTime end, ChronoUnit unit, Function<LocalDateTime, T> func) {
         return range(start, end, unit).stream().map(func).collect(Collectors.toList());
     }
 
+    /**
+     * 日期范围消费处理
+     *
+     * @param start    开始时间
+     * @param end      结束时间
+     * @param unit     时间单位
+     * @param consumer 消费函数
+     */
     public static void rangeConsume(LocalDateTime start, LocalDateTime end, ChronoUnit unit, Consumer<LocalDateTime> consumer) {
         range(start, end, unit).forEach(consumer);
     }
 
+    // ==================== 特殊日期判断 ====================
+
     /**
-     * 判断是否闰年
+     * 判断是否为闰年
+     *
+     * @param dateTime 日期时间
+     * @return 是否为闰年
      */
     public static boolean isLeapYear(LocalDateTime dateTime) {
         return dateTime.toLocalDate().isLeapYear();
     }
 
     /**
-     * 时间戳转换
+     * 判断是否为周末(周六或周日)
+     *
+     * @param dateTime 日期时间
+     * @return 是否为周末
+     */
+    public static boolean isWeekend(LocalDateTime dateTime) {
+        DayOfWeek day = dateTime.getDayOfWeek();
+        return day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY;
+    }
+
+    /**
+     * 判断是否为工作日(周一到周五)
+     *
+     * @param dateTime 日期时间
+     * @return 是否为工作日
+     */
+    public static boolean isWorkday(LocalDateTime dateTime) {
+        return !isWeekend(dateTime);
+    }
+
+    // ==================== 时间戳操作 ====================
+
+    /**
+     * 时间戳转LocalDateTime
+     *
+     * @param timestamp 毫秒时间戳
+     * @return 对应的日期时间
      */
     public static LocalDateTime fromTimestamp(long timestamp) {
         return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
     }
 
+    /**
+     * 日期时间转时间戳(毫秒)
+     *
+     * @param dateTime 日期时间
+     * @return 毫秒时间戳
+     */
     public static long toTimestamp(LocalDateTime dateTime) {
         return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
     }
 
+    // ==================== 时区转换 ====================
+
     /**
      * 时区转换
+     *
+     * @param dateTime  原始日期时间
+     * @param targetZone 目标时区
+     * @return 目标时区的日期时间
      */
     public static LocalDateTime convertTimeZone(LocalDateTime dateTime, ZoneId targetZone) {
-        return dateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(targetZone).toLocalDateTime();
+        ZonedDateTime zoned = dateTime.atZone(ZoneId.systemDefault());
+        return zoned.withZoneSameInstant(targetZone).toLocalDateTime();
     }
 
+    // ==================== 日期比较 ====================
+
     /**
-     * 比较日期
+     * 比较两个日期时间
+     *
+     * @param dt1 日期时间1
+     * @param dt2 日期时间2
+     * @return 比较结果(负数:dt1 < dt2,0:相等,正数:dt1 > dt2)
      */
     public static int compare(LocalDateTime dt1, LocalDateTime dt2) {
         return dt1.compareTo(dt2);
     }
 
     /**
-     * 判断同一天
+     * 判断是否为同一天
+     *
+     * @param dt1 日期时间1
+     * @param dt2 日期时间2
+     * @return 是否同一天
      */
     public static boolean isSameDay(LocalDateTime dt1, LocalDateTime dt2) {
         return dt1.toLocalDate().equals(dt2.toLocalDate());
     }
 
+    // ==================== 实用功能 ====================
+
     /**
-     * 年龄计算
+     * 计算年龄
+     *
+     * @param birthDate 出生日期
+     * @return 年龄(周岁)
      */
     public static int calculateAge(LocalDate birthDate) {
         return Period.between(birthDate, LocalDate.now()).getYears();
     }
 
     /**
-     * 时间段是否重叠
+     * 判断两个时间段是否重叠
+     *
+     * @param start1 时间段1开始
+     * @param end1   时间段1结束
+     * @param start2 时间段2开始
+     * @param end2   时间段2结束
+     * @return 是否重叠
      */
     public static boolean isOverlap(
-        LocalDateTime start1, LocalDateTime end1,
-        LocalDateTime start2, LocalDateTime end2
+            LocalDateTime start1, LocalDateTime end1,
+            LocalDateTime start2, LocalDateTime end2
     ) {
         return !start1.isAfter(end2) && !start2.isAfter(end1);
     }
 
     /**
-     * 季度处理
+     * 获取季度(1-4)
+     *
+     * @param dateTime 日期时间
+     * @return 所属季度
      */
     public static int getQuarter(LocalDateTime dateTime) {
         return (dateTime.getMonthValue() - 1) / 3 + 1;
     }
 
-    /**
-     * 星座计算
-     */
-    public static String getZodiac(LocalDateTime dateTime) {
-        int month = dateTime.getMonthValue();
-        int day = dateTime.getDayOfMonth();
-        
-        if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) {return "白羊座";};
-        if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) {return "金牛座";};
-        if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) {return "双子座";};
-        if ((month == 6 && day >= 22) || (month == 7 && day <= 22)) {return "巨蟹座";};
-        if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) {return "狮子座";};
-        if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) {return "处女座";};
-        if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) {return "天秤座";};
-        if ((month == 10 && day >= 24) || (month == 11 && day <= 22)) {return "天蝎座";};
-        if ((month == 11 && day >= 23) || (month == 12 && day <= 21)) {return "射手座";};
-        if ((month == 12 && day >= 22) || (month == 1 && day <= 19)) {return "摩羯座";};
-        if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) {return "水瓶座";};
-        return "双鱼座";
-    }
-
-    /**
-     * 生肖计算
-     */
-    public static String getChineseZodiac(LocalDateTime dateTime) {
-        String[] zodiacs = {"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"};
-        return zodiacs[dateTime.getYear() % 12];
-    }
-
-    /**
-     * 工作日计算
-     */
-    public static boolean isWorkday(LocalDateTime dateTime) {
-        return dateTime.getDayOfWeek().getValue() < 6;
-    }
 
     /**
      * 获取月末最后一天
+     *
+     * @param dateTime 日期时间
+     * @return 当月最后一天
      */
     public static int lastDayOfMonth(LocalDateTime dateTime) {
         return dateTime.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
     }
 
+    /**
+     * 获取下一个工作日(跳过周末)
+     *
+     * @param dateTime 起始日期
+     * @return 下一个工作日
+     */
+    public static LocalDateTime nextWorkday(LocalDateTime dateTime) {
+        LocalDateTime result = dateTime.plusDays(1);
+        while (isWeekend(result)) {
+            result = result.plusDays(1);
+        }
+        return result;
+    }
 }

+ 8 - 5
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/org/helper/AdminOrgHelper.java

@@ -4,6 +4,7 @@ import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
 import kd.hr.hbp.business.dao.factory.HRBaseDaoFactory;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
@@ -49,11 +50,13 @@ public class AdminOrgHelper {
     * @date: 2025/07/07 15:08
     */
     public static Long getParentOrg(Long adminOrgId) {
-        QFilter adminOrgIdFilter = new QFilter("adminorg.id", QCP.equals,adminOrgId);
-        DynamicObject parentOrg = HRBaseDaoFactory.getInstance("haos_adminorgstruct").queryOne("parentorg.id as parentorg",
-                new QFilter[]{QFilterCommonHelper.getCurrentVersionFilter(), QFilterCommonHelper.getInitStatusFinishFilter(),
-                QFilterCommonHelper.getDataStatusFilter(), adminOrgIdFilter});
-        return parentOrg.getLong("parentorg");
+        QFilter adminOrgIdFilter = new QFilter("id", QCP.equals,adminOrgId);
+        DynamicObject parentOrg = QueryServiceHelper.queryOne("haos_adminorghr","parent.id parentId",new QFilter[]{QFilterCommonHelper.getCurrentVersionFilter(), QFilterCommonHelper.getInitStatusFinishFilter(),
+                QFilterCommonHelper.getDataStatusFilter(),QFilterCommonHelper.getEnableFilter(),QFilterCommonHelper.getStatusFilter(), adminOrgIdFilter});
+        if(parentOrg != null) {
+            return parentOrg.getLong("parentId");
+        }
+        return null;
 
     }
 }

+ 58 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/org/helper/PersonHelper.java

@@ -0,0 +1,58 @@
+package nckd.jxccl.base.org.helper;
+
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.base.orm.helper.QFilterPersonHelper;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 人员辅助类
+ * @author W.Y.C
+ * @date 2025/7/7 18:23
+ * @version 1.0
+ */
+public class PersonHelper {
+
+    /** 组织人 */
+    public static final String DEP_EMP_ENTITY_ID = "hrpi_depemp";
+
+    /**
+     * 查询根据条件查询有效组织人(任职类型为全职、用工关系状态为在职、组织团队分类为行政组织、业务状态为生效中、最新版本、初始状态为完成)
+     * @param selectFields 查询字段
+     * @param filters 自定义过滤条件
+     * @return: kd.bos.dataentity.entity.DynamicObjectCollection
+     * @author W.Y.C
+     * @date: 2025/07/07 18:37
+     */
+    public static DynamicObjectCollection getDepEmpEffectivePerson(String selectFields, QFilter... filters) {
+        // 构建基础过滤条件
+        QFilter baseFilter = QFilterCommonHelper.getBusinessStatusFilter()
+                .and(QFilterPersonHelper.getPostCategoryOfStaffFilter())
+                .and(QFilterPersonHelper.getLaborRelStatusOfStaffFilter())
+                .and(QFilterPersonHelper.getOtClassifyFilter())
+                .and(QFilterCommonHelper.getCurrentVersionFilter())
+                .and(QFilterCommonHelper.getDataStatusFilter())
+                .and(QFilterCommonHelper.getInitStatusFinishFilter());
+
+        // 合并 filters
+        List<QFilter> filterList = new ArrayList<>();
+        filterList.add(baseFilter);
+        if (filters != null && filters.length > 0) {
+            filterList.addAll(Arrays.asList(filters));
+        }
+
+        // 防止 selectFields 为空
+        if (StringUtils.isBlank(selectFields)) {
+            selectFields = "id";
+        }
+        // 执行查询并返回结果
+        return QueryServiceHelper.query(DEP_EMP_ENTITY_ID, selectFields, filterList.toArray(new QFilter[0]));
+    }
+
+}

+ 1 - 1
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterCommonHelper.java

@@ -130,7 +130,7 @@ public final class QFilterCommonHelper {
      * @date: 2025/07/07 09:20
      */
     public static QFilter getIdEqFilter(Object id) {
-        return new QFilter(FromConstant.ID_KEY, QCP.in, ConvertUtil.toLong(id));
+        return new QFilter(FromConstant.ID_KEY, QCP.equals, ConvertUtil.toLong(id));
     }
 
     /**

+ 1 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterPersonHelper.java

@@ -56,4 +56,5 @@ public class QFilterPersonHelper {
     public static QFilter getOtClassifyFilter(){
         return new QFilter(OT_CLASSIFY_NUMBER_KEY, QCP.equals, OT_CLASSIFY_NUMBER);
     }
+
 }

+ 188 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/business/CreateEvalQuestService.java

@@ -0,0 +1,188 @@
+package nckd.jxccl.hr.hstu.business;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.hr.hbp.business.openservicehelper.hrpi.HRPIDepempServiceHelper;
+import nckd.jxccl.base.common.constant.FromConstant;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.org.helper.AdminOrgHelper;
+import nckd.jxccl.base.org.helper.PersonHelper;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+
+/**
+ * 【优秀生】-生成评价问卷
+ * @author W.Y.C
+ * @date 2025/7/2 16:41
+ * @version 1.0
+ */
+public class CreateEvalQuestService {
+
+    private static final Log logger = LogFactory.getLog(CreateEvalQuestService.class);
+
+
+    /**
+     * 批量生成评价问卷
+     * @param evalQuestTplId 评价问卷模板Id
+     * @param selectedEvalRule 评价规则
+     * @param selectedPerson 被评价人
+     * @return: void
+     * @author W.Y.C
+     * @date: 2025/07/02 17:24
+     */
+    public static void createEvalQuest(Long evalQuestTplId, DynamicObject selectedEvalRule, DynamicObjectCollection selectedPerson) {
+
+        //同级人员取数条件:
+        //1.最新一条党政职务履历为副处级及以上人员不作为同级取数
+        //2.工作性质大类过滤掉编码为H01(居休)、H02(退养)、H03(随任)、H04(女工长假)、H05(长期工伤病休)、H06(长期病休)、H07(其他不在岗)、J(外派)的员工,不做为同级
+        //3.除去领导和上级
+        //4.入职超半年、职位非协理员
+        logger.info("【职位体系】-生成综合评测问卷-开始");
+
+
+        StringJoiner ruleColum = new StringJoiner(",");
+        //其他同级评分人比例
+        ruleColum.add(HonorStudentConstant.NCKD_PROPORTION);
+        //同级评分人上限人数
+        ruleColum.add(HonorStudentConstant.NCKD_UPPER);
+        //同级评分人下限人数
+        ruleColum.add(HonorStudentConstant.NCKD_LOWER);
+        selectedEvalRule = QueryServiceHelper.queryOne(HonorStudentConstant.EVALUATIONRULE_ENTITYID, ruleColum.toString(), new QFilter[]{QFilterCommonHelper.getIdEqFilter(selectedEvalRule.getPkValue())});
+        int proportion = selectedEvalRule.getInt(HonorStudentConstant.NCKD_PROPORTION);
+        int upper = selectedEvalRule.getInt(HonorStudentConstant.NCKD_UPPER);
+        int lower = selectedEvalRule.getInt(HonorStudentConstant.NCKD_LOWER);
+        int otherLower = lower * proportion / 100;
+        try{
+            // 用工关系状态:正式员工、试用员工、见习期员工
+            for (DynamicObject row : selectedPerson) {
+                DynamicObject depEmpRow = (DynamicObject)row.getDynamicObject(FromConstant.BASEDATAID_KEY);
+
+                Map<String, Object> depEmp = HRPIDepempServiceHelper.getDepemp(ConvertUtil.toLong(depEmpRow.getPkValue()));
+                Long id = ConvertUtil.toLong(depEmp.get("id"));
+                //获取当前人员的组织
+                Long adminOrgId = ConvertUtil.toLong(depEmp.get("adminorg_id"));
+                //获取当前人员的岗位
+                Long positionId = ConvertUtil.toLong(depEmp.get("position_id"));
+
+                //获取领导(获取上上级岗位中的人员作为领导)
+                DynamicObject parentParentPosition = QueryServiceHelper.queryOne("hbpm_positionhr","parent.parent.id as parentId",new QFilter[]{QFilterCommonHelper.getIdEqFilter(positionId)});
+                QFilter positionFilter = new QFilter("position.id", QCP.equals, parentParentPosition.getLong("parentId"));
+                DynamicObjectCollection leadColl =  PersonHelper.getDepEmpEffectivePerson("id,person.name",positionFilter);
+
+                //获取上级(获取上级岗位中的人员作为上级)
+                DynamicObject parentPosition = QueryServiceHelper.queryOne("hbpm_positionhr","parent.id as parentId",new QFilter[]{QFilterCommonHelper.getIdEqFilter(positionId)});
+                positionFilter = new QFilter("position.id", QCP.equals, parentPosition.getLong("parentId"));
+                DynamicObjectCollection superiorColl = PersonHelper.getDepEmpEffectivePerson("id,person.name",positionFilter);
+
+                //获取同级人员
+                Set<Long> excludePersons = new HashSet<>(leadColl.size()+superiorColl.size());
+                excludePersons.add(id);
+                leadColl.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong(HonorStudentConstant.ID_KEY)));
+                superiorColl.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong(HonorStudentConstant.ID_KEY)));
+                DynamicObjectCollection peers = getPeers(adminOrgId,excludePersons, proportion,upper, lower, otherLower);
+
+
+                System.out.println();
+            }
+
+        }catch (Exception e){
+            logger.error("【职位体系】-生成综合评测问卷-异常",e);
+        }
+        logger.info("【职位体系】-生成综合评测问卷-结束");
+    }
+
+    /**
+     * 获取同级人员
+     *  1.最新一条党政职务履历为副处级及以上人员不作为同级取数
+     *  2.工作性质大类过滤掉编码为H01(居休)、H02(退养)、H03(随任)、H04(女工长假)、H05(长期工伤病休)、H06(长期病休)、H07(其他不在岗)、J(外派)的员工,不做为同级
+     *  3.除去领导和上级
+     *  4.入职超半年、职位非协理员
+     * @param adminOrgId 当前组织ID
+     * @param excludePersons 排除的ID
+     * @return: kd.bos.dataentity.entity.DynamicObjectCollection
+     * @author W.Y.C
+     * @date: 2025/07/08 17:48
+     */
+    private static DynamicObjectCollection getPeers(Long adminOrgId,Set<Long> excludePersons,int proportion,int upper,int lower,int otherLower){
+        /*
+        同级人数取数逻辑
+        │
+        ├─ 读取评价规则:proportion(其他同级评分人比例), upper(同级评分人上限人数), lower(同级评分人下限人数) → 计算 otherlower
+        │
+        ├─ 1:查询当前组织内的同级员工(排除上级、自己)
+        │   ├─ 1.1:若人数 >= lower → 只取前 upper 个
+        │   └─ 1.2:否则 继续向上级组织查找(最多 10 层)
+        │
+        ├─ 2:查询同级其他部门在职人员
+        │
+        └─ 返回最终的同级评分人列表
+        */
+        //最终的结果
+        DynamicObjectCollection finalResult = new DynamicObjectCollection();
+
+        //------ 基本条件 begin------
+        QFilter baseFilter = new QFilter(HonorStudentConstant.ID_KEY, QCP.not_in, excludePersons);
+        //入职超半年
+        baseFilter.and(new QFilter("startdate",QCP.less_equals, DateUtil.minusMonths(DateUtil.now(),6)));
+        //职位非协理员
+        baseFilter.and(new QFilter("position.name", QCP.not_like, "%协理员%"));
+        //------ 基本条件 end------
+
+        //1.查询当前组织内的同级员工
+        QFilter adminOrgFilter = new QFilter("adminorg.id", QCP.equals, adminOrgId);
+        DynamicObjectCollection depEmpEffectivePerson = PersonHelper.getDepEmpEffectivePerson("id,person.name", baseFilter, adminOrgFilter);
+
+        //当前组织人数小于下限人数,继续向上级组织查找直到 >= lower
+        if(depEmpEffectivePerson.size() < lower){
+            recursionGetParentPeers(adminOrgId, depEmpEffectivePerson, baseFilter, lower, 1);
+        }
+        //截取前 upper 个同级人员
+        Collections.shuffle(depEmpEffectivePerson);
+        List<DynamicObject> dynamicObjects = depEmpEffectivePerson.subList(0, depEmpEffectivePerson.size() > upper ? upper-1 : depEmpEffectivePerson.size() -1);
+        finalResult.addAll(dynamicObjects);
+
+        //2.查询同级其他部门在职人员
+
+        return finalResult;
+    }
+
+    /**
+     * 递归上级组织获取人员
+     * @param adminOrgId 组织id
+     * @param persons 已获取的同级人员
+     * @param baseFilter 基本条件
+     * @param lower 同级评分人下限人数
+     * @param count 递归累计
+     * @return: void
+     * @author W.Y.C
+     * @date: 2025/07/09 16:03
+     */
+    private static void recursionGetParentPeers(Long adminOrgId,DynamicObjectCollection persons,QFilter baseFilter,int lower,Integer count){
+        Long parentOrg = AdminOrgHelper.getParentOrg(adminOrgId);
+        if(parentOrg == null){
+            return;
+        }
+        QFilter adminOrgFilter = new QFilter("adminorg.id", QCP.equals, parentOrg);
+        DynamicObjectCollection depEmpEffectivePerson = PersonHelper.getDepEmpEffectivePerson("id,person.name", baseFilter, adminOrgFilter);
+        persons.addAll(depEmpEffectivePerson);
+        if(persons.size() >= lower || count > 10){
+            return;
+        }else{
+            count++;
+            recursionGetParentPeers(parentOrg,persons,baseFilter,lower,count);
+        }
+    }
+}

+ 11 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/business/helper/EvalQuestHelper.java

@@ -0,0 +1,11 @@
+package nckd.jxccl.hr.hstu.business.helper;
+
+/**
+ * 【优秀生】- 评价问卷帮助类
+ * @author W.Y.C
+ * @date 2025/7/3 14:20
+ * @version 1.0
+ */
+public class EvalQuestHelper {
+
+}

+ 106 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/common/HonorStudentConstant.java

@@ -0,0 +1,106 @@
+/**
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-05-26 16:28:10
+ */
+package nckd.jxccl.hr.hstu.common;
+
+/**
+ * hr云init应用-通用常量类<br>
+ * 代码中不能存在硬编码敏感信息,如账号、密码、http外链、ftp外链、邮箱等。<br>
+ * 标识或缓存的常量,需以"KEY_"、"FID_"、"ENTRY_"或"SUBENTRY_"作为变量的前缀。<br>
+ *
+ * @author nckd
+ * @date 2025-05-26 16:28:10
+ */
+
+import nckd.jxccl.base.common.constant.FromConstant;
+
+/**
+* 优秀生常量类
+* @author W.Y.C
+* @date 2025/6/18 15:28
+* @version 1.0
+*/
+public class HonorStudentConstant extends FromConstant {
+
+    /** 评价规则-实体标识 */
+    public static final String EVALUATIONRULE_ENTITYID = "nckd_evaluationrule";
+    /** 开始时间 */
+    public static final String NCKD_STARTTIME = "NCKD_STARTTIME";
+    /** 结束时间 */
+    public static final String NCKD_ENDTIME = "NCKD_ENDTIME";
+    /** 所属年度 */
+    public static final String NCKD_BIZYEAR = "NCKD_BIZYEAR";
+    /** 业绩贡献权重占比(%) */
+    public static final String NCKD_ALLYEARPROPORTION = "NCKD_ALLYEARPROPORTION";
+    /** 员工绩效权重占比(%) */
+    public static final String NCKD_INTEGERFIELD = "NCKD_INTEGERFIELD";
+    /** 业绩贡献封顶分 */
+    public static final String NCKD_ALLYEARMAX = "NCKD_ALLYEARMAX";
+    /** 地区差异权重占比(%) */
+    public static final String NCKD_DIFFPROPORTION = "NCKD_DIFFPROPORTION";
+    /** 综合测评权重占比(%) */
+    public static final String NCKD_PERFPROPORTION = "NCKD_PERFPROPORTION";
+    /** 综合测评封顶分 */
+    public static final String NCKD_PERFMAX = "NCKD_PERFMAX";
+    /** 领导评分权重占比(%) */
+    public static final String NCKD_LEADPROPORTION = "NCKD_LEADPROPORTION";
+    /** 上级评分权重占比(%) */
+    public static final String NCKD_SUPERIORRATIO = "NCKD_SUPERIORRATIO";
+    /** 同级评分权重占比(%) */
+    public static final String NCKD_PEEKPROPORTION = "NCKD_PEEKPROPORTION";
+    /** 同级评分人上限人数 */
+    public static final String NCKD_UPPER = "NCKD_UPPER";
+    /** 同级评分人下限人数 */
+    public static final String NCKD_LOWER = "NCKD_LOWER";
+    /** 其他同级评分人比例 */
+    public static final String NCKD_PROPORTION = "NCKD_PROPORTION";
+    /** 优秀评优排名基准(%) */
+    public static final String NCKD_COMMARKPERCENTAGE = "NCKD_COMMARKPERCENTAGE";
+    /** 所在单位评优排名基准(%) */
+    public static final String NCKD_HRMARKPERCENTAGE = "NCKD_HRMARKPERCENTAGE";
+    /** 评价规则状态 */
+    public static final String NCKD_PERIODSTATE = "NCKD_PERIODSTATE";
+
+
+    /** 地区差异分-实体标识 */
+    public static final String ORGDIFFERENCE_ENTITYID = "nckd_orgdifferencewh";
+    /** 行政组织 */
+    public static final String NCKD_ORG = "nckd_org";
+    /** 地区差异分 */
+    public static final String NCKD_DIFFERENCESCORE = "nckd_differencescore";
+
+
+    /** 生成评价对象-实体标识 */
+    public static final String NCKD_CREATEEVALQUEST_ENTITYID = "nckd_createevalquest";
+    /** 评价规则 */
+    public static final String NCKD_SELECTEDEVALRULE = "NCKD_SELECTEDEVALRULE";
+    /** 人员 */
+    public static final String NCKD_SELECTEDPERSON = "NCKD_SELECTEDPERSON";
+    /** 优秀生综合测评模板 */
+    public static final String NCKD_EVALQUESTTPLID = "nckd_evalquesttplid";
+    /** 生成评价对象 */
+    public static final String OP_CREATEEVAL = "createeval";
+    /** 生成评价对象任务*/
+    public static final String TASK_CREATEEVAL = "createevaltask";
+
+
+
+    /** 综合测评问卷模板-实体标识 */
+    public static final String NCKD_EVALQUESTTPL_ENTITYID = "nckd_evalquesttpl";
+    /** 待评价内容 */
+    public static final String NCKD_MATTER = "NCKD_MATTER";
+    /** 评价说明(低分) */
+    public static final String NCKD_LOWSCOREDWECLARE = "NCKD_LOWSCOREDWECLARE";
+    /** 评价说明(高分) */
+    public static final String NCKD_TOPSCOREDWECLARE = "NCKD_TOPSCOREDWECLARE";
+    /** 备注 */
+    public static final String NCKD_DESCRIPTION = "NCKD_DESCRIPTION";
+
+
+
+
+}

+ 0 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/.gitkeep → code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/mservice/.gitkeep


+ 112 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/CreateEvalQuestFormPlugin.java

@@ -0,0 +1,112 @@
+package nckd.jxccl.hr.hstu.plugin.form;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.ConfirmCallBackListener;
+import kd.bos.form.MessageBoxOptions;
+import kd.bos.form.MessageBoxResult;
+import kd.bos.form.control.Control;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.events.MessageBoxClosedEvent;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.schedule.api.JobInfo;
+import kd.bos.schedule.api.JobType;
+import kd.bos.schedule.form.JobForm;
+import kd.bos.schedule.form.JobFormInfo;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.hr.hstu.business.CreateEvalQuestService;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+import nckd.jxccl.hr.hstu.task.CreateEvalQuestTask;
+import nckd.jxccl.hr.hstu.task.CreateEvalQuestTaskClick;
+
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* 生成评价对象表单插件
+* @author W.Y.C
+* @date 2025/7/1 10:19
+* @version 1.0
+*/
+public class CreateEvalQuestFormPlugin extends AbstractFormPlugin implements Plugin {
+
+    @Override
+    public void registerListener(EventObject e) {
+        this.addClickListeners(HonorStudentConstant.OP_BTN_OK);
+    }
+
+    @Override
+    public void afterCreateNewData(EventObject e) {
+        super.afterCreateNewData(e);
+        Long evalQuestTplId = ConvertUtil.toLong(this.getView().getFormShowParameter().getCustomParams().get(HonorStudentConstant.NCKD_EVALQUESTTPLID));
+        this.getModel().setValue(HonorStudentConstant.NCKD_EVALQUESTTPLID, evalQuestTplId);
+    }
+
+    @Override
+    public void click(EventObject evt) {
+        Control source = (Control) evt.getSource();
+        if (HonorStudentConstant.OP_BTN_OK.equals(source.getKey())) {
+            DynamicObject selectedEvalRule = (DynamicObject)this.getModel().getValue(HonorStudentConstant.NCKD_SELECTEDEVALRULE);
+            if(selectedEvalRule == null){
+                this.getView().showTipNotification("请选择评价规则");
+                return;
+            }
+           DynamicObjectCollection selectedPerson = (DynamicObjectCollection)this.getModel().getValue(HonorStudentConstant.NCKD_SELECTEDPERSON);
+            if(selectedPerson.isEmpty()){
+                this.getView().showTipNotification("请选择评价对象");
+                return;
+            }
+
+            Map<String, Object> returnMap = new HashMap<>(2);
+            returnMap.put("selectedEvalRule", selectedEvalRule);
+            returnMap.put("selectedPerson", selectedPerson);
+            this.getView().showConfirm("是否确认生成已选人员的评测问卷?", MessageBoxOptions.YesNo, new ConfirmCallBackListener(HonorStudentConstant.SUBMIT_KEY, this));
+        }
+    }
+
+    @Override
+    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {
+        String callBackId = messageBoxClosedEvent.getCallBackId();
+        if(HonorStudentConstant.SUBMIT_KEY.equals(callBackId) && messageBoxClosedEvent.getResult() == MessageBoxResult.Yes){
+            Long evalQuestTplId = ConvertUtil.toLong(this.getView().getFormShowParameter().getCustomParams().get(HonorStudentConstant.NCKD_EVALQUESTTPLID));
+            DynamicObject selectedEvalRule = (DynamicObject)this.getModel().getValue(HonorStudentConstant.NCKD_SELECTEDEVALRULE);
+            DynamicObjectCollection selectedPerson = (DynamicObjectCollection)this.getModel().getValue(HonorStudentConstant.NCKD_SELECTEDPERSON);
+
+            if(selectedPerson.size() > 30) {
+                //选择生成人员超过30人开启异步任务
+                // 1. 创建任务实例
+                JobInfo jobInfo = new JobInfo();
+                jobInfo.setTaskClassname(CreateEvalQuestTask.class.getName());
+                jobInfo.setParams(new HashMap<>()); // 可传递参数
+                jobInfo.setJobType(JobType.REALTIME);
+                jobInfo.setSuccessNotify(Boolean.TRUE);
+
+                // 2. 配置进度界面
+                JobFormInfo formInfo = new JobFormInfo(jobInfo);
+                formInfo.setCaption("生成综合评测问卷进度");
+                formInfo.setCloseCallBack(new CloseCallBack(EvalQuestTplListPlugin.class.getName(), HonorStudentConstant.TASK_CREATEEVAL));
+                formInfo.setClickClassName(CreateEvalQuestTaskClick.class.getName());
+                // 允许用户中途取消
+                //formInfo.setCanStop(true);
+                // 允许切到后台
+                //formInfo.setCanBackground(true);
+
+                // 3. 发布任务并显示进度界面
+                JobForm.dispatch(formInfo, this.getView().getParentView());
+
+                this.getView().close();
+            }else{
+                CreateEvalQuestService.createEvalQuest(evalQuestTplId, selectedEvalRule, selectedPerson);
+            }
+
+        }
+    }
+
+    @Override
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        System.out.println();
+    }
+}

+ 112 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/EvalQuestTplListPlugin.java

@@ -0,0 +1,112 @@
+package nckd.jxccl.hr.hstu.plugin.form;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.constant.StatusEnum;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.ConfirmCallBackListener;
+import kd.bos.form.ConfirmTypes;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.MessageBoxOptions;
+import kd.bos.form.ShowType;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.operate.FormOperate;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.portal.util.SerializationUtils;
+import kd.bos.schedule.api.TaskInfo;
+import kd.bos.schedule.api.TaskStatusConstant;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+
+/**
+* 综合测评问卷模板
+* @author W.Y.C
+* @date 2025/6/30 16:17
+* @version 1.0
+*/
+public class EvalQuestTplListPlugin extends AbstractListPlugin implements Plugin {
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        String operateKey = ((FormOperate) args.getSource()).getOperateKey();
+        if(HonorStudentConstant.OP_CREATEEVAL.equals(operateKey)) {
+            ListSelectedRowCollection selectedRows = this.getSelectedRows();
+            if (selectedRows.size() != 1) {
+                this.getView().showErrorNotification("请选择一条数据!");
+                args.setCancel(true);
+                return;
+            }
+            DynamicObject basedata = BusinessDataServiceHelper.loadSingle(
+                    selectedRows.get(0).getPrimaryKeyValue(),
+                    HonorStudentConstant.NCKD_EVALQUESTTPL_ENTITYID,
+                    HonorStudentConstant.STATUS+","+HonorStudentConstant.ENABLE
+            );
+            if (basedata != null) {
+                String status = basedata.getString(HonorStudentConstant.STATUS);
+                Boolean enable = basedata.getBoolean(HonorStudentConstant.ENABLE);
+
+                // 是否可用
+                boolean isAvailable = StatusEnum.C.toString().equals(status) && Boolean.TRUE.equals(enable);
+                if(!isAvailable){
+                    this.getView().showErrorNotification(StrFormatter.format("【{}】该问卷模板状态不可用",selectedRows.get(0).getName()));
+                    args.setCancel(true);
+                    return;
+                }
+            }
+        }
+    }
+
+
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        String operateKey = e.getOperateKey();
+        if(HonorStudentConstant.OP_CREATEEVAL.equals(operateKey)){
+            ListSelectedRowCollection selectedRows = this.getSelectedRows();
+            FormShowParameter showParameter = new FormShowParameter();
+            showParameter.setFormId(HonorStudentConstant.NCKD_CREATEEVALQUEST_ENTITYID);
+            showParameter.getOpenStyle().setShowType(ShowType.Modal);
+            showParameter.setCloseCallBack(new CloseCallBack(this, HonorStudentConstant.NCKD_CREATEEVALQUEST_ENTITYID));
+            showParameter.setCustomParam(HonorStudentConstant.NCKD_EVALQUESTTPLID,selectedRows.get(0).getPrimaryKeyValue());
+            showParameter.setCaption("批量新增综合测评问卷");
+            this.getView().showForm(showParameter);
+        }
+    }
+
+    @Override
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        String actionId = closedCallBackEvent.getActionId();
+        if(HonorStudentConstant.NCKD_CREATEEVALQUEST_ENTITYID.equals(actionId)){
+
+        }else if(HonorStudentConstant.TASK_CREATEEVAL.equals(actionId)){
+            Map<String, Object> result = (Map<String, Object>)closedCallBackEvent.getReturnData();
+            if(result != null) {
+                String taskInfoStr = (String) result.get("taskinfo");
+                if (StringUtils.isNotBlank(taskInfoStr)) {
+                    TaskInfo taskInfo = SerializationUtils.fromJsonString(taskInfoStr, TaskInfo.class);
+
+                    if (taskInfo.isTaskEnd()) {
+                        String status = taskInfo.getStatus();
+                        if (TaskStatusConstant.COMPLETED.equals(status)) {
+                            this.getView().showConfirm(
+                                    "操作成功!",
+                                    "生成综合评测问卷完成,可在【查看评价列表】中查看",
+                                    MessageBoxOptions.OK,
+                                    ConfirmTypes.Save,
+                                    new ConfirmCallBackListener()
+                            );
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+}

+ 43 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/EvaluationRuleFormPlugin.java

@@ -0,0 +1,43 @@
+package nckd.jxccl.hr.hstu.plugin.form;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.operate.Save;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+
+import java.util.Date;
+
+/**
+* 评价规则表单插件
+* @author W.Y.C
+* @date 2025/6/25 15:40
+* @version 1.0
+*/
+public class EvaluationRuleFormPlugin extends AbstractFormPlugin implements Plugin {
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        super.beforeDoOperation(args);
+        if (args.getSource() instanceof Save) {
+            DynamicObject dataEntity = this.getView().getModel().getDataEntity();
+            Date date = dataEntity.getDate(HonorStudentConstant.NCKD_BIZYEAR);
+            QFilter qFilter = new QFilter(HonorStudentConstant.NCKD_BIZYEAR, QCP.equals, date);
+            Long pkValue = (Long) dataEntity.getPkValue();
+            if(pkValue != null && pkValue > 0L){
+                qFilter.and(new QFilter(HonorStudentConstant.ID_KEY, QCP.not_equals, dataEntity.getPkValue()));
+            }
+            boolean exists = QueryServiceHelper.exists(HonorStudentConstant.EVALUATIONRULE_ENTITYID, new QFilter[]{qFilter});
+            if(exists){
+                args.setCancel(true);
+                this.getView().showErrorNotification(StrFormatter.format("所属年份【{}】的规则已存在,不能重复添加", DateUtil.getYear(date)));
+            }
+        }
+    }
+}

+ 114 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/EvaluationRuleListPlugin.java

@@ -0,0 +1,114 @@
+package nckd.jxccl.hr.hstu.plugin.form;
+
+import kd.bos.dataentity.OperateOption;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.constant.StatusEnum;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.entity.operate.Delete;
+import kd.bos.entity.operate.OperateOptionConst;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.form.operate.FormOperate;
+import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.utils.ConvertUtil;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+
+import java.util.Date;
+
+/**
+* 优秀生-评价规则
+* @author W.Y.C
+* @date 2025/6/18 14:26
+* @version 1.0
+*/
+public class EvaluationRuleListPlugin extends AbstractListPlugin implements Plugin {
+
+
+    private final static Log logger = LogFactory.getLog(EvaluationRuleListPlugin.class);
+
+    /** 标记开始 */
+    public static final String OP_BEGIN = "begin";
+    /** 标记结束 */
+    public static final String OP_END = "end";
+    /** 查看优秀生评价 */
+    public static final String OP_PERFPLAN = "PerfPlan";
+
+    private final String[] PERIOD_STATE = {"未开始","进行中","已结束","已就绪","已废弃"};
+
+    //开始:触发->提交、审核,设置开始时间为当前
+    //结束:触发->禁用,判断是否存在未评分的评价对象->设置结束时间
+    //删除:判断是否是未开始的状态,判断是否被使用
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs e) {
+        super.beforeDoOperation(e);
+        FormOperate operate = (FormOperate) e.getSource();
+        String operateKey = operate.getOperateKey();
+        //获取选中行数据的《使用状态》和《数据状态》
+        ListSelectedRowCollection selectedRows = e.getListSelectedData();
+        if(!selectedRows.isEmpty()) {
+            Long billId = (Long) selectedRows.get(0).getPrimaryKeyValue();
+            OperateOption option = OperateOption.create();
+            //提交、审批op事件不提示消息
+            option.setVariableValue(OperateOptionConst.ISSHOWMESSAGE, Boolean.FALSE+"");
+            if (OP_BEGIN.equals(operateKey)) {
+                //标记开始:触发-启用->自动提交->审核->赋值开始时间
+                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(HonorStudentConstant.EVALUATIONRULE_ENTITYID, new QFilter[]{new QFilter("id", QCP.equals, billId)});
+                String periodState = dynamicObject.getString(HonorStudentConstant.NCKD_PERIODSTATE);
+                if(!"0".equals(periodState)){
+                    this.getView().showMessage(StrFormatter.format("该规则【{}】,不能标记开始",PERIOD_STATE[ConvertUtil.toInt(periodState)]));
+                    e.setCancel(true);
+                    return;
+                }
+                String status = dynamicObject.getString(HonorStudentConstant.STATUS);
+                String enable = dynamicObject.getString(HonorStudentConstant.ENABLE);
+                this.getView().invokeOperation(HonorStudentConstant.OP_ENABLE, option);
+                this.getView().invokeOperation(HonorStudentConstant.OP_SUBMIT, option);
+                this.getView().invokeOperation(HonorStudentConstant.OP_AUDIT, option);
+                dynamicObject.set(HonorStudentConstant.NCKD_STARTTIME,new Date());
+                dynamicObject.set(HonorStudentConstant.NCKD_PERIODSTATE,new Date());
+                dynamicObject.set(HonorStudentConstant.NCKD_PERIODSTATE, StatusEnum.B.ordinal());
+                SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
+                //刷新列表
+                this.getView().invokeOperation(HonorStudentConstant.REFRESH);
+                this.getView().showSuccessNotification("操作成功!");
+            }else if (OP_END.equals(operateKey)) {
+                DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(HonorStudentConstant.EVALUATIONRULE_ENTITYID, new QFilter[]{new QFilter("id", QCP.equals, billId)});
+                String periodState = dynamicObject.getString(HonorStudentConstant.NCKD_PERIODSTATE);
+                if(!"1".equals(periodState)){
+                    this.getView().showMessage(StrFormatter.format("该规则【{}】,不能标记结束",PERIOD_STATE[ConvertUtil.toInt(periodState)]));
+                    e.setCancel(true);
+                    return;
+                }
+                dynamicObject.set(HonorStudentConstant.NCKD_ENDTIME,new Date());
+                dynamicObject.set(HonorStudentConstant.NCKD_PERIODSTATE, StatusEnum.C.ordinal());
+                SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
+                //刷新列表
+                this.getView().invokeOperation(HonorStudentConstant.REFRESH);
+                this.getView().showSuccessNotification("操作成功!");
+            }
+        }
+        if(operate instanceof Delete){
+            //TODO 校验规则是否被使用
+        }
+    }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        super.afterDoOperation(e);
+        FormOperate operate = (FormOperate) e.getSource();
+        String operateKey = operate.getOperateKey();
+        if(OP_BEGIN.equals(operateKey)) {
+            //设置开始时间为当前时间
+        }else if(OP_END.equals(operateKey)){
+            //标记结束:触发->禁用,判断是否存在未评分的评价对象;设置结束时间
+        }
+    }
+}

+ 41 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/form/OrgDifferenceFormPlugin.java

@@ -0,0 +1,41 @@
+package nckd.jxccl.hr.hstu.plugin.form;
+
+import kd.bos.base.AbstractBasePlugIn;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.operate.Save;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.hr.hstu.common.HonorStudentConstant;
+
+/**
+* 地区差异分插件
+* @author W.Y.C
+* @date 2025/6/19 16:12
+* @version 1.0
+*/
+public class OrgDifferenceFormPlugin extends AbstractBasePlugIn implements Plugin {
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        super.beforeDoOperation(args);
+        if (args.getSource() instanceof Save) {
+            DynamicObject dataEntity = this.getView().getModel().getDataEntity();
+            DynamicObject org = dataEntity.getDynamicObject(HonorStudentConstant.NCKD_ORG);
+            QFilter qFilter = new QFilter(HonorStudentConstant.NCKD_ORG, QCP.equals, org.getPkValue());
+            Long pkValue = (Long) dataEntity.getPkValue();
+            if(pkValue != null && pkValue > 0L){
+                qFilter.and(new QFilter(HonorStudentConstant.ID_KEY, QCP.not_equals, dataEntity.getPkValue()));
+            }
+            boolean exists = QueryServiceHelper.exists(HonorStudentConstant.ORGDIFFERENCE_ENTITYID, new QFilter[]{qFilter});
+            if(exists){
+                args.setCancel(true);
+                this.getView().showErrorNotification(StrFormatter.format("【{}】组织已存在差异分,不能重复添加",org.getString("name")));
+            }
+        }
+    }
+
+}

+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/operate/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/other/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/report/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/plugin/workflow/.gitkeep


+ 44 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/task/CreateEvalQuestTask.java

@@ -0,0 +1,44 @@
+package nckd.jxccl.hr.hstu.task;
+
+import kd.bos.context.RequestContext;
+import kd.bos.exception.KDBizException;
+import kd.bos.schedule.executor.AbstractTask;
+
+import java.util.Map;
+
+/**
+ * 生成评价对象异步任务
+ * @author W.Y.C
+ * @date 2025/7/1 15:26
+ * @version 1.0
+ */
+public class CreateEvalQuestTask extends AbstractTask {
+
+    @Override
+    public void execute(RequestContext ctx, Map<String, Object> params) {
+        try {
+            int totalSteps = 100;
+            for (int i = 0; i <= totalSteps; i++) {
+                // 检查是否被终止(用户手动终止)
+                if (isStop()) {
+                    stop();
+                    return;
+                }
+
+                // 更新进度(百分比+描述)
+                int progress = (i * 100) / totalSteps;
+                String desc = "处理中:" + i + "/" + totalSteps;
+                feedbackProgress(progress, desc, null);
+
+                // 模拟业务处理(实际替换为业务逻辑)
+                Thread.sleep(100);
+            }
+            feedbackProgress(100, "任务完成", null);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new KDBizException("任务执行失败:" + e.getMessage());
+        }
+    }
+
+
+}

+ 30 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/task/CreateEvalQuestTaskClick.java

@@ -0,0 +1,30 @@
+package nckd.jxccl.hr.hstu.task;
+
+import kd.bos.schedule.api.TaskInfo;
+import kd.bos.schedule.form.AbstractTaskClick;
+import kd.bos.schedule.form.event.ClickEventArgs;
+
+/**
+ * 生成评价对象异步任务事件
+ * @author W.Y.C
+ * @date 2025/7/1 16:59
+ * @version 1.0
+ */
+public class CreateEvalQuestTaskClick extends AbstractTaskClick {
+
+
+    @Override
+    public void click(ClickEventArgs e) {
+        // 1. 查询任务状态
+        TaskInfo taskInfo = this.queryTask();
+
+        if (taskInfo.isTaskEnd()) {
+            System.out.println();
+        }
+    }
+
+    @Override
+    public boolean release() {
+        return false;
+    }
+}

+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/hstu/webapi/.gitkeep