YNUtdPlatform/pages/realName/index/index.vue

997 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<u-navbar
class="u-navbar"
title="首页"
placeholder
@leftClick="leftClick"
leftIconColor="#fff"
bgColor="#00337A"
:titleStyle="{ color: '#FFF', fontSize: '32rpx' }"
/>
<scroll-view scroll-y="true">
<!-- 轮播图区域 -->
<swiper class="swiper-container" autoplay interval="3000" circular indicator-dots>
<!-- 轮播图 1 -->
<swiper-item class="item_1 swiper-item-container">
<view>
<image
class="img-container"
src="../../../static/images/img-phase-two/index_img_one_person.png"
mode=""
></image>
<text>今日考勤{{ attPersonNum }}</text>
<text>固定人员{{ einFormalAttPersonNum }}</text>
<text>临时人员{{ einTemporaryAttPersonNum }}</text>
</view>
<view>
<image
class="img-container"
src="../../../static/images/img-phase-two/index_img_one_att.png"
mode=""
></image>
<text>在场考勤率{{ ((attPersonNum / einPersonNum) * 100).toFixed(2) }}%</text>
<text>计划考勤率{{ ((planAttNum / planPersonNum) * 100).toFixed(2) }}%</text>
<text class="none-box">计划考勤率20%</text>
</view>
</swiper-item>
<!-- 轮播图 2 -->
<swiper-item class="item_2 swiper-item-container">
<view>
<image
class="img-container-2"
src="../../../static/images/img-phase-two/index_img_two_risk.png"
mode=""
></image>
<text>今日风险</text>
</view>
<view>
<text>高风险{{ highRiskNum }}</text>
<text>中风险{{ mediumRiskNum }}</text>
<text>低风险{{ lowRiskNum }}</text>
<text>计划作业人数{{ planPersonNum }}</text>
</view>
</swiper-item>
<!-- 轮播图 3 -->
<swiper-item class="item_3 swiper-item-container">
<view>
<image
class="img-container"
src="../../../static/images/img-phase-two/index_img_three_ein.png"
mode=""
></image>
<text>在场人数{{ einPersonNum }}</text>
<text>固定人数{{ formalPersonNum }}</text>
<text>临时人数{{ temporaryPersonNum }}</text>
</view>
<view>
<image
class="img-container"
src="../../../static/images/img-phase-two/index_img_three_light.png"
mode=""
></image>
<text>绿灯人数{{ greenNum }}</text>
<text>黄灯人数{{ yellowNum }}</text>
<text>红灯人数{{ redNum }}</text>
</view>
</swiper-item>
<swiper-item class="item_4 swiper-item-container">
<view>
<image
class="img-container-2"
src="../../../static/images/img-phase-two/index_img_four_pro.png"
mode=""
></image>
<text>项目信息</text>
</view>
<view>
<text>在建工程{{ buildProNum }}</text>
<text>投入分包{{ subNum }}</text>
<text>在用班组{{ teamNum }}</text>
<text>在场人员{{ einPersonNum }}</text>
</view>
</swiper-item>
</swiper>
<!-- 风险提示 -->
<view class="today-warning">
<image class="warning-img" src="../../../static/images/img-phase-two/index_news.png" mode=""></image>
<text>今日风险</text>
<view class="uni-notice-bar" @tap="onJumpWorkPlan">
<uni-notice-bar
style="height: 100%"
:speed="30"
background-color="#fff"
scrollable
:text="noticeText"
></uni-notice-bar>
</view>
</view>
<!-- 数据概览 -->
<view class="data-overview common-style">
<h3>数据概览</h3>
<view class="data-overview-content">
<view v-for="item in dataOverviewList" :key="item.data_title">
<image class="data-overview-img" :src="item.data_img_src" mode=""></image>
<view class="data-overview-item">
<text>{{ item.data_num }}</text>
<text>{{ item.data_title }}</text>
</view>
</view>
</view>
</view>
<!-- 人员考勤 -->
<view class="check-work-attendance common-style">
<h3>人员考勤率</h3>
<view class="check-work-attendance-container">
<view v-for="item in progressList" :key="item.progress_title">
<view class="top-title">
<text>{{ item.progress_title }}</text>
<text :style="{ color: item.textColor }">{{ item.progress_proportion }}%</text>
</view>
<view class="bottom-progress">
<view class="progress-box">
<progress :activeColor="item.textColor" :percent="item.progress_proportion" stroke-width="6" />
</view>
<text>{{ item.progress_ready }}/{{ item.progress_amount }}</text>
</view>
</view>
</view>
</view>
<!-- 工程概况 -->
<view class="project-container common-style">
<h3>工程概况</h3>
<view class="project-content">
<view v-for="item in projectList" :key="item.project_title">
<view class="top-title">
<text>{{ item.project_title }}</text>
<text>{{ item.project_num }}</text>
</view>
<view class="bottom-progress">
<view class="progress-box">
<progress :activeColor="item.textColor" :percent="item.project_ratio" stroke-width="6" />
</view>
</view>
</view>
</view>
<!-- 饼图 -->
<view class="charts_container">
<PieChartsModel />
</view>
<!-- 柱状图 -->
<view class="charts_container">
<BarChartsModel />
</view>
</view>
<!-- 在场人员概况 -->
<view class="person-container common-style">
<h3>在场人员概况</h3>
<view class="person-content">
<view>
<image class="person-img" src="../../../static/images/img-phase-two/index_green_light.png" mode=""></image>
<text class="text-strong">{{ ((greenNum / colorAmount) * 100).toFixed(2) }}%</text>
<text>{{ greenNum }}</text>
</view>
<view>
<image class="person-img" src="../../../static/images/img-phase-two/index_yellow_light.png" mode=""></image>
<text class="text-strong">{{ ((yellowNum / colorAmount) * 100).toFixed(2) }}%</text>
<text>{{ yellowNum }}</text>
</view>
<view>
<image class="person-img" src="../../../static/images/img-phase-two/index_red_light.png" mode=""></image>
<text class="text-strong">{{ ((redNum / colorAmount) * 100).toFixed(2) }}%</text>
<text>{{ redNum }}</text>
</view>
</view>
<view class="gender-content">
<view class="man-left">
<view>
<view>{{ ((maleNum / sexAmount) * 100).toFixed(2) }}%</view>
<view>男({{ maleNum }})</view>
</view>
<view class="gender-img" style="margin-left: 30rpx; background-color: #67cde6"></view>
</view>
<view class="girl-right">
<view class="gender-img" style="margin-right: 30rpx; background-color: #fc8483"></view>
<view>
<view>{{ ((femaleNum / sexAmount) * 100).toFixed(2) }}%</view>
<view>女({{ femaleNum }})</view>
</view>
</view>
</view>
<h5>固定、临时人员</h5>
<view class="person-num">
<view style="color: #04cdfa">
<image
style="width: 60rpx; height: 60rpx; margin-left: 10rpx"
src="../../../static/images/img-phase-two/index_img_person.png"
mode=""
></image>
{{ formalPersonNum }}
</view>
<view style="color: #fd8d01">
<image
style="width: 60rpx; height: 60rpx; margin-right: 10rpx"
src="../../../static/images/img-phase-two/index_img_person.png"
mode=""
></image>
{{ temporaryPersonNum }}
</view>
</view>
<view class="person-num-progress">
<progress
activeColor="#52bff3"
backgroundColor="#fac13b"
:percent="(formalPersonNum / (formalPersonNum + temporaryPersonNum)) * 100"
stroke-width="6"
/>
</view>
<view class="person-proportion">
<text style="color: #04cdfa">
固定占比{{ ((formalPersonNum / (formalPersonNum + temporaryPersonNum)) * 100).toFixed(2) }}%
</text>
<text style="color: #fd8d01">
流动占比 {{ ((temporaryPersonNum / (formalPersonNum + temporaryPersonNum)) * 100).toFixed(2) }}%
</text>
</view>
<view class="charts_container">
<PieChartsModelRing />
</view>
<view class="charts_container">
<PieChartsModelRingTwo />
</view>
</view>
</scroll-view>
<m-tabbar fixed fill :current="0" :tabbar="tabbar"></m-tabbar>
</view>
</template>
<script>
import TabbarConfig from '../util/tabbar.js'
import config from '@/config'
import AES from '@/utils/realNameAes.js'
import PieChartsModel from './components/pie-charts-model'
import BarChartsModel from './components/bar-charts-model'
import PieChartsModelRing from './components/pie-charts-model-ring'
import PieChartsModelRingTwo from './components/pie-charts-model-ring-two'
import { getHomePageListApi } from '@/api/phaseTwo/homePage'
export default {
components: {
PieChartsModel,
BarChartsModel,
PieChartsModelRing,
PieChartsModelRingTwo
},
data() {
return {
userId: uni.getStorageSync('userId'),
tabbar: TabbarConfig,
msgList: [],
dataOverviewList: [
{
data_title: '在建工程',
data_num: 0,
data_img_src: '../../../static/images/img-phase-two/index_img_pro.png'
},
{
data_title: '在用分包单位',
data_num: 0,
data_img_src: '../../../static/images/img-phase-two/index_img_sub.png'
},
{
data_title: '在用班组',
data_num: 0,
data_img_src: '../../../static/images/img-phase-two/index_img_team.png'
},
{
data_title: '在场人数',
data_num: 0,
data_img_src: '../../../static/images/img-phase-two/index_img_person.png'
},
{
data_title: '日计划打卡数',
data_num: 0,
data_img_src: '../../../static/images/img-phase-two/index_img_plan_person.png'
},
{
data_title: '今日打卡',
data_num: 0,
data_img_src: '../../../static/images/img-phase-two/index_img_att.png'
}
],
progressList: [
{
progress_title: '在场考勤率',
progress_proportion: 0,
progress_amount: 0,
progress_ready: 0,
textColor: '#17cef3'
},
{
progress_title: '作业考勤率',
progress_proportion: 0,
progress_amount: 0,
progress_ready: 0,
textColor: '#25c294'
},
{
progress_title: '在场人员(固定)',
progress_proportion: 0,
progress_amount: 0,
progress_ready: 0,
textColor: '#f2df55'
},
{
progress_title: '在场人员(临时)',
progress_proportion: 0,
progress_amount: 0,
progress_ready: 0,
textColor: '#186ff0'
},
{
progress_title: '考勤率(固定人员)',
progress_proportion: 0,
progress_amount: 0,
progress_ready: 0,
textColor: '#f9971e'
},
{
progress_title: '考勤率(临时人员)',
progress_proportion: 0,
progress_amount: 0,
progress_ready: 0,
textColor: '#f44d46'
}
],
projectList: [
{
project_title: '在建',
project_ratio: 0,
project_num: 0,
textColor: '#186ff0'
},
{
project_title: '筹建',
project_ratio: 0,
project_num: 0,
textColor: '#f2df55'
},
{
project_title: '停工',
project_ratio: 0,
project_num: 0,
textColor: '#f9971e'
},
{
project_title: '完工',
project_ratio: 0,
project_num: 0,
textColor: '#25c294'
}
],
attPersonNum: 0,
einFormalAttPersonNum: 0,
einTemporaryAttPersonNum: 0,
highRiskNum: 0,
mediumRiskNum: 0,
lowRiskNum: 0,
planPersonNum: 0,
einPersonNum: 0,
formalPersonNum: 0,
temporaryPersonNum: 0,
greenNum: 0,
yellowNum: 0,
redNum: 0,
buildProNum: 0,
subNum: 0,
teamNum: 0,
planAttNum: 0,
noticeText: '',
maleNum: 0,
femaleNum: 0,
sexAmount: 0
// planProNum: 0,
// redPersonNum: 0,
// yellowPersonNum: 0,
// greenPersonNum: 0,
// buildProNum: 0,
// subNum: 0,
// teamNum: 0,
// subNum: 0
// formalPersonNum: 0
}
},
onLoad() {
console.log('?? ~ mounted ~ mounted-index:')
this.getLogin()
this.getHomePageListData()
},
methods: {
getLogin() {
const realParams = {
username: AES.encrypt(uni.getStorageSync('userPhone')),
password: AES.encrypt('YNsbd@123456'),
jwtToken: uni.getStorageSync('App-Token')
}
uni.request({
url: config.realLoginUrl + 'login',
method: 'POST',
data: JSON.stringify(realParams),
header: {
'Content-Type': 'application/json'
},
success: res => {
console.log('?? ~ gotoYy ~ res:', res)
// console.log('?? ~ gotoYy ~ res:', res.data.token)
if (res.data.code == 200) {
// uni.setStorageSync('tjToken', res.data.token)
uni.setStorageSync('realNameToken', res.data.data.access_token)
uni.setStorageSync('realNameUser', res.data.data.loginUser.sysUser)
uni.setStorageSync('realNamePermissions', res.data.data.loginUser.permissions)
uni.removeStorageSync('hasChosenPro')
} else {
uni.showToast({
title: res.message,
icon: 'none'
})
}
},
fail: err => {
console.log('?? ~ gotoYy ~ err:', err)
uni.showToast({
title: err.message,
icon: 'none'
})
}
})
},
// 获取消息列表
async getMsgList() {
uni.request({
url: config.bmwUrl + '/studentUsers/getNoticeList',
method: 'post',
data: {},
header: {
Authorization: uni.getStorageSync('access_token')
},
success: res => {
console.log('?? ~ getMsgList ~ res:', res)
this.msgList = res.data
console.log('?? ~ getMsgList ~ this.msgList:', this.msgList)
}
})
},
// 点击消息
handleMsg() {
uni.navigateTo({
url: '/pages/realName/my/myMsg'
})
},
openFaceScan() {
face.open(['a', 'c'], function (e) {
face.close()
})
},
// 返回
leftClick() {
console.log('返回')
// // 退出登录
// uni.removeStorageSync('access_token')
// uni.removeStorageSync('userId')
// uni.removeStorageSync('userName')
// uni.removeStorageSync('className')
// uni.removeStorageSync('facePath')
uni.reLaunch({
url: '/pages/gzt/index'
})
},
/* 获取首页数据 */
async getHomePageListData() {
const { data: res } = await getHomePageListApi({})
console.log('首页数据', res)
const { homePageBean, personAtt, workerMsgBean, proMsgBean } = res
const { highRiskNum, mediumRiskNum, lowRiskNum, planPersonNum } = homePageBean
const { buildProNum, prepareProNum, stopProNum, completeProNum } = proMsgBean
this.noticeText = `高风险:${highRiskNum} 中风险:${mediumRiskNum} 低风险:${lowRiskNum} 作业计划人数:${planPersonNum}`
this.highRiskNum = homePageBean.highRiskNum
this.mediumRiskNum = homePageBean.mediumRiskNum
this.lowRiskNum = homePageBean.lowRiskNum
this.planPersonNum = homePageBean.planPersonNum
this.attPersonNum = personAtt.attPersonNum
this.einFormalAttPersonNum = personAtt.einFormalAttPersonNum
this.einTemporaryAttPersonNum = personAtt.einTemporaryAttPersonNum
this.planAttNum = personAtt.planAttNum
this.einPersonNum = homePageBean.einPersonNum
this.formalPersonNum = personAtt.formalPersonNum
this.temporaryPersonNum = personAtt.temporaryPersonNum
this.greenNum = workerMsgBean.greenNum
this.yellowNum = workerMsgBean.yellowNum
this.redNum = workerMsgBean.redNum
this.maleNum = workerMsgBean.maleNum
this.femaleNum = workerMsgBean.femaleNum
this.sexAmount = this.maleNum + this.femaleNum
this.colorAmount = this.greenNum + this.yellowNum + this.redNum
this.buildProNum = homePageBean.buildProNum
this.subNum = homePageBean.subNum
this.teamNum = homePageBean.teamNum
// this.einPersonNum = homePageBean.einPersonNum
this.dataOverviewList[0].data_num = this.buildProNum
this.dataOverviewList[1].data_num = this.subNum
this.dataOverviewList[2].data_num = this.teamNum
this.dataOverviewList[3].data_num = this.einPersonNum
this.dataOverviewList[4].data_num = this.planAttNum
this.dataOverviewList[5].data_num = this.attPersonNum
this.progressList.forEach((e, i) => {
if (i === 0 || i === 2 || i === 3) {
e.progress_amount = this.einPersonNum
}
if (i === 0) {
e.progress_ready = this.attPersonNum
}
if (i === 1) {
e.progress_amount = this.planPersonNum
e.progress_ready = this.planAttNum
}
if (i === 2) {
e.progress_ready = this.formalPersonNum
}
if (i === 3) {
e.progress_ready = this.temporaryPersonNum
}
if (i === 4) {
e.progress_amount = this.formalPersonNum
e.progress_ready = this.einFormalAttPersonNum
}
if (i === 5) {
e.progress_amount = this.einTemporaryAttPersonNum
e.progress_ready = this.einTemporaryAttPersonNum
}
e.progress_proportion = ((e.progress_ready / e.progress_amount) * 100).toFixed(0)
})
console.log('this.progressList', this.progressList)
const proAmount = buildProNum + prepareProNum + stopProNum + completeProNum
this.projectList.forEach((e, i) => {
if (i === 0) {
e.project_num = buildProNum
}
if (i === 1) {
e.project_num = prepareProNum
}
if (i === 2) {
e.project_num = stopProNum
}
if (i === 3) {
e.project_num = completeProNum
}
e.project_ratio = ((e.project_num / proAmount) * 100).toFixed(0)
})
},
/* 跳转作业计划 */
onJumpWorkPlan() {
uni.navigateTo({ url: '/pages/realName/workPlan/index' })
}
},
onShow() {}
}
</script>
<style lang="scss" scoped>
/* 修改U-Navbar中链接的字体颜色 */
/deep/.u-navbar .navbar-nav > li > a {
color: #fff; /* 将颜色改为红色 */
}
/* 如果你想修改当前激活链接的字体颜色 */
/deep/.u-navbar .navbar-nav > li.active > a {
color: #fff; /* 将激活链接的颜色改为绿色 */
}
.page {
width: 100vw;
height: 100vh;
background-color: #efefef;
box-sizing: border-box;
padding: 0 10rpx;
.search {
width: 100%;
margin: 0 auto;
display: flex;
align-items: center;
}
.opt-grids {
width: 100%;
display: flex;
flex-wrap: wrap;
margin: 3vh auto;
view {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
//margin-bottom: 2vh;
image {
width: 60%;
height: 7vh;
margin-bottom: 10px;
}
span {
font-size: 26rpx;
font-weight: bold;
}
}
}
.swipe-area {
width: 100%;
height: 20vh;
border-radius: 15rpx;
overflow: hidden;
margin-bottom: 10rpx;
}
.my-task {
width: 100%;
height: 40vh;
background-color: #fff;
border-radius: 15rpx;
box-shadow: 3px 3px 3px #f4f4f4;
box-sizing: border-box;
padding: 15rpx;
display: flex;
flex-direction: column;
.task-list {
flex: 1;
overflow-y: auto;
.list-item {
margin: 10px 0;
background-color: #efefef;
border-radius: 5px;
padding: 5px;
font-size: 13px;
.item-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 5px;
}
.item-progress {
display: flex;
align-items: center;
.u-line-progress {
width: 80%;
margin-right: 10px;
}
}
}
.no-task {
width: 100%;
height: 100%;
display: flex;
.no-task-img {
width: 80%;
height: 80%;
margin: auto;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
image {
width: 100%;
height: 90%;
}
span {
font-size: 14px;
color: #c2c2c2;
}
}
}
}
}
h3 {
padding: 30rpx 20rpx;
letter-spacing: 3rpx;
}
.common-style {
margin-top: 20rpx;
border-radius: 20rpx;
background-color: #fff;
}
// 轮播图
.swiper-container {
height: 400rpx;
color: #fff;
.swiper-item-container {
height: 100%;
padding-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: space-around;
view {
display: flex;
flex-direction: column;
align-items: center;
font-size: 28rpx;
font-weight: bold;
text {
padding: 10rpx 0;
letter-spacing: 5rpx;
}
}
}
.item_2 view:last-child {
align-items: flex-start;
}
.item_1 {
background: url('../../../static/images/img-phase-two/index_img_one.png');
background-size: 100% 100%;
}
.item_2 {
background: url('../../../static/images/img-phase-two/index_img_two.png');
background-size: 100% 100%;
}
.item_3 {
background: url('../../../static/images/img-phase-two/index_img_three.png');
background-size: 100% 100%;
}
.item_4 {
background: url('../../../static/images/img-phase-two/index_img_four.png');
background-size: 100% 100%;
}
.img-container {
width: 90rpx;
height: 90rpx;
}
.img-container-2 {
width: 140rpx;
height: 140rpx;
}
.none-box {
color: transparent;
}
}
// 今日风险
.today-warning {
margin: 30rpx 0;
height: 68rpx;
padding: 0 30rpx;
display: flex;
align-items: center;
border: 1rpx solid #ccc;
background: #fff;
border-radius: 58rpx;
.warning-img {
width: 46rpx;
height: 46rpx;
}
.uni-notice-bar {
flex: 1;
height: 50rpx;
// line-height: 50rpx;
// background-color: orange;
}
}
// 数据概览
.data-overview {
.data-overview-content {
padding: 0 10rpx;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
view {
width: 33.33%;
display: flex;
align-items: center;
.data-overview-img {
width: 100rpx;
height: 100rpx;
}
.data-overview-item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: flex-start;
font-size: 24rpx;
font-weight: bold;
}
}
}
}
// 人员考勤率
.check-work-attendance {
.check-work-attendance-container {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
view {
width: calc(50% - 40rpx);
padding: 0 10rpx;
margin-bottom: 15rpx;
.top-title,
.bottom-progress {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.progress-box {
flex: 1;
margin-right: 15rpx;
}
}
.top-title text:last-child {
font-weight: bold;
}
}
}
}
// 工程概况
.project-container {
.project-content {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
view {
width: calc(50% - 40rpx);
padding: 0 10rpx;
margin-bottom: 15rpx;
.top-title,
.bottom-progress {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.progress-box {
flex: 1;
margin-right: 15rpx;
}
}
.top-title text:last-child {
font-weight: bold;
}
}
}
}
.charts_container {
width: 100%;
height: 460rpx;
}
// 在场人员概况
.person-container .person-content {
display: flex;
align-items: center;
justify-content: space-around;
.person-img {
width: 160rpx;
height: 160rpx;
}
view {
display: flex;
flex-direction: column;
align-items: center;
}
.text-strong {
font-size: 24rpx;
font-weight: bold;
}
}
.gender-content {
display: flex;
.man-left,
.girl-right {
width: 50%;
height: 300rpx;
display: flex;
align-items: center;
justify-content: center;
.gender-img {
width: 120rpx;
height: 240rpx;
background-color: orange;
}
}
}
h5 {
font-weight: normal;
margin: 30rpx 0 15rpx;
text-align: center;
letter-spacing: 2rpx;
font-size: 28rpx;
}
.person-num {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 40rpx;
image {
vertical-align: middle;
}
}
.person-num-progress {
padding: 0 15rpx;
margin: 20rpx 0;
}
.person-proportion {
margin: 15rpx 0;
padding: 0 25rpx;
display: flex;
align-content: center;
justify-content: space-between;
}
}
.charts-box {
width: 70%;
height: 460rpx;
margin: 0 auto;
}
.gender-img {
border-radius: 18rpx;
}
</style>