列表自动滚动
This commit is contained in:
@ -55,6 +55,7 @@
|
||||
"vue-router": "4.4.5",
|
||||
"vue-types": "5.1.3",
|
||||
"vue3-print-nb": "^0.1.4",
|
||||
"vue3-scroll-seamless": "^1.0.6",
|
||||
"vxe-table": "4.5.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
58
src/api/gis/index.ts
Normal file
58
src/api/gis/index.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { QualityVO, Query, ConstructionUserVO, MachineryrVO, MaterialsVO } from './type';
|
||||
/**
|
||||
* 查询大屏质量信息
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const getQualityList = (query?: Query): AxiosPromise<QualityVO> => {
|
||||
return request({
|
||||
url: '/quality/qualityInspection/gis',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询施工人员大屏数据
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const getConstructionUserList = (query?: Query): AxiosPromise<ConstructionUserVO> => {
|
||||
return request({
|
||||
url: '/project/constructionUser/gis',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询大屏机械列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const getMachineryrList = (query?: Query): AxiosPromise<MachineryrVO[]> => {
|
||||
return request({
|
||||
url: '/machinery/machinery/list/gis',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询大屏材料信息
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const getMaterialsList = (query?: Query): AxiosPromise<MaterialsVO[]> => {
|
||||
return request({
|
||||
url: '/materials/materials/list/gis',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
43
src/api/gis/type.ts
Normal file
43
src/api/gis/type.ts
Normal file
@ -0,0 +1,43 @@
|
||||
export interface QualityVO {
|
||||
count: number;
|
||||
correctSituation: string;
|
||||
list: Qualitylist[];
|
||||
}
|
||||
export interface Qualitylist {
|
||||
id: number;
|
||||
inspectionTypeLabel: string;
|
||||
inspectionHeadline: string;
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface Query {
|
||||
projectId: string | number;
|
||||
pageSize?: string | number;
|
||||
}
|
||||
|
||||
export interface ConstructionUserVO {
|
||||
peopleCount: number;
|
||||
attendanceCount: number;
|
||||
attendanceRate: string;
|
||||
}
|
||||
|
||||
export interface MachineryrVO {
|
||||
//机械名称
|
||||
machineryName: string;
|
||||
//机械数量
|
||||
machineryCount: string;
|
||||
}
|
||||
|
||||
export interface MaterialsVO {
|
||||
//材料名称
|
||||
materialsName: string;
|
||||
//计量单位
|
||||
weightId: string;
|
||||
//预计材料数量
|
||||
quantityCount: string;
|
||||
//入库数量
|
||||
putCount: string;
|
||||
//出库数量
|
||||
outCount: string;
|
||||
value: number;
|
||||
}
|
@ -49,6 +49,8 @@ VXETable.config({
|
||||
// 修改 el-dialog 默认点击遮照为不关闭
|
||||
/*import { ElDialog } from 'element-plus';
|
||||
ElDialog.props.closeOnClickModal.default = false;*/
|
||||
// **main.js**
|
||||
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
@ -60,6 +62,7 @@ app.use(print);
|
||||
app.use(i18n);
|
||||
app.use(VXETable);
|
||||
app.use(plugins);
|
||||
app.component('vue3ScrollSeamless', vue3ScrollSeamless);
|
||||
// 自定义指令
|
||||
directive(app);
|
||||
|
||||
|
125
src/views/gisHome/component/autoScroller.vue
Normal file
125
src/views/gisHome/component/autoScroller.vue
Normal file
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="auto-scroll-container" @mouseenter="pauseScroll" @mouseleave="resumeScroll" ref="container">
|
||||
<div class="auto-scroll-content" ref="content">
|
||||
<div class="auto-scroll-item" v-for="(item, index) in duplicatedList" :key="index">
|
||||
<slot :item="item">{{ item }}</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
items: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
speed: {
|
||||
type: Number,
|
||||
default: 0.5 // px/frame
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 100 // px
|
||||
},
|
||||
minItems: {
|
||||
type: Number,
|
||||
default: 2 // 小于这个数量不滚动
|
||||
},
|
||||
autoScroll: {
|
||||
type: Boolean,
|
||||
default: true // 控制是否自动滚动
|
||||
}
|
||||
});
|
||||
|
||||
// Refs and Computed
|
||||
const container = ref(null);
|
||||
const content = ref(null);
|
||||
const duplicatedList = computed(() => [...props.items, ...props.items]);
|
||||
const shouldScroll = computed(() => props.items.length >= props.minItems);
|
||||
|
||||
let scrollY = 0;
|
||||
let animationFrameId = null;
|
||||
let manualPaused = false; // 记录是否因为滚轮手动停止
|
||||
|
||||
// 滚动核心逻辑
|
||||
function normalizeScrollY(contentHeight) {
|
||||
if (scrollY <= -contentHeight) scrollY += contentHeight;
|
||||
if (scrollY >= 0) scrollY -= contentHeight;
|
||||
}
|
||||
|
||||
function step() {
|
||||
const contentHeight = content.value.offsetHeight / 2;
|
||||
scrollY -= props.speed;
|
||||
normalizeScrollY(contentHeight);
|
||||
content.value.style.transform = `translateY(${Math.round(scrollY)}px)`;
|
||||
|
||||
animationFrameId = requestAnimationFrame(step);
|
||||
}
|
||||
|
||||
function startScroll() {
|
||||
if (!animationFrameId) {
|
||||
animationFrameId = requestAnimationFrame(step);
|
||||
}
|
||||
}
|
||||
|
||||
function pauseScroll() {
|
||||
cancelAnimationFrame(animationFrameId);
|
||||
animationFrameId = null;
|
||||
}
|
||||
|
||||
// 鼠标滚轮事件:手动滚动并停止自动滚动
|
||||
function onWheel(e) {
|
||||
pauseScroll();
|
||||
manualPaused = true; // 标记为手动停止
|
||||
const contentHeight = content.value.offsetHeight / 2;
|
||||
scrollY -= e.deltaY;
|
||||
normalizeScrollY(contentHeight);
|
||||
content.value.style.transform = `translateY(${Math.round(scrollY)}px)`;
|
||||
}
|
||||
|
||||
// 鼠标移出时恢复自动滚动(如果不是手动暂停)
|
||||
function resumeScroll() {
|
||||
if (props.autoScroll && shouldScroll.value) {
|
||||
manualPaused = false; // 重置手动暂停标志
|
||||
startScroll();
|
||||
}
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
if (shouldScroll.value && props.autoScroll) {
|
||||
startScroll();
|
||||
}
|
||||
container.value.addEventListener('wheel', onWheel);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
pauseScroll();
|
||||
container.value.removeEventListener('wheel', onWheel);
|
||||
});
|
||||
|
||||
// 响应 items 数量变化
|
||||
watch(shouldScroll, (newVal) => {
|
||||
if (!newVal) {
|
||||
pauseScroll();
|
||||
} else if (props.autoScroll && !manualPaused) {
|
||||
startScroll();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.auto-scroll-container {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.auto-scroll-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
will-change: transform;
|
||||
}
|
||||
</style>
|
@ -21,21 +21,30 @@
|
||||
<img src="@/assets/images/totalnumber.png" alt="" />
|
||||
</div>
|
||||
<p>总人数</p>
|
||||
<div class="peopleNum"><span>259</span>人</div>
|
||||
<div class="peopleNum">
|
||||
<span>{{ constructionUserData?.peopleCount }}</span
|
||||
>人
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="iconImg">
|
||||
<img src="@/assets/images/attendanceperson.png" alt="" />
|
||||
</div>
|
||||
<p>出勤人</p>
|
||||
<div class="peopleNum"><span>259</span>人</div>
|
||||
<div class="peopleNum">
|
||||
<span>{{ constructionUserData?.attendanceCount }}</span
|
||||
>人
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="iconImg">
|
||||
<img src="@/assets/images/Attendancerate.png" alt="" />
|
||||
</div>
|
||||
<p>出勤率</p>
|
||||
<div class="peopleNum"><span>100</span>%</div>
|
||||
<div class="peopleNum">
|
||||
<span>{{ constructionUserData?.attendanceRate }}</span
|
||||
>%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">
|
||||
@ -75,20 +84,57 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getConstructionUserList, getMachineryrList, getMaterialsList } from '@/api/gis';
|
||||
import { ConstructionUserVO, MachineryrVO, MaterialsVO } from '@/api/gis/type';
|
||||
import * as echarts from 'echarts';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
const userStore = useUserStoreHook();
|
||||
//echarts节点
|
||||
const myMachineryChart = ref(null);
|
||||
const myOrderChart = ref(null);
|
||||
|
||||
type EChartsOption = echarts.EChartsOption;
|
||||
const constructionUserData = ref<ConstructionUserVO>(null);
|
||||
const machineryOption = ref<MachineryrVO[]>([]); //机械
|
||||
const orderOption = ref<MaterialsVO[]>([]); //材料
|
||||
const machineryDataAxis = computed(() => machineryOption.value.map((item) => item.machineryName)); //x轴数据
|
||||
const machineryData = computed(() => machineryOption.value.map((item) => item.machineryCount)); //柱状图数据
|
||||
const orderDataAxis = computed(() => orderOption.value.map((item) => item.materialsName)); //材料x轴数据
|
||||
const orderPutData = computed(() => orderOption.value.map((item) => item.putCount)); //柱状图领用量数据
|
||||
const orderOutData = computed(() => orderOption.value.map((item) => item.outCount)); //柱状图出库量数据
|
||||
const orderRankingData = computed(() => orderOption.value.map((item) => item.value)); //柱状图库存数据
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
|
||||
//获取施工人员信息
|
||||
const getConstructionUserData = async () => {
|
||||
const res = await getConstructionUserList({ projectId: currentProject.value.id });
|
||||
if (res.code !== 200) return;
|
||||
constructionUserData.value = res.data;
|
||||
};
|
||||
|
||||
//查询大屏机械列表
|
||||
const getMachineryData = async () => {
|
||||
const res = await getMachineryrList({ projectId: currentProject.value.id });
|
||||
if (res.code !== 200) return;
|
||||
machineryOption.value = res.data;
|
||||
initMachinerycharts();
|
||||
};
|
||||
|
||||
//查询大屏材料信息
|
||||
const getOrderData = async () => {
|
||||
const res = await getMaterialsList({ projectId: currentProject.value.id });
|
||||
if (res.code !== 200) return;
|
||||
orderOption.value = res.data;
|
||||
initOrderChart();
|
||||
console.log(orderDataAxis);
|
||||
};
|
||||
|
||||
const initMachinerycharts = () => {
|
||||
let chartDom = document.getElementById('machineryMain');
|
||||
let myMachineryChart = echarts.init(chartDom);
|
||||
myMachineryChart.value = markRaw(echarts.init(chartDom));
|
||||
let option: EChartsOption;
|
||||
|
||||
// prettier-ignore
|
||||
let dataAxis = ['水泥机', '搅拌机', '拖拉机', '推土机', '推土机', '推土机','推土机', ];
|
||||
// prettier-ignore
|
||||
let data = [11, 23, 21, 20, 22, 24, 24];
|
||||
|
||||
option = {
|
||||
title: {
|
||||
subtext: '单位:台数'
|
||||
@ -99,7 +145,7 @@ const initMachinerycharts = () => {
|
||||
bottom: '50vh'
|
||||
},
|
||||
xAxis: {
|
||||
data: dataAxis,
|
||||
data: machineryDataAxis.value,
|
||||
axisLabel: {
|
||||
// inside: true,
|
||||
color: 'rgba(202, 218, 226, 1)'
|
||||
@ -163,7 +209,6 @@ const initMachinerycharts = () => {
|
||||
},
|
||||
showDataShadow: false,
|
||||
// 手柄大小
|
||||
handleSize: 0,
|
||||
showDetail: false, //即拖拽时候是否显示详细数值信息 默认true
|
||||
moveHandleSize: 0, //移动手柄的大小
|
||||
// 滚动条高度
|
||||
@ -190,7 +235,7 @@ const initMachinerycharts = () => {
|
||||
},
|
||||
start: 0,
|
||||
// 计算初始结束百分比
|
||||
end: (6 / data.length) * 100
|
||||
end: (6 / machineryData.value.length) * 100
|
||||
}
|
||||
],
|
||||
|
||||
@ -205,21 +250,19 @@ const initMachinerycharts = () => {
|
||||
])
|
||||
},
|
||||
barWidth: '13vh',
|
||||
data: data
|
||||
data: machineryData.value
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myMachineryChart.setOption(option);
|
||||
option && myMachineryChart.value.setOption(option);
|
||||
};
|
||||
|
||||
const initOrderChart = () => {
|
||||
let chartDom = document.getElementById('orderMain');
|
||||
let myMachineryChart = echarts.init(chartDom);
|
||||
let option: EChartsOption;
|
||||
|
||||
// prettier-ignore
|
||||
let data = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
myOrderChart.value = markRaw(echarts.init(chartDom));
|
||||
let option: EChartsOption;
|
||||
|
||||
option = {
|
||||
tooltip: {
|
||||
@ -244,20 +287,21 @@ const initOrderChart = () => {
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
left: '5%', //距离dom间距
|
||||
right: '4%',
|
||||
bottom: '0',
|
||||
containLabel: true,
|
||||
width: '90%'
|
||||
top: '20%',
|
||||
bottom: '1%',
|
||||
height: '80%'
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data,
|
||||
offset: 60,
|
||||
data: orderDataAxis.value,
|
||||
offset: 0,
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
@ -266,13 +310,38 @@ const initOrderChart = () => {
|
||||
},
|
||||
inverse: true,
|
||||
axisLabel: {
|
||||
formatter: function (value, index) {
|
||||
return `{${data[index]}|No.${index + 1}} {value|${value}}`;
|
||||
formatter: function (value) {
|
||||
let bgType = '';
|
||||
let index = orderDataAxis.value.indexOf(value);
|
||||
switch (index) {
|
||||
case 0:
|
||||
bgType = 'a';
|
||||
break;
|
||||
case 1:
|
||||
bgType = 'b';
|
||||
break;
|
||||
case 2:
|
||||
bgType = 'c';
|
||||
break;
|
||||
default:
|
||||
return `No.${index + 1} {value|${value}}`;
|
||||
}
|
||||
return `{${bgType}|No.${index + 1}} {value|${value}}`;
|
||||
},
|
||||
align: 'left',
|
||||
verticalAlign: 'bottom',
|
||||
yAxisIndex: 0,
|
||||
// 横坐标 分割线等取消显示
|
||||
padding: [0, 10, 10, 6],
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
color: 'rgba(230, 247, 255, 1)',
|
||||
rich: {
|
||||
Mon: {
|
||||
a: {
|
||||
color: 'rgba(230, 247, 255, 1)',
|
||||
fontSize: 12,
|
||||
align: 'center',
|
||||
@ -283,7 +352,7 @@ const initOrderChart = () => {
|
||||
{ offset: 1, color: 'rgba(255, 208, 59, 0)' }
|
||||
])
|
||||
},
|
||||
Tue: {
|
||||
b: {
|
||||
color: 'rgba(230, 247, 255, 1)',
|
||||
fontSize: 12,
|
||||
align: 'left',
|
||||
@ -294,7 +363,7 @@ const initOrderChart = () => {
|
||||
{ offset: 1, color: 'rgba(31, 189, 237, 0)' }
|
||||
])
|
||||
},
|
||||
Wed: {
|
||||
c: {
|
||||
color: 'rgba(230, 247, 255, 1)',
|
||||
fontSize: 12,
|
||||
align: 'left',
|
||||
@ -408,7 +477,7 @@ const initOrderChart = () => {
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [320, 302, 301, 334, 345, 356, 367],
|
||||
data: orderPutData.value,
|
||||
barWidth: 3
|
||||
},
|
||||
{
|
||||
@ -421,7 +490,7 @@ const initOrderChart = () => {
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [120, 132, 101, 134, 152, 103, 150],
|
||||
data: orderOutData.value,
|
||||
showBackground: true,
|
||||
barWidth: 3,
|
||||
backgroundStyle: {
|
||||
@ -430,12 +499,34 @@ const initOrderChart = () => {
|
||||
}
|
||||
]
|
||||
};
|
||||
option && myMachineryChart.setOption(option);
|
||||
option && myOrderChart.value.setOption(option);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 防抖函数
|
||||
const debounce = <T,>(func: (this: T, ...args: any[]) => void, delay: number) => {
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
return function (this: T, ...args: any[]) {
|
||||
const context = this;
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
func.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
};
|
||||
|
||||
// 窗口大小变化时触发的函数
|
||||
const handleResize = () => {
|
||||
myMachineryChart.value && myMachineryChart.value.dispose();
|
||||
myOrderChart.value && myOrderChart.value.dispose();
|
||||
initMachinerycharts();
|
||||
initOrderChart();
|
||||
};
|
||||
const debouncedHandleResize = debounce(handleResize, 300);
|
||||
onMounted(() => {
|
||||
getOrderData();
|
||||
getConstructionUserData();
|
||||
getMachineryData();
|
||||
window.addEventListener('resize', debouncedHandleResize); //监听窗口变化重新生成echarts
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -17,19 +17,22 @@
|
||||
</div>
|
||||
<div class="events">
|
||||
<div class="content events-content event_s">
|
||||
<ul
|
||||
class="events-list"
|
||||
@mouseenter.native="autoScrollTable(true, 'projectRef')"
|
||||
@mouseleave.native="autoScrollTable(false, 'projectRef')"
|
||||
id="event_scroll"
|
||||
ref="projectScroll"
|
||||
>
|
||||
<li v-for="(item, index) in events" :key="index">
|
||||
<ul class="events-list">
|
||||
<!-- <li v-for="(item, index) in events" :key="index">
|
||||
<span class="text detail" style="display: inline"> {{ item.headline }}...</span>
|
||||
<span class="more" v-if="!item.show" @click="onMore(item, true)">查看详情</span>
|
||||
<span class="more" style="color: #ffb100eb" v-else @click="onMore(item, false)">关闭详情</span>
|
||||
</li> -->
|
||||
</ul>
|
||||
<AutoScroller :items="events" class="events-list">
|
||||
<template #default="{ item }">
|
||||
<li>
|
||||
<span class="text detail" style="display: inline"> {{ item.headline }}...</span>
|
||||
<span class="more" v-if="!item.show" @click="onMore(item, true)">查看详情</span>
|
||||
<span class="more" style="color: #ffb100eb" v-else @click="onMore(item, false)">关闭详情</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</AutoScroller>
|
||||
<!-- <span v-else style="font-size: 20px; letter-spacing: 10px">暂无数据</span> -->
|
||||
</div>
|
||||
</div>
|
||||
@ -93,12 +96,8 @@
|
||||
<el-table-column prop="status" label="操作" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div
|
||||
class="tbody"
|
||||
ref="tableScroll"
|
||||
@mouseenter.native="autoScrollTable(true, 'tableRef')"
|
||||
@mouseleave.native="autoScrollTable(false, 'tableRef')"
|
||||
>
|
||||
<AutoScroller :items="safetyData" class="tbody">
|
||||
<template #default="{ item }">
|
||||
<el-table
|
||||
:data="safetyData"
|
||||
stripe
|
||||
@ -108,16 +107,17 @@
|
||||
header-cell-class-name="bg-transparent"
|
||||
style="--el-table-border-color: none"
|
||||
>
|
||||
<el-table-column prop="teamName" label="" />
|
||||
<el-table-column prop="name" label="" />
|
||||
<el-table-column prop="meetingDate" label="" />
|
||||
<el-table-column prop="status" label="">
|
||||
<el-table-column prop="teamName" label="" class-name="teamNameWidth" />
|
||||
<el-table-column prop="name" label="" class-name="nameWidth" />
|
||||
<el-table-column prop="meetingDate" label="" class-name="meetingDateWidth" />
|
||||
<el-table-column prop="status" label="" class-name="statusWidth">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" :underline="false">查看</el-link>
|
||||
<el-link :underline="false">查看</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
</AutoScroller>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">
|
||||
@ -141,30 +141,27 @@
|
||||
</div>
|
||||
<div class="qualityNum">
|
||||
<div>巡检记录 <b></b></div>
|
||||
<p>14<span>件</span></p>
|
||||
<p>{{ qualityData?.count }}<span>件</span></p>
|
||||
</div>
|
||||
<div class="qualityNum ml-15">
|
||||
<div>整改情况 <b></b></div>
|
||||
<p>20<span>%</span></p>
|
||||
<p>{{ qualityData?.correctSituation }}<span>%</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="qualityList"
|
||||
@mouseenter.native="autoScrollTable(true, 'qualityRef')"
|
||||
@mouseleave.native="autoScrollTable(false, 'qualityRef')"
|
||||
ref="qualityScroll"
|
||||
>
|
||||
<div class="qualityItem flex items-center" v-for="item in 6">
|
||||
<AutoScroller :items="qualityData?.list" class="qualityList">
|
||||
<template #default="{ item }">
|
||||
<div class="qualityItem flex items-center">
|
||||
<div>
|
||||
<img src="@/assets/images/timeIcon.png" alt="" />
|
||||
<span class="text-white">2024-11-15</span>
|
||||
<span class="text-white">{{ item.createTime }}</span>
|
||||
</div>
|
||||
<div class="text-#43E2CB record">巡检记录</div>
|
||||
<div class="text-#43E2CB record">{{ item.inspectionTypeLabel }}</div>
|
||||
<div class="text-#E6F7FF text-truncate">
|
||||
<el-tooltip content="桩基钻孔深度、直径不足11111111" placement="top"> 桩基钻孔深度、直径不足</el-tooltip>
|
||||
</div>
|
||||
<el-tooltip :content="item.inspectionHeadline" placement="top"> {{ item.inspectionHeadline }}</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</AutoScroller>
|
||||
</div>
|
||||
<div class="title">
|
||||
<div class="flex items-center">
|
||||
@ -189,7 +186,12 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import * as echarts from 'echarts';
|
||||
//页面高度
|
||||
|
||||
import { QualityVO } from '@/api/gis/type';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { getQualityList } from '@/api/gis';
|
||||
import AutoScroller from './autoScroller.vue';
|
||||
const userStore = useUserStoreHook();
|
||||
type EChartsOption = echarts.EChartsOption;
|
||||
const option = ref<EChartsOption>(null);
|
||||
const myMachineryChart = ref(null);
|
||||
@ -210,13 +212,23 @@ const scrollList = reactive({
|
||||
intervalId: null
|
||||
}
|
||||
});
|
||||
const autoScrollTable = (isAuto, ref) => {
|
||||
if (isAuto) {
|
||||
clearInterval(scrollList[ref].intervalId);
|
||||
} else {
|
||||
startScroll(ref);
|
||||
}
|
||||
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const qualityData = ref<QualityVO>({ list: [], correctSituation: null, count: null });
|
||||
const classOptions = {
|
||||
limitMoveNum: 3,
|
||||
hoverStop: true,
|
||||
step: 1
|
||||
};
|
||||
|
||||
//获取质量信息
|
||||
const getQualityData = async () => {
|
||||
const res = await getQualityList({ projectId: currentProject.value.id });
|
||||
if (res.code !== 200) return;
|
||||
qualityData.value = res.data;
|
||||
};
|
||||
|
||||
const events = ref([
|
||||
{
|
||||
'id': 23,
|
||||
@ -390,23 +402,6 @@ const initUserChart = () => {
|
||||
option.value && myMachineryChart.value.setOption(option.value);
|
||||
};
|
||||
|
||||
//开始滚动
|
||||
const startScroll = (ref) => {
|
||||
const { dom } = scrollList[ref];
|
||||
const scrollContainer = dom.parentNode;
|
||||
scrollList[ref].intervalId = setInterval(() => {
|
||||
dom.scrollTop += 1;
|
||||
|
||||
if (dom.scrollHeight == dom.clientHeight + dom.scrollTop) {
|
||||
dom.scrollTop = 0;
|
||||
}
|
||||
}, 50);
|
||||
};
|
||||
//停止滚动
|
||||
const stopScroll = (intervalId) => {
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
|
||||
// 防抖函数
|
||||
const debounce = <T,>(func: (this: T, ...args: any[]) => void, delay: number) => {
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
@ -429,19 +424,11 @@ const debouncedHandleResize = debounce(handleResize, 300);
|
||||
|
||||
onMounted(() => {
|
||||
initUserChart();
|
||||
console.log(scrollList, 'scrollList');
|
||||
|
||||
getQualityData();
|
||||
window.addEventListener('resize', debouncedHandleResize);
|
||||
for (const key in scrollList) {
|
||||
startScroll(key);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
for (const key in scrollList) {
|
||||
stopScroll(scrollList[key].intervalId);
|
||||
}
|
||||
|
||||
window.removeEventListener('resize', debouncedHandleResize);
|
||||
});
|
||||
</script>
|
||||
@ -617,8 +604,9 @@ onUnmounted(() => {
|
||||
|
||||
.qualityList {
|
||||
margin-left: vw(21);
|
||||
display: block;
|
||||
height: vh(90);
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
margin-right: vw(10);
|
||||
font-size: vw(14);
|
||||
.qualityItem {
|
||||
@ -682,12 +670,12 @@ p {
|
||||
height: vh(82);
|
||||
.events-list {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
padding-right: vw(10);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
> li {
|
||||
li {
|
||||
width: 100%;
|
||||
padding-left: vw(20);
|
||||
background: url('@/assets/images/li.png') no-repeat 0 20%;
|
||||
@ -724,11 +712,11 @@ p {
|
||||
}
|
||||
}
|
||||
|
||||
> li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
// li:last-child {
|
||||
// margin-bottom: 0;
|
||||
// }
|
||||
|
||||
> li::after {
|
||||
li::after {
|
||||
content: '';
|
||||
border-left: vw(1) dashed rgba(0, 190, 247, 0.3);
|
||||
position: absolute;
|
||||
@ -739,10 +727,10 @@ p {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> li:last-child::after {
|
||||
content: '';
|
||||
border-left: none;
|
||||
}
|
||||
// li:last-child::after {
|
||||
// content: '';
|
||||
// border-left: none;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -763,7 +751,7 @@ p {
|
||||
|
||||
.tbody {
|
||||
height: vh(94);
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
padding-right: vw(14);
|
||||
}
|
||||
|
||||
@ -781,10 +769,22 @@ p {
|
||||
border: none; //这是设置透明边框
|
||||
color: rgba(255, 255, 255, 1); //这是设置字体颜色
|
||||
font-size: vw(12);
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
padding: vh(4) 0;
|
||||
height: vh(26) !important;
|
||||
}
|
||||
.nameWidth {
|
||||
width: vw(114);
|
||||
}
|
||||
.meetingDateWidth {
|
||||
width: vw(114);
|
||||
}
|
||||
.statusWidth {
|
||||
width: vw(44);
|
||||
}
|
||||
.teamNameWidth {
|
||||
width: vw(114);
|
||||
}
|
||||
|
||||
.el-table__row--striped {
|
||||
background: transparent !important; //这是设置透明背景色
|
||||
@ -815,6 +815,8 @@ p {
|
||||
/* 滚动条整体样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: vw(6);
|
||||
display: none;
|
||||
|
||||
/* 纵向滚动条宽度 */
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<AutoScroller :items="list2" :speed="0.7" class="h25" />
|
||||
<!-- <AutoScroller :items="list2" :height="150" :speed="1.2" /> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Index" lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import AutoScroller from './gisHome/component/autoScroller.vue';
|
||||
|
||||
const list1 = ['列表1 - 内容 A', '列表1 - 内容 B', '列表1 - 内容 C'];
|
||||
|
||||
const list2 = [
|
||||
'列表2 - 第一条长内容测试',
|
||||
'列表2 - 第二条长长长内容继续测试',
|
||||
'列表2 - 第三条内容',
|
||||
'列表2 - 第一条长内容测试',
|
||||
'列表2 - 第二条长长长内容继续测试',
|
||||
'列表2 - 第三条内容',
|
||||
'列表2 - 第一条长内容测试',
|
||||
'列表2 - 第二条长长长内容继续测试',
|
||||
'列表2 - 第三条内容'
|
||||
];
|
||||
const router = useRouter();
|
||||
|
||||
// 模拟数据
|
||||
|
Reference in New Issue
Block a user