<template>
|
<div class="dashboard">
|
<section class="dashboard-top">
|
<div class="dashboard-top__left">
|
<div class="stat-cards card">
|
<div class="stat-cards__item head_item--workorder" @click="jump(1)">
|
<div class="stat-cards__content">
|
<span class="stat-cards__label">待办工单</span>
|
<span class="stat-cards__value">{{ obj.waitDealWorkOrderSize || 0 }}</span>
|
<span class="stat-cards__link">查看更多</span>
|
</div>
|
<img class="stat-cards__icon" src="@/assets/indexIcon/ic_daibangongdan@2x.png" alt="" />
|
</div>
|
<div class="stat-cards__item head_item--inspect" @click="jump(2)">
|
<div class="stat-cards__content">
|
<span class="stat-cards__label">待巡检</span>
|
<span class="stat-cards__value">{{ obj.waitTaskSize || 0 }}</span>
|
<span class="stat-cards__link">查看更多</span>
|
</div>
|
<img class="stat-cards__icon" src="@/assets/indexIcon/ic_daixuncha@2x.png" alt="" />
|
</div>
|
<div class="stat-cards__item head_item--stock" @click="jump(3)">
|
<div class="stat-cards__content">
|
<span class="stat-cards__label">待盘点</span>
|
<span class="stat-cards__value">{{ obj.stocktakingSize || 0 }}</span>
|
<span class="stat-cards__link">查看更多</span>
|
</div>
|
<img class="stat-cards__icon" src="@/assets/indexIcon/ic_daipandian@2x.png" alt="" />
|
</div>
|
</div>
|
|
<div class="quick-menu card">
|
<div class="section-header">
|
<h3 class="section-header__title">常用功能</h3>
|
<div class="section-header__action" @click="$refs.commonFunctions.open('常用功能管理')">
|
<i class="el-icon-setting"></i>
|
<span>自定义功能</span>
|
</div>
|
</div>
|
<div class="quick-menu__grid">
|
<div
|
class="quick-menu__item"
|
v-for="(item, index) in list"
|
:key="index"
|
@click="jump1(item.path)"
|
>
|
<div class="quick-menu__item-left">
|
<img :src="item.icoPath" alt="" />
|
<span>{{ item.name }}</span>
|
</div>
|
<i class="el-icon-arrow-right quick-menu__arrow"></i>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<aside class="schedule-panel card">
|
<div class="section-header">
|
<h3 class="section-header__title">日程</h3>
|
</div>
|
<div class="schedule-panel__filters">
|
<el-select v-model="nian" class="schedule-panel__select" @change="getMonthNoticess" placeholder="请选择">
|
<el-option
|
v-for="item in yearList"
|
:key="item.val"
|
:label="item.name"
|
:value="item.val"
|
/>
|
</el-select>
|
<el-select v-model="yue" class="schedule-panel__select" @change="getMonthNoticess" placeholder="请选择">
|
<el-option
|
v-for="(item, index) in 12"
|
:key="index"
|
:label="item + '月'"
|
:value="item > 9 ? item : `0${item}`"
|
/>
|
</el-select>
|
</div>
|
<div class="schedule-panel__calendar">
|
<Calendar
|
ref="Calendar"
|
v-on:choseDay="clickDay"
|
:markDateMore="markDateMore"
|
/>
|
</div>
|
<div class="schedule-panel__list-wrap">
|
<div class="schedule-panel__list-title">当日日程({{ dataList.length }})</div>
|
<div class="schedule-panel__list" v-loading="loading">
|
<template v-if="dataList.length">
|
<div class="schedule-item" v-for="(item, index) in dataList" :key="index">
|
<div class="schedule-item__top">
|
<div class="schedule-item__title-wrap">
|
<div class="schedule-item__dot"></div>
|
<div class="schedule-item__title">{{ item.title }}</div>
|
</div>
|
<div class="schedule-item__time">{{ item.param1 }}</div>
|
</div>
|
<div class="schedule-item__content">{{ item.content }}</div>
|
</div>
|
</template>
|
<div v-else class="schedule-empty">当日暂无日程</div>
|
</div>
|
</div>
|
</aside>
|
</section>
|
|
<section class="dashboard-warning">
|
<ElectricalWarningWorkbench />
|
</section>
|
|
<section class="dashboard-energy">
|
<DailyEnergyTrendPanel
|
title="近30天智能电表每日总电量/总电费"
|
:load-data="electricalDailyEnergyStats"
|
/>
|
<DailyEnergyTrendPanel
|
title="近30天空调多联机每日总电量/总电费"
|
:load-data="conditionerDailyEnergyStats"
|
/>
|
</section>
|
|
<CommonFunctions ref="commonFunctions" @success="getYwQuickLists" />
|
</div>
|
</template>
|
|
<script>
|
import CommonFunctions from '@/components/business/commonFunctions'
|
import ElectricalWarningWorkbench from '@/components/business/ElectricalWarningWorkbench'
|
import DailyEnergyTrendPanel from '@/components/business/DailyEnergyTrendPanel'
|
import { getYwQuickList, getMonthNotices, workDeskData, electricalDailyEnergyStats, conditionerDailyEnergyStats } from '@/api/ywWorkDesk'
|
import { navigateByMenu } from '@/utils/menu'
|
import { mapState } from 'vuex'
|
import Calendar from 'vue-calendar-component'
|
|
export default {
|
data () {
|
return {
|
list: [],
|
value: new Date(),
|
yearList: [],
|
markDateMore: [],
|
nian: '',
|
yue: '',
|
obj: {},
|
dataList: [],
|
loading: false
|
}
|
},
|
components: { CommonFunctions, Calendar, ElectricalWarningWorkbench, DailyEnergyTrendPanel },
|
computed: {
|
...mapState(['menuData'])
|
},
|
created () {
|
this.getWorkDeskData()
|
this.getYwQuickLists()
|
this.getYear()
|
},
|
methods: {
|
electricalDailyEnergyStats,
|
conditionerDailyEnergyStats,
|
getYear () {
|
const currentYear = new Date().getFullYear()
|
const currentMonth = new Date().getMonth() + 1
|
this.nian = currentYear
|
this.yue = currentMonth > 9 ? currentMonth : `0${currentMonth}`
|
for (let i = currentYear - 10; i <= currentYear; i++) {
|
this.yearList.unshift({ name: i + '年', val: i })
|
}
|
this.getMonthNoticess()
|
},
|
getWorkDeskData () {
|
workDeskData({}).then(res => {
|
this.obj = res
|
})
|
},
|
clickDay (e) {
|
this.loading = true
|
const date = e.replace('/\\//g', '-')
|
const arr = this.markDateMore.filter(item => item.date === date)
|
this.dataList = arr.length > 0 ? arr[0].noticeList : []
|
this.loading = false
|
},
|
getMonthNoticess () {
|
getMonthNotices(this.nian + '-' + this.yue).then(res => {
|
const arr = res.filter(item => item.noticeList && item.noticeList.length > 0)
|
this.markDateMore = arr.map(item => ({
|
date: item.monthDate.replace('/-0/g', '-'),
|
className: 'markRed',
|
noticeList: item.noticeList
|
}))
|
const toDay = this.getDay()
|
this.markDateMore.forEach(item => {
|
if (item.date === toDay) {
|
this.dataList = item.noticeList
|
}
|
})
|
this.$refs.Calendar.ChoseMonth(`${this.nian}-${this.yue}`, false)
|
})
|
},
|
getYwQuickLists () {
|
getYwQuickList({}).then(res => {
|
this.list = res
|
})
|
},
|
getDay () {
|
const date = new Date()
|
const year = date.getFullYear()
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
return `${year}-${month}-${day}`
|
},
|
jump (type) {
|
const pathMap = {
|
1: '/workorder/workorderList',
|
2: '/Inspection/task',
|
3: '/stock/check'
|
}
|
this.navigateToMenu(pathMap[type])
|
},
|
jump1 (path) {
|
this.navigateToMenu(path)
|
},
|
navigateToMenu (path) {
|
navigateByMenu(this.$router, this.$store, path, this.menuData.list)
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.dashboard {
|
--dash-primary: #3E80EF;
|
--dash-primary-light: rgba(62, 128, 239, 0.08);
|
--dash-text: #222222;
|
--dash-text-secondary: #666666;
|
--dash-text-muted: #999999;
|
--dash-bg: #F4F7FC;
|
--dash-card-bg: #FFFFFF;
|
--dash-border: #EEF2F8;
|
--dash-radius: 10px;
|
--dash-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
--dash-gap: 16px;
|
|
width: 100%;
|
min-height: 100%;
|
padding: var(--dash-gap);
|
box-sizing: border-box;
|
background: var(--dash-bg);
|
display: flex;
|
flex-direction: column;
|
gap: var(--dash-gap);
|
}
|
|
.card {
|
background: var(--dash-card-bg);
|
border-radius: var(--dash-radius);
|
border: 1px solid var(--dash-border);
|
box-shadow: var(--dash-shadow);
|
}
|
|
.section-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 16px;
|
|
&__title {
|
margin: 0;
|
padding-left: 10px;
|
font-weight: 600;
|
font-size: 18px;
|
color: var(--dash-text);
|
line-height: 1.4;
|
border-left: 3px solid var(--dash-primary);
|
}
|
|
&__action {
|
cursor: pointer;
|
display: flex;
|
align-items: center;
|
gap: 4px;
|
font-size: 14px;
|
color: var(--dash-primary);
|
transition: opacity 0.2s;
|
|
&:hover {
|
opacity: 0.8;
|
}
|
|
i {
|
font-size: 15px;
|
}
|
}
|
}
|
|
.dashboard-top {
|
display: flex;
|
align-items: flex-start;
|
gap: var(--dash-gap);
|
|
&__left {
|
flex: 1;
|
min-width: 0;
|
display: flex;
|
flex-direction: column;
|
gap: var(--dash-gap);
|
}
|
}
|
|
.stat-cards {
|
display: flex;
|
align-items: stretch;
|
gap: 12px;
|
padding: 20px;
|
|
&__item {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 24px 20px;
|
border-radius: 8px;
|
cursor: pointer;
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
&:hover {
|
transform: translateY(-2px);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
.stat-cards__icon {
|
transform: scale(1.05);
|
}
|
}
|
|
&.head_item--workorder {
|
background: linear-gradient(135deg, #EEF4FF 0%, #F5F8FF 100%);
|
|
.stat-cards__value {
|
color: #3E80EF;
|
}
|
|
.stat-cards__link:hover {
|
color: #3E80EF;
|
}
|
}
|
|
&.head_item--inspect {
|
background: linear-gradient(135deg, #E8FAF0 0%, #F2FBF6 100%);
|
|
.stat-cards__value {
|
color: #36B37E;
|
}
|
|
.stat-cards__link:hover {
|
color: #36B37E;
|
}
|
}
|
|
&.head_item--stock {
|
background: linear-gradient(135deg, #FFF6E8 0%, #FFFAF2 100%);
|
|
.stat-cards__value {
|
color: #FF9E00;
|
}
|
|
.stat-cards__link:hover {
|
color: #FF9E00;
|
}
|
}
|
}
|
|
&__content {
|
display: flex;
|
flex-direction: column;
|
}
|
|
&__label {
|
font-weight: 600;
|
font-size: 16px;
|
color: var(--dash-text);
|
}
|
|
&__value {
|
font-weight: 700;
|
font-size: 32px;
|
line-height: 1.2;
|
margin: 6px 0 12px;
|
}
|
|
&__link {
|
font-size: 13px;
|
color: var(--dash-text-muted);
|
transition: color 0.2s;
|
}
|
|
&__icon {
|
width: 56px;
|
height: 56px;
|
flex-shrink: 0;
|
transition: transform 0.2s;
|
}
|
}
|
|
.quick-menu {
|
padding: 20px;
|
|
&__grid {
|
display: grid;
|
grid-template-columns: repeat(4, 1fr);
|
gap: 12px;
|
}
|
|
&__item {
|
cursor: pointer;
|
height: 72px;
|
background: var(--dash-card-bg);
|
border-radius: 8px;
|
border: 1px solid #EEEEEE;
|
padding: 0 16px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
|
|
&:hover {
|
border-color: var(--dash-primary);
|
box-shadow: 0 2px 8px rgba(62, 128, 239, 0.12);
|
transform: translateY(-1px);
|
|
.quick-menu__arrow {
|
color: var(--dash-primary);
|
}
|
}
|
}
|
|
&__item-left {
|
display: flex;
|
align-items: center;
|
min-width: 0;
|
|
img {
|
width: 40px;
|
height: 40px;
|
margin-right: 8px;
|
flex-shrink: 0;
|
}
|
|
span {
|
font-weight: 500;
|
font-size: 14px;
|
color: var(--dash-text);
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
}
|
|
&__arrow {
|
color: #C0C4CC;
|
font-size: 14px;
|
flex-shrink: 0;
|
transition: color 0.2s;
|
}
|
}
|
|
.schedule-panel {
|
flex-shrink: 0;
|
width: 480px;
|
padding: 20px;
|
|
&__filters {
|
display: flex;
|
gap: 12px;
|
margin-bottom: 12px;
|
}
|
|
&__select {
|
width: 140px;
|
}
|
|
&__calendar {
|
padding: 12px;
|
background: #FAFBFE;
|
border-radius: 8px;
|
border: 1px solid var(--dash-border);
|
}
|
|
&__list-wrap {
|
margin-top: 16px;
|
}
|
|
&__list-title {
|
font-weight: 500;
|
font-size: 15px;
|
color: var(--dash-text);
|
margin-bottom: 12px;
|
}
|
|
&__list {
|
height: 280px;
|
overflow-y: auto;
|
padding-right: 4px;
|
|
&::-webkit-scrollbar {
|
width: 5px;
|
}
|
|
&::-webkit-scrollbar-thumb {
|
background: #D8DCE6;
|
border-radius: 3px;
|
}
|
}
|
}
|
|
.schedule-item {
|
padding: 14px 14px 14px 12px;
|
background: #FAFBFE;
|
border-radius: 8px;
|
border: 1px solid var(--dash-border);
|
border-left: 3px solid #FF9E00;
|
margin-bottom: 10px;
|
|
&__top {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 8px;
|
}
|
|
&__title-wrap {
|
display: flex;
|
align-items: center;
|
min-width: 0;
|
}
|
|
&__dot {
|
width: 8px;
|
height: 8px;
|
border-radius: 50%;
|
background: #FF9E00;
|
margin-right: 8px;
|
flex-shrink: 0;
|
}
|
|
&__title {
|
font-weight: 500;
|
font-size: 14px;
|
color: var(--dash-text);
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
&__time {
|
font-size: 12px;
|
color: var(--dash-text-muted);
|
flex-shrink: 0;
|
}
|
|
&__content {
|
font-size: 13px;
|
color: var(--dash-text-secondary);
|
margin-top: 8px;
|
line-height: 1.5;
|
}
|
}
|
|
.schedule-empty {
|
height: 120px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
color: var(--dash-text-muted);
|
font-size: 14px;
|
}
|
|
.dashboard-warning,
|
.dashboard-energy {
|
display: flex;
|
flex-direction: column;
|
gap: var(--dash-gap);
|
}
|
|
::v-deep .electrical-warning-panel,
|
::v-deep .daily-energy-panel {
|
margin-top: 0 !important;
|
border: 1px solid var(--dash-border);
|
box-shadow: var(--dash-shadow);
|
border-radius: var(--dash-radius);
|
}
|
|
.schedule-panel__calendar {
|
::v-deep .wh_content_item {
|
height: 50px;
|
color: var(--dash-text);
|
font-size: 14px;
|
}
|
|
::v-deep .wh_item_date {
|
width: 30px;
|
height: 30px;
|
font-size: 14px;
|
}
|
|
::v-deep .wh_content_all {
|
background-color: transparent;
|
}
|
|
::v-deep .wh_top_changge {
|
display: none;
|
}
|
|
::v-deep .wh_container {
|
max-width: 100%;
|
}
|
|
::v-deep .wh_content_item .wh_isToday {
|
background-color: rgba(62, 128, 239, 0.47);
|
color: #ffffff;
|
}
|
|
::v-deep .wh_item_date:hover {
|
background-color: var(--dash-primary);
|
border-radius: 50%;
|
color: #ffffff;
|
}
|
|
::v-deep .wh_content_item .wh_chose_day {
|
background: var(--dash-primary);
|
color: #fff;
|
}
|
|
::v-deep .markRed {
|
position: relative;
|
}
|
|
::v-deep .markRed::after {
|
content: '●';
|
color: #FF9E00;
|
font-size: 11px;
|
position: absolute;
|
bottom: -30px;
|
left: 50%;
|
transform: translate(-50%, 0);
|
}
|
}
|
|
@media (max-width: 1400px) {
|
.dashboard-top {
|
flex-direction: column;
|
}
|
|
.schedule-panel {
|
width: 100%;
|
}
|
}
|
|
@media (max-width: 1200px) {
|
.quick-menu__grid {
|
grid-template-columns: repeat(3, 1fr);
|
}
|
|
.stat-cards {
|
flex-direction: column;
|
}
|
}
|
|
@media (max-width: 768px) {
|
.quick-menu__grid {
|
grid-template-columns: repeat(2, 1fr);
|
}
|
}
|
</style>
|