人效管理-绩效管理-绩效填报-接口对接

dev-scheduling
ysn 1 month ago
parent 8ece48edfb
commit a71eefc721
  1. 90
      src/api/performanceManagement/dataReporting.js
  2. 22
      src/views/personnelEfficiencyManagement/performanceManagement/components/batchAddContent.vue
  3. 335
      src/views/personnelEfficiencyManagement/performanceManagement/components/prefDetail.vue
  4. 277
      src/views/personnelEfficiencyManagement/performanceManagement/components/reportingPerf.vue
  5. 986
      src/views/personnelEfficiencyManagement/performanceManagement/dataReporting.vue
  6. 104
      src/views/personnelEfficiencyManagement/performanceManagement/performanceDisclosure.vue

@ -1,6 +1,6 @@
// 绩效填报相关接口 // 绩效填报相关接口
import request from '@/axios'; import request from '@/axios';
// 1. 绩效模板内容列表 // 1. 绩效内容维护内容列表
export function listBsEfficiencyTempParam(params) { export function listBsEfficiencyTempParam(params) {
return request({ return request({
url: '/blade-desk/bsEfficiencyTempParam/list', url: '/blade-desk/bsEfficiencyTempParam/list',
@ -8,7 +8,7 @@ export function listBsEfficiencyTempParam(params) {
params params
}) })
} }
// 2. 绩效模板内容删除 // 2. 绩效内容维护内容删除
export function removeBsEfficiencyTempParam(params) { export function removeBsEfficiencyTempParam(params) {
return request({ return request({
url: '/blade-desk/bsEfficiencyTempParam/remove', url: '/blade-desk/bsEfficiencyTempParam/remove',
@ -16,11 +16,95 @@ export function removeBsEfficiencyTempParam(params) {
params params
}) })
} }
// 3. 绩效模板内容新增 // 3. 绩效内容维护内容新增
export function submitBsEfficiencyTempParam(data) { export function submitBsEfficiencyTempParam(data) {
return request({ return request({
url: '/blade-desk/bsEfficiencyTempParam/submit', url: '/blade-desk/bsEfficiencyTempParam/submit',
method: 'post', method: 'post',
data data
}) })
}
// 绩效填报相关接口
// 4. 绩效填报分页查询
export function pageBsEfficiencyTask(params) {
return request({
url: '/blade-desk/bsEfficiencyTask/page',
method: 'get',
params
})
}
// 5. 绩效填报审批通过
export function approvalBsEfficiencyTask(data) {
return request({
url: '/blade-desk/bsEfficiencyTask/approval',
method: 'post',
data
})
}
// 6. 绩效填报审批不通过
export function rejectBsEfficiencyTask(data) {
return request({
url: '/blade-desk/bsEfficiencyTask/reject',
method: 'post',
data
})
}
// 7. 绩效填报任务明细填报
export function subReportBsEfficiencyTask(data) {
return request({
url: '/blade-desk/bsEfficiencyTask/subReport',
method: 'post',
data
})
}
// 8. 绩效填报任务明细重置
export function subResetBsEfficiencyTask(data) {
return request({
url: '/blade-desk/bsEfficiencyTask/subReset',
method: 'post',
data
})
}
// 9. 绩效填报任务明细删除
export function removeBsEfficiencyTask(params) {
return request({
url: '/blade-desk/bsEfficiencyTask/remove',
method: 'post',
params
})
}
// 10. 绩效填报读取Excel
export function readExcelBsEfficiencyTask(data) {
return request({
url: '/blade-desk/bsEfficiencyTask/read-excel',
method: 'post',
data,
headers: { 'Content-Type': 'multipart/form-data' }
})
}
// 11. 绩效填报详情
export function detailBsEfficiencyTask(params) {
return request({
url: '/blade-desk/bsEfficiencyTask/detail',
method: 'get',
params
})
}
// 12. 绩效填报任务填报
export function reportBsEfficiencyTask(data) {
return request({
url: '/blade-desk/bsEfficiencyTask/report',
method: 'post',
data
})
}
// 13.绩效填报下载任务填报
export function downloadBsEfficiencyTaskTemplate(params) {
return request({
url: '/blade-desk/bsEfficiencyTask/download-excel-template',
method: 'get',
params,
responseType: 'blob'
})
} }

@ -89,6 +89,10 @@ export default {
...item, ...item,
_select: false, _select: false,
})); }));
//
if (!hasTotalRow) {
this.form.tableData.push({ _select: false, paramName: '总分' });
}
} else { } else {
this.form.tableData = [{ _select: false, paramName: '总分' }]; this.form.tableData = [{ _select: false, paramName: '总分' }];
this.addTable(); this.addTable();
@ -166,17 +170,25 @@ export default {
}); });
return; return;
} }
const submitData = this.form.tableData.map(row => { const submitData = this.form.tableData
const { _select, ...validData } = row; // /
return validData; .filter(row => {
}); // name=cardNo=
return row.paramName !== '总分';
})
// _select
.map(row => {
const { _select, ...validData } = row;
return validData;
});
console.log('提交数据(已过滤总分)', submitData);
console.log('提交数据', submitData); // console.log('提交数据', submitData); //
submitBsEfficiencyTempParam(submitData).then(res => { submitBsEfficiencyTempParam(submitData).then(res => {
if (res.data.code === 200) { if (res.data.code === 200) {
this.$message.success('保存成功'); this.$message.success('保存成功');
this.closeDialog(true); // this.closeDialog(true); //
} }
}); })
}); });
}, },
}, },

@ -1,153 +1,208 @@
<template> <template>
<el-dialog title="详情" append-to-body :modelValue="openShow" fullscreen width="70%" @close="closeDialog()"> <el-dialog
<!-- 绩效详情 --> title="详情"
<avue-crud append-to-body
:option="option" :modelValue="openShow"
:table-loading="loading" fullscreen
:data="data" width="70%"
v-model="form" @close="closeDialog()"
v-model:page="page" >
ref="crud" <!-- 绩效详情 -->
@search-change="searchChange" <avue-crud
@search-reset="searchReset" :option="option"
@current-change="currentChange" :table-loading="loading"
@size-change="sizeChange" :data="data"
@refresh-change="refreshChange" v-model="form"
> v-model:page="page"
<template #menu-right> ref="crud"
<el-button type="primary">附件下载(明细)</el-button> @search-change="searchChange"
<el-button type="primary">附件下载(汇总)</el-button> @search-reset="searchReset"
</template> @current-change="currentChange"
</avue-crud> @size-change="sizeChange"
</el-dialog> @refresh-change="refreshChange"
>
<template #menu-right>
<el-button type="primary" @click="downloadDetail">附件下载(明细)</el-button>
<el-button type="primary" @click="downloadSummary">附件下载(汇总)</el-button>
</template>
</avue-crud>
</el-dialog>
</template> </template>
<script> <script>
import {
detailBsEfficiencyTask,
downloadBsEfficiencyTaskTemplate,
} from '@/api/performanceManagement/dataReporting';
import { downloadXls, downloadFile, downloadFileBlob } from '@/utils/util';
export default { export default {
props:{ props: {
showDetail:{ showDetail: {
type:Boolean, type: Boolean,
default:false default: false,
},
detailData:{
type:Object,
default:()=>({})
}
}, },
data() { row: {
return { type: Object,
openShow:false, default: () => ({}),
loading:false, },
form:{}, },
option:{ data() {
height: "auto", return {
align: "center", openShow: false,
calcHeight: 32, loading: false,
rowKey: "id", form: {},
rowParentKey: "parentId", option: {
tip: false, height: 'auto',
simplePage: true, align: 'center',
searchShow: true, calcHeight: 32,
searchMenuSpan:12, rowKey: 'id',
searchIcon: true, rowParentKey: 'parentId',
searchIndex: 3, tip: false,
tree: false, simplePage: true,
border: true, searchShow: true,
index: true, searchMenuSpan: 12,
selection: false, searchIcon: true,
viewBtn: false, searchIndex: 3,
delBtn: false, tree: false,
addBtn: false, border: true,
editBtn: false, index: true,
editBtnText: "修改", selection: false,
addBtnIcon: " ", viewBtn: false,
viewBtnIcon: " ", delBtn: false,
delBtnIcon: " ", addBtn: false,
editBtnIcon: " ", editBtn: false,
viewBtnText: "详情", editBtnText: '修改',
labelWidth: 120, addBtnIcon: ' ',
searchLabelWidth: 120, viewBtnIcon: ' ',
menu: false, delBtnIcon: ' ',
menuWidth: 100, editBtnIcon: ' ',
dialogWidth: 1200, viewBtnText: '详情',
dialogClickModal: false, labelWidth: 120,
searchEnter: true, searchLabelWidth: 120,
excelBtn: false, menu: false,
filterBtn: true, menuWidth: 100,
searchShowBtn: false, dialogWidth: 1200,
columnSort: true, dialogClickModal: false,
excelBtn: true, searchEnter: true,
columnSort: true, excelBtn: false,
showOverflowTooltip: true, filterBtn: true,
searchLabelPosition: "left", searchShowBtn: false,
searchLabelPosition: "left", columnSort: true,
searchGutter: 24, excelBtn: true,
searchSpan: 6, columnSort: true,
menuAlign: "center", showOverflowTooltip: true,
gridBtn: false, searchLabelPosition: 'left',
searchMenuPosition: "right", searchLabelPosition: 'left',
column: [] searchGutter: 24,
}, searchSpan: 6,
page: { menuAlign: 'center',
pageSize: 10, gridBtn: false,
currentPage: 1, searchMenuPosition: 'right',
total: 0, column: [],
}, },
data: [], page: {
columnData:[ pageSize: 10,
{label:'员工工号',prop:'cardNo'}, currentPage: 1,
{label:'姓名',prop:'name'}, total: 0,
] },
} data: [],
columnData: [
{ label: '员工工号', prop: 'cardNo' },
{ label: '姓名', prop: 'name' },
],
};
},
created() {
this.openShow = this.showDetail;
this.onLoad();
},
methods: {
closeDialog(val) {
this.openShow = false;
this.$emit('closeDetail', val);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad();
done();
},
searchReset() {
this.query = {};
this.onLoad();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
}, },
created(){ sizeChange(pageSize) {
this.openShow = this.showDetail this.page.pageSize = pageSize;
this.columnData.map(item =>{ },
this.option.column.push({ refreshChange() {
label:item.label, this.onLoad();
prop:item.prop, },
search:(item.label == '员工工号' || item.label == '姓名') ? true : false onLoad() {
}) this.loading = true;
const params = {
id: this.row.id,
...this.query,
};
detailBsEfficiencyTask(params)
.then(res => {
if (res.data.code === 200) {
this.data = res.data.data.table.tableDataList || [];
const arr = res.data.data.table.tableColumn;
arr.push({ ...arr[0], prop: arr[0].prop + 'Exact', hide: true, search: true });
arr.push({ ...arr[1], prop: arr[1].prop + 'Exact', hide: true, search: true });
res.data.data.table.tableColumn = arr.map(item => ({ ...item, sortable: true }));
this.option.column = res.data.data.table.tableColumn;
} else {
this.data = [];
this.page.total = 0;
}
this.loading = false;
})
.catch(() => {
this.data = [];
this.page.total = 0;
this.loading = false;
});
},
downloadDetail() {
if (!this.row.subTasks || this.row.subTasks.length === 0) {
this.$message.warning('暂无可下载文件!');
return;
}
const completedTasks = this.row.subTasks.filter(task => task.status === 2);
if (completedTasks.length === 0) {
this.$message.warning('暂无可下载文件!');
return;
}
//
downloadBsEfficiencyTaskTemplate()
.then(res => {
downloadXls(res.data, `${this.row.yearMonth}绩效填报模板.xlsx`);
this.row.subTasks.forEach(task => {
if (task.attachLink != '') {
downloadFileBlob(task.attachLink, task.taskName + '.xlsx');
return;
}
});
}) })
this.onLoad() .catch(error => {
console.error('下载模板失败:', error);
this.$message.error('下载失败,请检查网络或稍后重试');
});
}, },
methods:{ downloadSummary() {
closeDialog(val) { this.row.subTasks.forEach(task => {
console.log('3333333333333333333') if (task.attachLink != '') {
this.openShow = false downloadFileBlob(task.attachLink, task.taskName + '.xlsx');
this.$emit('closeDetail',val) return;
},
searchChange(params, done){
this.query = params;
this.page.currentPage = 1
this.onLoad()
done()
},
searchReset(){
this.query = {}
this.onLoad()
},
currentChange(currentPage){
this.page.currentPage = currentPage
},
sizeChange(pageSize){
this.page.pageSize = pageSize
},
refreshChange(){
this.onLoad()
},
onLoad(){
this.data = [
{id:"001",cardNo:"001",name:"张三"},
{id:"002",cardNo:"002",name:"李四"},
{id:"003",cardNo:"003",name:"王五"},
]
this.page.total = this.data.length
} }
} });
} },
},
};
</script> </script>
<style> <style>
</style> </style>

@ -1,93 +1,202 @@
<template> <template>
<el-dialog :title="title" append-to-body :modelValue="openShow" width="70%" @close="closeDialog()"> <el-dialog
<avue-form :title="title"
:option="excelOption" append-to-body
v-model="excelForm" :modelValue="openShow"
:upload-after="uploadAfter" width="70%"
></avue-form> @close="closeDialog()"
<el-button type="primary" v-if="!isDetail" text style="position: absolute;top: 80px;left: 460px;">读取文件</el-button> >
<el-table v-show="isRead && !isDetail" :data="tableData"> <avue-form
<el-table-column :option="excelOption"
type="index" v-model="excelForm"
width="50"> :upload-after="uploadAfter"
</el-table-column> :upload-before="uploadBefore"
<el-table-column v-for="item in tableColumn" :key="item.prop" :label="item.label" :prop="item.prop" align="center"></el-table-column> >
</el-table> <template #readExcel>
<template #footer> <el-button type="primary" @click="readExcel" v-if="!isDetail">
<span class="dialog-footer"> 读取文件<i class="el-icon-download el-icon--right"></i>
<el-button @click="closeDialog"> </el-button> </el-button>
<el-button type="primary" @click="submitForm"> </el-button> </template>
</span> </avue-form>
</template> <el-table v-show="isRead && !isDetail" :data="tableData">
</el-dialog> <el-table-column type="index" width="50" label="序号" />
<el-table-column
v-for="item in tableColumn"
:key="item.prop"
:label="item.label"
:prop="item.prop"
align="center"
/>
</el-table>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</span>
</template>
</el-dialog>
</template> </template>
<script> <script>
import {
readExcelBsEfficiencyTask,
reportBsEfficiencyTask,
subReportBsEfficiencyTask,
} from '@/api/performanceManagement/dataReporting';
export default { export default {
props:{ props: {
title:{ title: {
type:String, type: String,
default:'' default: '',
},
showReport:{
type:Boolean,
default:false
},
isDetail:{
type:Boolean,
default:false
}
}, },
data() { showReport: {
return { type: Boolean,
openShow: false, default: false,
excelOption:{ },
submitBtn: false, isDetail: {
emptyBtn: false, type: Boolean,
column: [ default: false,
{ },
label: '填报文件', row: {
prop: 'excelFile', type: Object,
type: 'upload', default: null,
drag: true, },
loadText: '文件上传中,请稍等', },
span: 24, data() {
propsHttp: { return {
res: 'data', openShow: false,
}, excelForm: {
accept: '.xls,.xlsx', excelFile: [],
tip: '请上传 .xls,.xlsx 标准格式文件,文件最大5M', },
action: '/blade-system/user/import-user', excelOption: {
rules: [ submitBtn: false,
{ emptyBtn: false,
required: true, column: [
message: '请上传文件', {
trigger: 'blur', label: '填报文件',
}, prop: 'excelFile',
], type: 'upload',
}, span: 12,
], limit: 1,
fileSize: 50000,
propsHttp: {
res: 'data',
attachId: 'attachId', // ID
}, },
tableData:[], accept: '.xls,.xlsx',
isRead:true, tip: '请上传 .xls,.xlsx 标准格式文件,文件最大5M',
tableColumn:[ action: '/api/blade-resource/oss/endpoint/put-file-attach',
{label: '员工工号',prop: 'cardNo'}, rules: [
{label: '姓名',prop: 'name'}, {
] required: true,
} message: '请上传文件',
trigger: 'blur',
},
],
},
{
label: '',
prop: 'readExcel',
formslot: true,
span: 12,
},
],
},
tableData: [],
isRead: false,
tableColumn: [
{ label: '员工工号', prop: 'cardNo' },
{ label: '姓名', prop: 'name' },
],
attachId: null,
formData: null,
};
},
created() {
this.openShow = this.showReport;
},
methods: {
closeDialog(val) {
this.openShow = false;
//
this.excelForm = { excelFile: [] };
this.attachId = null;
this.tableData = [];
this.isRead = false;
this.$emit('closeDialog', val);
}, },
created() { //
this.openShow = this.showReport uploadBefore(file, done, loading, column) {
this.formData = file;
done(); //
}, },
methods: { //
closeDialog(val) { uploadAfter(file, done, loading, column) {
this.openShow = false console.log('上传成功返回:', file);
this.$emit('closeDialog',val) // attachId
} this.attachId = file.attachId || file.data?.attachId;
} done();
} },
</script> // Excel
readExcel() {
<style> if (!this.attachId) {
this.$message.warning('请先上传文件');
</style> return;
}
readExcelBsEfficiencyTask({ file: this.formData })
.then(res => {
if (res.data.code === 200) {
this.tableData = res.data.data.tableData || [];
this.tableColumn = res.data.data.tableColumn || [];
this.isRead = true;
this.$message.success('文件读取成功');
} else {
this.$message.error('文件读取失败');
}
})
.catch(() => {
this.$message.error('文件读取接口异常');
});
},
//
submitForm() {
if (!this.attachId) {
this.$message.error('请先上传文件');
return;
}
let params = {};
if (!this.isDetail) {
params = {
id: this.row.id,
attachId: this.attachId,
table: {
tableData: this.tableData,
tableColumn: this.tableColumn,
},
};
reportBsEfficiencyTask(params).then(res => {
if (res.data.code === 200) {
this.$message.success('提交成功');
this.closeDialog(true);
} else {
this.$message.error('提交失败');
}
});
} else {
params = {
id: this.row.id,
attachId: this.attachId,
};
subReportBsEfficiencyTask(params).then(res => {
if (res.data.code === 200) {
this.$message.success('提交成功');
this.closeDialog(true);
} else {
this.$message.error('提交失败');
}
});
}
},
},
};
</script>

@ -17,39 +17,6 @@
@cell-click="cellClick" @cell-click="cellClick"
> >
</avue-crud> </avue-crud>
<!-- 绩效详情弹窗 -->
<el-dialog title="公示详情" v-model="showExcel" append-to-body width="85%">
<div>
月份
<el-date-picker
v-model="monthValue"
type="month"
placeholder="选择月份"
:disabled-date="pickerOptions"
>
</el-date-picker>
<el-button type="primary" style="margin-left: 10px" @click="queryPerformance">
查询
</el-button>
</div>
<el-table :data="detailList" style="margin-top: 10px" border>
<el-table-column align="center" label="KPI得分" prop="KPI" width="75" />
<el-table-column align="center" label="量化得分" prop="lh" width="80" />
<el-table-column align="center" label="订单准时完成率" prop="orderTime" width="130" />
<el-table-column align="center" label="重点零件完成率" prop="keyPoint" width="130" />
<el-table-column align="center" label="后工序审理单分数" prop="after" width="140" />
<el-table-column align="center" label="出厂不合格率DPP" prop="unqualified" width="140" />
<el-table-column align="center" label="成本费用率" prop="costMoney" width="95" />
<el-table-column align="center" label="通报" prop="notice" />
<el-table-column align="center" label="请假扣分" prop="leave" width="80" />
<el-table-column align="center" label="考勤扣分" prop="check" width="80" />
<el-table-column align="center" label="投稿加分项" prop="add" width="100" />
<el-table-column align="center" label="群策群力" prop="all" width="80" />
<el-table-column align="center" label="优秀员工加分" prop="excellence" width="120" />
<el-table-column align="center" label="成本" prop="cost" width="55" />
<el-table-column align="center" label="总分" prop="total" width="55" />
</el-table>
</el-dialog>
</basic-container> </basic-container>
</template> </template>
@ -59,7 +26,6 @@ export default {
name: 'PerformanceDisclosure', name: 'PerformanceDisclosure',
data() { data() {
return { return {
//
showExcel: false, showExcel: false,
monthValue: '', monthValue: '',
// //
@ -75,12 +41,10 @@ export default {
currentPage: 1, currentPage: 1,
total: 0, total: 0,
}, },
//
pickerOptions: time => { pickerOptions: time => {
const year = new Date().getFullYear(); const year = new Date().getFullYear();
return time.getFullYear() !== year; return time.getFullYear() !== year; //
}, },
//
option: { option: {
height: 'auto', height: 'auto',
align: 'center', align: 'center',
@ -243,34 +207,44 @@ export default {
}, },
}; };
}, },
mounted() {
// this.onLoad();
},
methods: { methods: {
// - cellClick(row, column, cell, event) {
cellClick(row, column) { const monthProps = [
const monthMap = { 'm01Score',
m01Score: '01', 'm02Score',
m02Score: '02', 'm03Score',
m03Score: '03', 'm04Score',
m04Score: '04', 'm05Score',
m05Score: '05', 'm06Score',
m06Score: '06', 'm07Score',
m07Score: '07', 'm08Score',
m08Score: '08', 'm09Score',
m09Score: '09', 'm10Score',
m10Score: '10', 'm11Score',
m11Score: '11', 'm12Score',
m12Score: '12', ];
};
const month = monthMap[column.prop]; // if (monthProps.includes(column.property)) {
if (!month) return; // const monthMap = {
// january: '01',
// february: '02',
// march: '03',
// april: '04',
// may: '05',
// june: '06',
// july: '07',
// august: '08',
// september: '09',
// october: '10',
// november: '11',
// december: '12',
// };
// const currentYear = new Date().getFullYear();
// this.monthValue = `${currentYear}-${monthMap[column.property]}`;
//
this.monthValue = `${row.year}-${month}`;
this.showExcel = true; this.showExcel = true;
// // }
this.queryPerformance();
}, },
// //
async queryPerformance() { async queryPerformance() {
@ -324,9 +298,9 @@ export default {
...this.query, ...this.query,
}; };
const res = await pageBsEfficiencyTaskReport(params); const res = await pageBsEfficiencyTaskReport(params);
if (res.code === 200) { if (res.data.code === 200) {
this.data = res.data.records || []; this.data = res.data.data.records || [];
this.page.total = res.data.total || 0; this.page.total = res.data.data.total || 0;
} }
} catch (error) { } catch (error) {
this.$message.error('加载失败'); this.$message.error('加载失败');

Loading…
Cancel
Save