内嵌查询代替LEFT JOIN导致的重复问题以及修改邮件不能发送图片和附件的问题

This commit is contained in:
2025-07-12 15:54:13 +08:00
parent 20edf904bc
commit 43642eeb4d
8 changed files with 559 additions and 74 deletions

19
pom.xml
View File

@@ -338,12 +338,19 @@
<version>${ruoyi-flowable-plus.version}</version>
</dependency>
<!-- SMS短信模块 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-sms</artifactId>
<version>${ruoyi-flowable-plus.version}</version>
</dependency>
<!-- SMS短信模块 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-sms</artifactId>
<version>${ruoyi-flowable-plus.version}</version>
</dependency>
<!-- 邮件发送相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- demo模块 -->
<dependency>

View File

@@ -51,6 +51,12 @@
<scope>compile</scope>
</dependency>
<!-- 邮件发送相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>

View File

@@ -0,0 +1,84 @@
package com.ruoyi.oa.config;
import com.ruoyi.oa.domain.OaEmailAccount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.Properties;
/**
* 动态邮件配置类
* 支持根据不同的邮箱账号动态配置邮件发送器
*
* @author ruoyi
*/
@Configuration
public class DynamicMailConfig {
/**
* 根据邮箱账号创建JavaMailSender
*
* @param account 邮箱账号信息
* @return JavaMailSender
*/
public JavaMailSender createMailSender(OaEmailAccount account) {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
// 设置SMTP服务器
mailSender.setHost(account.getSmtpHost());
mailSender.setPort(account.getSmtpPort() == null ? 465 : account.getSmtpPort().intValue());
mailSender.setUsername(account.getEmail());
mailSender.setPassword(account.getPassword());
// 设置邮件属性
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.connectiontimeout", "10000");
props.put("mail.smtp.timeout", "10000");
props.put("mail.smtp.writetimeout", "10000");
props.put("mail.debug", "false");
return mailSender;
}
/**
* 根据邮箱类型获取默认配置
*
* @param type 邮箱类型 0=网易 1=QQ 2=阿里云 3=飞书
* @return 默认配置
*/
public OaEmailAccount getDefaultConfig(int type) {
OaEmailAccount config = new OaEmailAccount();
switch (type) {
case 0: // 网易邮箱
config.setSmtpHost("smtp.163.com");
config.setSmtpPort(465L);
break;
case 1: // QQ邮箱
config.setSmtpHost("smtp.qq.com");
config.setSmtpPort(465L);
break;
case 2: // 阿里云邮箱
config.setSmtpHost("smtp.aliyun.com");
config.setSmtpPort(465L);
break;
case 3: // 飞书邮箱
config.setSmtpHost("smtp.feishu.cn");
config.setSmtpPort(465L);
break;
default:
config.setSmtpHost("smtp.163.com");
config.setSmtpPort(465L);
break;
}
return config;
}
}

View File

@@ -16,4 +16,8 @@ public class EmailSendRequest {
private String subject;
/** 邮件正文 */
private String content;
/** 附件文件路径列表 */
private List<String> attachmentPaths;
/** 内嵌图片路径列表 */
private List<String> inlineImagePaths;
}

View File

@@ -7,6 +7,7 @@ import com.ruoyi.oa.domain.SysOaTask;
import com.ruoyi.oa.domain.UserMonthlyData;
import com.ruoyi.oa.domain.bo.SysOaTaskBo;
import com.ruoyi.oa.domain.vo.SysOaTaskVo;
import com.ruoyi.oa.domain.vo.SysOaTaskItemVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
@@ -50,4 +51,9 @@ public interface SysOaTaskMapper extends BaseMapperPlus<SysOaTaskMapper, SysOaTa
*/
List<SysOaTaskVo> queryListPlus(SysOaTaskBo bo);
/**
* 嵌套查询根据任务ID获取报工单元列表
*/
List<SysOaTaskItemVo> selectTaskItemsByTaskId(Long taskId);
}

View File

@@ -26,8 +26,8 @@ import com.ruoyi.oa.domain.OaEmailAccount;
import com.ruoyi.oa.mapper.OaEmailAccountMapper;
import com.ruoyi.oa.service.IOaEmailAccountService;
import com.ruoyi.oa.domain.request.EmailSendRequest;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.ruoyi.oa.utils.EmailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@@ -45,6 +45,9 @@ import java.util.Collection;
public class OaEmailAccountServiceImpl implements IOaEmailAccountService {
private final OaEmailAccountMapper baseMapper;
@Autowired
private EmailUtil emailUtil;
/**
* 查询发件人邮箱账号管理
@@ -138,26 +141,60 @@ public class OaEmailAccountServiceImpl implements IOaEmailAccountService {
int success = 0, fail = 0;
StringBuilder failList = new StringBuilder();
if (type == 0 || type == 1) {
// 网易/QQ邮箱 SMTP方式(已实现)
MailAccount mailAccount = new MailAccount();
mailAccount.setHost(account.getSmtpHost());
mailAccount.setPort(account.getSmtpPort() == null ? 465 : account.getSmtpPort().intValue());
mailAccount.setAuth(true);
mailAccount.setFrom(account.getEmail());
mailAccount.setUser(account.getEmail());
mailAccount.setPass(account.getPassword());
mailAccount.setSslEnable(true);
if (type == 0 || type == 1) {
// 网易/QQ邮箱 SMTP方式
for (String to : request.getToList()) {
try {
MailUtil.send(mailAccount, to, request.getSubject(), request.getContent(), false);
// 判断是否为HTML内容
boolean isHtml = request.getContent() != null &&
(request.getContent().contains("<html") ||
request.getContent().contains("<div") ||
request.getContent().contains("<p>"));
// 检查是否有附件
boolean hasAttachments = request.getAttachmentPaths() != null && !request.getAttachmentPaths().isEmpty();
// 检查是否有内嵌图片
boolean hasInlineImages = request.getInlineImagePaths() != null && !request.getInlineImagePaths().isEmpty();
if (hasAttachments && hasInlineImages) {
// 既有附件又有内嵌图片
if (isHtml) {
String processedContent = emailUtil.processHtmlWithInlineImages(request.getContent(), request.getInlineImagePaths());
emailUtil.sendHtmlMailWithAttachmentsAndDynamicConfig(account, to, request.getSubject(), processedContent, request.getAttachmentPaths());
} else {
// 纯文本不支持内嵌图片,只发送附件
emailUtil.sendMailWithAttachmentAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getAttachmentPaths().get(0));
}
} else if (hasAttachments) {
// 只有附件
if (isHtml) {
emailUtil.sendHtmlMailWithAttachmentsAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getAttachmentPaths());
} else {
emailUtil.sendMailWithAttachmentAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getAttachmentPaths().get(0));
}
} else if (hasInlineImages) {
// 只有内嵌图片
if (isHtml) {
emailUtil.sendHtmlMailWithInlineImagesAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getInlineImagePaths());
} else {
// 纯文本不支持内嵌图片
emailUtil.sendMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
}
} else {
// 无附件无内嵌图片
if (isHtml) {
emailUtil.sendHtmlMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
} else {
emailUtil.sendMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
}
}
success++;
} catch (Exception e) {
fail++;
failList.append(to).append(", ");
}
}
}
}
else if (type == 2) {
// 阿里云邮件推送API
for (String to : request.getToList()) {

View File

@@ -0,0 +1,358 @@
package com.ruoyi.oa.utils;
import com.ruoyi.oa.domain.OaEmailAccount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import com.ruoyi.oa.config.DynamicMailConfig;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.List;
/**
* 邮件发送工具类
*
* @author ruoyi
*/
@Component
public class EmailUtil {
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private DynamicMailConfig dynamicMailConfig;
/**
* 发送纯文本邮件
*
* @param from 发件人邮箱
* @param to 收件人邮箱
* @param subject 邮件主题
* @param text 纯文本内容
*/
public void sendMail(String from, String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
javaMailSender.send(message);
}
/**
* 使用动态配置发送纯文本邮件
*
* @param account 邮箱账号信息
* @param to 收件人邮箱
* @param subject 邮件主题
* @param text 纯文本内容
*/
public void sendMailWithDynamicConfig(OaEmailAccount account, String to, String subject, String text) {
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(account.getEmail());
message.setTo(to);
message.setSubject(subject);
message.setText(text);
dynamicMailSender.send(message);
}
/**
* 发送纯文本邮件(批量)
*
* @param from 发件人邮箱
* @param toList 收件人邮箱列表
* @param subject 邮件主题
* @param text 纯文本内容
*/
public void sendMailBatch(String from, List<String> toList, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(toList.toArray(new String[0]));
message.setSubject(subject);
message.setText(text);
javaMailSender.send(message);
}
/**
* 发送富文本邮件
*
* @param from 发件人邮箱
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容
*/
public void sendHtmlMail(String from, String to, String subject, String htmlContent) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true); // 第二个参数true表示这是HTML内容
javaMailSender.send(mimeMessage);
}
/**
* 使用动态配置发送富文本邮件
*
* @param account 邮箱账号信息
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容
*/
public void sendHtmlMailWithDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String htmlContent) throws MessagingException {
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(account.getEmail());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
dynamicMailSender.send(mimeMessage);
}
/**
* 发送富文本邮件(批量)
*
* @param from 发件人邮箱
* @param toList 收件人邮箱列表
* @param subject 邮件主题
* @param htmlContent HTML内容
*/
public void sendHtmlMailBatch(String from, List<String> toList, String subject, String htmlContent) throws MessagingException {
for (String to : toList) {
sendHtmlMail(from, to, subject, htmlContent);
}
}
/**
* 发送带附件的邮件
*
* @param from 发件人邮箱
* @param to 收件人邮箱
* @param subject 邮件主题
* @param text 邮件内容
* @param filePath 附件文件路径
*/
public void sendMailWithAttachment(String from, String to, String subject, String text, String filePath) throws MessagingException {
File attachment = new File(filePath);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
helper.addAttachment(attachment.getName(), attachment);
javaMailSender.send(mimeMessage);
}
/**
* 使用动态配置发送带附件的邮件
*
* @param account 邮箱账号信息
* @param to 收件人邮箱
* @param subject 邮件主题
* @param text 邮件内容
* @param filePath 附件文件路径
*/
public void sendMailWithAttachmentAndDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String text, String filePath) throws MessagingException {
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
File attachment = new File(filePath);
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(account.getEmail());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
helper.addAttachment(attachment.getName(), attachment);
dynamicMailSender.send(mimeMessage);
}
/**
* 发送带附件的富文本邮件
*
* @param from 发件人邮箱
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容
* @param filePath 附件文件路径
*/
public void sendHtmlMailWithAttachment(String from, String to, String subject, String htmlContent, String filePath) throws MessagingException {
File attachment = new File(filePath);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
helper.addAttachment(attachment.getName(), attachment);
javaMailSender.send(mimeMessage);
}
/**
* 使用动态配置发送带附件的富文本邮件
*
* @param account 邮箱账号信息
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容
* @param filePath 附件文件路径
*/
public void sendHtmlMailWithAttachmentAndDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String htmlContent, String filePath) throws MessagingException {
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
File attachment = new File(filePath);
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(account.getEmail());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
helper.addAttachment(attachment.getName(), attachment);
dynamicMailSender.send(mimeMessage);
}
/**
* 发送带多个附件的邮件
*
* @param from 发件人邮箱
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容
* @param filePaths 附件文件路径列表
*/
public void sendHtmlMailWithAttachments(String from, String to, String subject, String htmlContent, List<String> filePaths) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
for (String filePath : filePaths) {
File attachment = new File(filePath);
if (attachment.exists()) {
helper.addAttachment(attachment.getName(), attachment);
}
}
javaMailSender.send(mimeMessage);
}
/**
* 使用动态配置发送带多个附件的邮件
*
* @param account 邮箱账号信息
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容
* @param filePaths 附件文件路径列表
*/
public void sendHtmlMailWithAttachmentsAndDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String htmlContent, List<String> filePaths) throws MessagingException {
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(account.getEmail());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
for (String filePath : filePaths) {
File attachment = new File(filePath);
if (attachment.exists()) {
helper.addAttachment(attachment.getName(), attachment);
}
}
dynamicMailSender.send(mimeMessage);
}
/**
* 发送带内嵌图片的邮件
*
* @param from 发件人邮箱
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容包含cid:xxx的图片引用
* @param imagePaths 内嵌图片路径列表
*/
public void sendHtmlMailWithInlineImages(String from, String to, String subject, String htmlContent, List<String> imagePaths) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
for (int i = 0; i < imagePaths.size(); i++) {
String imagePath = imagePaths.get(i);
File imageFile = new File(imagePath);
if (imageFile.exists()) {
String cid = "image" + i;
helper.addInline(cid, imageFile);
}
}
javaMailSender.send(mimeMessage);
}
/**
* 使用动态配置发送带内嵌图片的邮件
*
* @param account 邮箱账号信息
* @param to 收件人邮箱
* @param subject 邮件主题
* @param htmlContent HTML内容包含cid:xxx的图片引用
* @param imagePaths 内嵌图片路径列表
*/
public void sendHtmlMailWithInlineImagesAndDynamicConfig(OaEmailAccount account, String to, String subject, String htmlContent, List<String> imagePaths) throws MessagingException {
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(account.getEmail());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true);
for (int i = 0; i < imagePaths.size(); i++) {
String imagePath = imagePaths.get(i);
File imageFile = new File(imagePath);
if (imageFile.exists()) {
String cid = "image" + i;
helper.addInline(cid, imageFile);
}
}
dynamicMailSender.send(mimeMessage);
}
/**
* 处理HTML内容中的图片将外链图片转为内嵌
*
* @param htmlContent 原始HTML内容
* @param imagePaths 图片路径列表
* @return 处理后的HTML内容
*/
public String processHtmlWithInlineImages(String htmlContent, List<String> imagePaths) {
if (imagePaths == null || imagePaths.isEmpty()) {
return htmlContent;
}
String processedHtml = htmlContent;
for (int i = 0; i < imagePaths.size(); i++) {
String imagePath = imagePaths.get(i);
String cid = "image" + i;
// 这里可以根据需要替换图片URL为cid引用
// 例如:将 <img src="path/to/image.jpg"> 替换为 <img src="cid:image0">
processedHtml = processedHtml.replace("image" + i + ".jpg", "cid:" + cid);
processedHtml = processedHtml.replace("image" + i + ".png", "cid:" + cid);
}
return processedHtml;
}
}

View File

@@ -16,6 +16,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="content" column="content"/>
<result property="remark" column="remark"/>
<result property="state" column="state"/>
<result property="status" column="status"/>
<result property="taskRank" column="task_rank"/>
<result property="ownRank" column="own_rank"/>
<result property="timeGap" column="time_gap"/>
<result property="tempTime" column="temp_time"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="completedTime" column="completed_time"/>
@@ -23,20 +28,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="workerNickName" column="workerNickName"/>
<result property="postponements" column="postponements"/>
<result property="accessory" column="accessory"/>
<result property="projectName" column="project_name"/>
<result property="projectNum" column="project_num"/>
<result property="overDays" column="overDays"/>
<result property="itemId" column="item_id"/>
<result property="files" column="files"/>
<collection property="taskItemVoList" ofType="com.ruoyi.oa.domain.vo.SysOaTaskItemVo" javaType="list">
<result property="itemId" column="item_id"/>
<result property="content" column="itemContent"/>
<result property="signTime" column="sign_time"/>
<result property="status" column="itemStatus"/>
<result property="beginTime" column="itemBeginTime"/>
<result property="endTime" column="itemEndTime"/>
<result property="remark" column="itemRemark"/>
<result property="completedTime" column="itemCompletedTime"/>
<result property="files" column="files"/>
</collection>
<collection property="taskItemVoList"
ofType="com.ruoyi.oa.domain.vo.SysOaTaskItemVo"
javaType="list"
select="selectTaskItemsByTaskId"
column="task_id"/>
</resultMap>
@@ -57,27 +59,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sot.task_type,
sot.task_grade,
sot.collaborator,
COALESCE(sot.finish_time, soti.end_time) AS finish_time,
COALESCE(sot.temp_time, soti.temp_time) AS temp_time,
sot.finish_time,
sot.temp_time,
sot.begin_time,
sot.origin_finish_time,
sot.postponements,
sot.completed_time,
CASE
WHEN sot.completed_time IS NULL
THEN DATEDIFF(
NOW(),
COALESCE(
sot.finish_time,
(SELECT a.end_time
FROM sys_oa_task_item a
WHERE a.task_id = sot.task_id
AND a.completed_time IS NULL
LIMIT 1)
)
)
ELSE 0
END AS overDays,
sot.rank_number,
sot.remark,
sot.task_rank,
@@ -91,7 +78,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sot.del_flag,
sot.own_rank,
sop.project_name,
soti.item_id,
sop.project_num,
su1.nick_name AS createUserNickName,
su2.nick_name AS workerNickName
@@ -99,12 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LEFT JOIN sys_user su1 ON su1.user_id = sot.create_user_id
LEFT JOIN sys_user su2 ON su2.user_id = sot.worker_id
LEFT JOIN sys_oa_project sop ON sop.project_id = sot.project_id
LEFT JOIN sys_oa_task_item soti
ON soti.task_id = sot.task_id
AND soti.completed_time IS NULL
${ew.getCustomSqlSegment}
</select>
@@ -116,7 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sot.task_title,
sot.task_type,
sot.task_grade,
sot.accessory,
sot.accessory,
COALESCE(
sot.finish_time,
(SELECT a.end_time
@@ -142,7 +123,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
su1.nick_name AS createUserNickName,
su2.nick_name AS workerNickName,
sot.rank_number,
sot.remark,
sot.task_rank,
@@ -158,14 +138,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sop.project_name,
sop.project_num,
soti.item_id,
soti.content AS itemContent,
soti.sign_time,
soti.status AS itemStatus,
soti.begin_time AS itemBeginTime,
soti.completed_time AS itemCompletedTime,
soti.end_time AS itemEndTime,
soti.remark AS itemRemark,
CASE
WHEN sot.completed_time IS NULL
THEN DATEDIFF(
@@ -180,19 +152,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
)
)
ELSE 0
END AS overDays,
soti.files
END AS overDays
FROM sys_oa_task sot
LEFT JOIN sys_user su1
ON su1.user_id = sot.create_user_id
LEFT JOIN sys_user su1 ON su1.user_id = sot.create_user_id
LEFT JOIN sys_user su2 ON su2.user_id = sot.worker_id
LEFT JOIN sys_oa_project sop ON sop.project_id = sot.project_id
LEFT JOIN sys_oa_task_item soti ON soti.task_id = sot.task_id
LEFT JOIN sys_oss so2 ON FIND_IN_SET(so2.oss_id, soti.files)
WHERE
sot.task_id = #{taskId}
WHERE sot.task_id = #{taskId}
AND sot.del_flag = '0'
</select>
<!-- 嵌套查询根据任务ID获取报工单元列表 -->
<select id="selectTaskItemsByTaskId" resultType="com.ruoyi.oa.domain.vo.SysOaTaskItemVo">
SELECT soti.item_id,
soti.content,
soti.sign_time,
soti.status,
soti.begin_time,
soti.completed_time,
soti.end_time,
soti.remark,
soti.files
FROM sys_oa_task_item soti
WHERE soti.task_id = #{task_id}
AND soti.del_flag = '0'
ORDER BY soti.create_time DESC
</select>
<select id="getMonthlyData"