bt-xtgxq-system-bigdata-exa.../src/components/table/Wgz.vue

473 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<n-spin :show="dataLoading">
<n-space justify="center">
<h1>级网格长网格化工作考核细则以季度为考核周期</h1>
</n-space>
<n-space class="container" vertical>
<n-space class="search" vertical>
<n-grid :cols="7" :x-gap="10">
<n-grid-item>
<n-select placeholder="请选择街道" v-model:value="search.select.street.value"
:options="search.select.street.options" :clearable="true" />
</n-grid-item>
<n-grid-item>
<n-select placeholder="请选择社区" v-model:value="search.select.community.value"
:options="search.select.community.options" :clearable="true" />
</n-grid-item>
<n-grid-item>
<n-input v-model:value="search.input.keywords" type="text" placeholder="姓名|手机号" />
</n-grid-item>
<n-grid-item>
<n-select placeholder="请选择年份" v-model:value="search.select.year.value"
:options="search.select.year.options" :clearable="true" />
</n-grid-item>
<n-grid-item>
<n-select placeholder="请选择月份" v-model:value="search.select.month.value"
:options="search.select.month.options" :clearable="true" />
</n-grid-item>
<n-grid-item>
<n-space>
<n-button type="primary" @click="onSearchClick">搜索</n-button>
<n-button type="default" @click="onSaveClick">保存</n-button>
<n-button type="info" @click="onExportClick" :disabled="btnExportDisabled">导出</n-button>
</n-space>
</n-grid-item>
</n-grid>
</n-space>
<n-space class="body">
<n-data-table size="small" :columns="table.columns" :data="table.data" :bordered="true" :single-line="false"
:min-height="table.minHeight" :max-height="table.maxHeight" :scroll-x="table.scrollX" />
</n-space>
</n-space>
</n-spin>
<n-modal preset="dialog" style="width: 600px" :title="`【${modal.scoring.userName}】${modal.scoring.title}打分`"
:show="modal.scoring.show" :show-icon="false" :mask-closable="true" :closable="false"
:on-update-show="onScroingCloseClick">
<scoring :row-key="modal.scoring.rowKey" :row-index="modal.scoring.rowIndex" :score="modal.scoring.score"
:reason="modal.scoring.reason" :min-score="modal.scoring.minScore" :max-score="modal.scoring.maxScore"
@confirm="onScroingConfimClick" />
</n-modal>
</template>
<script>
import { h } from 'vue';
import {
NSpace,
NGrid,
NGridItem,
NSelect,
NRadio,
NInput,
NButton,
NDataTable,
NModal,
NSpin,
useMessage,
useDialog,
} from 'naive-ui';
import Scoring from '../common/Scoring.vue';
import { listYear, listMonth, getCurrentYear, getCurrentMonth, download } from '../utils/common'
export default {
name: 'Wgy3',
components: {
NSpace,
NGrid,
NGridItem,
NSelect,
NRadio,
NInput,
NButton,
NDataTable,
NModal,
NSpin,
Scoring,
},
data() {
let vueSelf = this;
return {
message: useMessage(),
dialog: useDialog(),
dataLoading: false,
btnExportDisabled: false,
search: {
userId: null,
userName: null,
select: {
street: {
value: null,
options: [
{ label: '稀土路街道', value: 'xtl' }
]
},
community: {
value: null,
options: [
{ label: '社区', value: 'sq' }
]
},
year: {
value: null,
options: [
{ label: '2023年', value: '2023' }
]
},
month: {
value: null,
options: [
{ label: '1月', value: '1' }
]
}
},
radio: {
level: {
value: 5,
}
},
input: {
keywords: ''
}
},
table: {
minHeight: 300,
maxHeight: 300,
scrollX: 900,
columns: [
{
align: 'center',
title: '序号',
key: 'A',
keyName: 'key',
fixed: 'left',
width: 60
},
{
align: 'center',
title: '姓名',
key: 'B',
keyName: 'name',
fixed: 'left',
width: 140
},
{
align: 'center',
title: '网格签到巡片情况',
children: [
{
align: 'center',
title: '基础分值',
key: 'C',
keyName: 'signBaseScore',
width: 60
},
{
align: 'center',
title: '不合格人员数',
key: 'E',
keyName: 'signUnPassCount',
width: 60
},
{
align: 'center',
title: '不合格扣分',
key: 'E',
keyName: 'signUnPassScore',
width: 60
},
]
},
{
align: 'center',
title: '网格案件调度情况',
children: [
{
align: 'center',
title: '基础分值',
key: 'F',
keyName: 'gridBaseScore',
width: 60
},
{
align: 'center',
title: '案件报送数量',
children: [
{
align: 'center',
title: '不合格人员数',
key: 'G',
keyName: 'gridUnPassCount',
width: 60
},
{
align: 'center',
title: '不合格扣分',
key: 'H',
keyName: 'gridUnPassScore',
width: 60
},
]
},
{
align: 'center',
title: '案件受理过程质量',
children: [
{
align: 'center',
title: '没完成办理流程',
key: 'I',
keyName: 'unComplete',
width: 60
},
{
align: 'center',
title: '未上报案件造成严重影响',
key: 'J',
keyName: 'unReportError',
width: 60,
render(row, index) {
return h('a', {
href: 'javascript:void(0);',
onClick() {
vueSelf.onUnReportErrorClick(row, index);
}
}, row.J);
}
},
{
align: 'center',
title: '其它情况',
key: 'K',
keyName: 'others',
width: 60,
render(row, index) {
return h('a', {
href: 'javascript:void(0);',
onClick() {
vueSelf.onOthersClick(row, index);
}
}, row.K);
}
},
]
},
{
align: 'center',
title: '网格案件调度情况得分',
key: 'L',
keyName: 'unComplete',
width: 60
},
]
},
{
align: 'center',
title: '网格工作季度考核',
key: 'M',
keyName: 'quarter',
width: 60,
render(row, index) {
return h('a', {
href: 'javascript:void(0);',
onClick() {
vueSelf.onQuarterClick(row, index);
}
}, row.M);
}
},
{
align: 'center',
title: '总得分',
key: 'N',
keyName: 'totalScore',
fixed: 'right',
width: 60,
render(row, index) {
return vueSelf.computeN(row);
}
},
{
align: 'center',
title: '应发绩效工资',
key: 'O',
keyName: 'shouldPay',
fixed: 'right',
width: 60
},
{
align: 'center',
title: '实发绩效工资',
key: 'P',
keyName: 'actualPay',
fixed: 'right',
width: 60,
render(row, index) {
return vueSelf.computeN(row) * row.O / 100;
}
}
],
data: []
},
modal: {
scoring: {
show: false,
userName: null,
title: null,
rowKey: null,
rowIndex: null,
score: 0,
reason: '',
minScore: null,
maxScore: null
}
}
}
},
methods: {
// 打分确定
onScroingConfimClick(key, index, { score, reason, userId, userName, date }) {
this.modal.scoring.show = false;
this.table.data[index][key] = score;
this.table.data[index][`reason${key}`] = reason;
},
// 打分关闭
onScroingCloseClick() {
this.modal.scoring.show = false;
},
// 未上报案件造成严重影响 -
onUnReportErrorClick(row, index) {
let unReportError = row.J;
this.modal.scoring.show = true;
this.modal.scoring.rowKey = 'J';
this.modal.scoring.rowIndex = index;
this.modal.scoring.score = unReportError;
this.modal.scoring.reason = row.reasonJ;
this.modal.scoring.maxScore = null;
this.modal.scoring.minScore = null;
this.modal.scoring.userName = row.B;
this.modal.scoring.title = '未上报案件造成严重影响';
},
// 其它情况 -
onOthersClick(row, index) {
let others = row.K;
this.modal.scoring.show = true;
this.modal.scoring.rowKey = 'K';
this.modal.scoring.rowIndex = index;
this.modal.scoring.score = others;
this.modal.scoring.reason = row.reasonK;
this.modal.scoring.maxScore = null;
this.modal.scoring.minScore = null;
this.modal.scoring.userName = row.B;
this.modal.scoring.title = '其它情况';
},
// 网格工作季度考核 +
onQuarterClick(row, index) {
let quarter = row.M;
this.modal.scoring.show = true;
this.modal.scoring.rowKey = 'M';
this.modal.scoring.rowIndex = index;
this.modal.scoring.score = quarter;
this.modal.scoring.reason = row.reasonM;
this.modal.scoring.maxScore = 30;
this.modal.scoring.minScore = 0;
this.modal.scoring.userName = row.B;
this.modal.scoring.title = '网格工作季度考核';
},
computeN(row) {
return row.C - row.E + row.L + row.M
},
resize() {
let body = document.body;
this.table.minHeight = body.clientHeight - 355;
this.table.maxHeight = body.clientHeight - 355;
// this.table.scrollX = body.clientWidth;
},
onSearchClick() {
this.listData();
},
onSaveClick() {
let vueSelf = this;
let tableDatas = [];
vueSelf.table.data.forEach(item => {
item.AE = vueSelf.computeAE(item);
item.AG = (item.AE * item.AF / 100).toFixed(2);
tableDatas.push({...item});
})
vueSelf.dialog.warning({
title: "提示",
content: "确定更新吗?",
positiveText: "确定",
negativeText: "取消",
onPositiveClick: () => {
vueSelf.dataLoading = true;
vueSelf.$axios.put(`api/kpi/khxz/update-wgy/${vueSelf.search.select.wgy.value}`, {
datas: tableDatas
}).then( resp => {
vueSelf.message.info('保存成功');
}).catch( ({data}) => {
console.error(resp);
vueSelf.message.error(data.data.msg);
}).finally(() => {
vueSelf.dataLoading = false;
});
},
onNegativeClick: () => {
}
})
},
onExportClick() {
let vueSelf = this;
vueSelf.btnExportDisabled = true;
download(vueSelf.$axios, `api/kpi/khxz/export-wgy`, vueSelf.getQuery(), () => {
vueSelf.btnExportDisabled = false;
});
},
getQuery() {
return {
khYear: this.search.select.year.value,
khMonth: this.search.select.month.value,
keywords: this.search.input.keywords
}
},
listData() {
let vueSelf = this;
vueSelf.dataLoading = true;
vueSelf.$axios.get(`api/kpi/khxz/list-wgz`, {
params: vueSelf.getQuery()
}).then(({ data }) => {
data.forEach((item, index) => {
item.A = index + 1;
})
this.table.data = data;
}).catch(({ data }) => {
vueSelf.message.error(data.msg);
}).finally(() => {
vueSelf.dataLoading = false;
});
},
init() {
this.search.select.year.options = listYear();
this.search.select.year.value = getCurrentYear();
this.search.select.month.options = listMonth();
this.search.select.month.value = getCurrentMonth();
this.listData();
}
},
mounted() {
let vueSelf = this;
vueSelf.init();
vueSelf.resize();
window.onresize = this.resize
}
}
</script>
<style lang="stylus" scoped>
.container
padding 0 10px
:deep(.score-plus)
background-color yellow
:deep(.score-minus)
background-color red
</style>