<template>
|
<div id="warp">
|
<div style="display: flex;position: relative">
|
<div style="width: 100%">
|
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect"
|
style="margin-bottom: 10px">
|
<el-menu-item index="0">省厅月度</el-menu-item>
|
<el-menu-item index="2">省厅季度</el-menu-item>
|
<el-menu-item index="1">区县月度</el-menu-item>
|
<el-menu-item index="3">区县季度</el-menu-item>
|
</el-menu>
|
</div>
|
<!-- 导出按钮 -->
|
<div style="position: absolute;top:10px; right: 5px;z-index: 2" v-hasPermi="['check:result:export']">
|
<el-popover
|
placement="left"
|
width="300px"
|
trigger="click">
|
<span style="font-weight: bold;font-size: 16px">导出</span>
|
|
<el-form ref="exportForm" :model="exportForm" :rules="exportRules" label-width="100px">
|
<el-form-item label="考核时间" prop="quarter" required>
|
<el-date-picker
|
:clearable="false"
|
v-model="exportForm.quarter"
|
type="monthrange"
|
format="yyyy-MM"
|
value-format="yyyy-MM"
|
unlink-panels
|
range-separator="至"
|
start-placeholder="开始月份"
|
end-placeholder="结束月份"
|
:picker-options="pickerOptions">
|
</el-date-picker>
|
</el-form-item>
|
<el-form-item label="区县" prop="deptIds">
|
<el-select v-model="exportForm.deptIds" multiple clearable>
|
<el-option v-for="dept in areaList"
|
:value="dept.id"
|
:key="dept.value"
|
:label="dept.value"/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="考核标签" prop="examineTags">
|
<el-checkbox-group v-model="exportForm.examineTags">
|
<el-checkbox
|
v-for="item in tagOptions"
|
:key="item.value"
|
:label="item.value"
|
>{{ item.label }}
|
</el-checkbox>
|
</el-checkbox-group>
|
</el-form-item>
|
<el-form-item label="计算平均值" prop="average">
|
<el-switch
|
v-model="exportForm.average"
|
>
|
</el-switch>
|
</el-form-item>
|
<el-button type="primary" size="small" style="width: 400px" @click="handleExport">导出</el-button>
|
</el-form>
|
<el-button slot="reference" type="primary" size="mini" plain>导出</el-button>
|
</el-popover>
|
</div>
|
</div>
|
<div class="data-chart-container">
|
<el-card class="data-card" :body-style="{ height: '100%' }">
|
<div class="card-content">
|
<div class="title-container">
|
<h1>考核成绩</h1>
|
</div>
|
<div class="echart-container">
|
<div id="barChart" ref="barChart"></div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
|
<div>
|
<el-row :gutter="100">
|
<el-col :span="6" v-for="(city, index) in checkScoreList" :key="index">
|
<div class="city-warp">
|
<div class="city">
|
<div class="title">
|
{{ translateDeptId(parseInt(index)) }}
|
</div>
|
<div class="score-warp">
|
<div class="score-item">
|
<div style="font-size: 15px; margin-bottom: 15px">{{ formatCreateDate(city[0]) }}</div>
|
</div>
|
<div v-for="(score, scoreIndex) in filterRepeat(city)" :key="scoreIndex">
|
<div class="score-item">
|
<div v-if="score.examineCategory == 2">车辆:</div>
|
<div v-else-if="score.examineCategory == 3">人脸:</div>
|
<div v-else-if="score.examineCategory == 1">视频:</div>
|
<div class="score">{{ score.score }}</div>
|
</div>
|
</div>
|
</div>
|
<div class="bottom-publish">
|
<el-button v-hasPermi="['check:score:publish']" size="medium"
|
:type="isAnyUnpublished(city) ? 'success' : 'danger'" @click="publish(city)">
|
{{ isAnyUnpublished(city) ? '发布' : '取消' }}
|
</el-button>
|
<el-button size="medium" @click="jumpDetail(index)" type="primary">详情</el-button>
|
</div>
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</div>
|
|
</template>
|
|
<script>
|
import {areaSelect} from '@/api/system/dept';
|
import {listScore, publishScore} from "@/api/platform/check-score";
|
import * as echarts from 'echarts';
|
|
let observer = null;
|
let chart = null;
|
export default {
|
name: 'index',
|
data() {
|
return {
|
tagOptions: [
|
{value: 0, label: '省厅'},
|
{value: 1, label: '区县'}
|
],
|
pickerOptions: {
|
shortcuts: [{
|
text: '第一季度',
|
onClick(picker) {
|
picker.$emit('pick', [new Date(new Date().getFullYear() + "-01"), new Date(new Date().getFullYear() + "-03")]);
|
}
|
},
|
{
|
text: '第二季度',
|
onClick(picker) {
|
picker.$emit('pick', [new Date(new Date().getFullYear() + "-04"), new Date(new Date().getFullYear() + "-06")]);
|
}
|
},
|
{
|
text: '第三季度',
|
onClick(picker) {
|
picker.$emit('pick', [new Date(new Date().getFullYear() + "-07"), new Date(new Date().getFullYear() + "-09")])
|
}
|
},
|
{
|
text: '第四季度',
|
onClick(picker) {
|
picker.$emit('pick', [new Date(new Date().getFullYear() + "-10"), new Date(new Date().getFullYear() + "-12")])
|
}
|
}]
|
},
|
province: {
|
id: [],
|
publish: null,
|
},
|
// 导出表单验证
|
exportRules: {
|
quarter: [
|
{ type: 'array', required: true, message: '请选择时间', trigger: 'change' }
|
],
|
},
|
checkScoreList: [],
|
areaList: [],
|
activeIndex: '0',
|
date: '',
|
company: '',
|
// 导出
|
exportForm: {
|
quarter: [],
|
deptIds: [],
|
examineTags: [],
|
examineCategories: [],
|
average: null,
|
},
|
// 查询参数
|
queryParams: {
|
examineTag: null,
|
createTime: null
|
},
|
}
|
},
|
created() {
|
},
|
mounted() {
|
this.queryParams.examineTag = this.activeIndex
|
chart = echarts.init(this.$refs.barChart);
|
this.areaSelect()
|
// this.setChartOption(this.checkScoreList);
|
},
|
methods: {
|
jumpDetail(index) {
|
this.$router.push({
|
path: '/check/detail',
|
query: {
|
index: index,
|
examineTag: this.activeIndex
|
}
|
})
|
},
|
initEchart() {
|
const option = {
|
grid: {
|
left: 0,
|
right: 0,
|
bottom: 0,
|
top: '20%',
|
containLabel: true
|
},
|
legend: {
|
right: 'right',
|
top: 'top',
|
icon: 'rect',
|
orient: "vertical",
|
},
|
tooltip: {},
|
xAxis: {
|
type: 'category',
|
axisLabel: {},
|
data: this.dataList.name
|
},
|
yAxis: {
|
min: 90,
|
},
|
series: [
|
{
|
type: 'bar',
|
name: '视频考核',
|
data: this.dataList.data1,
|
barWidth: '40',
|
itemStyle: {
|
color: 'rgba(255, 165, 0, 1)'
|
}
|
},
|
{
|
type: 'bar',
|
name: '人脸考核',
|
data: this.dataList.data2,
|
barWidth: '40',
|
itemStyle: {
|
color: 'rgba(85, 192, 191, 1)'
|
}
|
},
|
{
|
type: 'bar',
|
name: '车辆考核',
|
data: this.dataList.data3,
|
barWidth: '40',
|
itemStyle: {
|
color: 'rgba(62, 144, 247, 1)'
|
}
|
},
|
]
|
}
|
chart.setOption(option, true);
|
},
|
|
// 设置chart
|
setChartOption(data) {
|
if (!data) return;
|
const mapData = Object.keys(data).map(key => {
|
return {
|
name: this.translateDeptId(parseInt(key)),
|
data: data[key]
|
}
|
});
|
const nameArray = mapData.map(item => item.name);
|
const data1 = this.filterData(mapData, 1);
|
const data2 = this.filterData(mapData, 2);
|
const data3 = this.filterData(mapData, 3);
|
const option = {
|
grid: {
|
left: 0,
|
right: 0,
|
bottom: 0,
|
top: '20%',
|
containLabel: true
|
},
|
legend: {
|
right: 'right',
|
top: 'top',
|
icon: 'rect',
|
orient: "vertical",
|
},
|
tooltip: {},
|
xAxis: {
|
type: 'category',
|
axisLabel: {},
|
data: nameArray
|
|
},
|
yAxis: {
|
min: 0
|
},
|
series: [
|
{
|
type: 'bar',
|
name: '视频考核',
|
data: data1,
|
barWidth: '40',
|
itemStyle: {
|
color: 'rgba(255, 165, 0, 1)',
|
}
|
},
|
{
|
type: 'bar',
|
name: '人脸考核',
|
data: data2,
|
barWidth: '40',
|
itemStyle: {
|
color: 'rgba(85, 192, 191, 1)',
|
}
|
},
|
{
|
type: 'bar',
|
name: '车辆考核',
|
data: data3,
|
barWidth: '40',
|
itemStyle: {
|
color: 'rgba(62, 144, 247, 1)',
|
}
|
},
|
]
|
}
|
chart.setOption(option, true);
|
},
|
filterData(mapData, tag) {
|
if (!mapData) return;
|
if (!Array.isArray(mapData)) return;
|
const tempArray = [];
|
mapData.forEach((item) => {
|
if (item.data.length) {
|
let flag = false;
|
item.data.forEach((examine) => {
|
if (examine.examineCategory === tag) {
|
flag = true
|
tempArray.push(examine.score);
|
}
|
})
|
if (!flag) {
|
tempArray.push(0);
|
}
|
}
|
})
|
return tempArray;
|
},
|
// 区域下拉数据
|
areaSelect() {
|
areaSelect().then(res => {
|
this.areaList = res.data;
|
this.getList();
|
})
|
},
|
translateDeptId(deptId) {
|
const department = this.areaList.find(dept => dept.id === deptId);
|
console.log(deptId,this.areaList)
|
return department ? department.value : '未知';
|
},
|
|
isAnyUnpublished(city) {
|
// 检查 city 的 score 数组中是否有任何一个的 publish 属性为 'UNPUBLISHED'
|
return city.some(score => score.publish === 'UNPUBLISHED');
|
},
|
formatCreateDate(item) {
|
const date = new Date(item.createTime);
|
const year = date.getFullYear();
|
const month = date.getMonth() + 1; // getMonth() 返回的月份是从 0 开始的,所以要加 1
|
const day = date.getDate();
|
|
// 使用 padStart 方法确保月份和日期始终是两位数
|
const formattedMonth = month.toString().padStart(2, '0');
|
const formattedDay = day.toString().padStart(2, '0');
|
|
return `${year}年${formattedMonth}月${formattedDay}号`;
|
},
|
filterRepeat(city) {
|
let list = [];
|
let examineCategorys = [];
|
city.forEach(item => {
|
if (examineCategorys.indexOf(item.examineCategory) === -1) {
|
examineCategorys.push(item.examineCategory);
|
list.push(item);
|
}
|
});
|
return list;
|
},
|
/** 导航切换 */
|
handleSelect(key) {
|
this.activeIndex = key; // 更新当前激活的菜单项
|
this.queryParams.examineTag = key;
|
this.getList();
|
},
|
/** 查询考核成绩列表 */
|
getList() {
|
this.loading = true;
|
// 获取当前日期
|
const today = new Date();
|
|
// 将日期减去一天
|
const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
|
|
// 获取年、月、日
|
const year = yesterday.getFullYear();
|
let month = (yesterday.getMonth() + 1).toString().padStart(2, '0'); // 月份是从0开始的,所以加1
|
let day = yesterday.getDate().toString().padStart(2, '0');
|
|
// 拼接成 yyyy-MM-dd 格式
|
this.queryParams.createTime = `${year}-${month}-${day}`
|
|
console.log(this.queryParams);
|
listScore(this.queryParams).then(response => {
|
this.checkScoreList = response.data;
|
|
this.setChartOption(this.checkScoreList);
|
this.loading = false;
|
});
|
},
|
publish(city) {
|
let text = this.isAnyUnpublished(city) ? "发布" : "取消发布";
|
const cityName = this.translateDeptId(parseInt(city[0].deptId));
|
this.province.publish = text === "发布" ? "PUBLISHED" : "UNPUBLISHED";
|
this.province.id = city.map(city => city.id);
|
this.$modal.confirm('是否确认' + text + '考核名为"' + cityName + '"的成绩?')
|
.then(() => {
|
return publishScore(this.province);
|
})
|
.then(() => {
|
this.getList();
|
this.$modal.msgSuccess(text + "成功");
|
})
|
.catch(() => {
|
// 错误处理逻辑
|
});
|
},
|
// clickItem(value) {
|
// value === this.exportForm.examineTag ? this.exportForm.examineTag = null : this.exportForm.examineTag = value
|
// },
|
/** 导出按钮操作 */
|
handleExport() {
|
this.$refs['exportForm'].validate((valid) => {
|
if (valid) {
|
this.download(
|
"/check/score/export",
|
{
|
...this.exportForm,
|
},
|
`考核指标_${new Date().getTime()}.xlsx`
|
);
|
}
|
})
|
},
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.score-warp {
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
color: #797777
|
}
|
|
.score-item {
|
display: flex;
|
flex-direction: row;
|
|
}
|
|
.score {
|
width: 60px;
|
text-align: right;
|
padding: 3px 0;
|
}
|
|
#warp {
|
padding: 0 10px;
|
}
|
|
.city-warp {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
height: 210px;
|
margin-bottom: 25px;
|
}
|
|
.city {
|
width: 240px;
|
height: 100%;
|
box-shadow: 0 2px 6px hsla(0, 0%, 7%, .1);
|
border-radius: 10px;
|
position: relative;
|
text-align: center;
|
padding: 10px 0px;
|
}
|
|
.bottom-publish {
|
width: 100%;
|
position: absolute;
|
bottom: 10px;
|
}
|
|
.title {
|
font-size: larger;
|
margin-bottom: 5px;
|
}
|
|
.data-chart-container {
|
height: 400px;
|
margin-bottom: 20px;
|
|
.data-card {
|
height: 100%;
|
|
.card-content {
|
width: 100%;
|
height: 100%;
|
position: relative;
|
}
|
}
|
}
|
|
.title-container {
|
position: absolute;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
z-index: 2;
|
|
|
.more-button {
|
cursor: pointer;
|
font-size: 16px;
|
padding: 0 10px;
|
}
|
}
|
|
.echart-container {
|
width: 100%;
|
height: 100%;
|
|
#barChart {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
.select-container {
|
margin: 0 20px;
|
width: 180px;
|
}
|
</style>
|