feat(project-order):优化文件上传逻辑与合同状态关联- 调整 edit.html 中上传、下载、删除按钮的显示条件,增加对最终文件上传状态 (uploadFinalFile) 的判断

- 修改 JavaScript 中 file_log_arr 数组内容及索引处理逻辑,支持“已盖章合同信息”上传- 增加 Mapper 方法 listByIds 及其 XML 实现,用于根据 ID 列表查询文件记录
- 删除文件时同步删除服务器本地文件,增强数据一致性
- 控制器中新增 uploadFinalFile 权限控制,仅允许商务角色或管理员在审批完成后上传最终文件-服务层构建表格数据时传入订单状态,动态控制文件列表长度(3 或 4项)以匹配业务阶段
dev_1.0.0
chenhao 2025-09-22 18:00:52 +08:00
parent 940fe11624
commit 2862498b2f
6 changed files with 46 additions and 20 deletions

View File

@ -470,7 +470,7 @@
<td>[[${file.uploadUserName}]]</td> <td>[[${file.uploadUserName}]]</td>
<td>[[${#dates.format(file.uploadTime,'yyyy-MM-dd')}]]</td> <td>[[${#dates.format(file.uploadTime,'yyyy-MM-dd')}]]</td>
<td> <td>
<span th:if="${file.id == -1 && updateFile}" <span th:if="${file.id == -1 && ( (updateFile && file.fileSort!='3' )|| (uploadFinalFile && file.fileSort=='3' )) }"
style="cursor:pointer;color: #0075ff" style="cursor:pointer;color: #0075ff"
th:onclick="importList([[${fileStat.index}]])">上传</span> th:onclick="importList([[${fileStat.index}]])">上传</span>
<span th:if="${file.id != -1}" <span th:if="${file.id != -1}"
@ -479,7 +479,7 @@
<span th:if="${file.id != -1}" <span th:if="${file.id != -1}"
style="cursor:pointer;color: #ff5722" style="cursor:pointer;color: #ff5722"
th:onclick="downFile([[${file.filePath}]],[[${file.fileName}]])">下载</span> th:onclick="downFile([[${file.filePath}]],[[${file.fileName}]])">下载</span>
<span th:if="${file.id != -1 &&entry.key==projectOrderInfo.versionCode && updateFile}" <span th:if="${file.id != -1 &&entry.key==projectOrderInfo.versionCode && ( (updateFile && file.fileSort!='3' )|| (uploadFinalFile && file.fileSort=='3' ))}"
style="cursor:pointer;color: #ff5722" style="cursor:pointer;color: #ff5722"
th:onclick=" delUploadRow([[${fileStat.index}]],[[${file.id}]])">删除</span> th:onclick=" delUploadRow([[${fileStat.index}]],[[${file.id}]])">删除</span>
</td> </td>
@ -620,7 +620,7 @@
}, },
} }
}); });
const file_log_arr = [ "(请上传商务折扣审批邮件信息).pdf/.jpg/.png","(请上传合同信息).pdf/.jpg/.png", "(请上传现金折扣审批邮件信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png"] const file_log_arr = [ "(请上传商务折扣审批邮件信息).pdf/.jpg/.png","(请上传合同信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png","(请上传已盖章合同信息).pdf/.jpg/.png"]
var softwareProjectProductInfoList = [] var softwareProjectProductInfoList = []
var hardwareProjectProductInfoList = [] var hardwareProjectProductInfoList = []
var maintenanceProjectProductInfoList = [] var maintenanceProjectProductInfoList = []
@ -633,16 +633,16 @@
return return
} }
$(trElement).find('td').each(function (index, element) { $(trElement).find('td').each(function (index, element) {
if (index === 1) { if (index === 2) {
// $('#deleteFileId').val($('#deleteFileId').val()+$(element).text()+',') // $('#deleteFileId').val($('#deleteFileId').val()+$(element).text()+',')
$(element).text('-1') $(element).text('-1')
} else if (index === 2) {
$(element).text(file_log_arr[trIndex])
} else if (index === 3) { } else if (index === 3) {
$(element).text('') $(element).text(file_log_arr[trIndex])
} else if (index === 4) { } else if (index === 4) {
$(element).text('') $(element).text('')
} else if (index === 5) { } else if (index === 5) {
$(element).text('')
} else if (index === 6) {
$(element).html(`<span $(element).html(`<span
style="cursor:pointer;color: #ff5722" style="cursor:pointer;color: #ff5722"
onclick="importList(${trIndex})">上传</span>`) onclick="importList(${trIndex})">上传</span>`)
@ -1252,7 +1252,7 @@
style="cursor:pointer;color: #ff5722" style="cursor:pointer;color: #ff5722"
onclick="downFile('${data.filePath}','${data.fileName}')">下载</span> onclick="downFile('${data.filePath}','${data.fileName}')">下载</span>
<span <span
style="cursor:pointer;color: #ff5722" onclick=" delUploadRow(${sortNum})">删除</span>`) style="cursor:pointer;color: #ff5722" onclick=" delUploadRow(${sortNum},${data.id})">删除</span>`)
} }
}) })
}) })

View File

@ -216,6 +216,9 @@ public class ProjectOrderInfoController extends BaseController
("产品经理".equals(todoCompletedList.get(0).getTaskName()) || "售前".equals(todoCompletedList.get(0).getTaskName())) ("产品经理".equals(todoCompletedList.get(0).getTaskName()) || "售前".equals(todoCompletedList.get(0).getTaskName()))
: (boolean) mmap.get("canUpdate"); : (boolean) mmap.get("canUpdate");
mmap.put("updateFile", (ShiroUtils.getSubject().hasRole("sale_assistant")||ShiroUtils.getSubject().hasRole("business") ||ShiroUtils.getSysUser().isAdmin()) && updateFlag); mmap.put("updateFile", (ShiroUtils.getSubject().hasRole("sale_assistant")||ShiroUtils.getSubject().hasRole("business") ||ShiroUtils.getSysUser().isAdmin()) && updateFlag);
mmap.put("uploadFinalFile", (ShiroUtils.getSubject().hasRole("business") || ShiroUtils.getSysUser().isAdmin()) &&
ProjectOrderInfo.OrderStatus.APPROVE_COMPLETE.getCode().equals(projectOrderInfo.getOrderStatus()));
return prefix + "/edit"; return prefix + "/edit";
} }
/** /**

View File

@ -67,4 +67,7 @@ public interface ProjectOrderFileLogMapper
void updateOrderIdByIdList(@Param("orderId") Long orderId,@Param("list") List<Long> idList); void updateOrderIdByIdList(@Param("orderId") Long orderId,@Param("list") List<Long> idList);
List<ProjectOrderFileLog> listByIds(String[] strArray);
} }

View File

@ -6,6 +6,9 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.file.FileUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.ProjectOrderFileLogMapper; import com.ruoyi.sip.mapper.ProjectOrderFileLogMapper;
@ -82,6 +85,15 @@ public class ProjectOrderFileLogServiceImpl implements IProjectOrderFileLogServi
@Override @Override
public int deleteProjectOrderFileLogByIds(String ids) public int deleteProjectOrderFileLogByIds(String ids)
{ {
List<ProjectOrderFileLog> projectOrderFileLogs = projectOrderFileLogMapper.listByIds(Convert.toStrArray(ids));
for (ProjectOrderFileLog projectOrderFileLog : projectOrderFileLogs) {
// // 本地资源路径
String localPath = RuoYiConfig.getProfile();
// // 下载名称
String downloadPath = projectOrderFileLog.getFilePath().replace(Constants.RESOURCE_PREFIX, localPath);
FileUtils.deleteFile(downloadPath);
}
return projectOrderFileLogMapper.deleteProjectOrderFileLogByIds(Convert.toStrArray(ids)); return projectOrderFileLogMapper.deleteProjectOrderFileLogByIds(Convert.toStrArray(ids));
} }

View File

@ -110,7 +110,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
private static final List<String> LS_LIST = Arrays.asList("3130A6LD"); private static final List<String> LS_LIST = Arrays.asList("3130A6LD");
private static final List<String> ONE_STOR_LIST = Arrays.asList("3130A4NA", "3130A4N9", "3130A4N5"); private static final List<String> ONE_STOR_LIST = Arrays.asList("3130A4NA", "3130A4N9", "3130A4N5");
private static final List<String> N_VIDIA_LIST = Arrays.asList("0504A14F", "0504A14G", "0504A1JX"); private static final List<String> N_VIDIA_LIST = Arrays.asList("0504A14F", "0504A14G", "0504A1JX");
private static final List<String> FILE_INFO_LIST = Arrays.asList( "(请上传商务折扣审批邮件信息).pdf/.jpg/.png","(请上传合同信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png"); private static final List<String> FILE_INFO_LIST = Arrays.asList( "(请上传商务折扣审批邮件信息).pdf/.jpg/.png","(请上传未盖章合同信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png","(请上传已盖章合同信息).pdf/.jpg/.png");
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
@ -151,7 +151,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
projectOrderFileLogs.stream().collect(Collectors.groupingBy(ProjectOrderFileLog::getFileType)); projectOrderFileLogs.stream().collect(Collectors.groupingBy(ProjectOrderFileLog::getFileType));
List<ProjectOrderFileLog> contractFileList = fileLogMap.get(ProjectOrderFileLog.FileTypeEnum.CONTRACT.getCode()); List<ProjectOrderFileLog> contractFileList = fileLogMap.get(ProjectOrderFileLog.FileTypeEnum.CONTRACT.getCode());
// 构建表格数据 // 构建表格数据
Map<String, List<ProjectOrderFileLog>> tableData = buildFileTableData(contractFileList, projectOrderInfo.getVersionCode()); Map<String, List<ProjectOrderFileLog>> tableData = buildFileTableData(contractFileList, projectOrderInfo.getVersionCode(), projectOrderInfo.getOrderStatus());
projectOrderInfo.setContractTableData(tableData); projectOrderInfo.setContractTableData(tableData);
projectOrderInfo.setContractFileList(contractFileList); projectOrderInfo.setContractFileList(contractFileList);
@ -170,7 +170,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
return projectOrderInfo; return projectOrderInfo;
} }
private Map<String, List<ProjectOrderFileLog>> buildFileTableData(List<ProjectOrderFileLog> contractFileList, String versionCode) { private Map<String, List<ProjectOrderFileLog>> buildFileTableData(List<ProjectOrderFileLog> contractFileList, String versionCode, String orderStatus) {
Map<String, List<ProjectOrderFileLog>> result = new HashMap<>(); Map<String, List<ProjectOrderFileLog>> result = new HashMap<>();
if (CollUtil.isEmpty(contractFileList)) { if (CollUtil.isEmpty(contractFileList)) {
List<ProjectOrderFileLog> list = getProjectOrderFileLogs(); List<ProjectOrderFileLog> list = getProjectOrderFileLogs();
@ -192,7 +192,8 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
} else { } else {
//将list转为map 根据序号补齐差的数据 给初始化数据 //将list转为map 根据序号补齐差的数据 给初始化数据
Map<String, ProjectOrderFileLog> orderFileLogMap = fileLogs.stream().collect(Collectors.toMap(ProjectOrderFileLog::getFileSort, v -> v, (v1, v2) -> v1)); Map<String, ProjectOrderFileLog> orderFileLogMap = fileLogs.stream().collect(Collectors.toMap(ProjectOrderFileLog::getFileSort, v -> v, (v1, v2) -> v1));
for (int i = 0; i < 3; i++) { int fileSize = ProjectOrderInfo.OrderStatus.APPROVE_COMPLETE.getCode().equals(orderStatus) ? 4 : 3;
for (int i = 0; i < fileSize; i++) {
ProjectOrderFileLog fileLog = orderFileLogMap.get(String.valueOf(i)); ProjectOrderFileLog fileLog = orderFileLogMap.get(String.valueOf(i));
if (fileLog == null) { if (fileLog == null) {
//初始化map //初始化map

View File

@ -24,28 +24,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectProjectOrderFileLogList" parameterType="ProjectOrderFileLog" resultMap="ProjectOrderFileLogResult"> <select id="selectProjectOrderFileLogList" parameterType="ProjectOrderFileLog" resultMap="ProjectOrderFileLogResult">
<include refid="selectProjectOrderFileLogVo"/> <include refid="selectProjectOrderFileLogVo"/>
<where> <where>
<if test="orderId != null "> and order_id = #{orderId}</if> <if test="orderId != null "> and t1.order_id = #{orderId}</if>
<if test="fileName != null and fileName != ''"> and file_name like concat('%', #{fileName}, '%')</if> <if test="fileName != null and fileName != ''"> and t1.file_name like concat('%', #{fileName}, '%')</if>
<if test="uploadUser != null and uploadUser != ''"> and upload_user = #{uploadUser}</if> <if test="uploadUser != null and uploadUser != ''"> and t1.upload_user = #{uploadUser}</if>
<if test="uploadTime != null "> and upload_time = #{uploadTime}</if> <if test="uploadTime != null "> andt1. upload_time = #{uploadTime}</if>
<if test="filePath != null and filePath != ''"> and file_path = #{filePath}</if> <if test="filePath != null and filePath != ''"> and t1.file_path = #{filePath}</if>
<if test="fileType != null and fileType != ''"> and file_type = #{fileType}</if> <if test="fileType != null and fileType != ''"> and t1.file_type = #{fileType}</if>
</where> </where>
order by t1.id order by t1.id
</select> </select>
<select id="selectProjectOrderFileLogById" parameterType="Long" resultMap="ProjectOrderFileLogResult"> <select id="selectProjectOrderFileLogById" parameterType="Long" resultMap="ProjectOrderFileLogResult">
<include refid="selectProjectOrderFileLogVo"/> <include refid="selectProjectOrderFileLogVo"/>
where id = #{id} where t1.id = #{id}
</select> </select>
<select id="listByOrderId" resultType="com.ruoyi.sip.domain.ProjectOrderFileLog"> <select id="listByOrderId" resultType="com.ruoyi.sip.domain.ProjectOrderFileLog">
<include refid="selectProjectOrderFileLogVo"/> <include refid="selectProjectOrderFileLogVo"/>
where order_id in ( where t1.order_id in (
<foreach item="id" collection="list" separator=","> <foreach item="id" collection="list" separator=",">
#{id} #{id}
</foreach> </foreach>
) )
</select> </select>
<select id="listByIds" resultMap="ProjectOrderFileLogResult">
<include refid="selectProjectOrderFileLogVo"/>
where t1.id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<insert id="insertProjectOrderFileLog" parameterType="ProjectOrderFileLog" useGeneratedKeys="true" keyProperty="id"> <insert id="insertProjectOrderFileLog" parameterType="ProjectOrderFileLog" useGeneratedKeys="true" keyProperty="id">
insert into project_order_file_log insert into project_order_file_log