sc
This commit is contained in:
31
src/api/kpi/score.js
Normal file
31
src/api/kpi/score.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// 打分数据
|
||||||
|
export const getKpiEmployees = (params) => {
|
||||||
|
return request.get({ url: '/admin-api/oa/examine-score/getExamineUserExamineScore', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存考勤打分数据
|
||||||
|
export const saveKpiScore = (data) => {
|
||||||
|
return request.put({ url: '/admin-api/oa/examine-score/update', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除考核项
|
||||||
|
export const deleteKpiItem = (params) => {
|
||||||
|
return request.delete({ url: '/admin-api/oa/examine-score/delete', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 考评分页数据
|
||||||
|
export const getScorePage = (params) => {
|
||||||
|
return request.get({ url: '/admin-api/oa/examine-period/page', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 封存
|
||||||
|
export const saveScoreRecord = (params) => {
|
||||||
|
return request.get({ url: '/admin-api/oa/examine-period/confirm', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询周期是否已封存
|
||||||
|
export const getKpiPeriodStatus = (params) => {
|
||||||
|
return request.get({ url: '/admin-api/oa/examine-period/getExaminePeriodByPeriod', params })
|
||||||
|
}
|
||||||
@@ -23,9 +23,13 @@
|
|||||||
<el-col :span="24" :offset="0">
|
<el-col :span="24" :offset="0">
|
||||||
<el-form-item label="模式" prop="type">
|
<el-form-item label="模式" prop="type">
|
||||||
<el-radio-group v-model="form.type">
|
<el-radio-group v-model="form.type">
|
||||||
<el-radio :label="1"> 加总分 </el-radio>
|
<el-radio
|
||||||
<el-radio :label="2"> 减总分 </el-radio>
|
v-for="(item, index) in prop.kpiModeOoptions"
|
||||||
<el-radio :label="3"> 权重分 </el-radio>
|
:key="index"
|
||||||
|
:label="item.value"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -108,7 +112,13 @@
|
|||||||
|
|
||||||
<script setup name="DialogAppraise">
|
<script setup name="DialogAppraise">
|
||||||
import * as KpiApi from '@/api/kpi/index.js'
|
import * as KpiApi from '@/api/kpi/index.js'
|
||||||
import { getGeneralSysDictData } from '@/api/system/dict/dict.data'
|
|
||||||
|
const prop = defineProps({
|
||||||
|
kpiModeOoptions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
@@ -144,22 +154,18 @@ async function open(type, val) {
|
|||||||
isIndeterminate.value = checkedCount > 0 && checkedCount < employeeOptions.value.length
|
isIndeterminate.value = checkedCount > 0 && checkedCount < employeeOptions.value.length
|
||||||
}
|
}
|
||||||
|
|
||||||
const kpiModeOoptions = ref([])
|
|
||||||
function getOptions() {
|
function getOptions() {
|
||||||
KpiApi.getKpiEmployees().then((data) => {
|
KpiApi.getKpiEmployees().then((data) => {
|
||||||
employeeOptions.value = data
|
employeeOptions.value = data
|
||||||
handleCheckAllChange(true)
|
handleCheckAllChange(true)
|
||||||
checkAll.value = true
|
checkAll.value = true
|
||||||
})
|
})
|
||||||
getGeneralSysDictData('message_type').then((data) => {
|
|
||||||
kpiModeOoptions.value = data
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
form.value = {
|
form.value = {
|
||||||
examineTarget: '',
|
examineTarget: '',
|
||||||
type: 4,
|
type: '3',
|
||||||
weight: 0,
|
weight: 0,
|
||||||
examineContent: ``,
|
examineContent: ``,
|
||||||
examineRule: ``,
|
examineRule: ``,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<el-table v-loading="loading" :data="list" border>
|
<el-table v-loading="loading" :data="list" border>
|
||||||
<el-table-column prop="examineTarget" label="考核指标" width="180" />
|
<el-table-column prop="examineTarget" label="考核指标" width="180" />
|
||||||
<el-table-column prop="type" label="分值模式" width="90" />
|
<el-table-column prop="type" label="分值模式" width="90" :formatter="getKpiModeLabel" />
|
||||||
<el-table-column prop="weight" label="权重%" width="90" />
|
<el-table-column prop="weight" label="权重%" width="90" />
|
||||||
<el-table-column label="考核内容">
|
<el-table-column label="考核内容">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DialogAppraise ref="formRef" @success="handleQuery" />
|
<DialogAppraise ref="formRef" :kpiModeOoptions="kpiModeOoptions" @success="handleQuery" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -77,6 +77,7 @@
|
|||||||
import { removeNullField } from '@/utils'
|
import { removeNullField } from '@/utils'
|
||||||
import DialogAppraise from './Components/DialogAppraise.vue'
|
import DialogAppraise from './Components/DialogAppraise.vue'
|
||||||
import * as KpiApi from '@/api/kpi/index.js'
|
import * as KpiApi from '@/api/kpi/index.js'
|
||||||
|
import { getGeneralSysDictData } from '@/api/system/dict/dict.data'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
@@ -91,9 +92,21 @@ const total = ref(0)
|
|||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
getOptions()
|
||||||
handleQuery()
|
handleQuery()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const kpiModeOoptions = ref([])
|
||||||
|
function getOptions() {
|
||||||
|
getGeneralSysDictData('examine_type').then((data) => {
|
||||||
|
kpiModeOoptions.value = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getKpiModeLabel(row) {
|
||||||
|
return kpiModeOoptions.value.find((it) => it.value == row.type)?.label
|
||||||
|
}
|
||||||
|
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
|
|
||||||
<script setup name="KpiRecord">
|
<script setup name="KpiRecord">
|
||||||
import { removeNullField } from '@/utils'
|
import { removeNullField } from '@/utils'
|
||||||
import * as FalseDiligenceApi from '@/api/home/falseDiligence.js'
|
import * as KpiApi from '@/api/kpi/score.js'
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ async function getList() {
|
|||||||
month: new Date(params.period).getMonth() + 1
|
month: new Date(params.period).getMonth() + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const data = await FalseDiligenceApi.getPage(removeNullField(params))
|
const data = await KpiApi.getScorePage(removeNullField(params))
|
||||||
if (searchForm.value.name) {
|
if (searchForm.value.name) {
|
||||||
tableList.value = data.list.reduce((pre, cur) => {
|
tableList.value = data.list.reduce((pre, cur) => {
|
||||||
return pre.concat(cur.userDingAttendanceRespVOList)
|
return pre.concat(cur.userDingAttendanceRespVOList)
|
||||||
@@ -176,7 +176,7 @@ async function handleSealup(row) {
|
|||||||
// 二次确认
|
// 二次确认
|
||||||
await message.confirm('确认要封存"' + row.period + '"假勤吗?')
|
await message.confirm('确认要封存"' + row.period + '"假勤吗?')
|
||||||
// 发起修改状态
|
// 发起修改状态
|
||||||
await FalseDiligenceApi.saveFalseDiligence({
|
await KpiApi.saveFalseDiligence({
|
||||||
period: row.period
|
period: row.period
|
||||||
})
|
})
|
||||||
message.success('封存成功!')
|
message.success('封存成功!')
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<el-form :model="searchForm" inline label-width="0">
|
<el-form :model="searchForm" inline label-width="0">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="searchForm.peroid"
|
v-model="searchForm.period"
|
||||||
type="month"
|
type="month"
|
||||||
format="YYYY-MM"
|
format="YYYY-MM"
|
||||||
value-format="YYYY-MM"
|
value-format="YYYY-MM"
|
||||||
@@ -16,15 +16,17 @@
|
|||||||
<el-button @click="getList" v-hasPermi="['kpi:score:search']"> 搜索</el-button>
|
<el-button @click="getList" v-hasPermi="['kpi:score:search']"> 搜索</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-tabs v-model="searchForm.employeeId" @tab-click="getList">
|
<el-tabs v-model="employeeId" @tab-click="getList">
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-for="item in employeeOptions"
|
v-for="item in employeeOptions"
|
||||||
:key="item.id"
|
:key="item.examinedUser"
|
||||||
:label="item.name"
|
:label="item.examinedUserName"
|
||||||
:name="item.id"
|
:name="item.examinedUser"
|
||||||
>
|
>
|
||||||
<div class="mb-10px">
|
<div class="mb-10px">
|
||||||
<el-tag v-if="peroidSaved" type="danger"> 当前周期已封存,不可修改当月绩效考核 </el-tag>
|
<el-tag v-if="periodSaved == 1" type="danger">
|
||||||
|
当前周期已封存,不可修改当月绩效考核
|
||||||
|
</el-tag>
|
||||||
<el-tag v-else type="warning">
|
<el-tag v-else type="warning">
|
||||||
当前周期未封存,可选择修改当月绩效考核,两秒内不操作将自动保存考核结果
|
当前周期未封存,可选择修改当月绩效考核,两秒内不操作将自动保存考核结果
|
||||||
</el-tag>
|
</el-tag>
|
||||||
@@ -37,28 +39,28 @@
|
|||||||
show-summary
|
show-summary
|
||||||
:summary-method="getSummaries"
|
:summary-method="getSummaries"
|
||||||
>
|
>
|
||||||
<el-table-column prop="name" label="考核指标" width="180" />
|
<el-table-column prop="examineTarget" label="考核指标" width="180" />
|
||||||
<el-table-column prop="type" label="分值模式" width="90" />
|
<el-table-column prop="type" label="分值模式" width="90" />
|
||||||
<el-table-column prop="rate" label="权重%" width="90" />
|
<el-table-column prop="weight" label="权重%" width="90" />
|
||||||
<el-table-column label="考核内容">
|
<el-table-column label="考核内容">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-dompurify-html="row.kaoheneirong"></div>
|
<div v-dompurify-html="row.examineContent"></div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="考核规则" prop="kaoheguize">
|
<el-table-column label="考核规则" prop="examineRule">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-dompurify-html="row.kaoheguize"></div>
|
<div v-dompurify-html="row.examineRule"></div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="评分上限" prop="maxScore" width="90" />
|
<el-table-column label="评分上限" prop="examineScore" width="90" />
|
||||||
<el-table-column label="考核评分" width="120">
|
<el-table-column label="考核评分" width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-if="peroidSaved">{{ row.score }}</div>
|
<div v-if="periodSaved == 1">{{ row.score }}</div>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-else
|
v-else
|
||||||
v-model="row.score"
|
v-model="row.score"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="row.maxScore"
|
:max="row.examineScore"
|
||||||
:step="1"
|
:step="1"
|
||||||
:controls="false"
|
:controls="false"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -69,7 +71,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="评分备注" width="200">
|
<el-table-column label="评分备注" width="200">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-if="peroidSaved">{{ row.remark }}</div>
|
<div v-if="periodSaved == 1">{{ row.remark }}</div>
|
||||||
<el-input
|
<el-input
|
||||||
v-else
|
v-else
|
||||||
v-model="row.remark"
|
v-model="row.remark"
|
||||||
@@ -81,7 +83,14 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="加权得分" prop="jiaquandefen" width="90" />
|
<el-table-column label="加权得分" prop="weightSocre" width="90" />
|
||||||
|
<el-table-column label="操作" fixed="right" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button style="padding: 0" type="danger" text @click="handleDelete(row)">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
@@ -90,70 +99,52 @@
|
|||||||
|
|
||||||
<script setup name="KpiScore">
|
<script setup name="KpiScore">
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
import * as KpiApi from '@/api/kpi/index.js'
|
import * as KpiApi from '@/api/kpi/score.js'
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const loading = ref(false) // 列表的加载中
|
const loading = ref(false) // 列表的加载中
|
||||||
const list = ref() // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
peroid: undefined,
|
period: undefined
|
||||||
employeeId: undefined
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const peroidSaved = ref(true)
|
const periodSaved = ref(0)
|
||||||
|
|
||||||
const employeeOptions = ref([])
|
const employeeOptions = ref([])
|
||||||
|
const employeeId = ref('')
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(() => {
|
||||||
// 默认取上个月
|
// 默认取上个月
|
||||||
const today = new Date()
|
const today = new Date()
|
||||||
searchForm.value.peroid = formatDate(
|
searchForm.value.period = formatDate(
|
||||||
new Date(today.getFullYear(), today.getMonth() - 1),
|
new Date(today.getFullYear(), today.getMonth() - 1),
|
||||||
'YYYY-MM'
|
'YYYY-MM'
|
||||||
)
|
)
|
||||||
// 获取当前要考核的人员
|
|
||||||
const list = await KpiApi.getKpiEmployees()
|
KpiApi.getKpiPeriodStatus({ period: searchForm.value.period }).then((data) => {
|
||||||
employeeOptions.value = list || []
|
periodSaved.value = data.status
|
||||||
if (employeeOptions.value.length > 0) {
|
})
|
||||||
searchForm.value.employeeId = employeeOptions.value[0].id
|
|
||||||
}
|
|
||||||
|
|
||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
|
|
||||||
async function getList() {
|
async function getList() {
|
||||||
if (!searchForm.value.employeeId) {
|
|
||||||
message.error('当月无待考核员工!!!')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.value = true
|
|
||||||
try {
|
try {
|
||||||
const data = [
|
// 获取当前要考核的人员
|
||||||
{
|
const arr = await KpiApi.getKpiEmployees(searchForm.value)
|
||||||
name: '纳税申报',
|
employeeOptions.value = arr || []
|
||||||
rate: 40,
|
if (employeeOptions.value.length > 0) {
|
||||||
kaoheneirong:
|
if (!employeeId.value) {
|
||||||
'<p>1、每个月13号之前在柠檬云财税把上个月的财务数据录入系统出具财务报表;</p><p>2、社保和公积金及时增减人员,做好核定工作,及时申报缴纳;</p><p>3、按照税务局规定时间把自己所负责的公司增指税、附加税、所得税以及其他税种申报完成</p>',
|
employeeId.value = employeeOptions.value[0].examinedUser
|
||||||
kaoheguize: `当天处理完今日线索,连续2天未处理完,一次扣2分,最多扣5分`,
|
|
||||||
maxScore: 20,
|
|
||||||
score: 10,
|
|
||||||
checkEmployees: [1, 3, 4],
|
|
||||||
jiaquandefen: 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '数据统计',
|
|
||||||
rate: 20,
|
|
||||||
kaoheneirong:
|
|
||||||
'<p>1、每个月13号之前在柠檬云财税把上个月的财务数据录入系统出具财务报表;</p><p>2、社保和公积金及时增减人员,做好核定工作,及时申报缴纳;</p><p>3、按照税务局规定时间把自己所负责的公司增指税、附加税、所得税以及其他税种申报完成</p>',
|
|
||||||
kaoheguize: `当天处理完今日线索,连续2天未处理完,一次扣2分,最多扣5分`,
|
|
||||||
maxScore: 10,
|
|
||||||
score: 8,
|
|
||||||
checkEmployees: [1, 3, 4],
|
|
||||||
jiaquandefen: 1.6
|
|
||||||
}
|
}
|
||||||
]
|
} else {
|
||||||
list.value = data
|
message.error('当月无待考核员工!!!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list.value =
|
||||||
|
employeeOptions.value.find((it) => it.examinedUser == employeeId.value)
|
||||||
|
?.examineScoreRespVOList || []
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -161,12 +152,37 @@ async function getList() {
|
|||||||
|
|
||||||
let timer = ref(null)
|
let timer = ref(null)
|
||||||
const lastId = ref('')
|
const lastId = ref('')
|
||||||
function handleSave() {
|
function handleSave(row) {
|
||||||
lastId.value == row.id && clearTimeout(timer.value)
|
try {
|
||||||
// clearTimeout(timer.value)
|
lastId.value == row.id && clearTimeout(timer.value)
|
||||||
timer.value = setTimeout(() => {
|
timer.value = setTimeout(async () => {
|
||||||
message.success('正在保存数据,请稍后')
|
lastId.value = row.id
|
||||||
}, 2000)
|
// message.success('正在保存数据,请稍后')
|
||||||
|
await KpiApi.saveKpiScore({
|
||||||
|
id: row.id,
|
||||||
|
score: row.score,
|
||||||
|
remark: row.remark
|
||||||
|
})
|
||||||
|
message.success('修改成功!')
|
||||||
|
getList()
|
||||||
|
}, 2000)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleDelete(row) {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm(
|
||||||
|
`删除后,该员工于${searchForm.value.period}将不再考核此项,是否确认删除?`
|
||||||
|
)
|
||||||
|
// 发起删除
|
||||||
|
await KpiApi.deleteKpiItem({ id: row.id })
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSummaries({ columns, data }) {
|
function getSummaries({ columns, data }) {
|
||||||
@@ -178,7 +194,7 @@ function getSummaries({ columns, data }) {
|
|||||||
}
|
}
|
||||||
const values = data.map((item) => Number(item[column.property]))
|
const values = data.map((item) => Number(item[column.property]))
|
||||||
if (!values.every((value) => Number.isNaN(value))) {
|
if (!values.every((value) => Number.isNaN(value))) {
|
||||||
if (column.property == 'jiaquandefen') {
|
if (column.property == 'weightSocre') {
|
||||||
sums[index] = 5.6
|
sums[index] = 5.6
|
||||||
} else {
|
} else {
|
||||||
sums[index] = ''
|
sums[index] = ''
|
||||||
|
|||||||
Reference in New Issue
Block a user