修复文件bug
This commit is contained in:
@@ -108,5 +108,10 @@ public class OaRequirementsVo extends BaseEntity {
|
|||||||
/** 附件文件列表(已联查 sys_oss,每项形如 "<ossId>|<originalName>|<url>",逗号分隔) */
|
/** 附件文件列表(已联查 sys_oss,每项形如 "<ossId>|<originalName>|<url>",逗号分隔) */
|
||||||
private String accessoryFiles;
|
private String accessoryFiles;
|
||||||
|
|
||||||
|
/** 审批状态:null=未提交审批,0=待审,1=通过,2=驳回,3=撤回 */
|
||||||
|
private Integer approvalStatus;
|
||||||
|
/** 审批单 id(最新一次) */
|
||||||
|
private Long approvalInstanceId;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,19 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ruoyi.oa.domain.bo.OaRequirementsBo;
|
import com.ruoyi.oa.domain.bo.OaRequirementsBo;
|
||||||
import com.ruoyi.oa.domain.vo.OaRequirementsVo;
|
import com.ruoyi.oa.domain.vo.OaRequirementsVo;
|
||||||
|
import com.ruoyi.oa.domain.OaApprovalInstance;
|
||||||
import com.ruoyi.oa.domain.OaRequirements;
|
import com.ruoyi.oa.domain.OaRequirements;
|
||||||
import com.ruoyi.oa.domain.SysOaWarehouse;
|
import com.ruoyi.oa.domain.SysOaWarehouse;
|
||||||
|
import com.ruoyi.oa.mapper.OaApprovalInstanceMapper;
|
||||||
import com.ruoyi.oa.mapper.OaRequirementsMapper;
|
import com.ruoyi.oa.mapper.OaRequirementsMapper;
|
||||||
import com.ruoyi.oa.mapper.SysOaWarehouseMapper;
|
import com.ruoyi.oa.mapper.SysOaWarehouseMapper;
|
||||||
|
import com.ruoyi.oa.service.IOaApprovalService;
|
||||||
import com.ruoyi.oa.service.IOaRequirementsService;
|
import com.ruoyi.oa.service.IOaRequirementsService;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -39,12 +44,18 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
||||||
|
|
||||||
|
public static final String BIZ_TYPE = "purchase_req";
|
||||||
|
|
||||||
private final OaRequirementsMapper baseMapper;
|
private final OaRequirementsMapper baseMapper;
|
||||||
|
|
||||||
private final OaWarehouseAuditService auditService;
|
private final OaWarehouseAuditService auditService;
|
||||||
|
|
||||||
private final SysOaWarehouseMapper warehouseMapper;
|
private final SysOaWarehouseMapper warehouseMapper;
|
||||||
|
|
||||||
|
private final IOaApprovalService approvalService;
|
||||||
|
|
||||||
|
private final OaApprovalInstanceMapper approvalInstanceMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询OA 需求
|
* 查询OA 需求
|
||||||
*/
|
*/
|
||||||
@@ -52,9 +63,33 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
|||||||
public OaRequirementsVo queryById(Long requirementId){
|
public OaRequirementsVo queryById(Long requirementId){
|
||||||
OaRequirementsVo vo = baseMapper.selectVoById(requirementId);
|
OaRequirementsVo vo = baseMapper.selectVoById(requirementId);
|
||||||
enrichMaterials(Collections.singletonList(vo));
|
enrichMaterials(Collections.singletonList(vo));
|
||||||
|
enrichApproval(Collections.singletonList(vo));
|
||||||
return 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_ids(CSV)批量补全物料明细到 VO.materials */
|
/** 根据 material_ids(CSV)批量补全物料明细到 VO.materials */
|
||||||
private void enrichMaterials(List<OaRequirementsVo> list) {
|
private void enrichMaterials(List<OaRequirementsVo> list) {
|
||||||
if (list == null || list.isEmpty()) return;
|
if (list == null || list.isEmpty()) return;
|
||||||
@@ -110,6 +145,7 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
|||||||
QueryWrapper<OaRequirements> lqw = buildQueryWrapper(bo);
|
QueryWrapper<OaRequirements> lqw = buildQueryWrapper(bo);
|
||||||
Page<OaRequirementsVo> result = baseMapper.selectVoListPage(pageQuery.build(), lqw);
|
Page<OaRequirementsVo> result = baseMapper.selectVoListPage(pageQuery.build(), lqw);
|
||||||
enrichMaterials(result.getRecords());
|
enrichMaterials(result.getRecords());
|
||||||
|
enrichApproval(result.getRecords());
|
||||||
return TableDataInfo.build(result);
|
return TableDataInfo.build(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +157,7 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
|||||||
QueryWrapper<OaRequirements> lqw = buildQueryWrapper(bo);
|
QueryWrapper<OaRequirements> lqw = buildQueryWrapper(bo);
|
||||||
List<OaRequirementsVo> list = baseMapper.selectVoListForExport(lqw);
|
List<OaRequirementsVo> list = baseMapper.selectVoListForExport(lqw);
|
||||||
enrichMaterials(list);
|
enrichMaterials(list);
|
||||||
|
enrichApproval(list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +198,8 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
|||||||
bo.setRequirementId(add.getRequirementId());
|
bo.setRequirementId(add.getRequirementId());
|
||||||
auditService.log(OpType.REQ_CREATE, OpType.REF_REQUIREMENT, add.getRequirementId(),
|
auditService.log(OpType.REQ_CREATE, OpType.REF_REQUIREMENT, add.getRequirementId(),
|
||||||
"新建采购需求:" + add.getTitle());
|
"新建采购需求:" + add.getTitle());
|
||||||
|
// 触发审批流
|
||||||
|
approvalService.submit(BIZ_TYPE, add.getRequirementId(), add.getTitle());
|
||||||
}
|
}
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
@@ -172,6 +211,17 @@ public class OaRequirementsServiceImpl implements IOaRequirementsService {
|
|||||||
public Boolean updateByBo(OaRequirementsBo bo) {
|
public Boolean updateByBo(OaRequirementsBo bo) {
|
||||||
OaRequirements update = BeanUtil.toBean(bo, OaRequirements.class);
|
OaRequirements update = BeanUtil.toBean(bo, OaRequirements.class);
|
||||||
validEntityBeforeSave(update);
|
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;
|
boolean ok = baseMapper.updateById(update) > 0;
|
||||||
if (ok) {
|
if (ok) {
|
||||||
String op = OpType.REQ_UPDATE;
|
String op = OpType.REQ_UPDATE;
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
<span @click="gotoPurchase" style="cursor: pointer;">如要发放采购相关需求请移步采购需求管理(点击此处快速跳转)</span>
|
<span @click="gotoPurchase" style="cursor: pointer;">如要发放采购相关需求请移步采购需求管理(点击此处快速跳转)</span>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
|
|
||||||
<el-row :gutter="20" v-loading="loading">
|
<el-row :gutter="10" v-loading="loading">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="item in taskList" :key="item.taskId">
|
<el-col class="task-col" v-for="item in taskList" :key="item.taskId">
|
||||||
<el-card class="task-card" shadow="hover" @click.native="handleLookTask(item)">
|
<el-card class="task-card" shadow="hover" @click.native="handleLookTask(item)">
|
||||||
<!-- 卡片头部 -->
|
<!-- 卡片头部 -->
|
||||||
<template slot="header">
|
<template slot="header">
|
||||||
@@ -99,6 +99,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<span v-else>{{ item.workerNickName }}</span>
|
<span v-else>{{ item.workerNickName }}</span>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
<!-- 卡片底部操作按钮 -->
|
<!-- 卡片底部操作按钮 -->
|
||||||
@@ -352,11 +357,7 @@
|
|||||||
附件
|
附件
|
||||||
</template>
|
</template>
|
||||||
<div class="attachment-box">
|
<div class="attachment-box">
|
||||||
<div v-if="form.accessory" class="attachment-item">
|
<file-preview v-if="form.accessory" v-model="form.accessory" />
|
||||||
<el-link :href="form.accessory" :underline="false" target="_blank">
|
|
||||||
<i class="el-icon-document"></i> 查看附件
|
|
||||||
</el-link>
|
|
||||||
</div>
|
|
||||||
<div v-else class="no-attachment">暂无附件...</div>
|
<div v-else class="no-attachment">暂无附件...</div>
|
||||||
</div>
|
</div>
|
||||||
</el-descriptions-item>
|
</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 { deptTreeSelect, selectUser } from "@/api/system/user";
|
||||||
import UserSelect from "@/components/UserSelect";
|
import UserSelect from "@/components/UserSelect";
|
||||||
import ProjectSelect from "@/components/fad-service/ProjectSelect";
|
import ProjectSelect from "@/components/fad-service/ProjectSelect";
|
||||||
|
import FilePreview from "@/components/FilePreview";
|
||||||
import OperationLogDrawer from "@/views/oa/project/operationLog/OperationLogDrawer.vue";
|
import OperationLogDrawer from "@/views/oa/project/operationLog/OperationLogDrawer.vue";
|
||||||
|
|
||||||
|
|
||||||
@@ -382,6 +384,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
UserSelect,
|
UserSelect,
|
||||||
ProjectSelect,
|
ProjectSelect,
|
||||||
|
FilePreview,
|
||||||
OperationLogDrawer
|
OperationLogDrawer
|
||||||
},
|
},
|
||||||
dicts: ['sys_project_type', 'sys_project_status', 'sys_work_type', 'sys_sort_grade'],
|
dicts: ['sys_project_type', 'sys_project_status', 'sys_work_type', 'sys_sort_grade'],
|
||||||
@@ -426,7 +429,7 @@ export default {
|
|||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 20,
|
||||||
searchTime: [],
|
searchTime: [],
|
||||||
},
|
},
|
||||||
userList: [],
|
userList: [],
|
||||||
@@ -765,12 +768,116 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.task-col {
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
.task-card {
|
.task-card {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 12px;
|
||||||
height: 320px;
|
height: 300px;
|
||||||
/* 固定卡片高度 */
|
/* 固定卡片高度 */
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
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 {
|
.card-header {
|
||||||
@@ -817,6 +924,7 @@ export default {
|
|||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-item {
|
.info-item {
|
||||||
|
|||||||
Reference in New Issue
Block a user