feat(HRM): 添加附件显示组件并优化表单逻辑
添加FileList组件用于显示附件列表 在请假和外出申请详情页中显示附件 优化审批部门选择逻辑,仅在新增时显示 修复请假申请编辑时的审批类型校验问题
This commit is contained in:
119
klp-ui/src/components/FileList/index.vue
Normal file
119
klp-ui/src/components/FileList/index.vue
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-list-container">
|
||||||
|
<el-table
|
||||||
|
:data="fileList"
|
||||||
|
border
|
||||||
|
size="small"
|
||||||
|
v-loading="loading"
|
||||||
|
style="width: 100%;"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
label="文件名"
|
||||||
|
prop="originalName"
|
||||||
|
min-width="200"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<i class="el-icon-document" style="margin-right: 8px;"></i>
|
||||||
|
{{ scope.row.originalName }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="操作"
|
||||||
|
width="100"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-download"
|
||||||
|
@click="downloadFile(scope.row)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
下载
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 空数据提示 -->
|
||||||
|
<div v-if="fileList.length === 0 && !loading" class="empty-tip">
|
||||||
|
<el-empty description="暂无文件数据"></el-empty>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listByIds } from "@/api/system/oss";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "FileList",
|
||||||
|
props: {
|
||||||
|
ossIds: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
fileList: [],
|
||||||
|
loading: false // 加载状态
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
ossIds: {
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.getFileList();
|
||||||
|
} else {
|
||||||
|
this.fileList = []; // 清空文件列表
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getFileList() {
|
||||||
|
if (!this.ossIds) return;
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
try {
|
||||||
|
let res = await listByIds(this.ossIds);
|
||||||
|
this.fileList = res.data || [];
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error('获取文件列表失败:' + (error.message || '未知错误'));
|
||||||
|
this.fileList = [];
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 文件下载方法
|
||||||
|
downloadFile(file) {
|
||||||
|
if (!file || !file.ossId) {
|
||||||
|
this.$message.warning('文件下载地址不存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$download.oss(file.ossId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.file-list-container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tip {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-table {
|
||||||
|
--el-table-header-text-color: #606266;
|
||||||
|
--el-table-row-hover-bg-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- 左侧是新增表单 -->
|
<!-- 左侧是新增表单 -->
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
|
||||||
<el-form-item label="审批部门" prop="deptId">
|
<el-form-item v-if="!form.outId" label="审批部门" prop="deptId">
|
||||||
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="getDeptLeader">
|
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="getDeptLeader">
|
||||||
<el-option v-for="item in deptOptions" :key="item.deptId"
|
<el-option v-for="item in deptOptions" :key="item.deptId"
|
||||||
:label="item.deptName + '(' + (item.leaderNickName || '无负责人') + ')'" :value="item.deptId"></el-option>
|
:label="item.deptName + '(' + (item.leaderNickName || '无负责人') + ')'" :value="item.deptId"></el-option>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- 左侧是新增表单 -->
|
<!-- 左侧是新增表单 -->
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
|
||||||
<el-form-item label="审批部门" prop="deptId">
|
<el-form-item label="审批部门" prop="deptId" v-if="!form.leaveId">
|
||||||
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="getDeptLeader">
|
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="getDeptLeader">
|
||||||
<el-option v-for="item in deptOptions" :key="item.deptId"
|
<el-option v-for="item in deptOptions" :key="item.deptId"
|
||||||
:label="item.deptName + '(' + (item.leaderNickName || '无负责人') + ')'" :value="item.deptId"></el-option>
|
:label="item.deptName + '(' + (item.leaderNickName || '无负责人') + ')'" :value="item.deptId"></el-option>
|
||||||
@@ -29,14 +29,8 @@
|
|||||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
<span style="font-weight: 600;">请假时段 {{ index + 1 }}</span>
|
<span style="font-weight: 600;">请假时段 {{ index + 1 }}</span>
|
||||||
<!-- 只有多行时显示删除按钮 -->
|
<!-- 只有多行时显示删除按钮 -->
|
||||||
<el-button
|
<el-button v-if="form.list.length > 1" type="text" icon="el-icon-delete" size="mini"
|
||||||
v-if="form.list.length > 1"
|
@click="removeLeaveItem(index)" style="color: #f56c6c;">删除</el-button>
|
||||||
type="text"
|
|
||||||
icon="el-icon-delete"
|
|
||||||
size="mini"
|
|
||||||
@click="removeLeaveItem(index)"
|
|
||||||
style="color: #f56c6c;"
|
|
||||||
>删除</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 注意:prop需要指定数组索引,支持嵌套校验 -->
|
<!-- 注意:prop需要指定数组索引,支持嵌套校验 -->
|
||||||
<el-form-item label="开始时间" :prop="`list[${index}].startTime`" :rules="rules.listItem.startTime">
|
<el-form-item label="开始时间" :prop="`list[${index}].startTime`" :rules="rules.listItem.startTime">
|
||||||
@@ -79,7 +73,9 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<el-button type="primary" @click="handleSubmit" v-loading="buttonLoading">{{ form.leaveId ? '更新申请' : '批量提交申请' }}</el-button>
|
<el-button type="primary" @click="handleSubmit" v-loading="buttonLoading">{{ form.leaveId ? '更新申请' :
|
||||||
|
'批量提交申请'
|
||||||
|
}}</el-button>
|
||||||
<el-button @click="handleReset">重置表单</el-button>
|
<el-button @click="handleReset">重置表单</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -107,7 +103,8 @@
|
|||||||
<el-table-column label="审批情况" align="center" prop="approverName">
|
<el-table-column label="审批情况" align="center" prop="approverName">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 每行一个,不要出现换行,将英文映射成中文 -->
|
<!-- 每行一个,不要出现换行,将英文映射成中文 -->
|
||||||
<el-tag v-for="task in scope.row.tasks" :key="task.taskId" :type="getTaskStatusTagType(task.taskStatus)" style="margin-right: 8px;">
|
<el-tag v-for="task in scope.row.tasks" :key="task.taskId" :type="getTaskStatusTagType(task.taskStatus)"
|
||||||
|
style="margin-right: 8px;">
|
||||||
<!-- taskStatus包括pending, approved, rejected, 根据状态设置不同的标签类型 -->
|
<!-- taskStatus包括pending, approved, rejected, 根据状态设置不同的标签类型 -->
|
||||||
{{ task.approverName }} {{ getTaskStatusText(task.taskStatus) }}
|
{{ task.approverName }} {{ getTaskStatusText(task.taskStatus) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
@@ -307,7 +304,8 @@ export default {
|
|||||||
endTime: data.endTime,
|
endTime: data.endTime,
|
||||||
leaveShift: data.leaveShift,
|
leaveShift: data.leaveShift,
|
||||||
leaveDays: data.leaveDays,
|
leaveDays: data.leaveDays,
|
||||||
leaveReason: data.leaveReason
|
leaveReason: data.leaveReason,
|
||||||
|
oldApprovalType: data.approvalType,
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -327,7 +325,7 @@ export default {
|
|||||||
this.buttonLoading = true;
|
this.buttonLoading = true;
|
||||||
const { list, ...commonFields } = this.form; // 拆分公共字段和时段列表
|
const { list, ...commonFields } = this.form; // 拆分公共字段和时段列表
|
||||||
let successCount = 0;
|
let successCount = 0;
|
||||||
let failCount = 0;
|
let failCount = 0;
|
||||||
const failReasons = [];
|
const failReasons = [];
|
||||||
|
|
||||||
// 2. 循环处理每个时段,逐个发送请求
|
// 2. 循环处理每个时段,逐个发送请求
|
||||||
@@ -342,21 +340,23 @@ export default {
|
|||||||
leaveDays: item.leaveDays,
|
leaveDays: item.leaveDays,
|
||||||
leaveReason: item.leaveReason,
|
leaveReason: item.leaveReason,
|
||||||
// 生成单条记录的标题
|
// 生成单条记录的标题
|
||||||
leaveTitle: `${commonFields.applicantName}-${commonFields.leaveType}-时段${i+1}-${item.startTime}-${item.leaveReason || ''}`,
|
leaveTitle: `${commonFields.applicantName}-${commonFields.leaveType}-时段${i + 1}-${item.startTime}-${item.leaveReason || ''}`,
|
||||||
approvalType: approvalType,
|
approvalType: approvalType,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (commonFields.leaveId != null) {
|
if (commonFields.leaveId != null) {
|
||||||
|
if (singleRequestData.oldApprovalType !== approvalType) {
|
||||||
|
this.$message.warning('请假时长变动过大,请撤销后重新发起');
|
||||||
|
failCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
await updateLeaveRequest({ ...singleRequestData, leaveId: commonFields.leaveId });
|
||||||
|
successCount++;
|
||||||
// 编辑模式:仅支持修改单条(因为后端是单条记录)
|
// 编辑模式:仅支持修改单条(因为后端是单条记录)
|
||||||
if (list.length > 1) {
|
if (list.length > 1) {
|
||||||
this.$message.warning('编辑模式仅支持单条修改,已自动取第一行数据');
|
this.$message.warning('编辑模式仅支持单条修改,已自动取第一行数据');
|
||||||
await updateLeaveRequest({ ...singleRequestData, leaveId: commonFields.leaveId });
|
|
||||||
successCount++;
|
|
||||||
break; // 编辑时只处理第一条
|
break; // 编辑时只处理第一条
|
||||||
} else {
|
|
||||||
await updateLeaveRequest({ ...singleRequestData, leaveId: commonFields.leaveId });
|
|
||||||
successCount++;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 新增模式:批量提交多条
|
// 新增模式:批量提交多条
|
||||||
@@ -365,19 +365,23 @@ export default {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
failCount++;
|
failCount++;
|
||||||
failReasons.push(`时段${i+1}提交失败:${error.message || '未知错误'}`);
|
failReasons.push(`时段${i + 1}提交失败:${error.message || '未知错误'}`);
|
||||||
// 失败后继续提交下一条,不中断批量操作
|
// 失败后继续提交下一条,不中断批量操作
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 提交完成后反馈结果
|
// 3. 提交完成后反馈结果
|
||||||
if (failCount === 0) {
|
console.log(commonFields.leaveId);
|
||||||
this.$modal.msgSuccess(`批量提交成功!共提交${successCount}条请假申请`);
|
if (commonFields.leaveId == null) {
|
||||||
} else {
|
if (failCount === 0) {
|
||||||
this.$modal.msgWarning(`批量提交完成!成功${successCount}条,失败${failCount}条\n失败原因:${failReasons.join(';')}`);
|
this.$modal.msgSuccess(`批量提交成功!共提交${successCount}条请假申请`);
|
||||||
|
} else {
|
||||||
|
this.$modal.msgWarning(`批量提交完成!成功${successCount}条,失败${failCount}条\n失败原因:${failReasons.join(';')}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 4. 刷新列表并重置表单
|
// 4. 刷新列表并重置表单
|
||||||
this.getList();
|
this.getList();
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|||||||
@@ -182,6 +182,9 @@
|
|||||||
<el-descriptions-item label="请假天数">{{ currentDetail.leaveDays || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="请假天数">{{ currentDetail.leaveDays || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="请假原因">{{ currentDetail.leaveReason || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="请假原因">{{ currentDetail.leaveReason || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="备注">{{ currentDetail.remark || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="备注">{{ currentDetail.remark || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="附件">
|
||||||
|
<FileList :ossIds="currentDetail.attachmentUrls" />
|
||||||
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -196,6 +199,9 @@
|
|||||||
<el-descriptions-item label="外出地点">{{ currentDetail.outPlace || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="外出地点">{{ currentDetail.outPlace || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="外出原因">{{ currentDetail.outReason || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="外出原因">{{ currentDetail.outReason || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="备注">{{ currentDetail.remark || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="备注">{{ currentDetail.remark || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="附件">
|
||||||
|
<FileList :ossIds="currentDetail.attachmentUrls" />
|
||||||
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -208,9 +214,14 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listApprovalTask, rejectApprovalTask, resolveApprovalTask } from '@/api/wms/approvalTask'
|
import { listApprovalTask, rejectApprovalTask, resolveApprovalTask } from '@/api/wms/approvalTask'
|
||||||
|
import FileList from '@/components/FileList/index.vue'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TodoList',
|
name: 'TodoList',
|
||||||
|
components: {
|
||||||
|
FileList,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 查询参数
|
// 查询参数
|
||||||
|
|||||||
Reference in New Issue
Block a user