完成网格员、调度员、执法公安页面功能

This commit is contained in:
TS-QD1 2023-05-13 17:26:28 +08:00
parent d809fd9f6a
commit 569a03b7f3
9 changed files with 622 additions and 431 deletions

View File

@ -5,10 +5,10 @@
<n-button type="info" @click="onUpdateClick">更新</n-button>
<span>工作考核细则</span>
<n-button ghost @click="onWgyClick">街道社区4-5级网格</n-button>
<!-- <n-button ghost @click="onDdyClick">区级与街道指挥调度中心调度专管员</n-button> -->
<!-- <n-button ghost @click="onZfGAClick">执法局公安分局</n-button> -->
<!-- <n-button ghost @click="onWgy3Click">3 级网格长</n-button> -->
<!-- <n-button ghost @click="onZnbmClick">其他职能部门</n-button> -->
<n-button ghost @click="onDdyClick">区级与街道指挥调度中心调度专管员</n-button>
<n-button ghost @click="onZfGAClick">执法局公安分局</n-button>
<n-button ghost @click="onWgzClick">3 级网格长</n-button>
<n-button ghost @click="onZnbmClick">其他职能部门</n-button>
</n-space>
</n-layout-header>
<n-layout-content>
@ -85,8 +85,8 @@ const onDdyClick = () => {
const onZfGAClick = () => {
router.push({ name: 'zfga' });
}
const onWgy3Click = () => {
router.push({ name: 'wgy3' });
const onWgzClick = () => {
router.push({ name: 'wgz' });
}
const onZnbmClick = () => {
router.push({ name: 'znbm' });
@ -109,9 +109,9 @@ const checkProcess = () => {
if(percent >= 100) {
clearInterval(checkProcessInterval);
checkProcessInterval = null;
isKpiUpdatProgressModalShow.value = false;
// isKpiUpdatProgressModalShow.value = false;
} else {
isKpiUpdatProgressModalShow.value = true;
// isKpiUpdatProgressModalShow.value = true;
}
}).catch((resp) => {
console.error(resp)

View File

@ -21,6 +21,20 @@ export default {
NSpace,
NDataTable,
},
props: {
userId: {
required: true,
},
userName: {
required: true,
},
year: {
required: true,
},
month: {
required: true
}
},
data() {
let vueSelf = this;
return {
@ -28,37 +42,37 @@ export default {
columns: [
{
align: 'center',
title: '张三2023年1月考勤得分明细表',
title: `${vueSelf.userName}${vueSelf.year}${vueSelf.month}月考勤得分明细表`,
key: 'title',
children: [
{
align: 'center',
title: '月',
key: 'month',
width: 60,
},
{
align: 'center',
title: '日',
key: 'day',
title: '日期',
key: 'dayDate',
width: 60,
},
{
align: 'center',
title: '签到',
key: 'signIn',
key: 'isSignin',
width: 60,
render(row, index) {
return row.isSignin === 0 ? '否' : '是';
}
},
{
align: 'center',
title: '签退',
key: 'signOut',
key: 'isSignout',
width: 60,
render(row, index) {
return row.isSignout === 0 ? '否' : '是';
}
},
{
align: 'center',
title: '总分',
key: 'score',
key: 'dayScore',
width: 60,
},
{
@ -66,6 +80,9 @@ export default {
title: '备注',
key: 'remark',
width: 100,
render(row, index) {
return row.isHoliday === 1 ? '法定假期' : '工作日';
}
}
]
}
@ -75,20 +92,39 @@ export default {
}
},
methods: {
init() {
let vueSelf = this;
vueSelf.$axios.get(`api/kpi/list-n-person-case-day-count/user-id/${vueSelf.userId}`, {
params: {
year: vueSelf.year,
month: vueSelf.month
}
}).then(({data}) => {
let dayScoreTotal = 0;
let signinCount = 0;
let signinLateCount = 0;
let signoutCount = 0;
let signoutEarlyCount = 0;
let workDay = 0;
data.forEach(item => {
dayScoreTotal += item.dayScore;
signinCount += item.isSignin;
signinLateCount += item.isSigninLate;
signoutCount += item.isSignout;
signoutEarlyCount += item.isSignoutEarly;
if(item.isHoliday === 0) {
workDay++;
}
});
console.log(dayScoreTotal, workDay)
vueSelf.table.data = data;
}).catch(({ data }) => {
vueSelf.message.error(data.msg);
});
},
},
mounted() {
let data = [];
for(var i = 0; i < 100; i++) {
data.push({
month: 12,
day: 1,
signIn: 1,
signOut: 1,
remark: '123'
})
}
this.table.data = data;
this.init();
}
}
</script>

View File

@ -21,6 +21,20 @@ export default {
NSpace,
NDataTable,
},
props: {
userId: {
required: true,
},
userName: {
required: true,
},
year: {
required: true,
},
month: {
required: true
}
},
data() {
let vueSelf = this;
return {
@ -28,37 +42,37 @@ export default {
columns: [
{
align: 'center',
title: '张三2023年1月考勤得分明细表',
title: `${vueSelf.userName}${vueSelf.year}${vueSelf.month}考勤得分明细表`,
key: 'title',
children: [
{
align: 'center',
title: '月',
key: 'month',
width: 60,
},
{
align: 'center',
title: '日',
key: 'day',
title: '日期',
key: 'dayDate',
width: 60,
},
{
align: 'center',
title: '签到',
key: 'signIn',
key: 'isSignin',
width: 60,
render(row, index) {
return row.isSignin === 0 ? '否' : '是';
}
},
{
align: 'center',
title: '签退',
key: 'signOut',
key: 'isSignout',
width: 60,
render(row, index) {
return row.isSignout === 0 ? '否' : '是';
}
},
{
align: 'center',
title: '总分',
key: 'score',
key: 'dayScore',
width: 60,
},
{
@ -66,6 +80,9 @@ export default {
title: '备注',
key: 'remark',
width: 100,
render(row, index) {
return row.isHoliday === 1 ? '法定假期' : '工作日';
}
}
]
}
@ -75,20 +92,39 @@ export default {
}
},
methods: {
init() {
let vueSelf = this;
vueSelf.$axios.get(`api/kpi/list-n-person-case-day-count/user-id/${vueSelf.userId}`, {
params: {
year: vueSelf.year,
month: vueSelf.month
}
}).then(({data}) => {
let dayScoreTotal = 0;
let signinCount = 0;
let signinLateCount = 0;
let signoutCount = 0;
let signoutEarlyCount = 0;
let workDay = 0;
data.forEach(item => {
dayScoreTotal += item.dayScore;
signinCount += item.isSignin;
signinLateCount += item.isSigninLate;
signoutCount += item.isSignout;
signoutEarlyCount += item.isSignoutEarly;
if(item.isHoliday === 0) {
workDay++;
}
});
console.log(dayScoreTotal, workDay)
vueSelf.table.data = data;
}).catch(({ data }) => {
vueSelf.message.error(data.msg);
});
},
},
mounted() {
let data = [];
for(var i = 0; i < 100; i++) {
data.push({
month: 12,
day: 1,
signIn: 1,
signOut: 1,
remark: '123'
})
}
this.table.data = data;
this.init();
}
}
</script>

View File

@ -1,45 +1,41 @@
<template>
<n-space class="container" vertical>
<n-space justify="center">
<h1>区级与街道指挥调度中心调度专管员网格化工作考核细则以季度为考核周期</h1>
<n-spin :show="dataLoading">
<n-space class="container" vertical>
<n-space justify="center">
<h1>区级与街道指挥调度中心调度专管员网格化工作考核细则以季度为考核周期</h1>
</n-space>
<n-space class="search" vertical>
<n-grid :cols="7" :x-gap="10">
<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>
<n-data-table :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-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">搜索</n-button>
<n-button type="info">导出</n-button>
</n-space>
</n-grid-item>
</n-grid>
</n-space>
<n-space>
<n-data-table :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: 800px" :show="modal.sign.show" :show-icon="false" :mask-closable="true"
:closable="false" :on-update-show="onSignCloseClick">
<ddy-work />
<ddy-work :user-id="search.userId" :user-name="search.userName" :year="search.select.year.value"
:month="search.select.month.value"/>
</n-modal>
<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"
@ -61,9 +57,13 @@ import {
NInput,
NButton,
NModal,
NSpin,
useMessage,
useDialog,
} from 'naive-ui';
import Scoring from '../common/Scoring.vue';
import DdyWork from '../common/DdyWork.vue';
import { listYear, listMonth, getCurrentYear, getCurrentMonth, download } from '../utils/common'
export default {
name: 'Ddy',
@ -76,6 +76,7 @@ export default {
NInput,
NButton,
NModal,
NSpin,
DdyWork,
Scoring,
@ -83,21 +84,14 @@ export default {
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: [
@ -318,6 +312,8 @@ export default {
//
onSignClick(row, index) {
let sign = row.C;
this.search.userId = row.userId;
this.search.userName = row.B;
this.modal.sign.show = true;
},
//
@ -383,63 +379,88 @@ export default {
this.modal.scoring.title = '组织评价';
},
computeK(row) {
return row.C + row.D - row.F - row.G - row.H - row.I + row.J;
return Math.max(row.C + row.D - row.F - row.G - row.H - row.I + row.J, 0);
},
listTestData() {
let data = [];
for (let i = 0; i < 100; i++) {
let d = {
userId: 'userId',
key: i + 1,
name: i + 'name',
sign: i,
baseScore: Math.floor(Math.random() * 100),
dispatchCaseCount: 30,
dispatchCaseDeductPoints: 2,
shouldButNo: Math.floor(Math.random() * 10),
reasonShouldButNo: '',
timeout: Math.floor(Math.random() * 10),
reasonTimeout: '',
others: Math.floor(Math.random() * 10),
reasonOthers: '',
orgEvalution: Math.floor(Math.random() * 10),
reasonOrgEvalution: '',
totalScore: Math.floor(Math.random() * 10),
shouldPay: Math.floor(Math.random() * 10),
actualPay: Math.floor(Math.random() * 10),
onSearchClick() {
this.listData();
},
onSaveClick() {
let vueSelf = this;
let tableDatas = [];
vueSelf.table.data.forEach(item => {
item.K = vueSelf.computeK(item);
item.M = (item.K * item.L / 100).toFixed(2);
tableDatas.push({...item});
})
vueSelf.dialog.warning({
title: "提示",
content: "确定更新吗?",
positiveText: "确定",
negativeText: "取消",
onPositiveClick: () => {
vueSelf.dataLoading = true;
vueSelf.$axios.put(`api/kpi/khxz/update-ddy`, {
datas: tableDatas
}).then( resp => {
vueSelf.message.info('保存成功');
}).catch( ({data}) => {
console.error(resp);
vueSelf.message.error(data.data.msg);
}).finally(() => {
vueSelf.dataLoading = false;
});
},
onNegativeClick: () => {
}
data.push({
A: d.key,
B: d.name,
C: d.sign,
D: d.baseScore,
E: d.dispatchCaseCount,
F: d.dispatchCaseDeductPoints,
G: d.shouldButNo,
reasonG: d.reasonShouldButNo,
H: d.timeout,
reasonH: d.reasonTimeout,
I: d.others,
reasonI: d.reasonOthers,
J: d.orgEvalution,
reasonJ: d.reasonOrgEvalution,
K: d.totalScore,
L: d.shouldPay,
M: d.actualPay,
});
})
},
onExportClick() {
let vueSelf = this;
vueSelf.btnExportDisabled = true;
download(vueSelf.$axios, `api/kpi/khxz/export-ddy`, vueSelf.getQuery(), () => {
vueSelf.btnExportDisabled = false;
});
},
getQuery() {
return {
khYear: this.search.select.year.value,
khMonth: this.search.select.month.value,
keywords: this.search.input.keywords
}
this.table.data = data;
},
listData() {
let vueSelf = this;
vueSelf.dataLoading = true;
vueSelf.$axios.get(`api/kpi/khxz/list-ddy`, {
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;
});
},
resize() {
let body = document.body;
this.table.minHeight = body.clientHeight - 365;
this.table.maxHeight = body.clientHeight - 365;
this.table.scrollX = body.clientWidth;
// this.table.scrollX = body.clientWidth;
},
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.listTestData();
vueSelf.init();
vueSelf.resize();
window.onresize = this.resize;
}

View File

@ -937,6 +937,13 @@ export default {
}
})
},
onExportClick() {
let vueSelf = this;
vueSelf.btnExportDisabled = true;
download(vueSelf.$axios, `api/kpi/khxz/export-wgy`, vueSelf.getQuery(), () => {
vueSelf.btnExportDisabled = false;
});
},
getQuery() {
return {
areaId: this.search.select.area.value,
@ -947,13 +954,6 @@ export default {
keywords: this.search.input.keywords
}
},
onExportClick() {
let vueSelf = this;
vueSelf.btnExportDisabled = true;
download(vueSelf.$axios, `api/kpi/khxz/export-wgy`, vueSelf.getQuery(), () => {
vueSelf.btnExportDisabled = false;
});
},
resize() {
let body = document.body;
this.table.minHeight = body.clientHeight - 408;

View File

@ -1,42 +1,45 @@
<template>
<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">搜索</n-button>
<n-button type="info">导出</n-button>
</n-space>
</n-grid-item>
</n-grid>
<n-spin :show="dataLoading">
<n-space justify="center">
<h1>级网格长网格化工作考核细则以季度为考核周期</h1>
</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 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-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">
@ -59,8 +62,12 @@ import {
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',
@ -74,13 +81,20 @@ export default {
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,
@ -363,65 +377,86 @@ export default {
computeN(row) {
return row.C - row.E + row.L + row.M
},
listTestData() {
let data = [];
for (let i = 0; i < 100; i++) {
let d = {
userId: 'userId',
key: i + 1,
name: i + 'name',
signBaseScore: i,
signUnPassCount: Math.floor(Math.random() * 100),
signUnPassScore: 30,
gridBaseScore: 2,
gridUnPassCount: Math.floor(Math.random() * 10),
gridUnPassScore: Math.floor(Math.random() * 10),
unComplete: Math.floor(Math.random() * 10),
unReportError: Math.floor(Math.random() * 10),
reasonUnReportError: '',
others: Math.floor(Math.random() * 10),
reasonOthers: '',
unComplete: Math.floor(Math.random() * 10),
reasonUnComplete: '',
quarter: Math.floor(Math.random() * 10),
totalScore: Math.floor(Math.random() * 10),
shouldPay: Math.floor(Math.random() * 10),
actualPay: Math.floor(Math.random() * 10),
}
data.push({
A: d.key,
B: d.name,
C: d.signBaseScore,
D: d.signUnPassCount,
E: d.signUnPassScore,
F: d.gridBaseScore,
G: d.gridUnPassCount,
H: d.gridUnPassScore,
I: d.unComplete,
J: d.unReportError,
reasonJ: d.reasonUnReportError,
K: d.others,
reasonK: d.reasonOthers,
L: d.unComplete,
reasonL: d.reasonUnComplete,
M: d.quarter,
N: d.totalScore,
O: d.shouldPay,
P: d.actualPay,
});
}
this.table.data = data;
},
resize() {
let body = document.body;
this.table.minHeight = body.clientHeight - 355;
this.table.maxHeight = body.clientHeight - 355;
this.table.scrollX = body.clientWidth;
// 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.listTestData();
vueSelf.init();
vueSelf.resize();
window.onresize = this.resize
}

View File

@ -1,45 +1,45 @@
<template>
<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">搜索</n-button>
<n-button type="info">导出</n-button>
</n-space>
</n-grid-item>
</n-grid>
<n-spin :show="dataLoading">
<n-space justify="center">
<h1>执法局公安分局网格化工作考核细则以季度为考核周期</h1>
</n-space>
<n-space>
<n-data-table :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 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.department.value"
:options="search.select.department.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>
<n-data-table :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-space>
</n-spin>
<n-modal preset="dialog" style="width: 800px" :show="modal.sign.show" :show-icon="false" :mask-closable="true"
:closable="false" :on-update-show="onSignCloseClick">
<zf-ga-work />
<zf-ga-work :user-id="search.userId" :user-name="search.userName" :year="search.select.year.value"
:month="search.select.month.value"/>
</n-modal>
<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"
@ -61,9 +61,14 @@ import {
NInput,
NButton,
NModal,
NSpin,
useMessage,
useDialog,
} from 'naive-ui';
import Scoring from '../common/Scoring.vue';
import ZfGaWork from '../common/ZfGaWork.vue';
import { listYear, listMonth, getCurrentYear, getCurrentMonth, download } from '../utils/common'
export default {
name: 'ZfGa',
@ -76,6 +81,7 @@ export default {
NInput,
NButton,
NModal,
NSpin,
Scoring,
ZfGaWork,
@ -83,12 +89,19 @@ export default {
data() {
let vueSelf = this;
return {
message: useMessage(),
dialog: useDialog(),
dataLoading: false,
btnExportDisabled: false,
search: {
userId: null,
userName: null,
select: {
street: {
department: {
value: null,
options: [
{ label: '稀土路街道', value: 'xtl' }
{ label: '执法局', value: '1d74dfc8-f3a3-4517-87fe-7acf7891bab4' },
{ label: '公安分局', value: '2da5c4db-209b-4c28-bf35-153535fdfc78' }
]
},
community: {
@ -344,6 +357,8 @@ export default {
//
onSignClick(row, index) {
let sign = row.C;
this.search.userId = row.userId;
this.search.userName = row.B;
this.modal.sign.show = true;
},
//
@ -435,71 +450,89 @@ export default {
this.modal.scoring.title = '督察案件结案情况';
},
computeM(row) {
return row.C - row.G - row.H - row.I - row.J - row.K - row.L;
},
listTestData() {
let data = [];
for (let i = 0; i < 100; i++) {
let d = {
userId: 'userId',
key: i + 1,
name: i + 'name',
sign: i,
unCheck: Math.floor(Math.random() * 100),
checked: 30,
reward: 2,
backTimeout: Math.floor(Math.random() * 10),
reasonBackTimeout: '',
selfUnHandle: Math.floor(Math.random() * 10),
reasonSelfUnHandle: '',
unHandleError: Math.floor(Math.random() * 10),
reasonUnHandleError: '',
others: Math.floor(Math.random() * 10),
reasonOthers: '',
handleReasonOthers: Math.floor(Math.random() * 10),
reasonHandleResult: '',
superviseResult: Math.floor(Math.random() * 10),
reasonSuperviseResult: '',
totalScore: Math.floor(Math.random() * 10),
shouldPay: Math.floor(Math.random() * 10),
actualPay: Math.floor(Math.random() * 10),
}
data.push({
A: d.key,
B: d.name,
C: d.sign,
D: d.unCheck,
E: d.checked,
F: d.reward,
G: d.backTimeout,
reasonG: d.reasonBackTimeout,
H: d.selfUnHandle,
reasonH: d.reasonSelfUnHandle,
I: d.unHandleError,
reasonI: d.reasonUnHandleError,
J: d.others,
reasonJ: d.reasonOthers,
K: d.handleReasonOthers,
reasonJ: d.reasonHandleResult,
L: d.superviseResult,
reasonL: d.reasonSuperviseResult,
M: d.totalScore,
N: d.shouldPay,
O: d.actualPay,
});
}
this.table.data = data;
return Math.max(row.C - row.G - row.H - row.I - row.J - row.K - row.L, 0);
},
resize() {
let body = document.body;
this.table.minHeight = body.clientHeight - 379;
this.table.maxHeight = body.clientHeight - 379;
this.table.scrollX = body.clientWidth;
// this.table.scrollX = body.clientWidth;
},
onSearchClick() {
this.listData();
},
onSaveClick() {
let vueSelf = this;
let tableDatas = [];
vueSelf.table.data.forEach(item => {
item.M = vueSelf.computeM(item);
item.O = (item.M * item.N / 100).toFixed(2);
tableDatas.push({...item});
})
vueSelf.dialog.warning({
title: "提示",
content: "确定更新吗?",
positiveText: "确定",
negativeText: "取消",
onPositiveClick: () => {
vueSelf.dataLoading = true;
vueSelf.$axios.put(`api/kpi/khxz/update-zf-ga/`, {
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-zf-ga`, vueSelf.getQuery(), () => {
vueSelf.btnExportDisabled = false;
});
},
getQuery() {
return {
departmentId: this.search.select.department.value,
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-zf-ga`, {
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.listTestData();
vueSelf.init();
vueSelf.resize();
window.onresize = this.resize
}

View File

@ -1,42 +1,45 @@
<template>
<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">搜索</n-button>
<n-button type="info">导出</n-button>
</n-space>
</n-grid-item>
</n-grid>
<n-spin :show="dataLoading">
<n-space justify="center">
<h1>其他职能部门网格化工作考核细则以季度为考核周期</h1>
</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 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-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">
@ -58,8 +61,12 @@ import {
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: 'Znbm',
@ -73,13 +80,20 @@ export default {
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,
@ -383,67 +397,83 @@ export default {
computeN(row) {
return row.G - row.H - row.J - row.K + row.L + row.M;
},
listTestData() {
let data = [];
for (let i = 0; i < 100; i++) {
let d = {
userId: 'userId',
key: i + 1,
name: i + 'name',
caseCount: i,
handleCheck: Math.floor(Math.random() * 100),
handleUnCheck: 30,
reward: 2,
unBackError: Math.floor(Math.random() * 10),
reasonUnBackError: '',
selfReportUnComplete: Math.floor(Math.random() * 10),
selfReportUnCompleteDeduct: Math.floor(Math.random() * 10),
others: Math.floor(Math.random() * 10),
reasonOthers: '',
handleResult: Math.floor(Math.random() * 10),
reasonHandleResult: '',
superviseResult: Math.floor(Math.random() * 10),
reasonSuperviseResult: '',
totalScore: Math.floor(Math.random() * 10),
shouldPay: Math.floor(Math.random() * 10),
actualPay: Math.floor(Math.random() * 10),
}
data.push({
A: d.key,
B: d.name,
C: d.caseCount,
D: d.handleCheck,
E: d.handleUnCheck,
F: d.reward,
G: d.unBackError,
reasonG: d.reasonUnBackError,
H: d.selfReportUnComplete,
I: d.selfReportUnCompleteDeduct,
J: d.others,
reasonJ: d.reasonOthers,
K: d.handleResult,
reasonK: d.reasonHandleResult,
L: d.superviseResult,
reasonL: d.reasonSuperviseResult,
M: d.superviseResult,
reasonM: d.reasonSuperviseResult,
N: d.totalScore,
O: d.shouldPay,
P: d.actualPay,
});
}
this.table.data = data;
},
resize() {
let body = document.body;
this.table.minHeight = body.clientHeight - 378;
this.table.maxHeight = body.clientHeight - 378;
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-znbm`, {
params: vueSelf.getQuery()
}).then(({ data }) => {
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.listTestData();
vueSelf.init();
vueSelf.resize();
window.onresize = this.resize
}

View File

@ -7,7 +7,7 @@ import axios from 'axios';
import Wgy from './components/table/Wgy.vue';
import Ddy from './components/table/Ddy.vue';
import ZfGa from './components/table/ZfGa.vue';
import Wgy3 from './components/table/Wgy3.vue';
import Wgz from './components/table/Wgz.vue';
import Znbm from './components/table/Znbm.vue';
// 路由
@ -17,7 +17,7 @@ const router = createRouter({
{ name: 'wgy', path: '/', component: Wgy },
{ name: 'ddy', path: '/ddy', component: Ddy },
{ name: 'zfga', path: '/zfga', component: ZfGa },
{ name: 'wgy3', path: '/wgy3', component: Wgy3 },
{ name: 'wgz', path: '/wgz', component: Wgz },
{ name: 'znbm', path: '/znbm', component: Znbm },
]
});