Files
zhxg_pc/src/views/Home/index-2.vue

687 lines
18 KiB
Vue
Raw Normal View History

2025-07-28 15:52:07 +08:00
<template>
<div id="main">
<el-row>
<el-col :span="17">
<el-main>
<div style="height: fit-content">
<div class="six-action-container">
2025-10-18 17:13:04 +08:00
<div v-for="(v, i) in taskList" :key="i" style="padding: 1rem" class="six-action-item">
2025-07-28 15:52:07 +08:00
<div class="bubble" :style="{
2025-10-18 17:13:04 +08:00
backgroundImage: `url(${require('@/assets/index_bg/' +
(i + 1) +
'.png')})`,
}"
>
2025-07-28 15:52:07 +08:00
<div class="act-text">
<div class="title">{{ v.label }}·待办</div>
<div class="todo">
{{ v.value }}
</div>
</div>
<div class="bg-to" @click="toRoute(v.url)">更多</div>
<!-- <div class="bg-cloud">
</div> -->
</div>
</div>
</div>
</div>
<!-- <div>
<div style="height: fit-content;margin: 0px 15px 0 15px;">
<div class="bottom-charts-container">
<div class="bottom-charts-item">
<el-card style="height: fit-content;margin: 5px;">
<div slot="header">
<span>校区宿舍分布人数统计</span>
</div>
<div style="height: 280px;overflow-y: scroll;">
<div class="campus-dms-count-container">
<div class="campus-dms-count-item" v-for="(v, i) in init_park_list"
:key="i">
<circle-progress
:percentage="(isNaN(v.allIn / v.all) ? 0 : Math.round(v.allIn / v.all * 10000) / 100).toString()"
:abstract="v.allIn.toString()" :title="(v.campusName + '·' + v.parkName).length > 8 ? v.parkName : v.campusName
+ '·' +
v.parkName" :shade="progress_color[i]" />
<div>
<div class="stuCountText">男生人数
<span
:style="v.boyIn >= v.girlIn ? { color: progress_color[i][1] } : {}"
class="stuCountNumber">
{{ v.boyIn }}
</span>
</div>
<div class="stuCountText">女生人数
<span
:style="v.boyIn < v.girlIn ? { color: progress_color[i][1] } : {}"
class="stuCountNumber">
{{ v.girlIn }}
</span>
</div>
</div>
</div>
</div>
</div>
</el-card>
</div>
<div class="bottom-charts-item">
<el-card style="margin: 5px;">
<div slot="header">
<span>优秀毕业生情况</span>
</div>
<div style="position: relative;top: -20px;" class="echart" id="mychart2"
:style="myChartStyle"></div>
</el-card>
</div>
</div>
</div>
</div> -->
</el-main>
</el-col>
<el-col :span="6">
<el-main style="padding: 0">
<el-card style="margin-top: 20px; height: 220px" shadow="always">
<div slot="header">
<span>快捷功能</span>
</div>
<div style="height: 30vh; position: relative">
2025-10-18 17:13:04 +08:00
<el-col v-for="(v, i) in fast" :key="i" :span="6" style="text-align: center">
2025-07-28 15:52:07 +08:00
<div style="width: 100%; height: 11vh" class="fast-act">
2025-10-18 17:13:04 +08:00
<el-image :src="v.src" style="position: relative; width: 44.917px; height: 44px" />
2025-07-28 15:52:07 +08:00
<div style="font-size: 14px; position: relative; top: -5px">
{{ v.text }}
</div>
</div>
</el-col>
</div>
</el-card>
<el-card style="margin-top: 20px" shadow="always">
<div slot="header">
<span>提醒消息</span>
</div>
2025-10-18 17:13:04 +08:00
<el-row v-if="have_msg" style="overflow-y: scroll; height: 200px">
<el-col v-for="(v, i) in msg_list" :key="i" style="
2025-07-28 15:52:07 +08:00
margin-bottom: 10px;
border-bottom: 1px dotted lightblue;
cursor: pointer;
2025-10-18 17:13:04 +08:00
" :span="24" @click.native="msgVClick(v.content)"
>
2025-07-28 15:52:07 +08:00
<span style="overflow: hidden">{{
v.content.length > 20
? v.content.substr(0, 17) + "..."
: v.content
}}</span>
</el-col>
</el-row>
2025-10-18 17:13:04 +08:00
<div v-else style="height: 200px">暂无消息</div>
2025-07-28 15:52:07 +08:00
</el-card>
<el-card style="margin-top: 20px; height: 230px" shadow="always">
<div slot="header">
<span>公示栏</span>
</div>
<el-row v-if="have_comp">
<div style="height: 25vh; overflow-y: scroll; overflow-x: hidden">
<div v-for="(v, i) in comp_list" :key="i" style="cursor: pointer; margin-bottom: 5px">
{{ v.submitterName }}--{{ v.projectName }} -- 审核通过
</div>
</div>
</el-row>
<div v-else>暂无消息</div>
</el-card>
</el-main>
</el-col>
</el-row>
<el-dialog title="消息" :visible.sync="msgV" width="30%">
<span>{{ msg_content }}</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="msgV = false"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
2025-10-18 17:13:04 +08:00
import { getCompleted } from '@/api/stuCQS/process-center/auditDetails'
import { listMsg } from '@/api/stuCQS/process-center/msg'
import * as echarts from 'echarts'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import { countParkStuIn } from '@/api/dormitory/basedata/dormitory'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import { countBiyeYearDept, countXwUnDo } from '@/api/stuCQS/good/apply'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import { groupBy, isEmpty } from '@/api/helpFunc'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import CircleProgress from '@/components/CircleProgress'
2025-07-28 15:52:07 +08:00
export default {
2025-10-18 17:13:04 +08:00
name: 'Index2',
2025-07-28 15:52:07 +08:00
components: {
CircleProgress,
},
data () {
return {
progress_color: [
2025-10-18 17:13:04 +08:00
['rgb(71,192,93)', 'rgb(142,239,98)'],
['rgb(255,135,37)', 'rgb(255,179,127)'],
['rgb(255,54,125)', 'rgb(255,117,159)'],
2025-07-28 15:52:07 +08:00
],
taskList: [
{
2025-10-18 17:13:04 +08:00
label: '评优评先审核',
name: 'good',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/stuGood/about-good/xw',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
label: '静湖之星审核',
name: 'lake',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/stuGood/about-lake/xw',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
label: '优秀毕业生审核',
name: 'biye',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/stuGood/good-graduate/xw',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
label: '困难认定审核',
name: 'kn',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/hard/pks/xw',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
label: '助学金审核',
name: 'zx',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/hard/zxj/xw',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
label: '宿舍管理审核',
name: 'dms',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/dormitory/stuDormitoryManage/work',
2025-07-28 15:52:07 +08:00
},
// {
// label: "勤工助学学生岗位申请审核",
// name: "qgzxgw",
// value: 0,
// url: "/workstudy/stupost/zdls",
// },
// {
// label: "勤工助学学生工作记录审核",
// name: "qgzxgzjl",
// value: 0,
// url: "/workstudy/worklog/zdls",
// },
{
2025-10-18 17:13:04 +08:00
label: '任务管理审核',
name: 'rwgl',
2025-07-28 15:52:07 +08:00
value: 0,
2025-10-18 17:13:04 +08:00
url: '/task/todo',
2025-07-28 15:52:07 +08:00
},
],
myChartStyle: {
2025-10-18 17:13:04 +08:00
float: 'left',
width: '400px',
height: '300px',
2025-07-28 15:52:07 +08:00
margin: 0,
}, //图表样式
fast: [
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Folder.png'),
url: '',
text: '操作手册',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Arrow.png'),
url: '',
text: '我的申请',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Info.png'),
url: '',
text: '我的待办',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Clock.png'),
url: '',
text: '综合素质',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Send.png'),
url: '',
text: '我的流程',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Chart.png'),
url: '',
text: '优秀班级',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Home.png'),
url: '',
text: '优秀宿舍',
2025-07-28 15:52:07 +08:00
},
{
2025-10-18 17:13:04 +08:00
src: require('@/assets/icons/index-icon/Icon-Menu.png'),
url: '',
text: '已办任务',
2025-07-28 15:52:07 +08:00
},
],
msg_list: [],
have_msg: false,
2025-10-18 17:13:04 +08:00
msg_content: '',
2025-07-28 15:52:07 +08:00
msgV: false,
comp_list: [],
have_comp: false,
2025-10-18 17:13:04 +08:00
comp_msg: '',
2025-07-28 15:52:07 +08:00
compV: false,
init_park_list: [],
2025-10-18 17:13:04 +08:00
}
},
watch: {
iamChildType (newVal, oldVal) {
this.child_list.map((v) => {
if (v.ruleId == newVal) {
this.iam_add_record = v.maxScore
}
})
},
2025-07-28 15:52:07 +08:00
},
created () {
2025-10-18 17:13:04 +08:00
this.listMyMsg()
this.getCompleted()
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
this.countXwUnDo()
2025-07-28 15:52:07 +08:00
//this.countParkStuIn();
},
mounted () {
// this.initEcharts2();
},
methods: {
async countXwUnDo () {
2025-10-18 17:13:04 +08:00
let res = await countXwUnDo()
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
let data = [...res.data]
2025-07-28 15:52:07 +08:00
this.taskList.map((x) => {
2025-10-18 17:13:04 +08:00
let temp = data.filter((y) => y.startsWith(x.name))
2025-07-28 15:52:07 +08:00
if (!isEmpty(temp)) {
2025-10-18 17:13:04 +08:00
let result = temp[0].split('-')[1]
x.value = result
2025-07-28 15:52:07 +08:00
}
2025-10-18 17:13:04 +08:00
})
2025-07-28 15:52:07 +08:00
}
},
toRoute (url) {
if (!isEmpty(url)) {
2025-10-18 17:13:04 +08:00
this.$router.push(url)
2025-07-28 15:52:07 +08:00
}
},
async countParkStuIn () {
2025-10-18 17:13:04 +08:00
let res = await countParkStuIn()
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
this.init_park_list = [...res.data]
2025-07-28 15:52:07 +08:00
}
},
customColorMethod (percentage) {
if (percentage < 40) {
2025-10-18 17:13:04 +08:00
return '#67c23a'
2025-07-28 15:52:07 +08:00
} else if (percentage < 75) {
2025-10-18 17:13:04 +08:00
return '#e6a23c'
2025-07-28 15:52:07 +08:00
} else {
2025-10-18 17:13:04 +08:00
return 'red'
2025-07-28 15:52:07 +08:00
}
},
async initEcharts2 () {
2025-10-18 17:13:04 +08:00
let year_list = []
let dept_list = []
let v_list = []
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
let res = await countBiyeYearDept()
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
let data = [...res.data]
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
let temp1 = groupBy(data, (x) => x.deptName)
let temp2 = groupBy(data, (y) => y.stuYearName)
2025-07-28 15:52:07 +08:00
for (let key in temp1) {
2025-10-18 17:13:04 +08:00
dept_list.push(key.replace('"', '').replace('"', ''))
2025-07-28 15:52:07 +08:00
}
for (let key in temp2) {
2025-10-18 17:13:04 +08:00
year_list.push(key.replace('"', '').replace('"', ''))
2025-07-28 15:52:07 +08:00
}
dept_list.map((x) => {
let temp = {
name: x,
2025-10-18 17:13:04 +08:00
type: 'line',
stack: 'total',
2025-07-28 15:52:07 +08:00
data: [],
2025-10-18 17:13:04 +08:00
}
2025-07-28 15:52:07 +08:00
year_list.map((y) => {
let v_data = data.filter(
(z) => z.stuYearName == y && z.deptName == x
2025-10-18 17:13:04 +08:00
)
2025-07-28 15:52:07 +08:00
if (!isEmpty(v_data)) {
2025-10-18 17:13:04 +08:00
temp.data.push(v_data[0].majorCount)
2025-07-28 15:52:07 +08:00
} else {
2025-10-18 17:13:04 +08:00
temp.data.push(0)
2025-07-28 15:52:07 +08:00
}
2025-10-18 17:13:04 +08:00
})
v_list.push(temp)
})
2025-07-28 15:52:07 +08:00
}
let option = {
tooltip: {
2025-10-18 17:13:04 +08:00
trigger: 'axis',
2025-07-28 15:52:07 +08:00
},
legend: {
data: [...dept_list],
2025-10-18 17:13:04 +08:00
left: '3%',
right: '4%',
bottom: '0%',
2025-07-28 15:52:07 +08:00
// show: false
},
grid: {
2025-10-18 17:13:04 +08:00
top: '10%',
left: '3%',
right: '4%',
2025-07-28 15:52:07 +08:00
containLabel: true,
},
toolbox: {
feature: {
saveAsImage: {},
},
},
xAxis: {
2025-10-18 17:13:04 +08:00
type: 'category',
2025-07-28 15:52:07 +08:00
boundaryGap: false,
data: [...year_list],
},
yAxis: {
2025-10-18 17:13:04 +08:00
type: 'value',
2025-07-28 15:52:07 +08:00
},
series: [...v_list],
2025-10-18 17:13:04 +08:00
}
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
const myChart = echarts.init(document.getElementById('mychart2'))
myChart.setOption(option)
2025-07-28 15:52:07 +08:00
//随着屏幕大小调节图表
2025-10-18 17:13:04 +08:00
window.addEventListener('resize', () => {
myChart.resize()
})
2025-07-28 15:52:07 +08:00
},
async getCompleted () {
2025-10-18 17:13:04 +08:00
let res = await getCompleted()
2025-07-28 15:52:07 +08:00
if (res.rows.length > 0) {
2025-10-18 17:13:04 +08:00
this.have_comp = true
this.comp_list = [...res.rows]
2025-07-28 15:52:07 +08:00
}
},
msgVClick (v) {
2025-10-18 17:13:04 +08:00
this.msg_content = v
this.msgV = true
2025-07-28 15:52:07 +08:00
},
//列出我的消息
async listMyMsg () {
2025-10-18 17:13:04 +08:00
let res = await listMsg()
2025-07-28 15:52:07 +08:00
if (res.rows.length > 0) {
2025-10-18 17:13:04 +08:00
this.have_msg = true
this.msg_list = [...res.rows]
2025-07-28 15:52:07 +08:00
}
},
goTarget (href) {
2025-10-18 17:13:04 +08:00
window.open(href, '_blank')
2025-07-28 15:52:07 +08:00
},
getBackColor (i) {
2025-10-18 17:13:04 +08:00
let color = this.colors[i % 7]
2025-07-28 15:52:07 +08:00
return {
2025-10-18 17:13:04 +08:00
'background-color': color,
}
2025-07-28 15:52:07 +08:00
},
},
2025-10-18 17:13:04 +08:00
}
2025-07-28 15:52:07 +08:00
</script>
<style lang="scss" scoped>
.bottom-charts-container {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.bottom-charts-item {
flex-basis: 50%;
}
.six-action-container {
display: flex;
flex-wrap: wrap;
}
.six-action-item {
flex-basis: 33.33%;
}
.campus-dms-count-container {
display: flex;
flex-wrap: wrap;
}
.campus-dms-count-item {
flex-basis: 33.33%;
}
.stuCountText {
line-height: 2rem;
font-size: 1.125rem;
font-weight: bold;
}
.stuCountNumber {
font-size: 1rem;
}
.act-text {
width: 100%;
left: 1rem;
margin-top: -1rem;
z-index: 2;
.title {
text-align: left;
font-size: 1.25rem;
color: #fff;
}
.todo {
margin-top: 1rem;
font-size: 6rem;
color: #fff;
}
}
.bg-to {
cursor: pointer;
z-index: 3;
position: absolute;
bottom: 5%;
right: 3%;
margin-top: 10px;
color: white;
}
.bg-cloud {
text-align: right;
opacity: 0.5;
z-index: 0;
position: absolute;
bottom: 0;
right: 0;
width: 12rem;
height: 40%;
background-color: #fdfbfb;
border-radius: 3.125rem;
transition: transform 0.3s linear, opacity 0.3s linear;
}
.bg-cloud::before,
.bg-cloud::after {
content: "";
position: absolute;
background-color: #fdfbfb;
display: block;
border-radius: 6.25rem;
}
.bg-cloud::before {
width: 4.25rem;
height: 4.25rem;
top: -2rem;
right: 5.125rem;
}
.bg-cloud::after {
width: 4.75rem;
height: 4.75rem;
top: -2.5rem;
right: 1rem;
}
.bubble {
overflow: hidden;
margin: 0 auto;
width: 100%;
height: 170px;
border-radius: 1rem;
// background-image: linear-gradient(120deg, rgb(134, 233, 98) 0%, rgb(45, 175, 92) 100%);
position: relative;
background-size: cover;
min-width: 250px;
}
.six-action-to:hover,
.fast-act:hover {
cursor: pointer;
transform: scale(1.1);
}
div::-webkit-scrollbar {
width: 4px;
}
div::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
opacity: 0.2;
background: fade(blue, 60%);
}
div::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 0;
background: fade(blue, 30%);
}
.lunbo {
padding: 0 8px 0 0;
box-sizing: border-box;
text-overflow: ellipsis; //超出内容...展示
2025-08-01 14:37:54 +08:00
word-break: keep-all; //是否折断文本,keep-all表示不折断
2025-07-28 15:52:07 +08:00
white-space: nowrap; //不换行展示文本
2025-08-01 14:37:54 +08:00
overflow: hidden; //超出部分隐藏,与text-overflow配合使用
2025-07-28 15:52:07 +08:00
flex: 1; //这个是跟左侧的图片组成的一个flex布局
}
.arrow {
width: 0;
height: 0;
border-width: 10px;
border-style: solid;
border-color: transparent transparent transparent rgb(108, 108, 108);
position: relative;
top: 50px;
}
#main {
background-color: rgb(250, 254, 255);
padding: 10px 0 10px 20px;
position: absolute;
width: 100%;
height: 100%;
top: 0px;
overflow: scroll;
}
.el-card__header {
border: none;
}
.el-header,
.el-footer {
background-color: #b3c0d1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-main {
color: #333;
margin: 0;
.box-card {
margin: 0 auto;
}
.six-action {
height: 40vh;
}
.act-img {
width: 4.75rem;
height: 4.625rem;
position: relative;
top: 10px;
display: inline-block;
}
.act-text {
display: inline-block;
font-size: 1.4375rem;
height: 50px;
float: right;
position: relative;
right: 30px;
top: 28px;
}
}
</style>