Bläddra i källkod

Merge branch 'feat-20230920-b2b'

lixuesong 1 år sedan
förälder
incheckning
3c2c326d38
19 ändrade filer med 1494 tillägg och 30 borttagningar
  1. 5 0
      db/v2.0/20230921.sql
  2. 5 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/CacheConstants.java
  3. 1 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/UpmsType.java
  4. 55 2
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/SysDeptController.java
  5. 335 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmDeptTaskController.java
  6. 34 4
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmScorePackageController.java
  7. 90 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/WmDeptRegulations.java
  8. 5 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/WmScorePackage.java
  9. 6 1
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/WmTaskType.java
  10. 252 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/dto/DeptTaskDTO.java
  11. 11 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/vo/WmTaskVO.java
  12. 20 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/WmDeptRegulationsMapper.java
  13. 13 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmDeptRegulationsService.java
  14. 37 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmDeptTaskService.java
  15. 11 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmScorePackageService.java
  16. 22 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmDeptRegulationsServiceImpl.java
  17. 443 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmDeptTaskServiceImpl.java
  18. 140 22
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmScorePackageServiceImpl.java
  19. 9 1
      hnqz-upms/hnqz-upms-biz/src/test/java/com/qunzhixinxi/hnqz/admin/WmTaskTypeServiceTest.java

+ 5 - 0
db/v2.0/20230921.sql

@@ -0,0 +1,5 @@
+alter table wm_task_type
+    add task_receiver_type char default '1' null comment '承接对象(1-个人,2-企业)';
+
+alter table wm_score_package
+    add ent_task_limit decimal(5, 2) default 0.00 null comment '企业任务上限(单位%)'

+ 5 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/CacheConstants.java

@@ -192,4 +192,9 @@ public interface CacheConstants {
 	 */
 	String TERMINATE_PACKAGE_KEY = "TERMINATE:PACKAGE:KEY:";
 
+	/**
+	 * 企业任务类型缓存key
+	 */
+	String ENT_TASK_CACHE_KEY = "ENT:TASK:CACHE:KEY:";
+
 }

+ 1 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/UpmsType.java

@@ -89,6 +89,7 @@ public final class UpmsType {
 		SPECIAL_SERVICE("SPECIAL_SERVICE", null, "专项服务"),
 		BUSINESS_COMPANY_CUSTOMER_MANAGEMENT("BUSINESS_COMPANY_CUSTOMER_MANAGEMENT", null, "商业公司客户管理"),
 		AGENT_CUSTOMER_MANAGEMENT("AGENT_CUSTOMER_MANAGEMENT", null, "代理商客户管理"),
+		ENT_TASK("ENT_TASK", null, "企业任务"),
 		TASK_TYPE_CONFIG("TASK_TYPE_CONFIG", null, "任务类型配置");
 
 

+ 55 - 2
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/SysDeptController.java

@@ -19,21 +19,25 @@
 
 package com.qunzhixinxi.hnqz.admin.controller;
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qunzhixinxi.hnqz.admin.api.entity.SysDept;
 import com.qunzhixinxi.hnqz.admin.api.entity.SysDeptRelation;
 import com.qunzhixinxi.hnqz.admin.entity.WmDaAgent;
 import com.qunzhixinxi.hnqz.admin.entity.WmDaDrugEnt;
+import com.qunzhixinxi.hnqz.admin.entity.WmDeptRegulations;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.EnableEnum;
 import com.qunzhixinxi.hnqz.admin.service.SysDeptRelationService;
 import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
 import com.qunzhixinxi.hnqz.admin.service.WmDaAgentService;
 import com.qunzhixinxi.hnqz.admin.service.WmDaDrugEntService;
+import com.qunzhixinxi.hnqz.admin.service.WmDeptRegulationsService;
 import com.qunzhixinxi.hnqz.common.core.util.R;
 import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
 import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
 import io.swagger.annotations.Api;
-import io.swagger.models.auth.In;
 import lombok.AllArgsConstructor;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -41,10 +45,10 @@ import org.springframework.web.bind.annotation.*;
 import javax.validation.Valid;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -68,6 +72,8 @@ public class SysDeptController {
 
 	private final WmDaAgentService wmDaAgentService;
 
+	private final WmDeptRegulationsService wmDeptRegulationsService;
+
 	/**
 	 * 通过ID查询
 	 * @param id ID
@@ -442,4 +448,51 @@ public class SysDeptController {
 	public R<?> listEntAndAgent(Page page, String deptName) {
 		return R.ok(sysDeptService.listEntAndAgent(page, deptName));
 	}
+
+	/**
+	 * 查询部门规章制度列表
+	 *
+	 * @return {@link R}<{@link ?}> 返回结果
+	 */
+	@GetMapping("/dept-regulations/list")
+	public R<List<WmDeptRegulations>> listDeptRegulations() {
+		Integer deptId = SecurityUtils.getUser().getDeptId();
+		List<WmDeptRegulations> list = wmDeptRegulationsService.list(Wrappers.<WmDeptRegulations>lambdaQuery()
+				.eq(WmDeptRegulations::getDeptId, deptId)
+				.eq(WmDeptRegulations::getDelFlag, DelEnum.NOT_DEL.val()));
+		list.sort((o1, o2) -> {
+			if (o1.getSort() > 0 && o2.getSort() > 0) {
+				return o1.getSort() - o2.getSort();
+			}
+			return o1.getId() - o2.getId();
+		});
+
+		return R.ok(list);
+	}
+
+	/**
+	 * 保存部门规章制度
+	 *
+	 * @param list 列表
+	 * @return {@link R}<{@link ?}>
+	 */
+	@PostMapping("/dept-regulations/save")
+	public R<?> saveDeptRegulations(@RequestBody List<WmDeptRegulations> list) {
+		if (CollUtil.isEmpty(list)) {
+			throw new RuntimeException("必填参数为空");
+		}
+
+		Integer deptId = SecurityUtils.getUser().getDeptId();
+
+		// 先删除
+		wmDeptRegulationsService.remove(Wrappers.<WmDeptRegulations>lambdaQuery()
+				.eq(WmDeptRegulations::getDeptId, deptId));
+		// 后保存
+		list.forEach(regulations -> {
+			regulations.setDeptId(deptId);
+			regulations.setDelFlag(DelEnum.NOT_DEL.val());
+		});
+
+		return R.ok(wmDeptRegulationsService.saveBatch(list));
+	}
 }

+ 335 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmDeptTaskController.java

@@ -0,0 +1,335 @@
+package com.qunzhixinxi.hnqz.admin.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackage;
+import com.qunzhixinxi.hnqz.admin.entity.WmTask;
+import com.qunzhixinxi.hnqz.admin.entity.WmTaskType;
+import com.qunzhixinxi.hnqz.admin.entity.dto.DeptTaskDTO;
+import com.qunzhixinxi.hnqz.admin.entity.vo.WmTaskVO;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.EnableEnum;
+import com.qunzhixinxi.hnqz.admin.enums.ReportEnum;
+import com.qunzhixinxi.hnqz.admin.enums.TaskStatusEnum;
+import com.qunzhixinxi.hnqz.admin.service.SysUserService;
+import com.qunzhixinxi.hnqz.admin.service.WmDeptTaskService;
+import com.qunzhixinxi.hnqz.admin.service.WmScorePackageService;
+import com.qunzhixinxi.hnqz.admin.service.WmTaskService;
+import com.qunzhixinxi.hnqz.admin.service.WmTaskTypeService;
+import com.qunzhixinxi.hnqz.common.core.util.R;
+import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 企业任务控制器
+ *
+ * @author lixuesong
+ * @date 2023/09/21
+ */
+@Slf4j
+@RestController
+@AllArgsConstructor
+public class WmDeptTaskController {
+
+    private final WmScorePackageService wmScorePackageService;
+    private final WmDeptTaskService wmDeptTaskService;
+    private final WmTaskService wmTaskService;
+    private final WmTaskTypeService wmTaskTypeService;
+    private final SysUserService sysUserService;
+    private final RedisTemplate redisTemplate;
+
+    /**
+     * 查询关联的企业积分包
+     *
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @GetMapping("/dept-task/list-related-ent-package")
+    public R<?> listRelatedEntPackage() {
+        Integer deptId = SecurityUtils.getUser().getDeptId();
+
+        List<WmScorePackage> packageList = wmScorePackageService.getScorePackagekfpjf(null, deptId, new String[]{"0", "1", "2"}, null);
+
+        List<Map<String, String>> results = new ArrayList<>();
+        if (CollUtil.isNotEmpty(packageList)) {
+            Set<String> packageIdSet = packageList.stream().map(WmScorePackage::getId).collect(Collectors.toSet());
+            // 校验是否超过积分包企业任务上限
+            List<WmTask> queryTaskList = wmTaskService.list(Wrappers.<WmTask>lambdaQuery()
+                    .in(WmTask::getScorePackageId, packageIdSet)
+                    .eq(WmTask::getEnableFlag, EnableEnum.ENABLE.val())
+                    .eq(WmTask::getDelFlag, DelEnum.NOT_DEL.val())
+                    .eq(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val()));
+            Map<String, Integer> packageTasksScoreMap = new HashMap<>();
+            if (CollUtil.isNotEmpty(queryTaskList)) {
+                packageTasksScoreMap = queryTaskList.stream()
+                        .collect(Collectors.groupingBy(WmTask::getScorePackageId,
+                                Collectors.summingInt(WmTask::getScore)));
+            }
+
+            Map<String, Integer> finalPackageTasksScoreMap = packageTasksScoreMap;
+            packageList.stream()
+                    .filter(wmScorePackage -> {
+                        Integer tasksScore = finalPackageTasksScoreMap.getOrDefault(wmScorePackage.getId(), 0);
+                        // 是否超过企业任务上限
+                        boolean deptLimitFlag = BigDecimal.valueOf(tasksScore)
+                                .compareTo(BigDecimal.valueOf(wmScorePackage.getScore())
+                                        .multiply(wmScorePackage.getEntTaskLimit()).divide(new BigDecimal("100"))) < 0;
+                        // 同时满足以下条件:
+                        // 1.可分配积分值大于0的
+                        // 2.没有超过企业任务上限
+                        if (wmScorePackage.getKfpjf() > 0 && deptLimitFlag
+                                && wmScorePackage.getEntTaskLimit().compareTo(BigDecimal.ZERO) > 0) {
+                            return true;
+                        }
+                        return false;
+                    }).forEach(wmScorePackage -> {
+                        Map<String, String> result = new HashMap<>();
+                        result.put("id", wmScorePackage.getId());
+                        result.put("scorePackageName", wmScorePackage.getScorePackageName());
+                        result.put("score", String.valueOf(wmScorePackage.getScore()));
+                        result.put("kfpjf", String.valueOf(wmScorePackage.getKfpjf()));
+                        results.add(result);
+                    });
+        }
+
+        return R.ok(results);
+    }
+
+    /**
+     * 分页查询企业任务
+     *
+     * @param page             分页参数
+     * @param scorePackageName 积分包名称
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @GetMapping("/dept-task/page-ent-task")
+    public R<?> pageEntTask(Page<WmTaskVO> page, String scorePackageName) {
+
+        Integer deptId = SecurityUtils.getUser().getDeptId();
+
+        // 查询当前企业所有的企业大包(包括上级发给自己的,和自己发给自己的)
+        LambdaQueryWrapper<WmScorePackage> queryWrapper = Wrappers.<WmScorePackage>lambdaQuery()
+                .eq(WmScorePackage::getDeptId, deptId)
+                .in(WmScorePackage::getTypeid, "0", "1", "2")
+                .eq(WmScorePackage::getDelFlag, DelEnum.NOT_DEL.val())
+                .eq(WmScorePackage::getEnableFlag, EnableEnum.ENABLE.val())
+                .eq(WmScorePackage::getOldPackage, "0");
+        if (StrUtil.isNotBlank(scorePackageName)) {
+            queryWrapper.like(WmScorePackage::getScorePackageName, scorePackageName);
+        }
+        List<WmScorePackage> relatedPackages = wmScorePackageService.list(queryWrapper);
+        if (CollUtil.isEmpty(relatedPackages)) {
+            return R.ok(page);
+        }
+        // 积分包id列表
+        Set<String> packageIdSet = relatedPackages.stream().map(WmScorePackage::getId).collect(Collectors.toSet());
+        // 积分包名称map
+        Map<String, String> packageNameMap = relatedPackages.stream()
+                .collect(Collectors.toMap(WmScorePackage::getId, WmScorePackage::getScorePackageName));
+
+        // 查询积分包下的企业任务
+        Page<WmTask> taskPage = wmTaskService.page(new Page<>(page.getCurrent(), page.getSize()),
+                Wrappers.<WmTask>lambdaQuery()
+                        .in(WmTask::getScorePackageId, packageIdSet)
+                        .orderByDesc(WmTask::getLookintoDate));
+
+        if (CollUtil.isEmpty(taskPage.getRecords())) {
+            return R.ok(page);
+        }
+
+        // 查询taskType
+        List<WmTaskType> taskTypeList = wmTaskTypeService.list(Wrappers.<WmTaskType>lambdaQuery()
+                .eq(WmTaskType::getTaskTypeLevel, "1")
+                .eq(WmTaskType::getDelFlag, "0")
+                .eq(WmTaskType::getEnableFlag, "0"));
+        // taskType通过id分组(key为parentId,value为taskTypeName)
+        Map<String, String> taskTypeIdMap = taskTypeList.stream()
+                .collect(Collectors.toMap(WmTaskType::getId, WmTaskType::getTaskTypeName));
+
+        // 查询涉及到的user
+        Set<String> userIdSet = taskPage.getRecords().stream().map(WmTask::getTaskUserId).collect(Collectors.toSet());
+        List<SysUser> users = sysUserService.listByIds(userIdSet);
+        Map<Integer, String> userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getRealname));
+
+        List<WmTaskVO> vos = taskPage.getRecords().stream().map(wmTask -> {
+            WmTaskVO wmTaskVO = BeanUtil.copyProperties(wmTask, WmTaskVO.class);
+            // 积分包名称
+            wmTaskVO.setScorePackageName(packageNameMap.getOrDefault(wmTask.getScorePackageId(), ""));
+            // 任务类型名称
+            wmTaskVO.setTaskTypeName(taskTypeIdMap.getOrDefault(wmTask.getTaskTypeId(), ""));
+            // 姓名
+            wmTaskVO.setTaskUsername(userMap.getOrDefault(Integer.parseInt(wmTask.getTaskUserId()), ""));
+            // 报告审核状态
+            wmTaskVO.setApprovalOpinionName("");
+            if (StrUtil.isNotBlank(wmTask.getReportDrugApprovalOpinion())) {
+                if (ReportEnum.APPROVAL_OPINION_YES.getType().equals(wmTask.getReportDrugApprovalOpinion())) {
+                    wmTaskVO.setApprovalOpinion(ReportEnum.APPROVAL_OPINION_YES.getType());
+                    wmTaskVO.setApprovalOpinionName(ReportEnum.APPROVAL_OPINION_YES.getDescription());
+                } else if (ReportEnum.APPROVAL_OPINION_NO.getType().equals(wmTask.getReportDrugApprovalOpinion())) {
+                    wmTaskVO.setApprovalOpinion(ReportEnum.APPROVAL_OPINION_NO.getType());
+                    wmTaskVO.setApprovalOpinionName(ReportEnum.APPROVAL_OPINION_NO.getDescription());
+                }
+
+            } else if (StrUtil.isNotBlank(wmTask.getReportOneApprovalOpinion())) {
+                if (ReportEnum.APPROVAL_OPINION_YES.getType().equals(wmTask.getReportOneApprovalOpinion())) {
+                    wmTaskVO.setApprovalOpinion(ReportEnum.APPROVAL_OPINION_YES.getType());
+                    wmTaskVO.setApprovalOpinionName(ReportEnum.APPROVAL_OPINION_YES.getDescription());
+                } else if (ReportEnum.APPROVAL_OPINION_NO.getType().equals(wmTask.getReportOneApprovalOpinion())) {
+                    wmTaskVO.setApprovalOpinion(ReportEnum.APPROVAL_OPINION_NO.getType());
+                    wmTaskVO.setApprovalOpinionName(ReportEnum.APPROVAL_OPINION_NO.getDescription());
+                }
+            } else {
+                wmTaskVO.setUpdateTime(null);
+            }
+
+            return wmTaskVO;
+        }).collect(Collectors.toList());
+
+        page.setRecords(vos);
+        page.setTotal(taskPage.getTotal());
+        page.setPages(taskPage.getPages());
+
+        return R.ok(page);
+    }
+
+    /**
+     * 企业任务保存-企业通用
+     *
+     * @param params 参数
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @SysLog("企业任务保存-企业通用")
+    @PostMapping("/dept-task/save-task-type61")
+    public R<?> saveEntTaskForTaskType61(@Validated @RequestBody DeptTaskDTO.TaskType61 params) {
+        log.info("企业任务保存-企业通用请求参数:{}", params);
+
+        return R.ok(wmDeptTaskService.saveEntTaskForTaskType61(params));
+    }
+
+    /**
+     * 企业任务保存-医学会各级年会及卫星会
+     *
+     * @param params 参数
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @SysLog("企业任务保存-医学会各级年会及卫星会")
+    @PostMapping("/dept-task/save-task-type62")
+    public R<?> saveEntTaskForTaskType62(@Validated @RequestBody DeptTaskDTO.TaskType62 params) {
+        log.info("企业任务保存-医学会各级年会及卫星会请求参数:{}", params);
+
+        return R.ok(wmDeptTaskService.saveEntTaskForTaskType62(params));
+    }
+
+    /**
+     * 企业任务保存-专家共识巡讲会
+     *
+     * @param params 参数
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @SysLog("企业任务保存-专家共识巡讲会")
+    @PostMapping("/dept-task/save-task-type63")
+    public R<?> saveEntTaskForTaskType63(@Validated @RequestBody DeptTaskDTO.TaskType63 params) {
+        log.info("企业任务保存-专家共识巡讲会请求参数:{}", params);
+
+        return R.ok(wmDeptTaskService.saveEntTaskForTaskType63(params));
+    }
+
+    /**
+     * 企业任务保存-企业通用-缓存
+     *
+     * @param params 参数
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @SysLog("企业任务保存-企业通用-缓存")
+    @PostMapping("/dept-task/save-task-type61-temp")
+    public R<?> saveEntTaskForTaskType61Temp(@RequestBody DeptTaskDTO.TaskType61 params) {
+        log.info("企业任务保存-企业通用-缓存:{}", params);
+
+        String cacheKey = String.format("%s-%s-%s", CacheConstants.ENT_TASK_CACHE_KEY, "61", SecurityUtils.getUser().getId());
+        redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(params));
+
+        return R.ok();
+    }
+
+    /**
+     * 企业任务保存-医学会各级年会及卫星会-缓存
+     *
+     * @param params 参数
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @SysLog("企业任务保存-医学会各级年会及卫星会-缓存")
+    @PostMapping("/dept-task/save-task-type62-temp")
+    public R<?> saveEntTaskForTaskType62Temp(@RequestBody DeptTaskDTO.TaskType62 params) {
+        log.info("企业任务保存-医学会各级年会及卫星会-缓存:{}", params);
+
+        String cacheKey = String.format("%s-%s-%s", CacheConstants.ENT_TASK_CACHE_KEY, "62", SecurityUtils.getUser().getId());
+        redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(params));
+
+        return R.ok();
+    }
+
+    /**
+     * 企业任务保存-专家共识巡讲会-缓存
+     *
+     * @param params 参数
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @SysLog("企业任务保存-专家共识巡讲会-缓存")
+    @PostMapping("/dept-task/save-task-type63-temp")
+    public R<?> saveEntTaskForTaskType63Temp(@RequestBody DeptTaskDTO.TaskType63 params) {
+        log.info("企业任务保存-专家共识巡讲会-缓存:{}", params);
+
+        String cacheKey = String.format("%s-%s-%s", CacheConstants.ENT_TASK_CACHE_KEY, "63", SecurityUtils.getUser().getId());
+        redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(params));
+
+        return R.ok();
+    }
+
+    /**
+     * 获取企业任务保存缓存数据
+     *
+     * @param taskTypeId 任务类型 ID
+     * @return {@link R}<{@link ?}> 结果
+     */
+    @GetMapping("/dept-task/task-type-temp/{taskTypeId}")
+    public R<?> getEntTaskTemp(@PathVariable("taskTypeId") String taskTypeId) {
+        String cacheKey = String.format("%s-%s-%s", CacheConstants.ENT_TASK_CACHE_KEY, taskTypeId, SecurityUtils.getUser().getId());
+        String jsonStr = (String) redisTemplate.opsForValue().get(cacheKey);
+        if (StrUtil.isBlank(jsonStr)) {
+            return R.ok();
+        }
+        switch (taskTypeId) {
+            case "61":
+                return R.ok(JSONUtil.toBean(jsonStr, DeptTaskDTO.TaskType61.class));
+            case "62":
+                return R.ok(JSONUtil.toBean(jsonStr, DeptTaskDTO.TaskType62.class));
+            case "63":
+                return R.ok(JSONUtil.toBean(jsonStr, DeptTaskDTO.TaskType63.class));
+            default:
+                return R.ok();
+        }
+    }
+}

+ 34 - 4
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmScorePackageController.java

@@ -1769,6 +1769,17 @@ public class WmScorePackageController {
 						wmScorePackage.getScore(), deptRecharge.getScore(), limitScore);
 				throw new RuntimeException(String.format("积分余额:%s。积分不足", deptRecharge.getScore()));
 			}
+		} else {
+			// 校验上级可分配积分值
+			List<WmScorePackage> scorePackagekfpjf = wmScorePackageService.getScorePackagekfpjf(null, null, new String[]{"0", "1", "2"},
+					new String[]{wmScorePackage.getRelationScoreId()});
+
+			if (CollUtil.isNotEmpty(scorePackagekfpjf)) {
+				int kfpjf = scorePackagekfpjf.get(0).getKfpjf();
+				if (wmScorePackage.getScore() > kfpjf) {
+					throw new RuntimeException("可分配积分值不足");
+				}
+			}
 		}
 
 		wmScorePackage.setTypeid("");
@@ -2561,7 +2572,14 @@ public class WmScorePackageController {
 				.eq(SysDeptRechargeRecord::getPackageId, wmScorePackage.getId())
 				.in(SysDeptRechargeRecord::getType, RechargeRecordType.SEND_PACKAGE_DEPT, RechargeRecordType.SEND_PACKAGE_PERSONAL));
 		LocalDateTime now = LocalDateTime.now();
-		if (rechargeRecord != null) {
+
+		boolean relatedScoreId = StrUtil.isNotBlank(wmScorePackage.getRelationScoreId()) && Integer.parseInt(wmScorePackage.getRelationScoreId()) > 0;
+
+		// 积分值相比修改前的变动(相对于积分余额,增加则为负-消耗,减少则为正-回收)
+		int changeScore = oldPackageScore - wmScorePackage.getScore();
+
+		if (!relatedScoreId) {
+			// 没有关联上级包的情况
 			log.info("修改积分包,更新积分配置信息");
 			// 校验 发包积分 < 积分充值分配的积分 则可以发包
 			SysDeptRecharge deptRecharge = sysDeptRechargeMapper.selectOne(Wrappers.<SysDeptRecharge>lambdaQuery()
@@ -2571,8 +2589,6 @@ public class WmScorePackageController {
 				throw new RuntimeException("积分余额:0。积分不足");
 			}
 
-			// 积分值相比修改前的变动(相对于积分余额,增加则为负-消耗,减少则为正-回收)
-			int changeScore = oldPackageScore - wmScorePackage.getScore();
 			int currentScore = deptRecharge.getScore() + changeScore;
 
 			int limitScore = deptRecharge.getScore() + deptRecharge.getOverdrawScore();
@@ -2602,11 +2618,25 @@ public class WmScorePackageController {
 			newRechargeRecord.setCurrentScore(currentScore);
 			newRechargeRecord.setType(RechargeRecordType.RECOVERY);
 			newRechargeRecord.setDeptId(deptRecharge.getDeptId());
-			newRechargeRecord.setRelationDeptId(rechargeRecord.getRelationDeptId());
+			newRechargeRecord.setRelationDeptId(rechargeRecord != null ? rechargeRecord.getRelationDeptId() : null);
 			newRechargeRecord.setPackageType(RechargeRecordPackageType.TO_ENTERPRISE);
 			newRechargeRecord.setPackageId(wmScorePackage.getId());
 			newRechargeRecord.setCreateUser(userId);
 			sysDeptRechargeRecordMapper.insert(newRechargeRecord);
+		} else {
+			// 关联了上级包的情况
+			if (changeScore < 0) {
+				// 变动积分后比原先多,则校验上级可分配积分值
+				List<WmScorePackage> scorePackagekfpjf = wmScorePackageService.getScorePackagekfpjf(null, null, new String[]{"0", "1", "2"},
+						new String[]{wmScorePackage.getRelationScoreId()});
+
+				if (CollUtil.isNotEmpty(scorePackagekfpjf)) {
+					int kfpjf = scorePackagekfpjf.get(0).getKfpjf();
+					if (Math.abs(changeScore) > kfpjf) {
+						throw new RuntimeException("可分配积分值不足");
+					}
+				}
+			}
 		}
 
 		return R.ok(Boolean.TRUE);

+ 90 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/WmDeptRegulations.java

@@ -0,0 +1,90 @@
+package com.qunzhixinxi.hnqz.admin.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 企业规章制度
+ * @TableName wm_dept_regulations
+ */
+@TableName(value ="wm_dept_regulations", autoResultMap = true)
+@Data
+public class WmDeptRegulations implements Serializable {
+    private static final long serialVersionUID = 345213921273253849L;
+    
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 部门id
+     */
+    private Integer deptId;
+
+    /**
+     * 文件名称(见字典值dept_regulations_filename)
+     */
+    @NotBlank(message = "文件名称必填")
+    private String fileName;
+
+    /**
+     * 文件地址
+     */
+    @NotEmpty(message = "文件地址必填")
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private List<FileUrlObj> fileUrl;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 删除标记:0(未删除),1(已删除)
+     */
+    private String delFlag;
+
+    /**
+     * 是否禁用:0(启用),1(禁用)
+     */
+    @NotBlank(message = "是否禁用必填")
+    private String enableFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 修改时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 文件 URL obj
+     *
+     * @author lixuesong
+     * @date 2023/09/27
+     */
+    @Data
+    public static class FileUrlObj implements Serializable {
+        private static final long serialVersionUID = 7914265352319844404L;
+
+        private String fileName;
+
+        private String url;
+    }
+
+}

+ 5 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/WmScorePackage.java

@@ -559,6 +559,11 @@ public class WmScorePackage extends Model<WmScorePackage> {
 	 */
 	private Integer mahSettleDeptId;
 
+	/**
+	 * 企业任务上限(单位%)
+	 */
+	private BigDecimal entTaskLimit;
+
 	@AllArgsConstructor
 	public enum PackageStopStatus {
 		NOTHING(0, "不能操作"),

+ 6 - 1
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/WmTaskType.java

@@ -154,4 +154,9 @@ private static final long serialVersionUID = 1L;
 	 */
 	@ApiModelProperty(value="父级id")
 	private String parentId;
-    }
+
+	/**
+	 * 承接对象(1-个人,2-企业)
+	 */
+	private String taskReceiverType;
+}

+ 252 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/dto/DeptTaskDTO.java

@@ -0,0 +1,252 @@
+package com.qunzhixinxi.hnqz.admin.entity.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 企业任务请求参数DTO
+ *
+ * @author lixuesong
+ * @date 2023/09/21
+ */
+@Data
+public class DeptTaskDTO implements Serializable {
+    private static final long serialVersionUID = 410601826934557948L;
+
+    /**
+     * 任务类型61-企业通用
+     *
+     * @author lixuesong
+     * @date 2023/09/21
+     */
+    @Data
+    public static class TaskType61 implements Serializable {
+        private static final long serialVersionUID = -8969888154230924285L;
+
+        /**
+         * 积分包id
+         */
+        @NotBlank(message = "积分包id必填")
+        private String packageId;
+
+        /**
+         * 主题
+         */
+        @NotBlank(message = "主题必填")
+        private String meetingtTitle;
+
+        /**
+         * 时间
+         */
+        @NotBlank(message = "时间必填")
+        private String meetingTime;
+
+        /**
+         * 文件上传
+         */
+        @NotEmpty(message = "文件上传必填")
+        private List<FileUrlObj> files;
+
+        /**
+         * 外采费用
+         */
+        private String outsourcingAmount;
+
+        /**
+         * 外采费用-凭证
+         */
+        private List<FileUrlObj> outsourcingAmountProof;
+
+        /**
+         * 任务积分
+         */
+        @NotNull(message = "任务积分必填")
+        private Integer score;
+
+        /**
+         * 会议总结
+         */
+        private String meetingSummary;
+    }
+
+    /**
+     * 任务类型62-医学会各级年会及卫星会
+     *
+     * @author lixuesong
+     * @date 2023/09/21
+     */
+    @Data
+    public static class TaskType62 implements Serializable {
+        private static final long serialVersionUID = -2282200603021121878L;
+
+        /**
+         * 积分包id
+         */
+        @NotBlank(message = "积分包id必填")
+        private String packageId;
+
+        /**
+         * 会议主题
+         */
+        @NotBlank(message = "会议主题必填")
+        private String meetingtTitle;
+
+        /**
+         * 会议时间
+         */
+        @NotBlank(message = "会议时间必填")
+        private String meetingTime;
+
+        /**
+         * 会议人次
+         */
+        @NotBlank(message = "会议人次必填")
+        private String meetingNumber;
+
+        /**
+         * 会议邀请函
+         */
+        @NotEmpty(message = "会议邀请函必填")
+        private List<FileUrlObj> meetingInvitationUrl;
+
+        /**
+         * 会议计划表
+         */
+        @NotEmpty(message = "会议计划表必填")
+        private List<FileUrlObj> meetingPlanUrl;
+
+        /**
+         * 会议签到表
+         */
+        @NotEmpty(message = "会议签到表必填")
+        private List<FileUrlObj> meetingCheckInUrl;
+
+        /**
+         * 现场照片
+         */
+        @NotEmpty(message = "现场照片必填")
+        private List<FileUrlObj> livePhotosUrl;
+
+        /**
+         * 会议内容
+         */
+        @NotEmpty(message = "会议内容必填")
+        private List<FileUrlObj> meetingContentUrl;
+
+        /**
+         * 外采费用
+         */
+        private String outsourcingAmount;
+
+        /**
+         * 外采费用-凭证
+         */
+        private List<FileUrlObj> outsourcingAmountProof;
+
+        /**
+         * 会议总结
+         */
+        private String meetingSummary;
+    }
+
+    /**
+     * 任务类型63-专家共识巡讲会
+     *
+     * @author lixuesong
+     * @date 2023/09/21
+     */
+    @Data
+    public static class TaskType63 implements Serializable {
+        private static final long serialVersionUID = -1918885625462400849L;
+
+        /**
+         * 积分包id
+         */
+        @NotBlank(message = "积分包id必填")
+        private String packageId;
+
+        /**
+         * 主题
+         */
+        @NotBlank(message = "主题必填")
+        private String meetingtTitle;
+
+        /**
+         * 时间
+         */
+        @NotBlank(message = "时间必填")
+        private String meetingTime;
+
+        /**
+         * 参加人次
+         */
+        @NotBlank(message = "参加人次必填")
+        private String meetingNumber;
+
+        /**
+         * 活动策划书
+         */
+        @NotEmpty(message = "活动策划书必填")
+        private List<FileUrlObj> eventPlannerUrl;
+
+        /**
+         * 活动计划表
+         */
+        @NotEmpty(message = "活动计划表必填")
+        private List<FileUrlObj> meetingPlanUrl;
+
+        /**
+         * 会议签到表
+         */
+        @NotEmpty(message = "会议签到表必填")
+        private List<FileUrlObj> meetingCheckInUrl;
+
+        /**
+         * 现场照片
+         */
+        @NotEmpty(message = "现场照片必填")
+        private List<FileUrlObj> livePhotosUrl;
+
+        /**
+         * 会议内容
+         */
+        @NotEmpty(message = "会议内容必填")
+        private List<FileUrlObj> meetingContentUrl;
+
+        /**
+         * 外采费用
+         */
+        private String outsourcingAmount;
+
+        /**
+         * 外采费用-凭证
+         */
+        private List<FileUrlObj> outsourcingAmountProof;
+
+        /**
+         * 会议总结
+         */
+        private String meetingSummary;
+    }
+
+    /**
+     * 文件 URL obj
+     *
+     * @author lixuesong
+     * @date 2023/09/27
+     */
+    @Data
+    public static class FileUrlObj implements Serializable {
+        private static final long serialVersionUID = 7914265352319844404L;
+
+        private String fileName;
+        
+        private String url;
+    }
+
+}

+ 11 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/vo/WmTaskVO.java

@@ -50,6 +50,11 @@ public class WmTaskVO implements Serializable {
 	@ApiModelProperty(value="任务类型ID")
 	private String taskTypeId;
 
+	/**
+	 * 任务类型名称
+	 */
+	private String taskTypeName;
+
 	@ApiModelProperty(value="任务得分")
 	Integer score;
 
@@ -193,6 +198,12 @@ public class WmTaskVO implements Serializable {
 	 */
 	@ApiModelProperty(value="审批意见")
 	private String approvalOpinion;
+
+	/**
+	 * 审批意见中文名称
+	 */
+	private String approvalOpinionName;
+
 	/**
 	 * 审批说明
 	 */

+ 20 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/WmDeptRegulationsMapper.java

@@ -0,0 +1,20 @@
+package com.qunzhixinxi.hnqz.admin.mapper;
+
+import com.qunzhixinxi.hnqz.admin.entity.WmDeptRegulations;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author li312
+* @description 针对表【wm_dept_regulations(企业规章制度)】的数据库操作Mapper
+* @createDate 2023-09-20 17:49:45
+* @Entity com.qunzhixinxi.hnqz.admin.entity.WmDeptRegulations
+*/
+@Mapper
+public interface WmDeptRegulationsMapper extends BaseMapper<WmDeptRegulations> {
+
+}
+
+
+
+

+ 13 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmDeptRegulationsService.java

@@ -0,0 +1,13 @@
+package com.qunzhixinxi.hnqz.admin.service;
+
+import com.qunzhixinxi.hnqz.admin.entity.WmDeptRegulations;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author li312
+* @description 针对表【wm_dept_regulations(企业规章制度)】的数据库操作Service
+* @createDate 2023-09-20 17:49:45
+*/
+public interface WmDeptRegulationsService extends IService<WmDeptRegulations> {
+
+}

+ 37 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmDeptTaskService.java

@@ -0,0 +1,37 @@
+package com.qunzhixinxi.hnqz.admin.service;
+
+import com.qunzhixinxi.hnqz.admin.entity.dto.DeptTaskDTO;
+import com.qunzhixinxi.hnqz.common.core.util.R;
+
+/**
+ * 企业任务服务
+ *
+ * @author lixuesong
+ * @date 2023/09/21
+ */
+public interface WmDeptTaskService {
+
+    /**
+     * 企业任务保存-企业通用
+     *
+     * @param params 参数
+     * @return {@link Boolean} 结果
+     */
+    Boolean saveEntTaskForTaskType61(DeptTaskDTO.TaskType61 params);
+
+    /**
+     * 企业任务保存-医学会各级年会及卫星会
+     *
+     * @param params 参数
+     * @return {@link Boolean} 结果
+     */
+    Boolean saveEntTaskForTaskType62(DeptTaskDTO.TaskType62 params);
+
+    /**
+     * 企业任务保存-专家共识巡讲会
+     *
+     * @param params 参数
+     * @return {@link Boolean} 结果
+     */
+    Boolean saveEntTaskForTaskType63(DeptTaskDTO.TaskType63 params);
+}

+ 11 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmScorePackageService.java

@@ -212,4 +212,15 @@ public interface WmScorePackageService extends IService<WmScorePackage> {
 	 * @return {@link Boolean} 结果
 	 */
 	Boolean terminatePackageForDept(String packageId, UpmsType.TerminatePackageType terminatePackageType);
+
+	/**
+	 * 获取指定企业下积分包的可分配积分值
+	 *
+	 * @param superDeptId 上级企业id
+	 * @param deptId      企业id
+	 * @param typeIds     企业类型
+	 * @param packageIds  积分包id
+	 * @return 结果
+	 */
+	List<WmScorePackage> getScorePackagekfpjf(Integer superDeptId, Integer deptId, String[] typeIds, String[] packageIds);
 }

+ 22 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmDeptRegulationsServiceImpl.java

@@ -0,0 +1,22 @@
+package com.qunzhixinxi.hnqz.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qunzhixinxi.hnqz.admin.entity.WmDeptRegulations;
+import com.qunzhixinxi.hnqz.admin.service.WmDeptRegulationsService;
+import com.qunzhixinxi.hnqz.admin.mapper.WmDeptRegulationsMapper;
+import org.springframework.stereotype.Service;
+
+/**
+* @author li312
+* @description 针对表【wm_dept_regulations(企业规章制度)】的数据库操作Service实现
+* @createDate 2023-09-20 17:49:45
+*/
+@Service
+public class WmDeptRegulationsServiceImpl extends ServiceImpl<WmDeptRegulationsMapper, WmDeptRegulations>
+    implements WmDeptRegulationsService{
+
+}
+
+
+
+

+ 443 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmDeptTaskServiceImpl.java

@@ -0,0 +1,443 @@
+package com.qunzhixinxi.hnqz.admin.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
+import com.qunzhixinxi.hnqz.admin.api.constant.UpmsType;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmTaskSubmissionPercentRule;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackage;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackageStatus;
+import com.qunzhixinxi.hnqz.admin.entity.WmScoreTaskType;
+import com.qunzhixinxi.hnqz.admin.entity.WmTask;
+import com.qunzhixinxi.hnqz.admin.entity.WmTaskContent;
+import com.qunzhixinxi.hnqz.admin.entity.WmTaskType;
+import com.qunzhixinxi.hnqz.admin.entity.dto.DeptTaskDTO;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.EnableEnum;
+import com.qunzhixinxi.hnqz.admin.enums.PackageTypeEnum;
+import com.qunzhixinxi.hnqz.admin.enums.TaskStatusEnum;
+import com.qunzhixinxi.hnqz.admin.service.WmDeptTaskService;
+import com.qunzhixinxi.hnqz.admin.service.WmScorePackageService;
+import com.qunzhixinxi.hnqz.admin.service.WmScorePackageStatusService;
+import com.qunzhixinxi.hnqz.admin.service.WmScoreTaskTypeService;
+import com.qunzhixinxi.hnqz.admin.service.WmTaskContentService;
+import com.qunzhixinxi.hnqz.admin.service.WmTaskService;
+import com.qunzhixinxi.hnqz.admin.service.WmTaskSubmissionPercentRuleService;
+import com.qunzhixinxi.hnqz.admin.service.WmTaskTypeService;
+import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import com.qunzhixinxi.hnqz.common.sequence.sequence.Sequence;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 企业任务服务
+ *
+ * @author lixuesong
+ * @date 2023/09/21
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class WmDeptTaskServiceImpl implements WmDeptTaskService {
+
+    private final WmTaskSubmissionPercentRuleService wmTaskSubmissionPercentRuleService;
+    private final WmScorePackageService wmScorePackageService;
+    private final WmScorePackageStatusService wmScorePackageStatusService;
+    private final WmTaskContentService wmTaskContentService;
+    private final WmTaskService wmTaskService;
+    private final WmTaskTypeService wmTaskTypeService;
+    private final WmScoreTaskTypeService wmScoreTaskTypeService;
+    private final Sequence taskSequence;
+    private final RedisTemplate redisTemplate;
+
+    /**
+     * 企业任务保存-企业通用
+     *
+     * @param params 参数
+     * @return {@link Boolean} 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean saveEntTaskForTaskType61(DeptTaskDTO.TaskType61 params) {
+        String taskTypeId = "61";
+
+        // 校验任务类型启用状态
+        List<WmTaskSubmissionPercentRule> rules = wmTaskSubmissionPercentRuleService.list(Wrappers.<WmTaskSubmissionPercentRule>lambdaQuery()
+                .eq(WmTaskSubmissionPercentRule::getDeptId, SecurityUtils.getUser().getDeptId())
+                .eq(WmTaskSubmissionPercentRule::getSubCategory, UpmsType.TaskSubCategory2.TASK_TYPE_CONFIG));
+        if (CollUtil.isEmpty(rules)) {
+            throw new RuntimeException("当前企业未开启该任务!");
+        }
+        String[] taskTypeIds = rules.get(0).getRule().getTaskTypeIds();
+        if (!ArrayUtil.contains(taskTypeIds, taskTypeId)) {
+            throw new RuntimeException("当前企业未开启该任务!");
+        }
+
+        int scoreTaskTypeCount = wmScoreTaskTypeService.count(Wrappers.<WmScoreTaskType>lambdaQuery()
+                .eq(WmScoreTaskType::getScoreId, params.getPackageId())
+                .eq(WmScoreTaskType::getTaskTypeId, taskTypeId));
+        if (scoreTaskTypeCount <= 0) {
+            throw new RuntimeException("有效任务类型未启用该任务!");
+        }
+
+        // 查询积分包
+        WmScorePackage scorePackage = wmScorePackageService.getById(params.getPackageId());
+
+        // 校验是否超过可分配积分值
+        List<WmScorePackage> scorePackagekfpjf =
+                wmScorePackageService.getScorePackagekfpjf(null, SecurityUtils.getUser().getDeptId(),
+                        new String[]{"0", "1", "2"}, new String[]{params.getPackageId()});
+        if (params.getScore() > scorePackagekfpjf.get(0).getKfpjf()) {
+            throw new RuntimeException("可分配积分不足!");
+        }
+
+        // 校验是否超过积分包企业任务上限
+        List<WmTask> queryTaskList = wmTaskService.list(Wrappers.<WmTask>lambdaQuery()
+                .eq(WmTask::getScorePackageId, params.getPackageId())
+                .eq(WmTask::getEnableFlag, EnableEnum.ENABLE.val())
+                .eq(WmTask::getDelFlag, DelEnum.NOT_DEL.val())
+                .eq(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val()));
+
+        int totalScoreSum = 0;
+        totalScoreSum += params.getScore();
+        if (CollUtil.isNotEmpty(queryTaskList)) {
+            totalScoreSum += queryTaskList.stream().mapToInt(WmTask::getScore).sum();
+        }
+        if (BigDecimal.valueOf(totalScoreSum)
+                .compareTo(BigDecimal.valueOf(scorePackage.getScore())
+                        .multiply(scorePackage.getEntTaskLimit()).divide(new BigDecimal("100"))) > 0) {
+            throw new RuntimeException("已超过积分包的企业任务上限!");
+        }
+
+        // 保存taskContent
+        WmTaskContent taskContent = new WmTaskContent();
+        // 任务类型
+        taskContent.setTemp30(taskTypeId);
+        // 积分包id
+        taskContent.setTemp32(params.getPackageId());
+        // 主题
+        taskContent.setTemp2(params.getMeetingtTitle());
+        // 时间
+        taskContent.setTemp3(params.getMeetingTime());
+        // 文件上传
+        taskContent.setTemp4(this.convertFileUrlArrayToString(params.getFiles()));
+        // 外采费用
+        taskContent.setTemp5(params.getOutsourcingAmount());
+        // 凭证
+        taskContent.setTemp6(this.convertFileUrlArrayToString(params.getOutsourcingAmountProof()));
+        // 任务积分
+        taskContent.setTemp7(String.valueOf(params.getScore()));
+        // 总结
+        taskContent.setTemp8(params.getMeetingSummary());
+        log.info("保存taskContent参数:{}", taskContent);
+        wmTaskContentService.save(taskContent);
+
+        // 保存企业任务通用方法
+        this.saveEntTaskCommon(taskTypeId, taskContent, params.getScore(), scorePackage);
+
+        return Boolean.TRUE;
+    }
+
+    /**
+     * 企业任务保存-医学会各级年会及卫星会
+     *
+     * @param params 参数
+     * @return {@link Boolean} 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean saveEntTaskForTaskType62(DeptTaskDTO.TaskType62 params) {
+        String taskTypeId = "62";
+
+        // 查询任务类型启用状态
+        List<WmTaskSubmissionPercentRule> rules = wmTaskSubmissionPercentRuleService.list(Wrappers.<WmTaskSubmissionPercentRule>lambdaQuery()
+                .eq(WmTaskSubmissionPercentRule::getDeptId, SecurityUtils.getUser().getDeptId())
+                .eq(WmTaskSubmissionPercentRule::getSubCategory, UpmsType.TaskSubCategory2.TASK_TYPE_CONFIG));
+        if (CollUtil.isEmpty(rules)) {
+            throw new RuntimeException("当前企业未开启该任务!");
+        }
+        String[] taskTypeIds = rules.get(0).getRule().getTaskTypeIds();
+        if (!ArrayUtil.contains(taskTypeIds, taskTypeId)) {
+            throw new RuntimeException("当前企业未开启该任务!");
+        }
+
+        int scoreTaskTypeCount = wmScoreTaskTypeService.count(Wrappers.<WmScoreTaskType>lambdaQuery()
+                .eq(WmScoreTaskType::getScoreId, params.getPackageId())
+                .eq(WmScoreTaskType::getTaskTypeId, taskTypeId));
+        if (scoreTaskTypeCount <= 0) {
+            throw new RuntimeException("有效任务类型未启用该任务!");
+        }
+
+        // 查询积分包
+        WmScorePackage scorePackage = wmScorePackageService.getById(params.getPackageId());
+        // 查询任务规则积分
+        WmTaskType wmTaskType = new WmTaskType();
+        wmTaskType.setRuleId(scorePackage.getRuleId());
+        WmTaskType queryTaskType = wmTaskTypeService.getById(taskTypeId);
+        wmTaskType.setTaskTypeName(queryTaskType.getTaskTypeName());
+        int score = wmTaskTypeService.getWmTaskTypeByEnt(wmTaskType);
+
+        // 校验是否超过可分配积分值
+        List<WmScorePackage> scorePackagekfpjf =
+                wmScorePackageService.getScorePackagekfpjf(null, SecurityUtils.getUser().getDeptId(),
+                        new String[]{"0", "1", "2"}, new String[]{params.getPackageId()});
+        if (score > scorePackagekfpjf.get(0).getKfpjf()) {
+            throw new RuntimeException("可分配积分不足!");
+        }
+
+        // 校验是否超过积分包企业任务上限
+        List<WmTask> queryTaskList = wmTaskService.list(Wrappers.<WmTask>lambdaQuery()
+                .eq(WmTask::getScorePackageId, params.getPackageId())
+                .eq(WmTask::getEnableFlag, EnableEnum.ENABLE.val())
+                .eq(WmTask::getDelFlag, DelEnum.NOT_DEL.val())
+                .eq(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val()));
+
+        int totalScoreSum = 0;
+        totalScoreSum += score;
+        if (CollUtil.isNotEmpty(queryTaskList)) {
+            totalScoreSum += queryTaskList.stream().mapToInt(WmTask::getScore).sum();
+        }
+        if (BigDecimal.valueOf(totalScoreSum)
+                .compareTo(BigDecimal.valueOf(scorePackage.getScore())
+                        .multiply(scorePackage.getEntTaskLimit()).divide(new BigDecimal("100"))) > 0) {
+            throw new RuntimeException("已超过积分包的企业任务上限!");
+        }
+
+        // 保存taskContent
+        WmTaskContent taskContent = new WmTaskContent();
+        // 任务类型
+        taskContent.setTemp30(taskTypeId);
+        // 积分包id
+        taskContent.setTemp32(params.getPackageId());
+        // 主题
+        taskContent.setTemp2(params.getMeetingtTitle());
+        // 时间
+        taskContent.setTemp3(params.getMeetingTime());
+        // 会议人次
+        taskContent.setTemp4(params.getMeetingNumber());
+        // 会议邀请函
+        taskContent.setTemp5(this.convertFileUrlArrayToString(params.getMeetingInvitationUrl()));
+        // 会议计划表
+        taskContent.setTemp6(this.convertFileUrlArrayToString(params.getMeetingPlanUrl()));
+        // 会议签到表
+        taskContent.setTemp7(this.convertFileUrlArrayToString(params.getMeetingCheckInUrl()));
+        // 现场照片
+        taskContent.setTemp8(this.convertFileUrlArrayToString(params.getLivePhotosUrl()));
+        // 会议内容
+        taskContent.setTemp9(this.convertFileUrlArrayToString(params.getMeetingContentUrl()));
+        // 外采费用
+        taskContent.setTemp10(params.getOutsourcingAmount());
+        // 外采费用凭证
+        taskContent.setTemp11(this.convertFileUrlArrayToString(params.getOutsourcingAmountProof()));
+        // 总结
+        taskContent.setTemp12(params.getMeetingSummary());
+        log.info("保存taskContent参数:{}", taskContent);
+        wmTaskContentService.save(taskContent);
+
+        // 保存企业任务通用方法
+        this.saveEntTaskCommon(taskTypeId, taskContent, score, scorePackage);
+
+        return Boolean.TRUE;
+    }
+
+    /**
+     * 企业任务保存-专家共识巡讲会
+     *
+     * @param params 参数
+     * @return {@link Boolean} 结果
+     */
+    @Override
+    public Boolean saveEntTaskForTaskType63(DeptTaskDTO.TaskType63 params) {
+        String taskTypeId = "63";
+
+        // 查询任务类型启用状态
+        List<WmTaskSubmissionPercentRule> rules = wmTaskSubmissionPercentRuleService.list(Wrappers.<WmTaskSubmissionPercentRule>lambdaQuery()
+                .eq(WmTaskSubmissionPercentRule::getDeptId, SecurityUtils.getUser().getDeptId())
+                .eq(WmTaskSubmissionPercentRule::getSubCategory, UpmsType.TaskSubCategory2.TASK_TYPE_CONFIG));
+        if (CollUtil.isEmpty(rules)) {
+            throw new RuntimeException("当前企业未开启该任务!");
+        }
+        String[] taskTypeIds = rules.get(0).getRule().getTaskTypeIds();
+        if (!ArrayUtil.contains(taskTypeIds, taskTypeId)) {
+            throw new RuntimeException("当前企业未开启该任务!");
+        }
+
+        int scoreTaskTypeCount = wmScoreTaskTypeService.count(Wrappers.<WmScoreTaskType>lambdaQuery()
+                .eq(WmScoreTaskType::getScoreId, params.getPackageId())
+                .eq(WmScoreTaskType::getTaskTypeId, taskTypeId));
+        if (scoreTaskTypeCount <= 0) {
+            throw new RuntimeException("有效任务类型未启用该任务!");
+        }
+
+        // 查询积分包
+        WmScorePackage scorePackage = wmScorePackageService.getById(params.getPackageId());
+        // 查询任务规则积分
+        WmTaskType wmTaskType = new WmTaskType();
+        wmTaskType.setRuleId(scorePackage.getRuleId());
+        WmTaskType queryTaskType = wmTaskTypeService.getById(taskTypeId);
+        wmTaskType.setTaskTypeName(queryTaskType.getTaskTypeName());
+        int score = wmTaskTypeService.getWmTaskTypeByEnt(wmTaskType);
+
+        // 校验是否超过可分配积分值
+        List<WmScorePackage> scorePackagekfpjf =
+                wmScorePackageService.getScorePackagekfpjf(null, SecurityUtils.getUser().getDeptId(),
+                        new String[]{"0", "1", "2"}, new String[]{params.getPackageId()});
+        if (score > scorePackagekfpjf.get(0).getKfpjf()) {
+            throw new RuntimeException("可分配积分不足!");
+        }
+
+        // 校验是否超过积分包企业任务上限
+        List<WmTask> queryTaskList = wmTaskService.list(Wrappers.<WmTask>lambdaQuery()
+                .eq(WmTask::getScorePackageId, params.getPackageId())
+                .eq(WmTask::getEnableFlag, EnableEnum.ENABLE.val())
+                .eq(WmTask::getDelFlag, DelEnum.NOT_DEL.val())
+                .eq(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val()));
+
+        int totalScoreSum = 0;
+        totalScoreSum += score;
+        if (CollUtil.isNotEmpty(queryTaskList)) {
+            totalScoreSum += queryTaskList.stream().mapToInt(WmTask::getScore).sum();
+        }
+        if (BigDecimal.valueOf(totalScoreSum)
+                .compareTo(BigDecimal.valueOf(scorePackage.getScore())
+                        .multiply(scorePackage.getEntTaskLimit()).divide(new BigDecimal("100"))) > 0) {
+            throw new RuntimeException("已超过积分包的企业任务上限!");
+        }
+
+        // 保存taskContent
+        WmTaskContent taskContent = new WmTaskContent();
+        // 任务类型
+        taskContent.setTemp30(taskTypeId);
+        // 积分包id
+        taskContent.setTemp32(params.getPackageId());
+        // 主题
+        taskContent.setTemp2(params.getMeetingtTitle());
+        // 时间
+        taskContent.setTemp3(params.getMeetingTime());
+        // 参加人次
+        taskContent.setTemp4(params.getMeetingNumber());
+        // 活动策划书
+        taskContent.setTemp5(this.convertFileUrlArrayToString(params.getEventPlannerUrl()));
+        // 活动计划表
+        taskContent.setTemp6(this.convertFileUrlArrayToString(params.getMeetingPlanUrl()));
+        // 会议签到表
+        taskContent.setTemp7(this.convertFileUrlArrayToString(params.getMeetingCheckInUrl()));
+        // 现场照片
+        taskContent.setTemp8(this.convertFileUrlArrayToString(params.getLivePhotosUrl()));
+        // 会议内容
+        taskContent.setTemp9(this.convertFileUrlArrayToString(params.getMeetingContentUrl()));
+        // 外采费用
+        taskContent.setTemp10(params.getOutsourcingAmount());
+        // 外采费用凭证
+        taskContent.setTemp11(this.convertFileUrlArrayToString(params.getOutsourcingAmountProof()));
+        // 总结
+        taskContent.setTemp12(params.getMeetingSummary());
+        log.info("保存taskContent参数:{}", taskContent);
+        wmTaskContentService.save(taskContent);
+
+        // 保存企业任务通用方法
+        this.saveEntTaskCommon(taskTypeId, taskContent, score, scorePackage);
+
+        return Boolean.TRUE;
+    }
+
+    /**
+     * 保存企业任务通用方法
+     *
+     * @param taskTypeId  任务类型id
+     * @param taskContent  任务内容
+     * @param taskScore    任务积分
+     * @param scorePackage 积分包
+     */
+    private void saveEntTaskCommon(String taskTypeId, WmTaskContent taskContent, int taskScore, WmScorePackage scorePackage) {
+        HnqzUser user = SecurityUtils.getUser();
+        LocalDateTime now = LocalDateTime.now();
+
+        // 保存任务
+        WmTask task = new WmTask();
+        task.setTaskContentId(String.valueOf(taskContent.getId()));
+        task.setTaskFrom("1");
+        task.setTaskTypeId(taskTypeId);
+        task.setTaskUserId(String.valueOf(user.getId()));
+        task.setScorePackageId(scorePackage.getId());
+        task.setScore(taskScore);
+        task.setLookintoDate(now);
+        task.setUpdateTime(now);
+        task.setDrugEntId(scorePackage.getDrugEntId());
+        task.setTaskRuleId(scorePackage.getTaskRuleId());
+        task.setDeptId(String.valueOf(user.getDeptId()));
+        task.setSubmitStatus("0");
+        task.setRealFlag("0");
+        task.setTaskStatus(TaskStatusEnum.APPROVED.val());
+        task.setTaskNumber(taskSequence.nextNo());
+        if (ArrayUtil.containsAny(user.getRoles(), 3)) {
+            task.setTaskUserType("3");
+        } else if (ArrayUtil.containsAny(user.getRoles(), 4)) {
+            task.setTaskUserType("4");
+        } else {
+            task.setTaskUserType(ArrayUtil.join(user.getRoles(), ","));
+        }
+        log.info("保存任务参数:{}", task);
+        wmTaskService.save(task);
+
+        // 创建一条领包记录
+        WmScorePackageStatus wmScorePackageStatus = new WmScorePackageStatus();
+        wmScorePackageStatus.setPackageId(scorePackage.getId());
+        wmScorePackageStatus.setUserId(String.valueOf(user.getId()));
+        wmScorePackageStatus.setDelFlag("0");
+        wmScorePackageStatus.setEnableFlag("0");
+        List<WmScorePackageStatus> wmScorePackageStatusList = wmScorePackageStatusService.
+                list(Wrappers.query(wmScorePackageStatus).lambda().ne(WmScorePackageStatus::getStatus, 3));
+        if (CollUtil.isEmpty(wmScorePackageStatusList)) {
+            wmScorePackageStatus.setStatus("2");
+            wmScorePackageStatus.setTaskAddFlag("1");
+            if (PackageTypeEnum.TYPE1_SCOTE_PACKAGE.val().equals(scorePackage.getPackageType1())
+                    || PackageTypeEnum.TYPE1_SCORE_AND_TASK_PACKAGE.val().equals(scorePackage.getPackageType1())) {
+                wmScorePackageStatus.setUserScore(scorePackage.getScore() + "");
+            } else {
+                wmScorePackageStatus.setUserScore(scorePackage.getUserScore());
+            }
+            wmScorePackageStatus.setTaskNum(scorePackage.getTaskNum());
+            wmScorePackageStatus.setDeptId(String.valueOf(user.getDeptId()));
+            wmScorePackageStatus.setCreateTime(now);
+            wmScorePackageStatus.setUpdateTime(now);
+            log.info("创建领包记录参数:{}", wmScorePackageStatus);
+            wmScorePackageStatusService.save(wmScorePackageStatus);
+        }
+
+        // 扣减可分配积分值
+        WmScorePackage updatePackage = new WmScorePackage();
+        updatePackage.setId(scorePackage.getId());
+        updatePackage.setKfpjf(scorePackage.getKfpjf() - taskScore);
+        updatePackage.setUpdateUser(user.getId());
+        updatePackage.setUpdateTime(now);
+        log.info("扣减可分配积分值参数:{}", updatePackage);
+        wmScorePackageService.updateById(updatePackage);
+
+        // 保存成功后清除缓存
+        String cacheKey =
+                String.format("%s-%s-%s", CacheConstants.ENT_TASK_CACHE_KEY, taskTypeId, user.getId());
+        redisTemplate.delete(cacheKey);
+    }
+
+    /**
+     * 将文件地址数组转换为字符串
+     *
+     * @param array 数组
+     * @return {@link String}
+     */
+    private String convertFileUrlArrayToString(List<DeptTaskDTO.FileUrlObj> array) {
+        return JSONUtil.toJsonStr(array);
+    }
+
+}

+ 140 - 22
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmScorePackageServiceImpl.java

@@ -19,8 +19,8 @@ package com.qunzhixinxi.hnqz.admin.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.DesensitizedUtil;
-import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.csp.sentinel.util.StringUtil;
@@ -537,19 +537,29 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 	 */
 	@Override
 	public R getRelationScoreList(WmScorePackage wmScorePackage) {
+		long start = System.currentTimeMillis();
 		SysDept relatedService = new SysDept();
 		if (null != wmScorePackage.getRelatedService()) {
 			relatedService = sysDeptMapper.selectById(wmScorePackage.getRelatedService());
 		}
 		//查询分配给当前用户机构的积分包,deptid为当前用户,而且typeid=1或2
-		String deptId = SecurityUtils.getUser().getDeptId() + "";
-		wmScorePackage.setDeptId(deptId);
-		wmScorePackage.setTypeid("0,1,2");
-		wmScorePackage.setSendPackageDeptId(wmScorePackage.getRelatedService());
-		List<WmScorePackage> packageList = wmScorePackageMapper.getScorePackagekfpjf(wmScorePackage);
-
+		Integer deptId = SecurityUtils.getUser().getDeptId();
+		Integer superDeptId = StrUtil.isNotBlank(wmScorePackage.getRelatedService()) ?
+				Integer.valueOf(wmScorePackage.getRelatedService()) : null;
+		List<WmScorePackage> packageList =
+				this.getScorePackagekfpjf(superDeptId, deptId,
+						new String[]{"0", "1", "2"}, StrUtil.isNotBlank(wmScorePackage.getId()) ?
+								new String[]{wmScorePackage.getId()} : null);
+		log.info("查询关联积分包值耗时:{}ms", System.currentTimeMillis() - start);
+
+		Set<String> packageIdSet = packageList.stream().map(WmScorePackage::getId).collect(Collectors.toSet());
+		List<WmScoreTaskType> allTaskTypelist =
+				wmScoreTaskTypeMapper.getScoreTaskTypeByScoreId(CollUtil.join(packageIdSet, ","));
+		Map<String, List<WmScoreTaskType>> scoreTaskTypeMap = allTaskTypelist.stream()
+				.collect(Collectors.groupingBy(WmScoreTaskType::getScoreId));
 		for (WmScorePackage wmScorePackage1 : packageList) {
-			List<WmScoreTaskType> taskTypelist = wmScoreTaskTypeMapper.getScoreTaskTypeByScoreId(wmScorePackage1.getId());
+//			List<WmScoreTaskType> taskTypelist = wmScoreTaskTypeMapper.getScoreTaskTypeByScoreId(wmScorePackage1.getId());
+			List<WmScoreTaskType> taskTypelist = scoreTaskTypeMap.get(wmScorePackage1.getId());
 			wmScorePackage1.setTaskTypeList1(taskTypelist);
 			Set taskTypeSet = taskTypelist.stream().map(WmScoreTaskType::getTaskTypeId).collect(Collectors.toSet());
 			wmScorePackage1.setTaskTypeSet(taskTypeSet);
@@ -581,6 +591,8 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 			wmScorePackage1.setScorePackageName("无");
 			packageList.add(wmScorePackage1);
 		}
+		log.info("查询关联积分包值+拼装参数总耗时:{}ms", System.currentTimeMillis() - start);
+
 		return R.ok(packageList);
 	}
 
@@ -672,12 +684,17 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 		//判断预积分包值不能大于可分配积分值
 		if (!StringUtil.isEmpty(wmScorePackage.getRelationScoreId()) && !wmScorePackage.getRelationScoreId()
 				.equals("-1")) {
-			WmScorePackage wmScorePackage1 = new WmScorePackage();
-			wmScorePackage1.setId(wmScorePackage.getRelationScoreId());
-			WmScorePackage wmScorePackage2 = wmScorePackageMapper.selectById(wmScorePackage1.getId());
+//			WmScorePackage wmScorePackage1 = new WmScorePackage();
+//			wmScorePackage1.setId(wmScorePackage.getRelationScoreId());
+//			WmScorePackage wmScorePackage2 = wmScorePackageMapper.selectById(wmScorePackage1.getId());
 			Integer kfpjf = 0;
-			if (wmScorePackage2 != null) {
-				kfpjf = wmScorePackage2.getKfpjf() == null ? 0 : wmScorePackage2.getKfpjf();
+
+			List<WmScorePackage> scorePackagekfpjf = this.getScorePackagekfpjf(null, null, new String[]{"0", "1", "2"},
+					new String[]{wmScorePackage.getRelationScoreId()});
+
+			if (CollUtil.isNotEmpty(scorePackagekfpjf)) {
+				kfpjf = scorePackagekfpjf.get(0).getKfpjf();
+//				kfpjf = wmScorePackage2.getKfpjf() == null ? 0 : wmScorePackage2.getKfpjf();
 				if (kfpjf > 0 && wmScorePackage.getScore() > kfpjf) {
 					return R.failed("预积分包值不能大于可分配积分值");
 				}
@@ -1665,17 +1682,24 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 		SysDeptRechargeRecord rechargeRecord = sysDeptRechargeRecordMapper.selectOne(Wrappers.<SysDeptRechargeRecord>lambdaQuery()
 				.eq(SysDeptRechargeRecord::getPackageId, wmScorePackage.getId())
 				.in(SysDeptRechargeRecord::getType, RechargeRecordType.SEND_PACKAGE_DEPT, RechargeRecordType.SEND_PACKAGE_PERSONAL));
-		if (rechargeRecord != null) {
+
+		boolean relatedScoreId = StrUtil.isNotBlank(wmScorePackage.getRelationScoreId()) && Integer.parseInt(wmScorePackage.getRelationScoreId()) > 0;
+
+		// 积分值相比修改前的变动(相对于积分余额,增加则为负-消耗,减少则为正-回收)
+		int changeScore = oldPackageScore - wmScorePackage.getScore();
+
+		if (!relatedScoreId) {
+			// 没有关联上级积分包的情况
 			log.info("修改积分包,更新积分配置信息");
 			Integer userId = SecurityUtils.getUser().getId();
-			SysDeptRecharge deptRecharge = sysDeptRechargeMapper.selectById(rechargeRecord.getRechargeId());
+			Integer deptId = SecurityUtils.getUser().getDeptId();
+			SysDeptRecharge deptRecharge = sysDeptRechargeMapper.selectOne(Wrappers.<SysDeptRecharge>lambdaQuery()
+					.eq(SysDeptRecharge::getDeptId, deptId));
 			if (deptRecharge == null) {
 				log.warn("未配置积分充值信息");
 				throw new RuntimeException("积分余额:0。积分不足");
 			}
 
-			// 积分值相比修改前的变动(相对于积分余额,增加则为负-消耗,减少则为正-回收)
-			int changeScore = oldPackageScore - wmScorePackage.getScore();
 			int currentScore = deptRecharge.getScore() + changeScore;
 
 			int limitScore = deptRecharge.getScore() + deptRecharge.getOverdrawScore();
@@ -1688,7 +1712,7 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 
 			// 更新企业配置的积分信息
 			int update = sysDeptRechargeMapper.update(null, Wrappers.<SysDeptRecharge>lambdaUpdate()
-					.eq(SysDeptRecharge::getId, rechargeRecord.getRechargeId())
+					.eq(SysDeptRecharge::getId, deptRecharge.getId())
 					.eq(SysDeptRecharge::getVersion, deptRecharge.getVersion())
 					.set(SysDeptRecharge::getScore, currentScore)
 					.set(SysDeptRecharge::getVersion, deptRecharge.getVersion() + 1)
@@ -1705,11 +1729,24 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 			newRechargeRecord.setCurrentScore(currentScore);
 			newRechargeRecord.setType(RechargeRecordType.RECOVERY);
 			newRechargeRecord.setDeptId(deptRecharge.getDeptId());
-			newRechargeRecord.setRelationDeptId(rechargeRecord.getRelationDeptId());
+			newRechargeRecord.setRelationDeptId(rechargeRecord != null ? rechargeRecord.getRelationDeptId() : null);
 			newRechargeRecord.setPackageType(RechargeRecordPackageType.TO_PERSON);
 			newRechargeRecord.setPackageId(wmScorePackage.getId());
 			newRechargeRecord.setCreateUser(userId);
 			sysDeptRechargeRecordMapper.insert(newRechargeRecord);
+		} else {
+			if (changeScore < 0) {
+				// 变动积分值为增加,则校验上级可分配积分值
+				List<WmScorePackage> scorePackagekfpjf = this.getScorePackagekfpjf(null, null, new String[]{"0", "1", "2"},
+						new String[]{wmScorePackage.getRelationScoreId()});
+
+				if (CollUtil.isNotEmpty(scorePackagekfpjf)) {
+					int kfpjf = scorePackagekfpjf.get(0).getKfpjf();
+					if (Math.abs(changeScore) > kfpjf) {
+						throw new RuntimeException("可分配积分值不足");
+					}
+				}
+			}
 		}
 
 		return R.ok();
@@ -1962,7 +1999,7 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 		List<Map<String, Object>> m = new ArrayList<>(stepB_1.size() + stepB_2.size());
 		m.addAll(stepB_1);
 		m.addAll(stepB_2);
-		Map<String, Integer> result = step3(m);
+		Map<String, Integer> result = step3(m, wmScorePackage);
 		WmScorePackage p = step4(result, wmScorePackage);
 
 		return new AsyncResult<>(p);
@@ -2536,7 +2573,7 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 	}
 
 
-	public Map<String, Integer> step3(List<Map<String, Object>> m) {
+	public Map<String, Integer> step3(List<Map<String, Object>> m, WmScorePackage wmScorePackage) {
 		int payScore = 0;
 		int ysh = 0;
 
@@ -3056,11 +3093,18 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 
 		// 已分配积分值
 		int assignedScore = 0;
+		// 查询子包的积分
 		List<WmScorePackage> subPackages = this.list(Wrappers.<WmScorePackage>lambdaQuery()
 				.eq(WmScorePackage::getRelationScoreId, packageId)
 				.ne(WmScorePackage::getScorePackageStatus, ScorePackageStatusEnum.TERMINATED.val()));
 		if (CollUtil.isNotEmpty(subPackages)) {
-			assignedScore = subPackages.stream().mapToInt(WmScorePackage::getScore).sum();
+			assignedScore += subPackages.stream().mapToInt(WmScorePackage::getScore).sum();
+		}
+		// 查询企业任务的积分
+		List<WmTask> entTaskList = wmTaskMapper.selectList(Wrappers.<WmTask>lambdaQuery()
+				.eq(WmTask::getScorePackageId, packageId));
+		if (CollUtil.isNotEmpty(entTaskList)) {
+			assignedScore += entTaskList.stream().mapToInt(WmTask::getScore).sum();
 		}
 
 		log.info("当前积分包终止前数据:{}", scorePackage);
@@ -3173,4 +3217,78 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
 		newRechargeRecord.setCreateTime(now);
 		sysDeptRechargeRecordMapper.insert(newRechargeRecord);
 	}
+
+	/**
+	 * 获取指定企业下积分包的可分配积分值
+	 *
+	 * @param superDeptId 上级企业id
+	 * @param deptId      企业id
+	 * @param typeIds     企业类型
+	 * @param packageIds  积分包id
+	 * @return 结果
+	 */
+	@Override
+	public List<WmScorePackage> getScorePackagekfpjf(Integer superDeptId, Integer deptId, String[] typeIds, String[] packageIds) {
+		// 查询企业下的积分包
+		LambdaQueryWrapper<WmScorePackage> queryWrapper = Wrappers.<WmScorePackage>lambdaQuery()
+				.in(WmScorePackage::getTypeid, typeIds)
+				.eq(WmScorePackage::getDelFlag, DelEnum.NOT_DEL.val())
+				.eq(WmScorePackage::getEnableFlag, EnableEnum.ENABLE.val())
+				.eq(WmScorePackage::getOldPackage, "0");
+		if (superDeptId != null) {
+			queryWrapper.eq(WmScorePackage::getSendPackageDeptId, superDeptId);
+		}
+		if (deptId != null) {
+			queryWrapper.eq(WmScorePackage::getDeptId, deptId);
+		}
+		if (ArrayUtil.isNotEmpty(packageIds)) {
+			queryWrapper.in(WmScorePackage::getId, packageIds);
+		}
+		List<WmScorePackage> packages = this.list(queryWrapper);
+
+		if (CollUtil.isNotEmpty(packages)) {
+			// 查询积分包的子包
+			Set<String> packageIdSet = packages.stream().map(WmScorePackage::getId).collect(Collectors.toSet());
+			List<WmScorePackage> subPackages = this.list(Wrappers.<WmScorePackage>lambdaQuery()
+					.in(WmScorePackage::getRelationScoreId, packageIdSet)
+					.eq(WmScorePackage::getDelFlag, DelEnum.NOT_DEL.val())
+					.eq(WmScorePackage::getEnableFlag, EnableEnum.ENABLE.val()));
+			Map<String, Integer> relatedPackageScoresMap = new HashMap<>();
+			if (CollUtil.isNotEmpty(subPackages)) {
+				// 已分配的积分
+				relatedPackageScoresMap = subPackages.stream()
+						.collect(Collectors.groupingBy(WmScorePackage::getRelationScoreId, Collectors.summingInt(WmScorePackage::getScore)));
+			}
+
+			// 查询积分包的任务
+			List<WmTask> tasks = wmTaskMapper.selectList(Wrappers.<WmTask>lambdaQuery()
+					.in(WmTask::getScorePackageId, packageIdSet)
+                    .eq(WmTask::getDelFlag, DelEnum.NOT_DEL.val())
+                    .eq(WmTask::getEnableFlag, EnableEnum.ENABLE.val())
+					.eq(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val()));
+			Map<String, Integer> relatedTaskScoresMap = new HashMap<>();
+			if (CollUtil.isNotEmpty(tasks)) {
+                // 已分配的积分
+                relatedTaskScoresMap = tasks.stream()
+                        .collect(Collectors.groupingBy(WmTask::getScorePackageId, Collectors.summingInt(WmTask::getScore)));
+            }
+
+			Map<String, Integer> finalRelatedPackageScoresMap = relatedPackageScoresMap;
+			Map<String, Integer> finalRelatedTaskScoresMap = relatedTaskScoresMap;
+			packages.forEach(pkg -> {
+				String packageId = pkg.getId();
+				// 统计可分配积分值
+                Integer score = pkg.getScore();
+                if (finalRelatedPackageScoresMap.containsKey(packageId)) {
+					score -= finalRelatedPackageScoresMap.get(packageId);
+                }
+                if (finalRelatedTaskScoresMap.containsKey(packageId)) {
+					score -= finalRelatedTaskScoresMap.get(packageId);
+                }
+                pkg.setKfpjf(score);
+			});
+		}
+
+		return packages;
+	}
 }

+ 9 - 1
hnqz-upms/hnqz-upms-biz/src/test/java/com/qunzhixinxi/hnqz/admin/WmTaskTypeServiceTest.java

@@ -52,7 +52,9 @@ public class WmTaskTypeServiceTest {
 	
 	// 任务类型list
 	private static final List<String> taskTypeIdList = new ArrayList<String>(){{
-		add("41");
+		add("58");
+		add("59");
+		add("60");
 	}};
 
 	/**
@@ -94,6 +96,7 @@ public class WmTaskTypeServiceTest {
 				newOne.setBaseId(wmTaskType1.getId());
 				newOne.setRuleId(wmDaDrugEnt.getId());
 				newOne.setParentId(wmTaskType1.getParentId());
+				newOne.setTaskReceiverType(wmTaskType1.getTaskReceiverType());
 				List<WmTaskType> taskTypeList = wmTaskTypeMapper.selectList(Wrappers.<WmTaskType>lambdaQuery()
 						.eq(WmTaskType::getTaskTypeName, wmTaskType1.getTaskTypeName())
 						.eq(WmTaskType::getRuleId, newOne.getRuleId())
@@ -141,6 +144,7 @@ public class WmTaskTypeServiceTest {
 					newOne.setDeptId(wmDaAgent.getDeptId());
 					newOne.setStatus("0");
 					newOne.setBaseId(wmTaskType1.getId());
+					newOne.setTaskReceiverType(wmTaskType1.getTaskReceiverType());
 					List<WmTaskType> taskTypeList = wmTaskTypeMapper.selectList(Wrappers.<WmTaskType>lambdaQuery()
 							.eq(WmTaskType::getTaskTypeName, wmTaskType1.getTaskTypeName())
 							.eq(WmTaskType::getRuleId, newOne.getRuleId())
@@ -163,6 +167,7 @@ public class WmTaskTypeServiceTest {
 					newOne.setDeptId(wmDaAgent.getDeptId());
 					newOne.setStatus("0");
 					newOne.setBaseId(wmTaskType2.getId());
+					newOne.setTaskReceiverType(wmTaskType2.getTaskReceiverType());
 					List<WmTaskType> taskTypeList = wmTaskTypeMapper.selectList(Wrappers.<WmTaskType>lambdaQuery()
 							.eq(WmTaskType::getTaskTypeName, wmTaskType2.getTaskTypeName())
 							.eq(WmTaskType::getRuleId, newOne.getRuleId())
@@ -199,6 +204,7 @@ public class WmTaskTypeServiceTest {
 						newOne.setDeptId(wmDaAgent2.getDeptId());
 						newOne.setStatus("0");
 						newOne.setBaseId(wmTaskType2.getId());
+						newOne.setTaskReceiverType(wmTaskType2.getTaskReceiverType());
 						List<WmTaskType> taskTypeList = wmTaskTypeMapper.selectList(Wrappers.<WmTaskType>lambdaQuery()
 								.eq(WmTaskType::getTaskTypeName, wmTaskType2.getTaskTypeName())
 								.eq(WmTaskType::getRuleId, newOne.getRuleId())
@@ -248,6 +254,7 @@ public class WmTaskTypeServiceTest {
 				newOne.setDeptId(wmDaAgent.getDeptId());
 				newOne.setStatus("0");
 				newOne.setBaseId(wmTaskType2.getId());
+				newOne.setTaskReceiverType(wmTaskType2.getTaskReceiverType());
 				List<WmTaskType> taskTypeList = wmTaskTypeMapper.selectList(Wrappers.<WmTaskType>lambdaQuery()
 						.eq(WmTaskType::getTaskTypeName, wmTaskType2.getTaskTypeName())
 						.eq(WmTaskType::getRuleId, newOne.getRuleId())
@@ -284,6 +291,7 @@ public class WmTaskTypeServiceTest {
 					newOne.setDeptId(wmDaAgent2.getDeptId());
 					newOne.setStatus("0");
 					newOne.setBaseId(wmTaskType2.getId());
+					newOne.setTaskReceiverType(wmTaskType2.getTaskReceiverType());
 					List<WmTaskType> taskTypeList = wmTaskTypeMapper.selectList(Wrappers.<WmTaskType>lambdaQuery()
 						.eq(WmTaskType::getTaskTypeName, wmTaskType2.getTaskTypeName())
 						.eq(WmTaskType::getRuleId, newOne.getRuleId())