480 lines
13 KiB
Vue
480 lines
13 KiB
Vue
<!--
|
||
* @Author: XHC
|
||
* @Date: 2025-05-19 11:07:37
|
||
* @LastEditors: XHC
|
||
* @LastEditTime: 2025-06-09 09:40:25
|
||
* @Description: 首页
|
||
-->
|
||
<template>
|
||
<view class="index">
|
||
<view class="header">
|
||
<image src="/static/image/index/logo.png" mode="scaleToFill" />
|
||
<view class="title">
|
||
<view>多技术集约多部门协同综合巡检</view>
|
||
<view><text>◎ 集中管控</text> <text>◎ 部门协同</text> <text>◎ 提升效能</text></view>
|
||
</view>
|
||
</view>
|
||
<view class="nav-content">
|
||
<scroll-view
|
||
scroll-x="true"
|
||
class="content-scroll"
|
||
:show-scrollbar="false"
|
||
enable-flex
|
||
>
|
||
<view
|
||
v-for="(item, index) in departments"
|
||
:key="index"
|
||
:class="navCurIndex == index ? 'active' : ''"
|
||
class="control-item"
|
||
@click="changeTitle(index)"
|
||
>
|
||
{{ item.name }}
|
||
</view>
|
||
</scroll-view>
|
||
<view v-if="navCurIndex == 0">
|
||
<uni-card :is-shadow="false" class="patrol-card" >
|
||
<view class="time">巡检时间:<text>{{ patrolData.time }}</text></view>
|
||
<view class="card-info">
|
||
<view class="card-box">
|
||
<view class="total line"><text>线路总数</text><text>{{ patrolData.linesTotal }}</text></view>
|
||
<view class="lines" v-for="(item, index) in patrolData.lines" :key="index"><text class="title">{{ item.title }}</text><text class="num">{{ item.total }}</text></view>
|
||
|
||
</view>
|
||
<view class="card-box">
|
||
<view class="total point"><text>点位总数</text><text>{{ patrolData.pointTotal }}</text></view>
|
||
<view class="completion-rate">
|
||
<Dashboard :data="70.8"></Dashboard>
|
||
</view>
|
||
<view class="points-box">
|
||
<view class="points" v-for="(item, index) in patrolData.points" :key="index"><text class="title">{{ item.title }}</text><text class="num">{{ item.total }}</text></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="inlet-box">
|
||
<view class="history" @click="goToHistory">
|
||
<view class="title">
|
||
<view>历史巡检</view>
|
||
<view class="english">HISTORICAL INSPECTION</view>
|
||
</view>
|
||
<view class="go">GO</view>
|
||
</view>
|
||
<view class="report">
|
||
<view class="title">
|
||
<view>巡检报告</view>
|
||
<view class="english">INSPECTION REPORT</view>
|
||
</view>
|
||
<view class="go">GO</view>
|
||
</view>
|
||
</view>
|
||
</uni-card>
|
||
<view class="category-box">
|
||
<view
|
||
v-for="(item, index) in category"
|
||
:key="index"
|
||
:class="categoryCurIndex == index ? 'active' : ''"
|
||
class="category-item grey"
|
||
@click="changeCategory(index)"
|
||
>
|
||
{{ item.name }}
|
||
</view>
|
||
</view>
|
||
<view class="category-content">
|
||
<view>
|
||
<uni-card class="list-card" v-for="(item, index) in listData.taskList" :key="index" @click="goToStartInspection(item)">
|
||
<view class="head">
|
||
<text class="title">{{ item.title }}</text>
|
||
<!-- <uni-tag :inverted="true" :text="item.state == 0 ? '已巡检' : '未巡检'" :type="item.state == 0 ? 'success' : 'error'" /> -->
|
||
<uni-tag :inverted="true" :text="item.state" :type="item.state == '已巡检' ? 'success' : 'error'" />
|
||
</view>
|
||
<view class="num grey">线路编号:{{ item.num }}</view>
|
||
<view class="info-box grey">
|
||
<view class="info"> <uni-icons fontFamily="iconfont" color="#808185">{{''}}</uni-icons> {{ item.info }}</view>
|
||
<text class="info">任务 {{ item.task }}</text>
|
||
</view>
|
||
</uni-card>
|
||
<view v-if="listData.isLoadMore">
|
||
<uni-load-more :status="listData.loadStatus" ></uni-load-more>
|
||
</view>
|
||
</view>
|
||
<!-- <view v-if="categoryCurIndex == 1"></view>
|
||
<view v-if="categoryCurIndex == 2"></view>
|
||
<view v-if="categoryCurIndex == 3"></view> -->
|
||
</view>
|
||
</view>
|
||
<view v-if="navCurIndex == 1">发电分部</view>
|
||
<view v-if="navCurIndex == 2">自动分部</view>
|
||
<view v-if="navCurIndex == 3">保护分部</view>
|
||
</view>
|
||
<!-- 回到顶部 -->
|
||
<view class="top-back" @click="topBack" v-if="isShow">
|
||
<uni-icons type="up" size="16" color="#fff"></uni-icons>
|
||
<text>顶部</text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { nextTick, onMounted, reactive, ref } from "vue";
|
||
import { onReachBottom, onLoad, onShow, onPullDownRefresh, onPageScroll } from "@dcloudio/uni-app";
|
||
import Dashboard from "@/components/echarts/dashboard.vue";
|
||
import { getRouteList, getRoutePage } from '@/api/api.js'
|
||
|
||
|
||
let isShow = ref(false)
|
||
// 导航栏
|
||
let navCurIndex = ref(0)
|
||
const departments = reactive([
|
||
{ id: 1, name: "运行部" },
|
||
{ id: 2, name: "发电分部" },
|
||
{ id: 3, name: "自动分部" },
|
||
{ id: 4, name: "保护分部" },
|
||
{ id: 5, name: "测试分部" },
|
||
]);
|
||
|
||
const patrolData = reactive({
|
||
time: '2025 2-15 12:00:00',
|
||
linesTotal: 14,
|
||
lines: [
|
||
{ title: '已巡路线', total: 11 },
|
||
{ title: '未巡路线', total: 3 },
|
||
{ title: '异常问题', total: 3 },
|
||
],
|
||
pointTotal: 397,
|
||
points: [
|
||
{ title: '已巡点位', total: 285 },
|
||
{ title: '未巡点位', total: 112 },
|
||
],
|
||
completionRate: 71.8
|
||
})
|
||
// 巡检类别
|
||
let categoryCurIndex = ref(0)
|
||
const category = reactive([
|
||
{ id: 1, name: "全部" },
|
||
{ id: 2, name: "未巡检" },
|
||
{ id: 3, name: "巡检中" },
|
||
{ id: 4, name: "已巡检" },
|
||
])
|
||
|
||
// 列表数据
|
||
let listData = reactive({
|
||
page: {//请求参数
|
||
size: 10, // 条数
|
||
num: 1, // 页数
|
||
},
|
||
loadStatus:'loading', //加载样式:more-加载前样式,loading-加载中样式,nomore-没有数据样式
|
||
isLoadMore:false, //是否加载中
|
||
taskList: [
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '已巡检', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '已巡检', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '未巡检', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '未巡检', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
{ title: '左岸白班机组', state: '巡检中', num: 'BHT-YX-XJ-L1.2', info: '白班每班一次,由当班值执行', task: '5/32' },
|
||
]//数据
|
||
})
|
||
|
||
// 下拉刷新
|
||
onPullDownRefresh(() => {
|
||
nextTick(() => {
|
||
console.log('下拉刷新完成');
|
||
queryList(listData.page)
|
||
// 停止下拉刷新动画
|
||
uni.stopPullDownRefresh();
|
||
});
|
||
})
|
||
|
||
//上拉触底
|
||
onReachBottom(() => {
|
||
if(!listData.isLoadMore){
|
||
listData.isLoadMore = true
|
||
listData.filtrate.num += 1
|
||
queryList(listData.page)
|
||
}
|
||
})
|
||
|
||
// 根据滚动距离以推断是否有显示返回顶部功能
|
||
onPageScroll((e) => {
|
||
isShow.value = e.scrollTop >= 200
|
||
});
|
||
|
||
onLoad(() => {
|
||
queryList(listData.page)
|
||
})
|
||
|
||
const queryList = (data) => {
|
||
console.log(data)
|
||
getRoutePage(data).then((res) => {
|
||
console.log(res.data);
|
||
|
||
// if(res.records.length!==0){
|
||
// //首次加载10条数据,后进行拼接
|
||
// state.taskList = state.taskList.concat(res.records)
|
||
// //判断接口返回数据量小于请求数据量,则表示此为最后一页
|
||
// if(res.records.length<state.filtrate.size){
|
||
// state.isLoadMore=true
|
||
// state.loadStatus='nomore'
|
||
// }else{
|
||
// state.isLoadMore=false
|
||
// }
|
||
// }else{
|
||
// state.isLoadMore=true
|
||
// state.loadStatus='nomore'
|
||
// }
|
||
|
||
// if (res.code == 200) {
|
||
// listData.taskList = res.data
|
||
// }
|
||
}).catch((err) => {
|
||
|
||
});
|
||
}
|
||
|
||
// 切换导航
|
||
const changeTitle = (index) => {
|
||
navCurIndex.value = index
|
||
};
|
||
|
||
const changeCategory = (index) => {
|
||
categoryCurIndex.value = index
|
||
console.log(index);
|
||
|
||
switch (index) {
|
||
case 1:
|
||
queryList({ state: 1 })
|
||
break;
|
||
case 2:
|
||
// queryList({ state: 1 })
|
||
break;
|
||
case 3:
|
||
queryList({ state: 0 })
|
||
break;
|
||
default:
|
||
// queryList({})
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 历史巡检跳转
|
||
const goToHistory = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/history/history'
|
||
});
|
||
}
|
||
|
||
// 列表跳转
|
||
const goToStartInspection = (item) => {
|
||
console.log(item);
|
||
// if (item.state == 0) {
|
||
uni.navigateTo({
|
||
url: `/pages/startInspection/startInspection?data=${JSON.stringify(item)}`
|
||
});
|
||
// }
|
||
|
||
}
|
||
|
||
// 点击绑定的事件
|
||
const topBack = () => {
|
||
uni.pageScrollTo({
|
||
scrollTop: 0, // 滚动到顶部
|
||
duration: 300 // 动画时长 300ms
|
||
});
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.index {
|
||
padding-top: 100rpx;
|
||
.header {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
image {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
}
|
||
.title {
|
||
color: #fff;
|
||
view:nth-child(1) {
|
||
font-weight: 700;
|
||
font-size: 36rpx;
|
||
background-image: linear-gradient(to bottom, #fff, #ffffffef, #ffffff00); /* 渐变方向和颜色 */
|
||
-webkit-background-clip: text;
|
||
color: transparent; /* 文字颜色设置为透明,使背景色显示 */
|
||
}
|
||
view:nth-child(2) {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin: 15rpx 60rpx 0 0;
|
||
font-size: 24rpx;
|
||
border-bottom: 2rpx solid #fff;
|
||
}
|
||
}
|
||
}
|
||
.nav-content {
|
||
box-sizing: border-box;
|
||
.content-scroll {
|
||
height: 100rpx;
|
||
line-height: 100rpx;
|
||
white-space: nowrap;
|
||
.control-item {
|
||
height: 35rpx;
|
||
line-height: 35rpx;
|
||
display: inline-block;
|
||
padding: 0 20rpx;
|
||
margin-left: 30rpx;
|
||
position: relative;
|
||
&.active {
|
||
padding: 15rpx 20rpx!important;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.patrol-card {
|
||
border-radius: 10rpx;
|
||
padding: 5rpx 10rpx;
|
||
.time {
|
||
color: #808185;
|
||
}
|
||
.card-info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
.card-box {
|
||
width: 42%;
|
||
background: #EDF3FD;
|
||
border-radius: 10rpx;
|
||
padding: 20rpx;
|
||
.total {
|
||
display: grid;
|
||
grid-template-columns: 180rpx 50rpx;
|
||
padding-left: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
font-weight: 600;
|
||
border-left: 6rpx solid;
|
||
height: 30rpx;
|
||
line-height: 30rpx;
|
||
}
|
||
.lines {
|
||
display: grid;
|
||
grid-template-columns: 205rpx 50rpx;
|
||
align-items: center;
|
||
margin-top: 20rpx;
|
||
|
||
.title {
|
||
padding: 10rpx 24rpx;
|
||
border-radius: 10rpx;
|
||
background: linear-gradient(to right,#c7dcfbb5,#e7f1fd28);
|
||
}
|
||
|
||
&:nth-child(3) {
|
||
color: #E99A71;
|
||
}
|
||
&:nth-child(4) {
|
||
color: #DE503B;
|
||
}
|
||
}
|
||
.line {
|
||
border-color: #5291FF;
|
||
}
|
||
.point {
|
||
border-color: #4AC1B3;
|
||
}
|
||
|
||
.title {
|
||
color: #7E848D;
|
||
}
|
||
|
||
.num {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.points-box {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.points {
|
||
display: flex;
|
||
flex-direction: column-reverse;
|
||
align-items: center;
|
||
.num {
|
||
font-size: 27rpx;
|
||
}
|
||
&:nth-last-child(1) {
|
||
color: #E99A71;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
.inlet-box {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin: 20rpx -40rpx -20rpx -40rpx;
|
||
color: #fff;
|
||
i { font-size: 40rpx; }
|
||
.history {
|
||
background: url('@/static/image/index/history.png') no-repeat;
|
||
}
|
||
.report {
|
||
background: url('@/static/image/index/report.png');
|
||
}
|
||
.history, .report {
|
||
width: 50%;
|
||
display: grid;
|
||
grid-template-columns: 90% 50rpx;
|
||
align-items: center;
|
||
justify-items: center;
|
||
background-size: 100% 100%;
|
||
.title {
|
||
font-size: 27rpx;
|
||
font-weight: bold;
|
||
margin: 20rpx 0 0 60rpx;
|
||
.english {
|
||
font-size: 14rpx;
|
||
color: #B6DED2;
|
||
}
|
||
}
|
||
.go {
|
||
font-size: 11rpx;
|
||
font-weight: bold;
|
||
margin: -30rpx 0 0 -100rpx;
|
||
border-radius: 15rpx;
|
||
background: #ffffff6f;
|
||
width: 40rpx;
|
||
height: 20rpx;
|
||
line-height: 20rpx;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
.category-box {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
font-weight: bold;
|
||
font-size: 31rpx;
|
||
.active {
|
||
position: relative;
|
||
color: #146FF3;
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: -10rpx;
|
||
transform: translateX(-50%);
|
||
width: 30rpx;
|
||
height: 6rpx;
|
||
background: #146FF3;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
</style> |