修复文件bug

This commit is contained in:
2026-06-16 15:13:51 +08:00
parent 8e34f2eb62
commit d294c7b5cd
3 changed files with 173 additions and 10 deletions

View File

@@ -108,5 +108,10 @@ public class OaRequirementsVo extends BaseEntity {
/** 附件文件列表(已联查 sys_oss每项形如 "<ossId>|<originalName>|<url>",逗号分隔) */
private String accessoryFiles;
/** 审批状态null=未提交审批0=待审1=通过2=驳回3=撤回 */
private Integer approvalStatus;
/** 审批单 id最新一次 */
private Long approvalInstanceId;
}

View File

@@ -14,14 +14,19 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaRequirementsBo;
import com.ruoyi.oa.domain.vo.OaRequirementsVo;
import com.ruoyi.oa.domain.OaApprovalInstance;
import com.ruoyi.oa.domain.OaRequirements;
import com.ruoyi.oa.domain.SysOaWarehouse;
import com.ruoyi.oa.mapper.OaApprovalInstanceMapper;
import com.ruoyi.oa.mapper.OaRequirementsMapper;
import com.ruoyi.oa.mapper.SysOaWarehouseMapper;
import com.ruoyi.oa.service.IOaApprovalService;
import com.ruoyi.oa.service.IOaRequirementsService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -39,12 +44,18 @@ import java.util.stream.Collectors;
@Service
public class OaRequirementsServiceImpl implements IOaRequirementsService {
public static final String BIZ_TYPE = "purchase_req";
private final OaRequirementsMapper baseMapper;
private final OaWarehouseAuditService auditService;
private final SysOaWarehouseMapper warehouseMapper;
private final IOaApprovalService approvalService;
private final OaApprovalInstanceMapper approvalInstanceMapper;
/**
* 查询OA 需求
*/
@@ -52,9 +63,33 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
public OaRequirementsVo queryById(Long requirementId){
OaRequirementsVo vo = baseMapper.selectVoById(requirementId);
enrichMaterials(Collections.singletonList(vo));
enrichApproval(Collections.singletonList(vo));
return vo;
}
/** 给 VO 列表注入审批状态(最新一条实例) */
private void enrichApproval(List<OaRequirementsVo> list) {
if (list == null || list.isEmpty()) return;
List<Long> ids = list.stream().filter(v -> v != null && v.getRequirementId() != null)
.map(OaRequirementsVo::getRequirementId).collect(Collectors.toList());
if (ids.isEmpty()) return;
List<OaApprovalInstance> insts = approvalInstanceMapper.selectList(
Wrappers.<OaApprovalInstance>lambdaQuery()
.eq(OaApprovalInstance::getBusinessType, BIZ_TYPE)
.in(OaApprovalInstance::getBusinessId, ids)
.orderByAsc(OaApprovalInstance::getId));
Map<Long, OaApprovalInstance> latest = new HashMap<>();
for (OaApprovalInstance i : insts) latest.put(i.getBusinessId(), i);
for (OaRequirementsVo v : list) {
if (v == null) continue;
OaApprovalInstance i = latest.get(v.getRequirementId());
if (i != null) {
v.setApprovalStatus(i.getStatus());
v.setApprovalInstanceId(i.getId());
}
}
}
/** 根据 material_idsCSV批量补全物料明细到 VO.materials */
private void enrichMaterials(List<OaRequirementsVo> list) {
if (list == null || list.isEmpty()) return;
@@ -110,6 +145,7 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
QueryWrapper<OaRequirements> lqw = buildQueryWrapper(bo);
Page<OaRequirementsVo> result = baseMapper.selectVoListPage(pageQuery.build(), lqw);
enrichMaterials(result.getRecords());
enrichApproval(result.getRecords());
return TableDataInfo.build(result);
}
@@ -121,6 +157,7 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
QueryWrapper<OaRequirements> lqw = buildQueryWrapper(bo);
List<OaRequirementsVo> list = baseMapper.selectVoListForExport(lqw);
enrichMaterials(list);
enrichApproval(list);
return list;
}
@@ -161,6 +198,8 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
bo.setRequirementId(add.getRequirementId());
auditService.log(OpType.REQ_CREATE, OpType.REF_REQUIREMENT, add.getRequirementId(),
"新建采购需求:" + add.getTitle());
// 触发审批流
approvalService.submit(BIZ_TYPE, add.getRequirementId(), add.getTitle());
}
return flag;
}
@@ -172,6 +211,17 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
public Boolean updateByBo(OaRequirementsBo bo) {
OaRequirements update = BeanUtil.toBean(bo, OaRequirements.class);
validEntityBeforeSave(update);
// 推进到采购中/完成 前必须审批通过
if (bo.getStatus() != null && (bo.getStatus() == 1 || bo.getStatus() == 2)) {
OaApprovalInstance i = approvalInstanceMapper.selectOne(
Wrappers.<OaApprovalInstance>lambdaQuery()
.eq(OaApprovalInstance::getBusinessType, BIZ_TYPE)
.eq(OaApprovalInstance::getBusinessId, bo.getRequirementId())
.orderByDesc(OaApprovalInstance::getId).last("LIMIT 1"));
if (i == null || i.getStatus() == null || i.getStatus() != 1) {
throw new com.ruoyi.common.exception.ServiceException("该采购需求尚未审批通过,无法推进状态");
}
}
boolean ok = baseMapper.updateById(update) > 0;
if (ok) {
String op = OpType.REQ_UPDATE;

View File

@@ -42,8 +42,8 @@
<span @click="gotoPurchase" style="cursor: pointer;">如要发放采购相关需求请移步采购需求管理(点击此处快速跳转)</span>
</el-alert>
<el-row :gutter="20" v-loading="loading">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="item in taskList" :key="item.taskId">
<el-row :gutter="10" v-loading="loading">
<el-col class="task-col" v-for="item in taskList" :key="item.taskId">
<el-card class="task-card" shadow="hover" @click.native="handleLookTask(item)">
<!-- 卡片头部 -->
<template slot="header">
@@ -99,6 +99,11 @@
</div>
<span v-else>{{ item.workerNickName }}</span>
</div>
<div class="info-item attachment-row" @click.stop>
<span class="info-label">附件</span>
<file-preview v-if="item.accessory" :value="item.accessory" class="card-attachment" />
<el-tag v-else type="info" size="mini">无附件</el-tag>
</div>
</div>
<!-- 卡片底部操作按钮 -->
@@ -352,11 +357,7 @@
附件
</template>
<div class="attachment-box">
<div v-if="form.accessory" class="attachment-item">
<el-link :href="form.accessory" :underline="false" target="_blank">
<i class="el-icon-document"></i> 查看附件
</el-link>
</div>
<file-preview v-if="form.accessory" v-model="form.accessory" />
<div v-else class="no-attachment">暂无附件...</div>
</div>
</el-descriptions-item>
@@ -374,6 +375,7 @@ import { addTask, delTask, getTask, listTask, updateTask } from "@/api/oa/task";
import { deptTreeSelect, selectUser } from "@/api/system/user";
import UserSelect from "@/components/UserSelect";
import ProjectSelect from "@/components/fad-service/ProjectSelect";
import FilePreview from "@/components/FilePreview";
import OperationLogDrawer from "@/views/oa/project/operationLog/OperationLogDrawer.vue";
@@ -382,6 +384,7 @@ export default {
components: {
UserSelect,
ProjectSelect,
FilePreview,
OperationLogDrawer
},
dicts: ['sys_project_type', 'sys_project_status', 'sys_work_type', 'sys_sort_grade'],
@@ -426,7 +429,7 @@ export default {
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
pageSize: 20,
searchTime: [],
},
userList: [],
@@ -765,12 +768,116 @@ export default {
</script>
<style scoped>
.task-col {
flex: 0 0 20%;
max-width: 20%;
}
.task-card {
margin-bottom: 20px;
height: 320px;
margin-bottom: 12px;
height: 300px;
/* 固定卡片高度 */
display: flex;
flex-direction: column;
font-size: 12px;
}
.task-card >>> .el-card__header {
padding: 10px 12px;
}
.task-card >>> .el-card__body {
padding: 10px 12px;
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
}
.task-card .task-title {
font-size: 13px;
}
.task-card .info-label {
font-size: 12px;
min-width: 56px;
}
.task-card .info-item {
margin-bottom: 6px;
}
.task-card .card-footer .el-button {
margin-right: 4px;
padding: 4px 2px;
font-size: 12px;
}
@media (max-width: 1366px) {
.task-col {
flex: 0 0 25%;
max-width: 25%;
}
}
@media (max-width: 992px) {
.task-col {
flex: 0 0 33.3333%;
max-width: 33.3333%;
}
}
@media (max-width: 768px) {
.task-col {
flex: 0 0 50%;
max-width: 50%;
}
}
@media (max-width: 480px) {
.task-col {
flex: 0 0 100%;
max-width: 100%;
}
}
.attachment-row {
align-items: flex-start;
}
.card-attachment {
flex: 1;
min-width: 0;
margin: 0;
}
.card-attachment >>> .el-upload-list__item {
margin: 0;
border: none;
padding: 0;
background: transparent;
line-height: 1.4;
}
.card-attachment >>> .el-upload-list__item:hover {
background: transparent;
}
.card-attachment >>> .ele-upload-list__item-content-action {
display: none;
}
.card-attachment >>> .el-upload-list__item:hover .ele-upload-list__item-content-action {
display: flex;
gap: 4px;
}
.card-attachment >>> .el-icon-document {
color: #409eff;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
.card-header {
@@ -817,6 +924,7 @@ export default {
padding: 10px 0;
flex: 1;
overflow-y: auto;
min-height: 0;
}
.info-item {