大屏修改

This commit is contained in:
zzyuan 2025-11-27 09:24:46 +08:00
parent d45319783b
commit a1c8637d10
3 changed files with 990 additions and 666 deletions

View File

@ -112,23 +112,23 @@ service.interceptors.response.use(res => {
const username = Cookies.get('username')
const password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe')
if(rememberMe==true){
let loginForm = {
code: "",
loginMethod: "password",
loginType: "",
mobile: "",
mobileCodeType: "LOGIN",
password: password,
phoneUuid: "",
rememberMe: rememberMe,
username: username,
uuid: "",
verificationCode: ""
}
console.log(loginForm)
store.dispatch('Login', loginForm).then(() => {})
}else{
// if(rememberMe==true){
// let loginForm = {
// code: "",
// loginMethod: "password",
// loginType: "",
// mobile: "",
// mobileCodeType: "LOGIN",
// password: password,
// phoneUuid: "",
// rememberMe: rememberMe,
// username: username,
// uuid: "",
// verificationCode: ""
// }
// console.log(loginForm)
// store.dispatch('Login', loginForm).then(() => {})
// }else{
let loginForm = {
code: "",
loginMethod: "password",
@ -162,9 +162,9 @@ service.interceptors.response.use(res => {
// isRelogin.show = false
// })
// }
}
// }
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
// return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
const username = Cookies.get('username')
const password = Cookies.get('password')

682
src/views/view copy.vue Normal file
View File

@ -0,0 +1,682 @@
<template>
<div class="container">
<div class="topdiv">
<div class="dateTimeClass">
<span style="color:#D8E2FF;font-size: 24px;margin-top: 12px;">{{dateTime}}</span>
</div>
<div class="titlediv">
公示大屏
</div>
<div class="hourTimeClass">
<span style="color:#D8E2FF;font-size: 24px;margin-top: 12px;">{{hourTime}}</span>
</div>
</div>
<div style="height: auto;width: 100%;margin-bottom: 40px;">
<div class="partthree_title"><span>健康晨检</span></div>
<div class="partthree_title2"><div class="fegexian2" style="margin-top: 2px;"></div></div>
<div class="contentclass">
<table style="width: 100%;height: 100%;">
<tr>
<td>晨检</td>
<td>健康证</td>
</tr>
<tr style="height: 100%;width: 100%;">
<!-- 图表容器统一设置固定宽高+100%填充避免尺寸偏差 -->
<td rowspan="5" style="width: 50%;">
<div style="width: 100%;height: 240px;display: flex;align-items: center;justify-content: center;">
<div ref="chartone" style="width: 90%;height: 90%;"></div>
</div>
</td>
<td rowspan="5" style="width: 50%;">
<div style="width: 100%;height: 240px;display: flex;align-items: center;justify-content: center;">
<div ref="chartfour" style="width: 90%;height: 90%;"></div>
</div>
</td>
</tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr>
<td>晨检正常{{Number(morningCheckNum)-Number(morningCheckAbno)}}</td>
<td>正常{{Number(healthNum)-Number(healthAbno)}}</td>
</tr>
<tr>
<td>晨检异常{{morningCheckAbno}}</td>
<td>过期{{healthAbno}}</td>
</tr>
</table>
</div>
</div>
<div style="height: auto;width: 100%;margin-bottom: 40px;">
<div class="partthree_title"><span>今日菜品</span></div>
<div class="partthree_title2"><div class="fegexian2" style="margin-top: 2px;"></div></div>
<div class="contentclass">
<div style="width: 80%;border: 1px solid rgba(191,191,255,0.04);margin-top: 10px;">
<div class="dishclass">
<img src="../assets/images/Frame1.png"/><span>早餐供应</span><img src="../assets/images/breakfast.png" style="float: right;"/>
</div>
<div class="dishcontentclass">
<template v-if="onedataList.length>0">
<template v-for="(group, groupIndex) in groupedBreakfastList">
<div class="dishcontentrefclass" v-for="item in group.dishes" :key="item.id || item.dishesName">
{{item.dishesName}}&nbsp;&nbsp;&nbsp;&nbsp;
</div>
</template>
</template>
</div>
</div>
<div style="width: 80%;border: 2px solid rgba(191,191,255,0.04);margin-top: 10px;">
<div class="dishclass">
<img src="../assets/images/Frame2.png"/><span>午餐供应</span><img src="../assets/images/lunch.png" style="float: right;"/>
</div>
<div class="dishcontentclass">
<template v-if="twodataList.length>0">
<div v-for="(group, groupIndex) in groupedLunchList" :key="groupIndex" style="width: 100%;display: flex;align-items: baseline;">
<div class="dishtypeclass" v-if="group.dishes.length>0 && group.typeName" :key="'type-' + groupIndex">
{{getDisplayTypeName(group.typeName)}}
</div>
<div style="width: 80%;display: flex;align-items: center;flex-wrap: wrap;">
<div class="dishcontentrefclass" style="width: 30%;" v-for="item in group.dishes" :key="item.id || item.dishesName">
{{item.dishesName}}&nbsp;&nbsp;&nbsp;&nbsp;
</div>
</div>
</div>
</template>
</div>
</div>
<div style="width: 80%;border: 2px solid rgba(191,191,255,0.04);margin-top: 10px;">
<div class="dishclass">
<img src="../assets/images/Frame.png"/><span>晚餐供应</span><img src="../assets/images/dinner.png" style="float: right;"/>
</div>
<div class="dishcontentclass">
<template v-if="fourdataList.length>0">
<div class="dishcontentrefclass" v-for="item in fourdataList" :key="item.id || item.dishesName">
{{item.dishesName}}&nbsp;&nbsp;&nbsp;&nbsp;
</div>
</template>
</div>
</div>
</div>
</div>
<div style="height: auto;width: 90%;margin: 0 auto;">
<div class="partthree_title"><span>证件公示(健康证)</span></div>
<div class="partthree_title2"><div class="fegexian2" style="margin-top: 2px;"></div></div>
<div style="width: 100%; height:100%; ">
<carousel :per-page="4" :mouse-drag="true" :autoplay="true" :autoplay-timeout="4000" :loop="true" >
<slide v-for="(item, index) in staffNums" :key="index">
<div style="padding: 10px;;width: 240px;overflow: hidden;">
<img style="width: 240px; object-fit: cover;" :src="item.healthCertFrontImg"/>
</div>
</slide>
</carousel>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import VueCarousel from 'vue-carousel';
Vue.use(VueCarousel);
import axios from 'axios';
import Cookies from 'js-cookie';
import { getCurrentRecipeListApi,getCertificateListApi,getMorningCheckInfoApi } from "@/api/view";
import * as echarts from 'echarts';
export default {
name: "Index",
data() {
return {
version: "24.7.1",
mealNum:0,
dateTime:'',
hourTime:'',
countTime:0,
sysTime:0,
timer:null,
timer2:null,
morningCheckNum:0, //
morningCheckPerc:0,//
morningCheckAbno:0,//
healthNum:0, //
healthPerc:0,//
healthAbno:0,//
onedataList:[{"dishesName":"无菜单","salePrice":""}],
twodataList:[{"dishesName":"无菜单","salePrice":""}],
threedataList:[{"dishesName":"无菜单","salePrice":""}],
fourdataList:[{"dishesName":"无菜单","salePrice":""}],
fivedataList:[{"dishesName":"无菜单","salePrice":""}],
staffNums:[],
dataForm:{type:1},
angle:0,
queryParams: {
pageNum: 1,
pageSize: 10,
key:"2",
applyDate:"",
areaId:null,
canteenId:null,
stallId:null,
recipeName:"",
},
// resize
chartOne: null,
chartFour: null
};
},
created() {
},
mounted() {
this.handleLogin()
window.addEventListener('popstate', this.handlePopState);
this.getMorningCheck()
this.timer = setInterval(() => {
this.initData();
}, 600000);
this.timer2 = setInterval(this.getCurrentTime, 1000);
setTimeout(()=>{
this.initData();
},1500)
// ------------ 1. ------------
document.addEventListener('touchstart', this.handleTouchStart);
document.addEventListener('touchmove', this.handleTouchMove, { passive: false });
document.addEventListener('wheel', this.handleWheel, { passive: false });
// resize
window.addEventListener('resize', this.handleWindowResize);
},
beforeDestroy() {
window.removeEventListener('popstate', this.handlePopState);
clearInterval(this.timer);
clearInterval(this.timer2);
// ------------ ------------
document.removeEventListener('touchstart', this.handleTouchStart);
document.removeEventListener('touchmove', this.handleTouchMove);
document.removeEventListener('wheel', this.handleWheel);
window.removeEventListener('resize', this.handleWindowResize);
//
if (this.chartOne) this.chartOne.dispose();
if (this.chartFour) this.chartFour.dispose();
},
computed: {
groupedBreakfastList() {
if (!this.onedataList || this.onedataList.length === 0) {
return [];
}
const hasTypeName = this.onedataList.some(item => item.dishesTypeName);
if (!hasTypeName) {
return [{ typeName: '', dishes: this.onedataList, isBreakfastMingdang: false }];
}
const typeMap = {};
this.onedataList.forEach(item => {
const typeName = item.dishesTypeName || '其他';
if (!typeMap[typeName]) typeMap[typeName] = [];
typeMap[typeName].push(item);
});
const result = [];
if (typeMap['早餐-明档']) {
result.push({ typeName: '早餐-明档', dishes: typeMap['早餐-明档'], isBreakfastMingdang: true });
delete typeMap['早餐-明档'];
}
if (typeMap['早餐明档']) {
result.push({ typeName: '早餐明档', dishes: typeMap['早餐明档'], isBreakfastMingdang: true });
delete typeMap['早餐明档'];
}
Object.keys(typeMap).forEach(typeName => {
if (typeMap[typeName].length > 0) {
result.push({ typeName, dishes: typeMap[typeName], isBreakfastMingdang: false });
}
});
return result;
},
groupedLunchList() {
if (!this.twodataList || this.twodataList.length === 0) return [];
const hasTypeName = this.twodataList.some(item => item.dishesTypeName);
if (!hasTypeName) return [{ typeName: '', dishes: this.twodataList }];
const typeMap = {};
this.twodataList.forEach(item => {
const typeName = item.dishesTypeName || '其他';
if (!typeMap[typeName]) typeMap[typeName] = [];
typeMap[typeName].push(item);
});
const lunchOrder = ['午餐-荤菜', '午餐-炒菜', '午餐-素菜', '午餐-汤类', '午餐-五谷杂粮', '荤菜', '炒菜', '素菜', '汤类', '五谷杂粮','杂粮'];
const result = [];
lunchOrder.forEach(typeName => {
if (typeMap[typeName]?.length > 0) {
result.push({ typeName, dishes: typeMap[typeName] });
delete typeMap[typeName];
}
});
Object.keys(typeMap).forEach(typeName => {
if (typeMap[typeName].length > 0) result.push({ typeName, dishes: typeMap[typeName] });
});
return result;
},
groupedAfternoonTeaList() {
if (!this.threedataList || this.threedataList.length === 0) return [];
const hasTypeName = this.threedataList.some(item => item.dishesTypeName);
if (!hasTypeName) return [{ typeName: '', dishes: this.threedataList }];
const typeMap = {};
this.threedataList.forEach(item => {
const typeName = item.dishesTypeName || '其他';
if (!typeMap[typeName]) typeMap[typeName] = [];
typeMap[typeName].push(item);
});
return Object.keys(typeMap).map(typeName => ({ typeName, dishes: typeMap[typeName] }));
},
groupedDinnerList() {
if (!this.fourdataList || this.fourdataList.length === 0) return [];
const hasTypeName = this.fourdataList.some(item => item.dishesTypeName);
if (!hasTypeName) return [{ typeName: '', dishes: this.fourdataList }];
const typeMap = {};
this.fourdataList.forEach(item => {
const typeName = item.dishesTypeName || '其他';
if (!typeMap[typeName]) typeMap[typeName] = [];
typeMap[typeName].push(item);
});
return Object.keys(typeMap).map(typeName => ({ typeName, dishes: typeMap[typeName] }));
},
groupedNightSnackList() {
if (!this.fivedataList || this.fivedataList.length === 0) return [];
const hasTypeName = this.fivedataList.some(item => item.dishesTypeName);
if (!hasTypeName) return [{ typeName: '', dishes: this.fivedataList }];
const typeMap = {};
this.fivedataList.forEach(item => {
const typeName = item.dishesTypeName || '其他';
if (!typeMap[typeName]) typeMap[typeName] = [];
typeMap[typeName].push(item);
});
return Object.keys(typeMap).map(typeName => ({ typeName, dishes: typeMap[typeName] }));
}
},
methods: {
// ------------ 2. ------------
handlePopState(event) {
event.preventDefault();
},
//
handleTouchStart(e) {
this.touchStartX = e.touches[0].clientX;
this.touchStartY = e.touches[0].clientY;
},
//
handleTouchMove(e) {
if (!this.touchStartX || !this.touchStartY) return;
const diffX = e.touches[0].clientX - this.touchStartX;
const diffY = e.touches[0].clientY - this.touchStartY;
// /退
if (Math.abs(diffX) > Math.abs(diffY)) {
e.preventDefault();
}
},
//
handleWheel(e) {
if (e.deltaX !== 0) {
e.preventDefault();
}
},
// resize
handleWindowResize() {
if (this.chartOne) this.chartOne.resize();
if (this.chartFour) this.chartFour.resize();
},
//
handleLogin(){
let param = {
code: "",
loginType: "PHONE_PASSWORD",
password: "e07e2a30f7431f4aa173e8ba4e97fedc",
phoneUuid: "",
username: "60064de642247faee1559140f80c7246",
uuid: "",
verificationCode: ""
}
this.$store.dispatch('Login',param).then(res => {}).catch(() => {})
},
refrespage(){
this.$router.go(0);
return;
},
getMorningCheck(){
getMorningCheckInfoApi({type:1}).then(res => {
this.morningCheckNum=res.data.morningCheckNum;
this.morningCheckAbno=res.data.morningCheckAbno;
this.healthNum=res.data.healthNum;
this.healthAbno=res.data.healthAbno;
this.sysTime=Number(res.data.thisTime)
// DOM
this.$nextTick(() => {
this.initChartOne();
this.initChartFour();
});
});
},
getCurrentTime() {
this.countTime = this.countTime+1000;
var nowTime = this.countTime+this.sysTime
const now = new Date(nowTime);
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
this.dateTime = year+'-'+month+'-'+day;
this.hourTime = hours+':'+minutes+':'+seconds;
},
initData(){
this.queryParams.applyDate=this.dateTime;
getCurrentRecipeListApi(this.queryParams).then(response => {
if(response.rows!=null&&response.rows.length>0){
const datas= response.rows[0].detail.detailList;
if(datas!=null&&datas.length>0){
datas.map((item,index)=>{
if("1"==item.mealtimeType){
if(item.dishesList!=null&&item.dishesList.length>0){
this.onedataList=item.dishesList;
}
}else if("2"==item.mealtimeType){
if(item.dishesList!=null&&item.dishesList.length>0){
this.twodataList=item.dishesList;
}
}else if("3"==item.mealtimeType){
if(item.dishesList!=null&&item.dishesList.length>0){
this.threedataList=item.dishesList;
}
}else if("4"==item.mealtimeType){
if(item.dishesList!=null&&item.dishesList.length>0){
this.fourdataList=item.dishesList;
}
}else if(""==item.mealtimeType){
if(item.dishesList!=null&&item.dishesList.length>0){
this.fivedataList=item.dishesList;
}
}
})
}
}
});
this.queryParams.pageNum=1;
this.queryParams.pageSize=20;
getCertificateListApi(this.queryParams).then(res => {
this.staffNums=res.rows;
});
},
goTarget(href) {
window.open(href, "_blank");
},
// ------------ 3. ------------
initChartOne() {
this.morningCheckPerc = this.morningCheckNum == 0 ? 0 : ((this.morningCheckNum - this.morningCheckAbno) / this.morningCheckNum * 100).toFixed(2);
//
if (!this.$refs.chartone) return;
this.chartOne = echarts.init(this.$refs.chartone);
//
const option = {
title: {
text: `${this.morningCheckPerc}%`,
subtext: '合格率',
x: 'center',
y: 'center',
subtextStyle: { fontSize: 15, color: '#fff' },
textStyle: { fontWeight: 'normal', color: '#0580f2', fontSize: 15 }
},
color: ['rgba(176, 212, 251, 1)'],
legend: { show: false },
series: [{
name: 'Line 1',
type: 'pie',
clockWise: true,
radius: ['76%', '96%'], //
itemStyle: { normal: { label: { show: false }, labelLine: { show: false } } },
hoverAnimation: false,
data: [
{
value: this.morningCheckNum - this.morningCheckAbno,
name: '01',
itemStyle: {
normal: {
color: {
colorStops: [{ offset: 0, color: '#00cefc' }, { offset: 1, color: '#367bec' }]
}
}
}
},
{ name: '02', value: this.morningCheckAbno }
]
}]
};
this.chartOne.setOption(option);
},
initChartFour() {
this.healthPerc = this.healthNum == 0 ? 0 : ((this.healthNum - this.healthAbno) / this.healthNum * 100).toFixed(2);
if (!this.$refs.chartfour) return;
this.chartFour = echarts.init(this.$refs.chartfour);
//
const option = {
title: {
text: `${this.healthPerc}%`,
subtext: '合格率',
x: 'center',
y: 'center',
subtextStyle: { fontSize: 15, color: '#fff' },
textStyle: { fontWeight: 'normal', color: '#0580f2', fontSize: 15 }
},
color: ['rgba(176, 212, 251, 1)'],
legend: { show: false },
series: [{
name: 'Line 1',
type: 'pie',
clockWise: true,
radius: ['76%', '96%'], //
itemStyle: { normal: { label: { show: false }, labelLine: { show: false } } },
hoverAnimation: false,
data: [
{
value: this.healthNum - this.healthAbno,
name: '01',
itemStyle: {
normal: {
color: {
colorStops: [{ offset: 0, color: '#00cefc' }, { offset: 1, color: '#367bec' }]
}
}
}
},
{ name: '02', value: this.healthAbno }
]
}]
};
this.chartFour.setOption(option);
},
closeView(){
Cookies.remove('password')
this.$router.push({ path:'/login' });
},
getDisplayTypeName(typeName) {
if (!typeName) return '';
return typeName.replace(/^(早餐-|午餐-|下午茶-|晚餐-|夜宵-)/, '');
},
},
};
</script>
<style lang="scss" scoped>
/* ------------ 4. 禁止横向滚动样式 ------------ */
html, body, #app, .container {
width: 100%;
height: 100%;
overflow-x: hidden !important; /* 关键:禁止横向滚动 */
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
height: 100%;
width: 100%;
background-image: url("../assets/images/background.jpg");
background-size: cover;
background-position: center;
overflow-y: hidden; /* 保留垂直滚动(如果内容超出屏幕) */
// display: flex;
// justify-content: center;
// flex-wrap: wrap;
}
.topdiv{
width: 100%;
display: flex;
background-image: url("../assets/images/canteen1.png");
background-size: cover;
background-position: center;
height: 5%;
margin-bottom: 20px;
}
.titlediv{
display: flex;
width: 40%;
justify-content: center;
font-family: Alibaba PuHuiTi 2.0, Alibaba PuHuiTi 20;
font-weight: normal;
font-size: 34px;
color: #E1EFFF;
}
.dateTimeClass{
display: flex;
justify-content: center;
color:#fff;
width:30%;
align-items: center;
}
.hourTimeClass{
display: flex;
justify-content: center;
align-items: center;
color:#fff;
width:30%;
}
.titlediv2{
display: flex;
width: 100%;
// height: 10px;
justify-content: center;
align-items: flex-start;
color:#fff;
font-size: 28px;
// background-image: url("../assets/images/caidanline.png");
// background-size: cover;
// background-position:bottom;
}
.contentclass{
display: flex;
width: 100%;
justify-content: center;
flex-wrap: wrap;
color:#fff;
}
.fegexian{
width: 50%;
height: 5px;
// background-image: url("../assets/images/caidanline.png");
// background-size: cover;
// background-position: center;
}
.fegexian2{
width: 50%;
height: 5px;
background-image: url("../assets/images/caidanline.png");
background-size: cover;
background-position: center;
}
.dishclass{
font-family: Alibaba PuHuiTi 2.0, Alibaba PuHuiTi 20;
font-weight: normal;
font-size: 24px;
color: #D8E2FF;
text-align: left;
font-style: normal;
text-transform: none;
display: flex;
align-items: center;
margin: 1%;
}
.dishclass span{
background-image: linear-gradient(0deg, rgba(111,169,255,0.5) 30%, #6FA9FF 86%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.dishcontentclass{
display: flex;
align-items: flex-end;
flex-wrap: wrap;
margin-top: 1%;
font-family: Alibaba PuHuiTi 2.0, Alibaba PuHuiTi 20;
font-weight: normal;
font-size: 22px;
color: #D8E2FF;
text-align: left;
font-style: normal;
padding-bottom: 1%;
}
.dishcontentrefclass{
width: 22%;
margin-left: 2%;
margin-right: 1%;
margin-bottom: 10px;
}
.dishtypeclass{
width: 20%;
margin-left: 2%;
margin-bottom: 1%;
font-family: Alibaba PuHuiTi 2.0, Alibaba PuHuiTi 20;
font-weight: bold;
font-size: 24px;
color: #6FA9FF;
text-align: left;
font-style: normal;
}
.partthree{
height: 100%;
width: 85%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.partthree_title{
display: flex;
color:#fff;
font-size: 25px;
justify-content: center;
margin-bottom: 5px;
}
.partthree_title2{
display: flex;
height: 20px;
width: 100%;
justify-content: center;
}
.big-number {
font-size: 30px;
font-family: 'Arial', sans-serif;
color: #fff;
padding: 5px;
border-radius: 10px;
display: inline-flex;
}
.digit {
margin: 0 5px;
text-shadow: 0 0 10px rgba(255,255,255,0.5);
}
table, th, td {
text-align: center;
}
</style>

File diff suppressed because it is too large Load Diff