Add points task submission and review workflow
This commit is contained in:
@@ -54,6 +54,10 @@ public class AppIntegralRecord extends BaseEntity {
|
||||
private Date integralTime;
|
||||
private Long fId;
|
||||
private Long resourceId;
|
||||
/** 业务类型,用于积分操作幂等。 */
|
||||
private String bizType;
|
||||
/** 业务记录主键。 */
|
||||
private Long bizId;
|
||||
|
||||
/**
|
||||
* 资源标题
|
||||
@@ -123,6 +127,22 @@ public class AppIntegralRecord extends BaseEntity {
|
||||
public void setResourceId(Long resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getBizType() {
|
||||
return bizType;
|
||||
}
|
||||
|
||||
public void setBizType(String bizType) {
|
||||
this.bizType = bizType;
|
||||
}
|
||||
|
||||
public Long getBizId() {
|
||||
return bizId;
|
||||
}
|
||||
|
||||
public void setBizId(Long bizId) {
|
||||
this.bizId = bizId;
|
||||
}
|
||||
|
||||
public String getResourceTitle() {
|
||||
return resourceTitle;
|
||||
@@ -141,6 +161,8 @@ public class AppIntegralRecord extends BaseEntity {
|
||||
.append("integralNumber", getIntegralNumber())
|
||||
.append("userId", getUserId())
|
||||
.append("resourceId", getResourceId())
|
||||
.append("bizType", getBizType())
|
||||
.append("bizId", getBizId())
|
||||
.append("resourceTitle", getResourceTitle())
|
||||
.append("integralTime", getIntegralTime())
|
||||
.toString();
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ruoyi.app.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/** 积分任务。 */
|
||||
public class AppPointTask extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private String taskName;
|
||||
private String taskType;
|
||||
private String cycleType;
|
||||
private String coverUrl;
|
||||
private String description;
|
||||
private String operationGuide;
|
||||
private String exampleImages;
|
||||
private Integer rewardPoints;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
private Integer allowResubmit;
|
||||
private String status;
|
||||
private Integer sortOrder;
|
||||
|
||||
/** 当前用户在本周期的状态,非数据库字段。 */
|
||||
private Integer currentStatus;
|
||||
private Boolean canSubmit;
|
||||
private Long currentSubmissionId;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date nextAvailableAt;
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getTaskName() { return taskName; }
|
||||
public void setTaskName(String taskName) { this.taskName = taskName; }
|
||||
public String getTaskType() { return taskType; }
|
||||
public void setTaskType(String taskType) { this.taskType = taskType; }
|
||||
public String getCycleType() { return cycleType; }
|
||||
public void setCycleType(String cycleType) { this.cycleType = cycleType; }
|
||||
public String getCoverUrl() { return coverUrl; }
|
||||
public void setCoverUrl(String coverUrl) { this.coverUrl = coverUrl; }
|
||||
public String getDescription() { return description; }
|
||||
public void setDescription(String description) { this.description = description; }
|
||||
public String getOperationGuide() { return operationGuide; }
|
||||
public void setOperationGuide(String operationGuide) { this.operationGuide = operationGuide; }
|
||||
public String getExampleImages() { return exampleImages; }
|
||||
public void setExampleImages(String exampleImages) { this.exampleImages = exampleImages; }
|
||||
public Integer getRewardPoints() { return rewardPoints; }
|
||||
public void setRewardPoints(Integer rewardPoints) { this.rewardPoints = rewardPoints; }
|
||||
public Date getStartTime() { return startTime; }
|
||||
public void setStartTime(Date startTime) { this.startTime = startTime; }
|
||||
public Date getEndTime() { return endTime; }
|
||||
public void setEndTime(Date endTime) { this.endTime = endTime; }
|
||||
public Integer getAllowResubmit() { return allowResubmit; }
|
||||
public void setAllowResubmit(Integer allowResubmit) { this.allowResubmit = allowResubmit; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
public Integer getSortOrder() { return sortOrder; }
|
||||
public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
|
||||
public Integer getCurrentStatus() { return currentStatus; }
|
||||
public void setCurrentStatus(Integer currentStatus) { this.currentStatus = currentStatus; }
|
||||
public Boolean getCanSubmit() { return canSubmit; }
|
||||
public void setCanSubmit(Boolean canSubmit) { this.canSubmit = canSubmit; }
|
||||
public Long getCurrentSubmissionId() { return currentSubmissionId; }
|
||||
public void setCurrentSubmissionId(Long currentSubmissionId) { this.currentSubmissionId = currentSubmissionId; }
|
||||
public Date getNextAvailableAt() { return nextAvailableAt; }
|
||||
public void setNextAvailableAt(Date nextAvailableAt) { this.nextAvailableAt = nextAvailableAt; }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ruoyi.app.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/** 积分任务截图附件。 */
|
||||
public class AppPointTaskAttachment implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private Long submissionId;
|
||||
private Long userId;
|
||||
private String objectKey;
|
||||
private String originalName;
|
||||
private Long fileSize;
|
||||
private String fileType;
|
||||
private String uploadStatus;
|
||||
private Integer submitBatch;
|
||||
private Integer isCurrent;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
/** 七牛临时访问地址,非数据库字段。 */
|
||||
private String previewUrl;
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public Long getSubmissionId() { return submissionId; }
|
||||
public void setSubmissionId(Long submissionId) { this.submissionId = submissionId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getObjectKey() { return objectKey; }
|
||||
public void setObjectKey(String objectKey) { this.objectKey = objectKey; }
|
||||
public String getOriginalName() { return originalName; }
|
||||
public void setOriginalName(String originalName) { this.originalName = originalName; }
|
||||
public Long getFileSize() { return fileSize; }
|
||||
public void setFileSize(Long fileSize) { this.fileSize = fileSize; }
|
||||
public String getFileType() { return fileType; }
|
||||
public void setFileType(String fileType) { this.fileType = fileType; }
|
||||
public String getUploadStatus() { return uploadStatus; }
|
||||
public void setUploadStatus(String uploadStatus) { this.uploadStatus = uploadStatus; }
|
||||
public Integer getSubmitBatch() { return submitBatch; }
|
||||
public void setSubmitBatch(Integer submitBatch) { this.submitBatch = submitBatch; }
|
||||
public Integer getIsCurrent() { return isCurrent; }
|
||||
public void setIsCurrent(Integer isCurrent) { this.isCurrent = isCurrent; }
|
||||
public Date getCreateTime() { return createTime; }
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
public String getPreviewUrl() { return previewUrl; }
|
||||
public void setPreviewUrl(String previewUrl) { this.previewUrl = previewUrl; }
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.ruoyi.app.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/** 积分任务审核日志。 */
|
||||
public class AppPointTaskAuditLog implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Long submissionId;
|
||||
private Integer beforeStatus;
|
||||
private Integer afterStatus;
|
||||
private String operatorName;
|
||||
private String remark;
|
||||
private Date createTime;
|
||||
|
||||
public Long getSubmissionId() { return submissionId; }
|
||||
public void setSubmissionId(Long submissionId) { this.submissionId = submissionId; }
|
||||
public Integer getBeforeStatus() { return beforeStatus; }
|
||||
public void setBeforeStatus(Integer beforeStatus) { this.beforeStatus = beforeStatus; }
|
||||
public Integer getAfterStatus() { return afterStatus; }
|
||||
public void setAfterStatus(Integer afterStatus) { this.afterStatus = afterStatus; }
|
||||
public String getOperatorName() { return operatorName; }
|
||||
public void setOperatorName(String operatorName) { this.operatorName = operatorName; }
|
||||
public String getRemark() { return remark; }
|
||||
public void setRemark(String remark) { this.remark = remark; }
|
||||
public Date getCreateTime() { return createTime; }
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.ruoyi.app.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/** 积分任务提交记录。 */
|
||||
public class AppPointTaskSubmission extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private String submissionNo;
|
||||
private Long taskId;
|
||||
private Long userId;
|
||||
private String cycleKey;
|
||||
private Integer rewardPoints;
|
||||
private Integer status;
|
||||
private Integer attemptCount;
|
||||
private String rejectReason;
|
||||
private String reviewBy;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reviewTime;
|
||||
private Long rewardRecordId;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date firstSubmitTime;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date lastSubmitTime;
|
||||
|
||||
private String taskName;
|
||||
private String taskType;
|
||||
private String cycleType;
|
||||
private String userName;
|
||||
private String nickName;
|
||||
private List<String> attachmentKeys;
|
||||
private List<AppPointTaskAttachment> attachments;
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getSubmissionNo() { return submissionNo; }
|
||||
public void setSubmissionNo(String submissionNo) { this.submissionNo = submissionNo; }
|
||||
public Long getTaskId() { return taskId; }
|
||||
public void setTaskId(Long taskId) { this.taskId = taskId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getCycleKey() { return cycleKey; }
|
||||
public void setCycleKey(String cycleKey) { this.cycleKey = cycleKey; }
|
||||
public Integer getRewardPoints() { return rewardPoints; }
|
||||
public void setRewardPoints(Integer rewardPoints) { this.rewardPoints = rewardPoints; }
|
||||
public Integer getStatus() { return status; }
|
||||
public void setStatus(Integer status) { this.status = status; }
|
||||
public Integer getAttemptCount() { return attemptCount; }
|
||||
public void setAttemptCount(Integer attemptCount) { this.attemptCount = attemptCount; }
|
||||
public String getRejectReason() { return rejectReason; }
|
||||
public void setRejectReason(String rejectReason) { this.rejectReason = rejectReason; }
|
||||
public String getReviewBy() { return reviewBy; }
|
||||
public void setReviewBy(String reviewBy) { this.reviewBy = reviewBy; }
|
||||
public Date getReviewTime() { return reviewTime; }
|
||||
public void setReviewTime(Date reviewTime) { this.reviewTime = reviewTime; }
|
||||
public Long getRewardRecordId() { return rewardRecordId; }
|
||||
public void setRewardRecordId(Long rewardRecordId) { this.rewardRecordId = rewardRecordId; }
|
||||
public Date getFirstSubmitTime() { return firstSubmitTime; }
|
||||
public void setFirstSubmitTime(Date firstSubmitTime) { this.firstSubmitTime = firstSubmitTime; }
|
||||
public Date getLastSubmitTime() { return lastSubmitTime; }
|
||||
public void setLastSubmitTime(Date lastSubmitTime) { this.lastSubmitTime = lastSubmitTime; }
|
||||
public String getTaskName() { return taskName; }
|
||||
public void setTaskName(String taskName) { this.taskName = taskName; }
|
||||
public String getTaskType() { return taskType; }
|
||||
public void setTaskType(String taskType) { this.taskType = taskType; }
|
||||
public String getCycleType() { return cycleType; }
|
||||
public void setCycleType(String cycleType) { this.cycleType = cycleType; }
|
||||
public String getUserName() { return userName; }
|
||||
public void setUserName(String userName) { this.userName = userName; }
|
||||
public String getNickName() { return nickName; }
|
||||
public void setNickName(String nickName) { this.nickName = nickName; }
|
||||
public List<String> getAttachmentKeys() { return attachmentKeys; }
|
||||
public void setAttachmentKeys(List<String> attachmentKeys) { this.attachmentKeys = attachmentKeys; }
|
||||
public List<AppPointTaskAttachment> getAttachments() { return attachments; }
|
||||
public void setAttachments(List<AppPointTaskAttachment> attachments) { this.attachments = attachments; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ruoyi.app.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/** 七牛任务截图上传凭证请求。 */
|
||||
public class AppPointTaskUploadRequest implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String fileName;
|
||||
private Long fileSize;
|
||||
private String contentType;
|
||||
|
||||
public String getFileName() { return fileName; }
|
||||
public void setFileName(String fileName) { this.fileName = fileName; }
|
||||
public Long getFileSize() { return fileSize; }
|
||||
public void setFileSize(Long fileSize) { this.fileSize = fileSize; }
|
||||
public String getContentType() { return contentType; }
|
||||
public void setContentType(String contentType) { this.contentType = contentType; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.ruoyi.app.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.app.domain.AppPointTask;
|
||||
|
||||
public interface AppPointTaskMapper
|
||||
{
|
||||
AppPointTask selectAppPointTaskById(Long id);
|
||||
List<AppPointTask> selectAppPointTaskList(AppPointTask task);
|
||||
List<AppPointTask> selectActiveAppPointTaskList();
|
||||
int insertAppPointTask(AppPointTask task);
|
||||
int updateAppPointTask(AppPointTask task);
|
||||
int deleteAppPointTaskByIds(Long[] ids);
|
||||
int countSubmissionByTaskIds(Long[] ids);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ruoyi.app.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import com.ruoyi.app.domain.AppPointTaskAttachment;
|
||||
import com.ruoyi.app.domain.AppPointTaskAuditLog;
|
||||
import com.ruoyi.app.domain.AppPointTaskSubmission;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface AppPointTaskSubmissionMapper
|
||||
{
|
||||
AppPointTaskSubmission selectSubmissionById(Long id);
|
||||
AppPointTaskSubmission selectSubmissionByIdForUpdate(Long id);
|
||||
AppPointTaskSubmission selectByTaskUserCycle(@Param("taskId") Long taskId,
|
||||
@Param("userId") Long userId,
|
||||
@Param("cycleKey") String cycleKey);
|
||||
List<AppPointTaskSubmission> selectSubmissionList(AppPointTaskSubmission submission);
|
||||
List<AppPointTaskSubmission> selectMySubmissionList(@Param("userId") Long userId);
|
||||
int insertSubmission(AppPointTaskSubmission submission);
|
||||
int updateSubmission(AppPointTaskSubmission submission);
|
||||
|
||||
int insertTempAttachment(AppPointTaskAttachment attachment);
|
||||
Long lockUserForUpload(@Param("userId") Long userId);
|
||||
int countTempAttachmentsByUser(@Param("userId") Long userId);
|
||||
int countAttachmentsByUserSince(@Param("userId") Long userId, @Param("since") String since);
|
||||
List<AppPointTaskAttachment> selectTempAttachments(@Param("userId") Long userId,
|
||||
@Param("keys") List<String> keys);
|
||||
int bindAttachments(@Param("userId") Long userId,
|
||||
@Param("submissionId") Long submissionId,
|
||||
@Param("submitBatch") Integer submitBatch,
|
||||
@Param("keys") List<String> keys);
|
||||
int markAttachmentsNotCurrent(Long submissionId);
|
||||
List<AppPointTaskAttachment> selectAttachmentsBySubmissionId(Long submissionId);
|
||||
List<AppPointTaskAttachment> selectExpiredTempAttachments(Date beforeTime);
|
||||
int deleteTempAttachmentById(Long id);
|
||||
int insertAuditLog(AppPointTaskAuditLog auditLog);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ruoyi.app.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.app.domain.AppPointTask;
|
||||
import com.ruoyi.app.domain.AppPointTaskAttachment;
|
||||
import com.ruoyi.app.domain.AppPointTaskSubmission;
|
||||
|
||||
public interface IAppPointTaskService
|
||||
{
|
||||
AppPointTask selectAppPointTaskById(Long id);
|
||||
List<AppPointTask> selectAppPointTaskList(AppPointTask task);
|
||||
List<AppPointTask> selectActiveTaskList(Long userId);
|
||||
AppPointTask selectActiveTaskDetail(Long id, Long userId);
|
||||
int insertAppPointTask(AppPointTask task);
|
||||
int updateAppPointTask(AppPointTask task);
|
||||
int deleteAppPointTaskByIds(Long[] ids);
|
||||
|
||||
AppPointTaskAttachment createTempAttachment(AppPointTaskAttachment attachment);
|
||||
AppPointTaskSubmission submitTask(Long taskId, AppPointTaskSubmission request, Long userId);
|
||||
AppPointTaskSubmission resubmitTask(Long submissionId, AppPointTaskSubmission request, Long userId);
|
||||
List<AppPointTaskSubmission> selectMySubmissionList(Long userId);
|
||||
AppPointTaskSubmission selectMySubmissionDetail(Long id, Long userId);
|
||||
List<AppPointTaskSubmission> selectSubmissionList(AppPointTaskSubmission submission);
|
||||
AppPointTaskSubmission selectSubmissionDetail(Long id);
|
||||
int approveSubmission(Long id, String operator);
|
||||
int rejectSubmission(Long id, String rejectReason, String operator);
|
||||
int revokeSubmission(Long id, String reason, String operator);
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
package com.ruoyi.app.service.impl;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import com.ruoyi.app.domain.AppIntegralRecord;
|
||||
import com.ruoyi.app.domain.AppPointTask;
|
||||
import com.ruoyi.app.domain.AppPointTaskAttachment;
|
||||
import com.ruoyi.app.domain.AppPointTaskAuditLog;
|
||||
import com.ruoyi.app.domain.AppPointTaskSubmission;
|
||||
import com.ruoyi.app.mapper.AppIntegralRecordMapper;
|
||||
import com.ruoyi.app.mapper.AppPointTaskMapper;
|
||||
import com.ruoyi.app.mapper.AppPointTaskSubmissionMapper;
|
||||
import com.ruoyi.app.service.IAppPointTaskService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class AppPointTaskServiceImpl implements IAppPointTaskService
|
||||
{
|
||||
private static final String CYCLE_ONCE = "ONCE";
|
||||
private static final String CYCLE_DAILY = "DAILY";
|
||||
private static final int STATUS_PENDING = 0;
|
||||
private static final int STATUS_APPROVED = 1;
|
||||
private static final int STATUS_REJECTED = 2;
|
||||
private static final int STATUS_REVOKED = 3;
|
||||
private static final int MAX_TEMP_ATTACHMENTS_PER_USER = 9;
|
||||
private static final int MAX_DAILY_ATTACHMENTS_PER_USER = 30;
|
||||
private static final ZoneId SHANGHAI_ZONE = ZoneId.of("Asia/Shanghai");
|
||||
|
||||
@Autowired
|
||||
private AppPointTaskMapper taskMapper;
|
||||
@Autowired
|
||||
private AppPointTaskSubmissionMapper submissionMapper;
|
||||
@Autowired
|
||||
private AppIntegralRecordMapper integralRecordMapper;
|
||||
@Autowired
|
||||
private SysUserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public AppPointTask selectAppPointTaskById(Long id)
|
||||
{
|
||||
return taskMapper.selectAppPointTaskById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AppPointTask> selectAppPointTaskList(AppPointTask task)
|
||||
{
|
||||
return taskMapper.selectAppPointTaskList(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AppPointTask> selectActiveTaskList(Long userId)
|
||||
{
|
||||
List<AppPointTask> tasks = taskMapper.selectActiveAppPointTaskList();
|
||||
for (AppPointTask task : tasks)
|
||||
{
|
||||
populateUserState(task, userId);
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppPointTask selectActiveTaskDetail(Long id, Long userId)
|
||||
{
|
||||
AppPointTask task = taskMapper.selectAppPointTaskById(id);
|
||||
if (task == null)
|
||||
{
|
||||
throw new ServiceException("任务不存在");
|
||||
}
|
||||
populateUserState(task, userId);
|
||||
if (!isTaskActive(task, DateUtils.getNowDate()))
|
||||
{
|
||||
task.setCanSubmit(false);
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertAppPointTask(AppPointTask task)
|
||||
{
|
||||
normalizeAndValidateTask(task);
|
||||
Date now = DateUtils.getNowDate();
|
||||
task.setCreateTime(now);
|
||||
task.setUpdateTime(now);
|
||||
return taskMapper.insertAppPointTask(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateAppPointTask(AppPointTask task)
|
||||
{
|
||||
if (task.getId() == null)
|
||||
{
|
||||
throw new ServiceException("任务不存在");
|
||||
}
|
||||
AppPointTask current = taskMapper.selectAppPointTaskById(task.getId());
|
||||
if (current == null)
|
||||
{
|
||||
throw new ServiceException("任务不存在");
|
||||
}
|
||||
normalizeAndValidateTask(task);
|
||||
if (taskMapper.countSubmissionByTaskIds(new Long[] { task.getId() }) > 0
|
||||
&& (!current.getRewardPoints().equals(task.getRewardPoints())
|
||||
|| !current.getCycleType().equals(task.getCycleType())))
|
||||
{
|
||||
throw new ServiceException("任务已有用户提交,不能修改奖励积分或任务周期");
|
||||
}
|
||||
task.setUpdateTime(DateUtils.getNowDate());
|
||||
return taskMapper.updateAppPointTask(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteAppPointTaskByIds(Long[] ids)
|
||||
{
|
||||
if (ids == null || ids.length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (taskMapper.countSubmissionByTaskIds(ids) > 0)
|
||||
{
|
||||
throw new ServiceException("任务已有用户提交,请停用任务,不要删除");
|
||||
}
|
||||
return taskMapper.deleteAppPointTaskByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public AppPointTaskAttachment createTempAttachment(AppPointTaskAttachment attachment)
|
||||
{
|
||||
Long userId = attachment.getUserId();
|
||||
if (userId == null || submissionMapper.lockUserForUpload(userId) == null)
|
||||
{
|
||||
throw new ServiceException("用户不存在,请重新登录");
|
||||
}
|
||||
if (submissionMapper.countTempAttachmentsByUser(userId) >= MAX_TEMP_ATTACHMENTS_PER_USER)
|
||||
{
|
||||
throw new ServiceException("未提交截图已达上限,请先完成任务提交或等待临时截图清理后再试");
|
||||
}
|
||||
String todayStart = LocalDate.now(SHANGHAI_ZONE) + " 00:00:00";
|
||||
if (submissionMapper.countAttachmentsByUserSince(userId, todayStart) >= MAX_DAILY_ATTACHMENTS_PER_USER)
|
||||
{
|
||||
throw new ServiceException("今日上传次数已达上限,请明日再试");
|
||||
}
|
||||
attachment.setUploadStatus("TEMP");
|
||||
attachment.setSubmitBatch(0);
|
||||
attachment.setIsCurrent(0);
|
||||
attachment.setCreateTime(DateUtils.getNowDate());
|
||||
if (submissionMapper.insertTempAttachment(attachment) != 1)
|
||||
{
|
||||
throw new ServiceException("创建上传记录失败,请重试");
|
||||
}
|
||||
return attachment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public AppPointTaskSubmission submitTask(Long taskId, AppPointTaskSubmission request, Long userId)
|
||||
{
|
||||
AppPointTask task = requireActiveTask(taskId);
|
||||
List<String> keys = normalizeAttachmentKeys(request.getAttachmentKeys());
|
||||
String cycleKey = cycleKey(task);
|
||||
if (submissionMapper.selectByTaskUserCycle(taskId, userId, cycleKey) != null)
|
||||
{
|
||||
throw new ServiceException(CYCLE_DAILY.equals(task.getCycleType())
|
||||
? "今日已经提交过该任务" : "该任务已经提交过");
|
||||
}
|
||||
assertTempAttachments(userId, keys);
|
||||
|
||||
Date now = DateUtils.getNowDate();
|
||||
AppPointTaskSubmission submission = new AppPointTaskSubmission();
|
||||
submission.setSubmissionNo("RW" + DateUtils.dateTimeNow() + IdUtils.fastSimpleUUID().substring(0, 6).toUpperCase());
|
||||
submission.setTaskId(taskId);
|
||||
submission.setUserId(userId);
|
||||
submission.setCycleKey(cycleKey);
|
||||
submission.setRewardPoints(task.getRewardPoints());
|
||||
submission.setRemark(normalizeRemark(request.getRemark()));
|
||||
submission.setStatus(STATUS_PENDING);
|
||||
submission.setAttemptCount(1);
|
||||
submission.setFirstSubmitTime(now);
|
||||
submission.setLastSubmitTime(now);
|
||||
submission.setCreateBy(String.valueOf(userId));
|
||||
submission.setCreateTime(now);
|
||||
submission.setUpdateBy(String.valueOf(userId));
|
||||
submission.setUpdateTime(now);
|
||||
try
|
||||
{
|
||||
if (submissionMapper.insertSubmission(submission) != 1)
|
||||
{
|
||||
throw new ServiceException("任务提交失败,请重试");
|
||||
}
|
||||
}
|
||||
catch (DuplicateKeyException ex)
|
||||
{
|
||||
throw new ServiceException("该任务本周期已经提交过");
|
||||
}
|
||||
bindAttachments(userId, submission.getId(), 1, keys);
|
||||
insertAudit(submission.getId(), null, STATUS_PENDING, String.valueOf(userId), "用户提交任务");
|
||||
return selectSubmissionDetail(submission.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public AppPointTaskSubmission resubmitTask(Long submissionId, AppPointTaskSubmission request, Long userId)
|
||||
{
|
||||
AppPointTaskSubmission current = submissionMapper.selectSubmissionByIdForUpdate(submissionId);
|
||||
if (current == null || !userId.equals(current.getUserId()))
|
||||
{
|
||||
throw new ServiceException("任务记录不存在");
|
||||
}
|
||||
if (current.getStatus() != STATUS_REJECTED)
|
||||
{
|
||||
throw new ServiceException("只有审核未通过的任务可以重新提交");
|
||||
}
|
||||
AppPointTask task = requireActiveTask(current.getTaskId());
|
||||
if (CYCLE_DAILY.equals(task.getCycleType()) && !cycleKey(task).equals(current.getCycleKey()))
|
||||
{
|
||||
throw new ServiceException("该每日任务周期已结束,请提交今日任务");
|
||||
}
|
||||
List<String> keys = normalizeAttachmentKeys(request.getAttachmentKeys());
|
||||
assertTempAttachments(userId, keys);
|
||||
int nextBatch = current.getAttemptCount() + 1;
|
||||
submissionMapper.markAttachmentsNotCurrent(submissionId);
|
||||
bindAttachments(userId, submissionId, nextBatch, keys);
|
||||
|
||||
current.setRemark(normalizeRemark(request.getRemark()));
|
||||
current.setStatus(STATUS_PENDING);
|
||||
current.setAttemptCount(nextBatch);
|
||||
current.setRejectReason(null);
|
||||
current.setReviewBy(null);
|
||||
current.setReviewTime(null);
|
||||
current.setLastSubmitTime(DateUtils.getNowDate());
|
||||
current.setUpdateBy(String.valueOf(userId));
|
||||
current.setUpdateTime(DateUtils.getNowDate());
|
||||
submissionMapper.updateSubmission(current);
|
||||
insertAudit(submissionId, STATUS_REJECTED, STATUS_PENDING, String.valueOf(userId), "用户重新提交任务");
|
||||
return selectSubmissionDetail(submissionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AppPointTaskSubmission> selectMySubmissionList(Long userId)
|
||||
{
|
||||
return submissionMapper.selectMySubmissionList(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppPointTaskSubmission selectMySubmissionDetail(Long id, Long userId)
|
||||
{
|
||||
AppPointTaskSubmission submission = selectSubmissionDetail(id);
|
||||
if (submission == null || !userId.equals(submission.getUserId()))
|
||||
{
|
||||
throw new ServiceException("任务记录不存在");
|
||||
}
|
||||
return submission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AppPointTaskSubmission> selectSubmissionList(AppPointTaskSubmission submission)
|
||||
{
|
||||
return submissionMapper.selectSubmissionList(submission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppPointTaskSubmission selectSubmissionDetail(Long id)
|
||||
{
|
||||
AppPointTaskSubmission submission = submissionMapper.selectSubmissionById(id);
|
||||
if (submission != null)
|
||||
{
|
||||
submission.setAttachments(submissionMapper.selectAttachmentsBySubmissionId(id));
|
||||
}
|
||||
return submission;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int approveSubmission(Long id, String operator)
|
||||
{
|
||||
AppPointTaskSubmission submission = requirePendingSubmission(id);
|
||||
AppPointTask task = taskMapper.selectAppPointTaskById(submission.getTaskId());
|
||||
if (task == null)
|
||||
{
|
||||
throw new ServiceException("关联任务不存在");
|
||||
}
|
||||
if (userMapper.addIntegralByUserId(submission.getRewardPoints(), submission.getUserId()) != 1)
|
||||
{
|
||||
throw new ServiceException("积分发放失败,请重试");
|
||||
}
|
||||
AppIntegralRecord record = insertIntegralRecord(submission, 0L, task.getTaskName() + "奖励", "POINT_TASK");
|
||||
submission.setStatus(STATUS_APPROVED);
|
||||
submission.setRewardRecordId(record.getId());
|
||||
submission.setRejectReason(null);
|
||||
submission.setReviewBy(operator);
|
||||
submission.setReviewTime(DateUtils.getNowDate());
|
||||
submission.setUpdateBy(operator);
|
||||
submission.setUpdateTime(DateUtils.getNowDate());
|
||||
int rows = submissionMapper.updateSubmission(submission);
|
||||
insertAudit(id, STATUS_PENDING, STATUS_APPROVED, operator, "审核通过并发放" + submission.getRewardPoints() + "积分");
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int rejectSubmission(Long id, String rejectReason, String operator)
|
||||
{
|
||||
String reason = StringUtils.trim(rejectReason);
|
||||
if (StringUtils.isEmpty(reason))
|
||||
{
|
||||
throw new ServiceException("审核不通过时必须填写原因");
|
||||
}
|
||||
AppPointTaskSubmission submission = requirePendingSubmission(id);
|
||||
submission.setStatus(STATUS_REJECTED);
|
||||
submission.setRejectReason(reason);
|
||||
submission.setReviewBy(operator);
|
||||
submission.setReviewTime(DateUtils.getNowDate());
|
||||
submission.setUpdateBy(operator);
|
||||
submission.setUpdateTime(DateUtils.getNowDate());
|
||||
int rows = submissionMapper.updateSubmission(submission);
|
||||
insertAudit(id, STATUS_PENDING, STATUS_REJECTED, operator, reason);
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int revokeSubmission(Long id, String reason, String operator)
|
||||
{
|
||||
String revokeReason = StringUtils.trim(reason);
|
||||
if (StringUtils.isEmpty(revokeReason))
|
||||
{
|
||||
throw new ServiceException("撤销奖励时必须填写原因");
|
||||
}
|
||||
AppPointTaskSubmission submission = submissionMapper.selectSubmissionByIdForUpdate(id);
|
||||
if (submission == null || submission.getStatus() != STATUS_APPROVED)
|
||||
{
|
||||
throw new ServiceException("只有已通过的任务可以撤销奖励");
|
||||
}
|
||||
AppPointTask task = taskMapper.selectAppPointTaskById(submission.getTaskId());
|
||||
if (userMapper.delIntegralByUserId(submission.getRewardPoints(), submission.getUserId()) != 1)
|
||||
{
|
||||
throw new ServiceException("用户当前积分不足,无法撤销奖励");
|
||||
}
|
||||
insertIntegralRecord(submission, 1L, "撤销:" + (task == null ? "积分任务" : task.getTaskName()), "POINT_TASK_REVOKE");
|
||||
submission.setStatus(STATUS_REVOKED);
|
||||
submission.setRejectReason(revokeReason);
|
||||
submission.setReviewBy(operator);
|
||||
submission.setReviewTime(DateUtils.getNowDate());
|
||||
submission.setUpdateBy(operator);
|
||||
submission.setUpdateTime(DateUtils.getNowDate());
|
||||
int rows = submissionMapper.updateSubmission(submission);
|
||||
insertAudit(id, STATUS_APPROVED, STATUS_REVOKED, operator, revokeReason);
|
||||
return rows;
|
||||
}
|
||||
|
||||
private void populateUserState(AppPointTask task, Long userId)
|
||||
{
|
||||
AppPointTaskSubmission submission = submissionMapper.selectByTaskUserCycle(task.getId(), userId, cycleKey(task));
|
||||
if (submission == null)
|
||||
{
|
||||
task.setCanSubmit(true);
|
||||
return;
|
||||
}
|
||||
task.setCurrentStatus(submission.getStatus());
|
||||
task.setCurrentSubmissionId(submission.getId());
|
||||
task.setCanSubmit(submission.getStatus() == STATUS_REJECTED);
|
||||
if (CYCLE_DAILY.equals(task.getCycleType()) && submission.getStatus() == STATUS_APPROVED)
|
||||
{
|
||||
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"));
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
task.setNextAvailableAt(calendar.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
private AppPointTask requireActiveTask(Long id)
|
||||
{
|
||||
AppPointTask task = taskMapper.selectAppPointTaskById(id);
|
||||
Date now = DateUtils.getNowDate();
|
||||
if (task == null || !"0".equals(task.getStatus()))
|
||||
{
|
||||
throw new ServiceException("任务不存在或已停用");
|
||||
}
|
||||
if (task.getStartTime() != null && task.getStartTime().after(now))
|
||||
{
|
||||
throw new ServiceException("任务尚未开始");
|
||||
}
|
||||
if (task.getEndTime() != null && task.getEndTime().before(now))
|
||||
{
|
||||
throw new ServiceException("任务已经结束");
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
private boolean isTaskActive(AppPointTask task, Date now)
|
||||
{
|
||||
return task != null && "0".equals(task.getStatus())
|
||||
&& (task.getStartTime() == null || !task.getStartTime().after(now))
|
||||
&& (task.getEndTime() == null || !task.getEndTime().before(now));
|
||||
}
|
||||
|
||||
private AppPointTaskSubmission requirePendingSubmission(Long id)
|
||||
{
|
||||
AppPointTaskSubmission submission = submissionMapper.selectSubmissionByIdForUpdate(id);
|
||||
if (submission == null)
|
||||
{
|
||||
throw new ServiceException("任务记录不存在");
|
||||
}
|
||||
if (submission.getStatus() != STATUS_PENDING)
|
||||
{
|
||||
throw new ServiceException("该任务已经处理,请勿重复操作");
|
||||
}
|
||||
return submission;
|
||||
}
|
||||
|
||||
private String cycleKey(AppPointTask task)
|
||||
{
|
||||
return CYCLE_DAILY.equals(task.getCycleType()) ? LocalDate.now(SHANGHAI_ZONE).toString() : CYCLE_ONCE;
|
||||
}
|
||||
|
||||
private List<String> normalizeAttachmentKeys(List<String> keys)
|
||||
{
|
||||
if (keys == null)
|
||||
{
|
||||
throw new ServiceException("请上传任务截图");
|
||||
}
|
||||
Set<String> unique = new LinkedHashSet<>();
|
||||
for (String key : keys)
|
||||
{
|
||||
if (StringUtils.isNotEmpty(StringUtils.trim(key)))
|
||||
{
|
||||
unique.add(StringUtils.trim(key));
|
||||
}
|
||||
}
|
||||
if (unique.isEmpty() || unique.size() > 3)
|
||||
{
|
||||
throw new ServiceException("请上传1至3张任务截图");
|
||||
}
|
||||
return new ArrayList<>(unique);
|
||||
}
|
||||
|
||||
private void assertTempAttachments(Long userId, List<String> keys)
|
||||
{
|
||||
if (submissionMapper.selectTempAttachments(userId, keys).size() != keys.size())
|
||||
{
|
||||
throw new ServiceException("截图无效或已经被其他任务使用,请重新上传");
|
||||
}
|
||||
}
|
||||
|
||||
private void bindAttachments(Long userId, Long submissionId, Integer batch, List<String> keys)
|
||||
{
|
||||
if (submissionMapper.bindAttachments(userId, submissionId, batch, keys) != keys.size())
|
||||
{
|
||||
throw new ServiceException("任务截图绑定失败,请重新上传");
|
||||
}
|
||||
}
|
||||
|
||||
private void insertAudit(Long submissionId, Integer before, Integer after, String operator, String remark)
|
||||
{
|
||||
AppPointTaskAuditLog log = new AppPointTaskAuditLog();
|
||||
log.setSubmissionId(submissionId);
|
||||
log.setBeforeStatus(before);
|
||||
log.setAfterStatus(after);
|
||||
log.setOperatorName(operator);
|
||||
log.setRemark(remark);
|
||||
log.setCreateTime(DateUtils.getNowDate());
|
||||
submissionMapper.insertAuditLog(log);
|
||||
}
|
||||
|
||||
private AppIntegralRecord insertIntegralRecord(AppPointTaskSubmission submission, Long isAdd, String source, String bizType)
|
||||
{
|
||||
AppIntegralRecord record = new AppIntegralRecord();
|
||||
record.setSource(source);
|
||||
record.setIsAdd(isAdd);
|
||||
record.setIntegralNumber(submission.getRewardPoints().longValue());
|
||||
record.setUserId(submission.getUserId());
|
||||
record.setIntegralTime(DateUtils.getNowDate());
|
||||
record.setBizType(bizType);
|
||||
record.setBizId(submission.getId());
|
||||
if (integralRecordMapper.insertAppIntegralRecord(record) != 1)
|
||||
{
|
||||
throw new ServiceException("积分流水记录失败,请重试");
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
private void normalizeAndValidateTask(AppPointTask task)
|
||||
{
|
||||
task.setTaskName(StringUtils.trim(task.getTaskName()));
|
||||
task.setDescription(StringUtils.trim(task.getDescription()));
|
||||
task.setOperationGuide(StringUtils.trim(task.getOperationGuide()));
|
||||
if (StringUtils.isEmpty(task.getTaskName()) || task.getTaskName().length() > 80)
|
||||
{
|
||||
throw new ServiceException("任务名称需填写1至80个字");
|
||||
}
|
||||
if (!CYCLE_ONCE.equals(task.getCycleType()) && !CYCLE_DAILY.equals(task.getCycleType()))
|
||||
{
|
||||
throw new ServiceException("任务周期不正确");
|
||||
}
|
||||
if (task.getRewardPoints() == null || task.getRewardPoints() <= 0 || task.getRewardPoints() > 100000)
|
||||
{
|
||||
throw new ServiceException("奖励积分必须在1至100000之间");
|
||||
}
|
||||
if (task.getStartTime() != null && task.getEndTime() != null && !task.getStartTime().before(task.getEndTime()))
|
||||
{
|
||||
throw new ServiceException("结束时间必须晚于开始时间");
|
||||
}
|
||||
task.setAllowResubmit(1);
|
||||
if (task.getSortOrder() == null || task.getSortOrder() < 0)
|
||||
{
|
||||
task.setSortOrder(0);
|
||||
}
|
||||
if (!"1".equals(task.getStatus()))
|
||||
{
|
||||
task.setStatus("0");
|
||||
}
|
||||
if (StringUtils.isEmpty(task.getTaskType()))
|
||||
{
|
||||
task.setTaskType("OTHER");
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeRemark(String remark)
|
||||
{
|
||||
String value = StringUtils.trim(remark);
|
||||
if (value != null && value.length() > 300)
|
||||
{
|
||||
throw new ServiceException("补充说明不能超过300个字");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="integralNumber" column="integral_number" />
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="resourceId" column="resource_id" />
|
||||
<result property="bizType" column="biz_type" />
|
||||
<result property="bizId" column="biz_id" />
|
||||
<result property="resourceTitle" column="resource_title" />
|
||||
<result property="integralTime" column="integral_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectAppIntegralRecordVo">
|
||||
select a.id, a.source, a.is_add, a.integral_number, a.user_id, a.resource_id, a.integral_time, r.resource_title
|
||||
select a.id, a.source, a.is_add, a.integral_number, a.user_id, a.resource_id,
|
||||
a.biz_type, a.biz_id, a.integral_time, r.resource_title
|
||||
from app_integral_record a
|
||||
left join app_resource r on a.resource_id = r.id
|
||||
</sql>
|
||||
@@ -68,6 +71,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="integralNumber != null">integral_number,</if>
|
||||
<if test="userId != null">user_id,</if>
|
||||
<if test="resourceId != null">resource_id,</if>
|
||||
<if test="bizType != null">biz_type,</if>
|
||||
<if test="bizId != null">biz_id,</if>
|
||||
<if test="integralTime != null">integral_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
@@ -76,6 +81,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="integralNumber != null">#{integralNumber},</if>
|
||||
<if test="userId != null">#{userId},</if>
|
||||
<if test="resourceId != null">#{resourceId},</if>
|
||||
<if test="bizType != null">#{bizType},</if>
|
||||
<if test="bizId != null">#{bizId},</if>
|
||||
<if test="integralTime != null">#{integralTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
@@ -88,6 +95,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="integralNumber != null">integral_number = #{integralNumber},</if>
|
||||
<if test="userId != null">user_id = #{userId},</if>
|
||||
<if test="resourceId != null">resource_id = #{resourceId},</if>
|
||||
<if test="bizType != null">biz_type = #{bizType},</if>
|
||||
<if test="bizId != null">biz_id = #{bizId},</if>
|
||||
<if test="integralTime != null">integral_time = #{integralTime},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.app.mapper.AppPointTaskMapper">
|
||||
<resultMap type="AppPointTask" id="AppPointTaskResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="taskName" column="task_name" />
|
||||
<result property="taskType" column="task_type" />
|
||||
<result property="cycleType" column="cycle_type" />
|
||||
<result property="coverUrl" column="cover_url" />
|
||||
<result property="description" column="description" />
|
||||
<result property="operationGuide" column="operation_guide" />
|
||||
<result property="exampleImages" column="example_images" />
|
||||
<result property="rewardPoints" column="reward_points" />
|
||||
<result property="startTime" column="start_time" />
|
||||
<result property="endTime" column="end_time" />
|
||||
<result property="allowResubmit" column="allow_resubmit" />
|
||||
<result property="status" column="status" />
|
||||
<result property="sortOrder" column="sort_order" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectTaskVo">
|
||||
select id, task_name, task_type, cycle_type, cover_url, description, operation_guide,
|
||||
example_images, reward_points, start_time, end_time, allow_resubmit, status,
|
||||
sort_order, create_by, create_time, update_by, update_time
|
||||
from app_point_task
|
||||
</sql>
|
||||
|
||||
<select id="selectAppPointTaskById" resultMap="AppPointTaskResult">
|
||||
<include refid="selectTaskVo" /> where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectAppPointTaskList" parameterType="AppPointTask" resultMap="AppPointTaskResult">
|
||||
<include refid="selectTaskVo" />
|
||||
<where>
|
||||
<if test="taskName != null and taskName != ''">and task_name like concat('%', #{taskName}, '%')</if>
|
||||
<if test="taskType != null and taskType != ''">and task_type = #{taskType}</if>
|
||||
<if test="cycleType != null and cycleType != ''">and cycle_type = #{cycleType}</if>
|
||||
<if test="status != null and status != ''">and status = #{status}</if>
|
||||
</where>
|
||||
order by sort_order asc, id desc
|
||||
</select>
|
||||
|
||||
<select id="selectActiveAppPointTaskList" resultMap="AppPointTaskResult">
|
||||
<include refid="selectTaskVo" />
|
||||
where status = '0'
|
||||
and (start_time is null or start_time <= now())
|
||||
and (end_time is null or end_time >= now())
|
||||
order by sort_order asc, id desc
|
||||
</select>
|
||||
|
||||
<insert id="insertAppPointTask" parameterType="AppPointTask" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into app_point_task
|
||||
(task_name, task_type, cycle_type, cover_url, description, operation_guide, example_images,
|
||||
reward_points, start_time, end_time, allow_resubmit, status, sort_order,
|
||||
create_by, create_time, update_by, update_time)
|
||||
values
|
||||
(#{taskName}, #{taskType}, #{cycleType}, #{coverUrl}, #{description}, #{operationGuide}, #{exampleImages},
|
||||
#{rewardPoints}, #{startTime}, #{endTime}, #{allowResubmit}, #{status}, #{sortOrder},
|
||||
#{createBy}, #{createTime}, #{updateBy}, #{updateTime})
|
||||
</insert>
|
||||
|
||||
<update id="updateAppPointTask" parameterType="AppPointTask">
|
||||
update app_point_task
|
||||
<set>
|
||||
<if test="taskName != null">task_name = #{taskName},</if>
|
||||
<if test="taskType != null">task_type = #{taskType},</if>
|
||||
<if test="cycleType != null">cycle_type = #{cycleType},</if>
|
||||
<if test="coverUrl != null">cover_url = #{coverUrl},</if>
|
||||
<if test="description != null">description = #{description},</if>
|
||||
<if test="operationGuide != null">operation_guide = #{operationGuide},</if>
|
||||
<if test="exampleImages != null">example_images = #{exampleImages},</if>
|
||||
<if test="rewardPoints != null">reward_points = #{rewardPoints},</if>
|
||||
start_time = #{startTime},
|
||||
end_time = #{endTime},
|
||||
<if test="allowResubmit != null">allow_resubmit = #{allowResubmit},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="sortOrder != null">sort_order = #{sortOrder},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
update_time = #{updateTime}
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteAppPointTaskByIds">
|
||||
delete from app_point_task where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="countSubmissionByTaskIds" resultType="int">
|
||||
select count(1) from app_point_task_submission where task_id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,201 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.app.mapper.AppPointTaskSubmissionMapper">
|
||||
<resultMap type="AppPointTaskSubmission" id="SubmissionResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="submissionNo" column="submission_no" />
|
||||
<result property="taskId" column="task_id" />
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="cycleKey" column="cycle_key" />
|
||||
<result property="rewardPoints" column="reward_points" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="status" column="status" />
|
||||
<result property="attemptCount" column="attempt_count" />
|
||||
<result property="rejectReason" column="reject_reason" />
|
||||
<result property="reviewBy" column="review_by" />
|
||||
<result property="reviewTime" column="review_time" />
|
||||
<result property="rewardRecordId" column="reward_record_id" />
|
||||
<result property="firstSubmitTime" column="first_submit_time" />
|
||||
<result property="lastSubmitTime" column="last_submit_time" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="taskName" column="task_name" />
|
||||
<result property="taskType" column="task_type" />
|
||||
<result property="cycleType" column="cycle_type" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="nickName" column="nick_name" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap type="AppPointTaskAttachment" id="AttachmentResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="submissionId" column="submission_id" />
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="objectKey" column="object_key" />
|
||||
<result property="originalName" column="original_name" />
|
||||
<result property="fileSize" column="file_size" />
|
||||
<result property="fileType" column="file_type" />
|
||||
<result property="uploadStatus" column="upload_status" />
|
||||
<result property="submitBatch" column="submit_batch" />
|
||||
<result property="isCurrent" column="is_current" />
|
||||
<result property="createTime" column="create_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectSubmissionVo">
|
||||
select s.id, s.submission_no, s.task_id, s.user_id, s.cycle_key, s.reward_points,
|
||||
s.remark, s.status, s.attempt_count, s.reject_reason, s.review_by, s.review_time,
|
||||
s.reward_record_id, s.first_submit_time, s.last_submit_time,
|
||||
s.create_by, s.create_time, s.update_by, s.update_time,
|
||||
t.task_name, t.task_type, t.cycle_type, u.user_name, u.nick_name
|
||||
from app_point_task_submission s
|
||||
left join app_point_task t on t.id = s.task_id
|
||||
left join sys_user u on u.user_id = s.user_id
|
||||
</sql>
|
||||
|
||||
<select id="selectSubmissionById" resultMap="SubmissionResult">
|
||||
<include refid="selectSubmissionVo" /> where s.id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectSubmissionByIdForUpdate" resultMap="SubmissionResult">
|
||||
select id, submission_no, task_id, user_id, cycle_key, reward_points, remark, status,
|
||||
attempt_count, reject_reason, review_by, review_time, reward_record_id,
|
||||
first_submit_time, last_submit_time, create_by, create_time, update_by, update_time
|
||||
from app_point_task_submission where id = #{id} for update
|
||||
</select>
|
||||
|
||||
<select id="selectByTaskUserCycle" resultMap="SubmissionResult">
|
||||
select id, submission_no, task_id, user_id, cycle_key, reward_points, remark, status,
|
||||
attempt_count, reject_reason, review_by, review_time, reward_record_id,
|
||||
first_submit_time, last_submit_time, create_by, create_time, update_by, update_time
|
||||
from app_point_task_submission
|
||||
where task_id = #{taskId} and user_id = #{userId} and cycle_key = #{cycleKey}
|
||||
</select>
|
||||
|
||||
<select id="selectSubmissionList" parameterType="AppPointTaskSubmission" resultMap="SubmissionResult">
|
||||
<include refid="selectSubmissionVo" />
|
||||
<where>
|
||||
<if test="submissionNo != null and submissionNo != ''">and s.submission_no like concat('%', #{submissionNo}, '%')</if>
|
||||
<if test="taskId != null">and s.task_id = #{taskId}</if>
|
||||
<if test="taskName != null and taskName != ''">and t.task_name like concat('%', #{taskName}, '%')</if>
|
||||
<if test="status != null">and s.status = #{status}</if>
|
||||
<if test="cycleKey != null and cycleKey != ''">and s.cycle_key = #{cycleKey}</if>
|
||||
<if test="userName != null and userName != ''">
|
||||
and (u.user_name like concat('%', #{userName}, '%') or u.nick_name like concat('%', #{userName}, '%'))
|
||||
</if>
|
||||
<if test="params.beginTime != null and params.beginTime != ''">
|
||||
and date_format(s.last_submit_time, '%Y%m%d') >= date_format(#{params.beginTime}, '%Y%m%d')
|
||||
</if>
|
||||
<if test="params.endTime != null and params.endTime != ''">
|
||||
and date_format(s.last_submit_time, '%Y%m%d') <= date_format(#{params.endTime}, '%Y%m%d')
|
||||
</if>
|
||||
</where>
|
||||
order by s.last_submit_time desc, s.id desc
|
||||
</select>
|
||||
|
||||
<select id="selectMySubmissionList" resultMap="SubmissionResult">
|
||||
<include refid="selectSubmissionVo" />
|
||||
where s.user_id = #{userId}
|
||||
order by s.last_submit_time desc, s.id desc
|
||||
</select>
|
||||
|
||||
<insert id="insertSubmission" parameterType="AppPointTaskSubmission" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into app_point_task_submission
|
||||
(submission_no, task_id, user_id, cycle_key, reward_points, remark, status, attempt_count,
|
||||
reject_reason, review_by, review_time, reward_record_id, first_submit_time, last_submit_time,
|
||||
create_by, create_time, update_by, update_time)
|
||||
values
|
||||
(#{submissionNo}, #{taskId}, #{userId}, #{cycleKey}, #{rewardPoints}, #{remark}, #{status}, #{attemptCount},
|
||||
#{rejectReason}, #{reviewBy}, #{reviewTime}, #{rewardRecordId}, #{firstSubmitTime}, #{lastSubmitTime},
|
||||
#{createBy}, #{createTime}, #{updateBy}, #{updateTime})
|
||||
</insert>
|
||||
|
||||
<update id="updateSubmission" parameterType="AppPointTaskSubmission">
|
||||
update app_point_task_submission
|
||||
<set>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="attemptCount != null">attempt_count = #{attemptCount},</if>
|
||||
reject_reason = #{rejectReason},
|
||||
review_by = #{reviewBy},
|
||||
review_time = #{reviewTime},
|
||||
<if test="rewardRecordId != null">reward_record_id = #{rewardRecordId},</if>
|
||||
<if test="lastSubmitTime != null">last_submit_time = #{lastSubmitTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
update_time = #{updateTime}
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<insert id="insertTempAttachment" parameterType="AppPointTaskAttachment" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into app_point_task_attachment
|
||||
(submission_id, user_id, object_key, original_name, file_size, file_type,
|
||||
upload_status, submit_batch, is_current, create_time)
|
||||
values
|
||||
(null, #{userId}, #{objectKey}, #{originalName}, #{fileSize}, #{fileType},
|
||||
'TEMP', 0, 0, #{createTime})
|
||||
</insert>
|
||||
|
||||
<select id="lockUserForUpload" resultType="long">
|
||||
select user_id from sys_user where user_id = #{userId} for update
|
||||
</select>
|
||||
|
||||
<select id="countTempAttachmentsByUser" resultType="int">
|
||||
select count(1)
|
||||
from app_point_task_attachment
|
||||
where user_id = #{userId} and upload_status = 'TEMP'
|
||||
</select>
|
||||
|
||||
<select id="countAttachmentsByUserSince" resultType="int">
|
||||
select count(1)
|
||||
from app_point_task_attachment
|
||||
where user_id = #{userId} and create_time >= #{since}
|
||||
</select>
|
||||
|
||||
<select id="selectTempAttachments" resultMap="AttachmentResult">
|
||||
select id, submission_id, user_id, object_key, original_name, file_size, file_type,
|
||||
upload_status, submit_batch, is_current, create_time
|
||||
from app_point_task_attachment
|
||||
where user_id = #{userId} and upload_status = 'TEMP' and object_key in
|
||||
<foreach item="key" collection="keys" open="(" separator="," close=")">#{key}</foreach>
|
||||
</select>
|
||||
|
||||
<update id="bindAttachments">
|
||||
update app_point_task_attachment
|
||||
set submission_id = #{submissionId}, upload_status = 'BOUND', submit_batch = #{submitBatch}, is_current = 1
|
||||
where user_id = #{userId} and upload_status = 'TEMP' and object_key in
|
||||
<foreach item="key" collection="keys" open="(" separator="," close=")">#{key}</foreach>
|
||||
</update>
|
||||
|
||||
<update id="markAttachmentsNotCurrent">
|
||||
update app_point_task_attachment set is_current = 0 where submission_id = #{submissionId}
|
||||
</update>
|
||||
|
||||
<select id="selectAttachmentsBySubmissionId" resultMap="AttachmentResult">
|
||||
select id, submission_id, user_id, object_key, original_name, file_size, file_type,
|
||||
upload_status, submit_batch, is_current, create_time
|
||||
from app_point_task_attachment
|
||||
where submission_id = #{submissionId}
|
||||
order by submit_batch desc, id asc
|
||||
</select>
|
||||
|
||||
<select id="selectExpiredTempAttachments" resultMap="AttachmentResult">
|
||||
select id, submission_id, user_id, object_key, original_name, file_size, file_type,
|
||||
upload_status, submit_batch, is_current, create_time
|
||||
from app_point_task_attachment
|
||||
where upload_status = 'TEMP' and create_time < #{beforeTime}
|
||||
order by id asc
|
||||
limit 500
|
||||
</select>
|
||||
|
||||
<delete id="deleteTempAttachmentById">
|
||||
delete from app_point_task_attachment where id = #{id} and upload_status = 'TEMP'
|
||||
</delete>
|
||||
|
||||
<insert id="insertAuditLog" parameterType="AppPointTaskAuditLog">
|
||||
insert into app_point_task_audit_log
|
||||
(submission_id, before_status, after_status, operator_name, remark, create_time)
|
||||
values
|
||||
(#{submissionId}, #{beforeStatus}, #{afterStatus}, #{operatorName}, #{remark}, #{createTime})
|
||||
</insert>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user