|
@@ -1,10 +1,15 @@
|
|
|
package com.etotem.cfc.service;
|
|
package com.etotem.cfc.service;
|
|
|
|
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.etotem.cfc.entity.FamilyMember;
|
|
|
import com.etotem.cfc.entity.Task;
|
|
import com.etotem.cfc.entity.Task;
|
|
|
import com.etotem.cfc.entity.TaskPlanInstance;
|
|
import com.etotem.cfc.entity.TaskPlanInstance;
|
|
|
|
|
+import com.etotem.cfc.entity.TaskTemplateItem;
|
|
|
import com.etotem.cfc.entity.User;
|
|
import com.etotem.cfc.entity.User;
|
|
|
|
|
+import com.etotem.cfc.mapper.FamilyMemberMapper;
|
|
|
import com.etotem.cfc.mapper.TaskMapper;
|
|
import com.etotem.cfc.mapper.TaskMapper;
|
|
|
import com.etotem.cfc.mapper.TaskPlanInstanceMapper;
|
|
import com.etotem.cfc.mapper.TaskPlanInstanceMapper;
|
|
|
|
|
+import com.etotem.cfc.mapper.TaskTemplateItemMapper;
|
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
@@ -14,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
|
import java.util.Calendar;
|
|
import java.util.Calendar;
|
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 方案激活服务。
|
|
* 方案激活服务。
|
|
@@ -33,11 +39,18 @@ public class PlanActivationService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private UserMapper userMapper;
|
|
private UserMapper userMapper;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private FamilyMemberMapper familyMemberMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private TaskTemplateItemMapper templateItemMapper;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 激活方案:
|
|
* 激活方案:
|
|
|
* 1. 校验状态必须为 reviewed
|
|
* 1. 校验状态必须为 reviewed
|
|
|
* 2. 生成一条引导性任务(方案概览/首日任务)
|
|
* 2. 生成一条引导性任务(方案概览/首日任务)
|
|
|
- * 3. 标记方案为 active
|
|
|
|
|
|
|
+ * 3. 若方案关联了模板包(packageId),按模板项批量生成日常任务(任务分解)
|
|
|
|
|
+ * 4. 标记方案为 active
|
|
|
*/
|
|
*/
|
|
|
@Transactional
|
|
@Transactional
|
|
|
public void activate(Long planId, Long operatorId) {
|
|
public void activate(Long planId, Long operatorId) {
|
|
@@ -46,34 +59,68 @@ public class PlanActivationService {
|
|
|
if (!"reviewed".equals(plan.getStatus())) {
|
|
if (!"reviewed".equals(plan.getStatus())) {
|
|
|
throw new IllegalStateException("方案状态异常,需要先审核通过");
|
|
throw new IllegalStateException("方案状态异常,需要先审核通过");
|
|
|
}
|
|
}
|
|
|
- User child = userMapper.selectById(plan.getChildId());
|
|
|
|
|
- if (child == null) throw new IllegalStateException("孩子不存在");
|
|
|
|
|
|
|
+ // childId 兼容 user 或 family_members 两种 ID 域,任一存在即可激活
|
|
|
|
|
+ boolean childExists = userMapper.selectById(plan.getChildId()) != null
|
|
|
|
|
+ || familyMemberMapper.selectById(plan.getChildId()) != null;
|
|
|
|
|
+ if (!childExists) throw new IllegalStateException("孩子不存在");
|
|
|
|
|
|
|
|
// 生成首日引导任务
|
|
// 生成首日引导任务
|
|
|
- Task task = new Task();
|
|
|
|
|
- task.setFamilyId(plan.getFamilyId());
|
|
|
|
|
- task.setChildId(plan.getChildId());
|
|
|
|
|
- task.setCreatorId(operatorId);
|
|
|
|
|
- task.setExecutorType("child");
|
|
|
|
|
- task.setExecutorId(plan.getChildId());
|
|
|
|
|
- task.setTitle("方案启动: " + plan.getName());
|
|
|
|
|
- task.setDescription("请阅读并开始执行测评方案");
|
|
|
|
|
- task.setPoints(2);
|
|
|
|
|
- task.setCategory("成长");
|
|
|
|
|
- task.setStatus("pending");
|
|
|
|
|
- task.setSourceType("plan");
|
|
|
|
|
- task.setSourceId(plan.getId());
|
|
|
|
|
- task.setNeedReview(0);
|
|
|
|
|
- task.setIsTemplate(0);
|
|
|
|
|
- task.setMemberOnly(1); // B20: 方案/套餐生成的任务为会员专属
|
|
|
|
|
- Calendar cal = Calendar.getInstance();
|
|
|
|
|
- cal.set(Calendar.HOUR_OF_DAY, 23);
|
|
|
|
|
- cal.set(Calendar.MINUTE, 59);
|
|
|
|
|
- cal.set(Calendar.SECOND, 59);
|
|
|
|
|
- task.setDeadline(cal.getTime());
|
|
|
|
|
- task.setCreatedAt(new Date());
|
|
|
|
|
- task.setUpdatedAt(new Date());
|
|
|
|
|
- taskMapper.insert(task);
|
|
|
|
|
|
|
+ Task guideTask = new Task();
|
|
|
|
|
+ guideTask.setFamilyId(plan.getFamilyId());
|
|
|
|
|
+ guideTask.setChildId(plan.getChildId());
|
|
|
|
|
+ guideTask.setCreatorId(operatorId);
|
|
|
|
|
+ guideTask.setExecutorType("child");
|
|
|
|
|
+ guideTask.setExecutorId(plan.getChildId());
|
|
|
|
|
+ guideTask.setTitle("方案启动: " + plan.getName());
|
|
|
|
|
+ guideTask.setDescription("请阅读并开始执行测评方案");
|
|
|
|
|
+ guideTask.setPoints(2);
|
|
|
|
|
+ guideTask.setCategory("成长");
|
|
|
|
|
+ guideTask.setStatus("pending");
|
|
|
|
|
+ guideTask.setSourceType("plan");
|
|
|
|
|
+ guideTask.setSourceId(plan.getId());
|
|
|
|
|
+ guideTask.setNeedReview(0);
|
|
|
|
|
+ guideTask.setIsTemplate(0);
|
|
|
|
|
+ guideTask.setMemberOnly(1); // B20: 方案/套餐生成的任务为会员专属
|
|
|
|
|
+ fillDeadline(guideTask);
|
|
|
|
|
+ guideTask.setCreatedAt(new Date());
|
|
|
|
|
+ guideTask.setUpdatedAt(new Date());
|
|
|
|
|
+ taskMapper.insert(guideTask);
|
|
|
|
|
+
|
|
|
|
|
+ // 按模板包任务项批量生成日常任务(任务分解)
|
|
|
|
|
+ if (plan.getPackageId() != null) {
|
|
|
|
|
+ List<TaskTemplateItem> items = templateItemMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<TaskTemplateItem>()
|
|
|
|
|
+ .eq(TaskTemplateItem::getPackageId, plan.getPackageId())
|
|
|
|
|
+ .orderByAsc(TaskTemplateItem::getSortOrder));
|
|
|
|
|
+ int itemCount = 0;
|
|
|
|
|
+ for (TaskTemplateItem item : items) {
|
|
|
|
|
+ if (item.getTaskName() == null || item.getTaskName().isEmpty()) continue;
|
|
|
|
|
+ Task t = new Task();
|
|
|
|
|
+ t.setFamilyId(plan.getFamilyId());
|
|
|
|
|
+ t.setChildId(plan.getChildId());
|
|
|
|
|
+ t.setCreatorId(operatorId);
|
|
|
|
|
+ t.setExecutorType("child");
|
|
|
|
|
+ t.setExecutorId(plan.getChildId());
|
|
|
|
|
+ t.setTitle(item.getTaskName());
|
|
|
|
|
+ t.setDescription(item.getDescription());
|
|
|
|
|
+ t.setPoints(item.getPoints() != null ? item.getPoints() : 2);
|
|
|
|
|
+ t.setCategory("成长");
|
|
|
|
|
+ t.setStatus("pending");
|
|
|
|
|
+ t.setSourceType("plan");
|
|
|
|
|
+ t.setSourceId(plan.getId());
|
|
|
|
|
+ t.setNeedReview(0);
|
|
|
|
|
+ t.setIsTemplate(0);
|
|
|
|
|
+ t.setMemberOnly(1);
|
|
|
|
|
+ t.setFrequency(item.getFrequency() != null ? item.getFrequency() : "daily");
|
|
|
|
|
+ t.setDuration(item.getDuration());
|
|
|
|
|
+ fillDeadline(t);
|
|
|
|
|
+ t.setCreatedAt(new Date());
|
|
|
|
|
+ t.setUpdatedAt(new Date());
|
|
|
|
|
+ taskMapper.insert(t);
|
|
|
|
|
+ itemCount++;
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("方案{}激活按模板包{}生成{}条任务", planId, plan.getPackageId(), itemCount);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 标记方案已激活
|
|
// 标记方案已激活
|
|
|
plan.setStatus("active");
|
|
plan.setStatus("active");
|
|
@@ -83,6 +130,14 @@ public class PlanActivationService {
|
|
|
plan.setUpdatedAt(new Date());
|
|
plan.setUpdatedAt(new Date());
|
|
|
planMapper.updateById(plan);
|
|
planMapper.updateById(plan);
|
|
|
|
|
|
|
|
- log.info("方案激活 planId={}, childId={}, taskId={}", planId, plan.getChildId(), task.getId());
|
|
|
|
|
|
|
+ log.info("方案激活 planId={}, childId={}, taskId={}", planId, plan.getChildId(), guideTask.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fillDeadline(Task task) {
|
|
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
|
|
+ cal.set(Calendar.HOUR_OF_DAY, 23);
|
|
|
|
|
+ cal.set(Calendar.MINUTE, 59);
|
|
|
|
|
+ cal.set(Calendar.SECOND, 59);
|
|
|
|
|
+ task.setDeadline(cal.getTime());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|