bht-app/src/pages/index/index.vue

480 lines
13 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.

<!--
* @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">{{'&#xe74e;'}}</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>