中航光电热表web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

638 lines
19 KiB

<template>
<basic-container>
<!-- 绩效填报 -->
<avue-crud
:option="option"
:table-loading="loading"
:data="data"
v-model="form"
v-model:page="page"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad"
@sort-change="sortChange"
>
<template #menu-left>
<el-button
type="primary"
@click="maintenanceContents"
v-if="permission.maintenance_perf_maintenance"
>
绩效内容维护
</el-button>
</template>
<template #status="scope">
<el-tag
:type="
scope.row.status == 1
? 'warning'
: scope.row.status == 2 || scope.row.status == 4
? 'success'
: scope.row.status == 3
? 'info'
: scope.row.status == 5 || scope.row.status == 6
? 'danger'
: ''
"
>
{{ scope.row.statusName }}
</el-tag>
</template>
<!-- || scope.row.status == 5 -->
<template #menu="scope">
<el-button
v-if="
(scope.row.status == 1 &&
(scope.row.parentId === 0 || scope.row.parentId === null) &&
permission.main_task_download) ||
(scope.row.status == 2 && permission.subtask_download)
"
type="text"
@click="downloadTask(scope.row)"
>
下载
</el-button>
<el-button
v-if="
((scope.row.parentId === 0 || scope.row.parentId === null) &&
scope.row.status == 1 &&
permission.main_task_reporting) ||
(scope.row.parentId && scope.row.status == 1 && permission.subtask_reporting) ||
((scope.row.parentId === 0 || scope.row.parentId === null) &&
scope.row.status == 5 &&
permission.main_task_reporting)
"
type="text"
@click="fillRow(scope.row)"
>
填报
</el-button>
<el-button
v-if="
(scope.row.status == 3 || scope.row.status == 4 || scope.row.status == 5) &&
permission.main_task_detail
"
type="text"
@click="detailRow(scope.row)"
>
详情
</el-button>
<el-button
v-if="scope.row.status == 3 && permission.main_task_examine"
type="text"
@click="examineRow(scope.row)"
>
审批
</el-button>
<el-button
v-if="scope.row.parentId && scope.row.status == 1 && permission.subtask_delete"
type="text"
@click="removeRow(scope.row)"
>
删除
</el-button>
<el-button
v-if="
scope.row.parentId &&
scope.row.status == 2 &&
scope.row.parentStatus == 1 &&
permission.subtask_reset
"
type="text"
@click="resetTaskDetail(scope.row)"
>
重置
</el-button>
</template>
</avue-crud>
<reportingPerf
v-if="showReport"
:showReport="showReport"
:isDetail="isDetail"
:title="title"
:row="currentRow"
@closeDialog="closeDialog"
></reportingPerf>
<prefDetail
v-if="showDetail"
:showDetail="showDetail"
@closeDetail="closeDetail"
:row="currentRow"
:type="'1'"
/>
<el-dialog append-to-body title="审批" v-model="showExamine" width="85%">
<!-- 👇 这里全部换成原生 Element UI -->
<el-form :model="examineForm" :rules="rules" ref="examineFormRef" label-width="100px">
<el-form-item label="审批结果" prop="result">
<el-radio-group v-model="examineForm.result">
<el-radio label="1">通过</el-radio>
<el-radio label="2">不通过</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="审批意见" prop="remark">
<el-input
v-model="examineForm.remark"
type="textarea"
:rows="3"
placeholder="请输入审批意见"
></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeExamine">取 消</el-button>
<el-button type="primary" @click="handleApproval"> </el-button>
</span>
</template>
</el-dialog>
<batchAddContent
v-if="showContent"
:showContent="showContent"
:title="title"
@closeDialog="closeDialog"
/>
</basic-container>
</template>
<script>
import { mapGetters } from 'vuex';
import reportingPerf from './components/reportingPerf.vue';
import prefDetail from './components/prefDetail.vue';
import batchAddContent from './components/batchAddContent.vue';
import {
pageBsEfficiencyTask,
approvalBsEfficiencyTask,
rejectBsEfficiencyTask,
removeBsEfficiencyTask,
subResetBsEfficiencyTask,
downloadBsEfficiencyTaskTemplate,
} from '@/api/performanceManagement/dataReporting';
import { downloadXls, downloadFile, downloadFileBlob } from '@/utils/util';
import { saveAs } from 'file-saver';
import JSZip from 'jszip';
export default {
components: { reportingPerf, prefDetail, batchAddContent },
data() {
return {
showDialog: false,
typeValue: '1',
resultValue: '',
showReport: false,
isDetail: false,
title: '',
showContent: false,
currentRow: null,
showDetail: false,
showExamine: false,
examineForm: {
result: '1',
remark: '',
},
rules: {
result: [{ required: true, message: '请选择审批结果', trigger: 'change' }],
},
loading: false,
data: [],
form: {},
page: {
pageSize: 10,
currentPage: 1,
total: 0,
},
query: {},
option: {
height: 'auto',
align: 'center',
calcHeight: 32,
rowKey: 'id',
rowParentKey: 'parentId',
tip: false,
simplePage: true,
searchShow: true,
searchMenuSpan: 12,
searchIcon: true,
searchIndex: 3,
tree: true,
treeProps: {
children: 'subTasks',
hasChildren: 'hasChildren',
},
border: true,
index: false,
selection: false,
viewBtn: false,
delBtn: false,
addBtn: false,
editBtn: false,
editBtnText: '修改',
addBtnIcon: ' ',
viewBtnIcon: ' ',
delBtnIcon: ' ',
editBtnIcon: ' ',
viewBtnText: '详情',
menu: true,
menuWidth: 150,
dialogWidth: 1200,
dialogClickModal: false,
searchEnter: true,
excelBtn: false,
filterBtn: true,
searchShowBtn: false,
columnSort: true,
excelBtn: true,
columnSort: true,
showOverflowTooltip: true,
searchLabelPosition: 'left',
searchGutter: 24,
searchSpan: 6,
menuAlign: 'center',
gridBtn: false,
searchMenuPosition: 'right',
labelWidth: 120,
searchLabelWidth: 'auto',
column: [
{
label: '任务名称',
prop: 'taskName',
search: true,
sortable: 'custom',
overHidden: true,
align: 'left',
headerAlign: 'center',
},
{
label: '绩效填报人',
prop: 'reportUserName',
search: true,
sortable: 'custom',
overHidden: true,
width: 110,
},
{
label: '状态',
prop: 'status',
type: 'select',
search: false,
sortable: 'custom',
overHidden: true,
width: 100,
dicData: [
{ label: '进行中', value: 1, type: 'warning' }, // 橙色 - 处理中
{ label: '已完成', value: 2, type: 'success' }, // 绿色 - 成功完成
{ label: '待审批', value: 3, type: 'info' }, // 灰色 - 等待状态
{ label: '审批通过', value: 4, type: 'success' }, // 绿色 - 成功
{ label: '审批不通过', value: 5, type: 'danger' }, // 红色 - 失败/拒绝
{ label: '已超期', value: 6, type: 'danger' }, // 红色 - 失败/拒绝
{ label: '任务失败', value: 7, type: 'danger' },
],
},
{
label: '下发人',
prop: 'createUserName',
search: false,
sortable: 'custom',
overHidden: true,
width: 100,
},
{
label: '下发时间',
prop: 'createTime',
search: false,
sortable: 'custom',
overHidden: true,
width: 150,
},
{
label: '填报时间',
prop: 'reportTime',
search: false,
sortable: 'custom',
overHidden: true,
width: 150,
},
],
},
};
},
mounted() {},
methods: {
maintenanceContents() {
this.title = '模板内容维护';
this.showContent = true;
},
// 填报
fillRow(row) {
if (row.parentId !== 0) {
const currentUser = this.$store.state.user.userInfo;
if (currentUser && currentUser.account !== row.reportUserName) {
this.$message.error(
row.parentId == 0 ? '无权限填报任务明细填报!' : '无权限填报任务填报!'
);
return;
}
}
this.currentRow = row;
this.title = row.parentId !== 0 ? '任务明细填报' : '任务填报';
this.isDetail = row.parentId !== 0 ? true : false;
this.showReport = true;
},
closeDialog(val) {
this.showReport = false;
this.isDetail = false;
this.showDetail = false;
this.showContent = false;
if (val) {
this.onLoad();
}
},
closeDetail(val) {
this.showDetail = false;
},
detailRow(row) {
this.currentRow = row;
this.showDetail = true;
},
// 汇总
collectRow(row) {
this.$confirm('确定汇总当前绩效?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(res => {});
},
// 审批
examineRow(row) {
this.examineForm = {
result: '1',
remark: '',
};
this.currentRow = row;
this.showExamine = true;
},
// 任务行下载模板 → 打包ZIP
async downloadTask(row) {
const zip = new JSZip();
const promises = []; // 存储下载Promise
if (row.parentId == 0) {
if (!row.subTasks || row.subTasks.length === 0) {
this.$message.warning('暂无可下载文件!');
return;
}
// 只下载状态为2(已完成)的任务
const completedTasks = row.subTasks.filter(task => task.status === 2);
if (completedTasks.length === 0) {
this.$message.warning('暂无可下载文件!');
return;
}
try {
// 1. 下载模板文件并加入压缩包
const templateRes = await downloadBsEfficiencyTaskTemplate();
zip.file(`${row.yearMonth}绩效填报模板.xlsx`, templateRes.data);
// 2. 下载所有已完成的子任务附件
completedTasks.forEach(task => {
if (task.attachLink) {
const promise = fetch(task.attachLink)
.then(res => res.blob())
.then(blob => {
zip.file(`${task.taskName}.xlsx`, blob);
});
promises.push(promise);
}
});
// 等待所有文件下载完成 → 生成zip并下载
await Promise.all(promises);
const content = await zip.generateAsync({ type: 'blob' });
saveAs(content, `${row.yearMonth}绩效填报文件包.zip`);
this.$message.success('打包下载成功');
} catch (error) {
console.error('打包下载失败:', error);
this.$message.error('打包下载失败,请稍后重试');
}
} else {
// 子任务 → 单文件打包成zip
// if (!row.attachLink) {
// this.$message.warning('暂无可下载文件!');
// return;
// }
// try {
// const res = await fetch(row.attachLink);
// const blob = await res.blob();
// zip.file(`${row.taskName}.xlsx`, blob);
// const content = await zip.generateAsync({ type: 'blob' });
// saveAs(content, `${row.taskName}.zip`);
// this.$message.success('打包下载成功');
// } catch (error) {
// console.error('下载失败:', error);
// this.$message.error('文件下载失败');
// }
if (row.attachLink == '') {
this.$message.warning('暂无可下载文件!');
return;
}
downloadFileBlob(row.attachLink, row.taskName + '.xlsx');
}
},
// 任务明细行重置
resetTaskDetail(row) {
this.$confirm(
'确定重置当前任务明细?重置后状态将变更为【进行中】,之前上传的文件将被作废。',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
subResetBsEfficiencyTask({ id: row.id }).then(res => {
if (res.data.code === 200) {
this.$message.success('重置成功');
this.onLoad();
} else {
this.$message.error('重置失败');
}
});
});
},
// 关闭审批弹框
closeExamine() {
this.showExamine = false;
// 重置表单数据
this.examineForm = {
result: '',
remark: '',
};
},
// 处理审批
handleApproval() {
if (!this.currentRow) return;
// 表单验证
this.$refs.examineFormRef.validate(valid => {
if (valid) {
if (this.examineForm.result === '1') {
this.approvalRow(this.currentRow);
} else if (this.examineForm.result === '2') {
this.rejectRow(this.currentRow);
}
}
});
},
// 删除
removeRow(row) {
this.$confirm('确定删除当前绩效任务明细?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
removeBsEfficiencyTask({ ids: row.id }).then(res => {
if (res.data.code === 200) {
this.$message.success('删除成功');
this.onLoad();
} else {
this.$message.error('删除失败');
}
});
});
},
// 审批通过
approvalRow(row) {
this.$confirm('确定审批通过当前绩效任务?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'success',
}).then(() => {
approvalBsEfficiencyTask({ id: row.id, remark: this.examineForm.remark }).then(res => {
if (res.data.code === 200) {
this.$message.success('审批通过成功');
this.closeExamine();
this.onLoad();
} else {
this.$message.error('审批通过失败');
}
});
});
},
// 审批不通过
rejectRow(row) {
this.$confirm('确定审批不通过当前绩效任务?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
rejectBsEfficiencyTask({ id: row.id, remark: this.examineForm.remark }).then(res => {
if (res.data.code === 200) {
this.$message.success('审批不通过成功');
this.closeExamine();
this.onLoad();
} else {
this.$message.error('审批不通过失败');
}
});
});
},
// 表格排序
sortChange({ prop, order }) {
if (!prop) {
// 如果取消排序,清空排序参数
this.query.orderByField = undefined;
this.query.asc = undefined;
} else {
const orderByField = prop.replace(/([a-z])([A-Z0-9])/g, '$1_$2').toUpperCase();
this.query.orderByField =
orderByField == 'REPORT_USER_NAME'
? 'bu.real_name'
: orderByField == 'STATUS'
? 't.STATUS'
: orderByField == 'CREATE_USER_NAME'
? 'bu1.real_name'
: orderByField == 'CREATE_TIME'
? 't.CREATE_TIME'
: orderByField;
this.query.asc = order === 'ascending' ? true : false;
}
// 重新加载数据
this.onLoad();
},
onLoad() {
this.loading = true;
const params = {
pageSize: this.page.pageSize,
currentPage: this.page.currentPage,
...this.query,
};
console.log(params);
pageBsEfficiencyTask(params)
.then(res => {
if (res.data.code === 200) {
// 为子任务添加父级状态
const processTasks = tasks => {
return tasks.map(task => {
if (task.subTasks && task.subTasks.length > 0) {
// 为每个子任务添加父级状态
task.subTasks = task.subTasks.map(subTask => ({
...subTask,
parentStatus: task.status, // 添加父级状态
}));
// 递归处理子任务的子任务
processTasks(task.subTasks);
}
return task;
});
};
this.data = processTasks(res.data.data.records || []);
this.page.total = res.data.data.total || 0;
} else {
this.data = [];
this.page.total = 0;
}
this.loading = false;
})
.catch(() => {
this.data = [];
this.page.total = 0;
this.loading = false;
});
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
searchReset() {
this.query = {};
this.treeDeptId = '';
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
},
computed: {
...mapGetters(['userInfo', 'permission']),
permissionList() {
return {
addBtn: true,
viewBtn: true,
delBtn: true,
editBtn: true,
};
},
},
};
</script>
<style></style>