package cn.iocoder.yudao.module.research.service.guideline;
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.module.research.controller.admin.guideline.vo.ResearchGuidelinePageReqVO;
|
import cn.iocoder.yudao.module.research.controller.admin.guideline.vo.ResearchGuidelineSaveReqVO;
|
import cn.iocoder.yudao.module.research.dal.dataobject.guideline.ResearchGuidelineDO;
|
import cn.iocoder.yudao.module.research.dal.mysql.application.ResearchApplicationMapper;
|
import cn.iocoder.yudao.module.research.dal.mysql.guideline.ResearchGuidelineMapper;
|
import cn.iocoder.yudao.module.research.dal.redis.ResearchNoRedisDAO;
|
import cn.iocoder.yudao.module.research.enums.ResearchGuidelineStatusEnum;
|
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.Collection;
|
import java.util.List;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.module.research.enums.ErrorCodeConstants.*;
|
|
@Service
|
@Validated
|
@Slf4j
|
public class ResearchGuidelineServiceImpl implements ResearchGuidelineService {
|
|
public static final String GUIDELINE_RECORD_TYPE = "research_guideline";
|
|
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
|
|
@Resource
|
private ResearchGuidelineMapper guidelineMapper;
|
|
@Resource
|
private ResearchApplicationMapper applicationMapper;
|
|
@Resource
|
private ResearchNoRedisDAO noRedisDAO;
|
|
@Resource
|
private StorageAttachmentApi storageAttachmentApi;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Long createGuideline(ResearchGuidelineSaveReqVO createReqVO) {
|
validateApplyTime(createReqVO);
|
|
String no = noRedisDAO.generate(ResearchNoRedisDAO.GUIDELINE_NO_PREFIX);
|
if (guidelineMapper.selectByNo(no) != null) {
|
throw exception(GUIDELINE_NO_EXISTS);
|
}
|
|
ResearchGuidelineDO guideline = BeanUtils.toBean(createReqVO, ResearchGuidelineDO.class, in -> in
|
.setNo(no)
|
.setPublishStatus(ResearchGuidelineStatusEnum.DRAFT.getStatus()));
|
guidelineMapper.insert(guideline);
|
|
storageAttachmentApi.bindAttachments("file", GUIDELINE_RECORD_TYPE,
|
guideline.getId(), createReqVO.getBlobIds());
|
return guideline.getId();
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void updateGuideline(ResearchGuidelineSaveReqVO updateReqVO) {
|
ResearchGuidelineDO guideline = validateGuidelineExists(updateReqVO.getId());
|
if (!ResearchGuidelineStatusEnum.DRAFT.getStatus().equals(guideline.getPublishStatus())) {
|
throw exception(GUIDELINE_UPDATE_FAIL_NOT_DRAFT, guideline.getNo());
|
}
|
validateApplyTime(updateReqVO);
|
|
ResearchGuidelineDO updateObj = BeanUtils.toBean(updateReqVO, ResearchGuidelineDO.class);
|
guidelineMapper.updateById(updateObj);
|
|
storageAttachmentApi.updateAttachments("file", GUIDELINE_RECORD_TYPE,
|
updateReqVO.getId(), updateReqVO.getBlobIds());
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void deleteGuideline(Long id) {
|
ResearchGuidelineDO guideline = validateGuidelineExists(id);
|
if (!ResearchGuidelineStatusEnum.DRAFT.getStatus().equals(guideline.getPublishStatus())) {
|
throw exception(GUIDELINE_DELETE_FAIL_NOT_DRAFT, guideline.getNo());
|
}
|
// 已产生申报单时禁止删除,避免申报单悬挂在已删除指南上
|
Long applicationCount = applicationMapper.selectCountByGuidelineId(id);
|
if (applicationCount != null && applicationCount > 0) {
|
throw exception(GUIDELINE_HAS_APPLICATION, guideline.getNo(), applicationCount);
|
}
|
|
guidelineMapper.deleteById(id);
|
storageAttachmentApi.deleteAttachmentsByRecord(GUIDELINE_RECORD_TYPE, id);
|
}
|
|
@Override
|
public ResearchGuidelineDO getGuideline(Long id) {
|
return guidelineMapper.selectById(id);
|
}
|
|
@Override
|
public PageResult<ResearchGuidelineDO> getGuidelinePage(ResearchGuidelinePageReqVO pageReqVO) {
|
return guidelineMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
public List<ResearchGuidelineDO> getPublishedGuidelineList() {
|
return guidelineMapper.selectPublishedList();
|
}
|
|
@Override
|
public List<ResearchGuidelineDO> getGuidelineList(Collection<Long> ids) {
|
return guidelineMapper.selectListByIds(ids);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void publishGuideline(Long id) {
|
ResearchGuidelineDO guideline = validateGuidelineExists(id);
|
if (!ResearchGuidelineStatusEnum.DRAFT.getStatus().equals(guideline.getPublishStatus())) {
|
throw exception(GUIDELINE_PUBLISH_FAIL_STATUS);
|
}
|
guidelineMapper.updateById(new ResearchGuidelineDO()
|
.setId(id)
|
.setPublishStatus(ResearchGuidelineStatusEnum.PUBLISHED.getStatus())
|
.setPublishTime(LocalDateTime.now()));
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void closeGuideline(Long id) {
|
ResearchGuidelineDO guideline = validateGuidelineExists(id);
|
if (!ResearchGuidelineStatusEnum.PUBLISHED.getStatus().equals(guideline.getPublishStatus())) {
|
throw exception(GUIDELINE_CLOSE_FAIL_STATUS);
|
}
|
guidelineMapper.updateById(new ResearchGuidelineDO()
|
.setId(id)
|
.setPublishStatus(ResearchGuidelineStatusEnum.CLOSED.getStatus()));
|
}
|
|
@Override
|
public ResearchGuidelineDO validateGuidelineSubmittable(Long guidelineId) {
|
ResearchGuidelineDO guideline = guidelineMapper.selectById(guidelineId);
|
if (guideline == null) {
|
throw exception(GUIDELINE_NOT_EXISTS);
|
}
|
// 逐维度校验,提示里给出「指南名 + 实际状态/时间 + 下一步动作」
|
if (!ResearchGuidelineStatusEnum.PUBLISHED.getStatus().equals(guideline.getPublishStatus())) {
|
throw exception(APPLICATION_SUBMIT_FAIL_GUIDELINE_STATUS,
|
guideline.getTitle(), ResearchGuidelineStatusEnum.nameOf(guideline.getPublishStatus()));
|
}
|
LocalDateTime now = LocalDateTime.now();
|
boolean beforeStart = guideline.getApplyStartTime() != null && now.isBefore(guideline.getApplyStartTime());
|
boolean afterEnd = guideline.getApplyEndTime() != null && now.isAfter(guideline.getApplyEndTime());
|
if (beforeStart || afterEnd) {
|
throw exception(APPLICATION_SUBMIT_FAIL_NOT_IN_PERIOD,
|
format(now), guideline.getTitle(),
|
format(guideline.getApplyStartTime()), format(guideline.getApplyEndTime()));
|
}
|
return guideline;
|
}
|
|
// =================== 内部方法 ===================
|
|
private ResearchGuidelineDO validateGuidelineExists(Long id) {
|
ResearchGuidelineDO guideline = guidelineMapper.selectById(id);
|
if (guideline == null) {
|
throw exception(GUIDELINE_NOT_EXISTS);
|
}
|
return guideline;
|
}
|
|
private void validateApplyTime(ResearchGuidelineSaveReqVO reqVO) {
|
if (reqVO.getApplyStartTime() != null && reqVO.getApplyEndTime() != null
|
&& reqVO.getApplyEndTime().isBefore(reqVO.getApplyStartTime())) {
|
throw exception(GUIDELINE_APPLY_TIME_INVALID,
|
format(reqVO.getApplyEndTime()), format(reqVO.getApplyStartTime()));
|
}
|
}
|
|
private static String format(LocalDateTime time) {
|
return time == null ? "未设置" : time.format(DATE_TIME_FORMATTER);
|
}
|
|
}
|