| | |
| | | ElDrawer: typeof import('element-plus/es')['ElDrawer'] |
| | | ElRadio: typeof import('element-plus/es')['ElRadio'] |
| | | ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] |
| | | EmptyCom: typeof import('./src/components/empty-com/empty-com.vue')['default'] |
| | | ItemWrap: typeof import('./src/components/item-wrap/item-wrap.vue')['default'] |
| | | MessageContent: typeof import('./src/components/Plugins/MessageContent/index.vue')['default'] |
| | | RouterLink: typeof import('vue-router')['RouterLink'] |
| | | RouterView: typeof import('vue-router')['RouterView'] |
| | | ScaleScreen: typeof import('./src/components/scale-screen/scale-screen.vue')['default'] |
| | | SeamlessScroll: typeof import('./src/components/seamless-scroll/seamless-scroll.vue')['default'] |
| | | } |
| | | } |
| | |
| | | "centerMap":"/bigscreen/centerMap",
|
| | | "centerBottom":"/bigscreen/installationPlan",
|
| | |
|
| | | // 'big3':"/bigscreen/sbtx", //设备提醒
|
| | | 'leftBottom':"/bigscreen/leftBottom", //坐下
|
| | | 'rightTop':"/bigscreen/alarmNum", //报警次数
|
| | | // 'big5':'/bigscreen/ssyj',//实时预警 |
| | | 'rightBottom':'/bigscreen/rightBottom',//右下 |
| | | 'rightCenter':'/bigscreen/ranking',// 报警排名
|
| | | } |
| | |
| | | .el-message__content {
|
| | | color: var(--yh-text-color-primary);
|
| | | }
|
| | | }
|
| | |
|
| | | .beautify-scroll-def {
|
| | | overflow-y: auto;
|
| | | |
| | | &::-webkit-scrollbar-thumb {
|
| | | //滚动条的设置
|
| | | background-color: rgba(14, 59, 150, 0);
|
| | | background-clip: padding-box;
|
| | | border-radius: 4px;
|
| | | }
|
| | | |
| | | &:hover {
|
| | | &::-webkit-scrollbar-thumb {
|
| | | //滚动条的设置
|
| | | background-color: rgba(14, 59, 150, 0.5);
|
| | | background-clip: padding-box;
|
| | | border-radius: 4px;
|
| | | }
|
| | | }
|
| | | |
| | | &::-webkit-scrollbar-track-piece {
|
| | | //滚动条凹槽的颜色,还可以设置边框属性
|
| | | background-color: transparent;
|
| | | }
|
| | | |
| | | &::-webkit-scrollbar {
|
| | | //滚动条的宽度
|
| | | width: 8px;
|
| | | height: 8px;
|
| | | }
|
| | | |
| | | |
| | | |
| | | &::-webkit-scrollbar-thumb:hover {
|
| | | background-color: rgba(14, 59, 150, .8);
|
| | | }
|
| | | }
|
| | |
|
| | | .text-content {
|
| | | width: 100%;
|
| | | display: flex;
|
| | | min-height: calc(100% - 60px);
|
| | | justify-content: space-between;
|
| | | } |
New file |
| | |
| | | <script setup lang="ts"></script>
|
| | |
|
| | | <template>
|
| | | <div>
|
| | | <slot></slot>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <style scoped lang="scss"></style>
|
New file |
| | |
| | | import EmptyCom from "./empty-com.vue"
|
| | | export default EmptyCom |
New file |
| | |
| | | import SeamlessScroll from "./seamless-scroll.vue"
|
| | | export default SeamlessScroll |
New file |
| | |
| | | <script setup lang="ts">
|
| | | import {
|
| | | computed,
|
| | | defineComponent,
|
| | | onBeforeMount,
|
| | | onMounted,
|
| | | ref,
|
| | | watch,
|
| | | nextTick,
|
| | | } from "vue";
|
| | | import type { CSSProperties } from "vue";
|
| | | import throttle from "lodash/throttle";
|
| | | type propsType = {
|
| | | modelValue?: boolean;
|
| | | list: Array<any>;
|
| | | step?: number;
|
| | | limitScrollNum?: number;
|
| | | hover?: boolean;
|
| | | direction?: string;
|
| | | singleHeight?: number;
|
| | | singleWidth?: number;
|
| | | singleWaitTime?: number;
|
| | | isRemUnit?: boolean;
|
| | | isWatch?: boolean;
|
| | | delay?: number;
|
| | | ease?: any;
|
| | | count?: number;
|
| | | copyNum?: number;
|
| | | wheel?: boolean;
|
| | | singleLine?: boolean;
|
| | | };
|
| | | const props = withDefaults(defineProps<propsType>(), {
|
| | | // 是否开启自动滚动
|
| | | modelValue: true,
|
| | | // 原始数据列表
|
| | | list: () => [],
|
| | | // 步进速度,step 需是单步大小的约数
|
| | | step: 1,
|
| | | // 开启滚动的数据量
|
| | | limitScrollNum: 3,
|
| | | // 是否开启鼠标悬停
|
| | | hover: false,
|
| | | // 控制滚动方向
|
| | | direction: "up",
|
| | | // 单步运动停止的高度
|
| | | singleHeight: 0,
|
| | | // 单步运动停止的宽度
|
| | | singleWidth: 0,
|
| | | // 单步停止等待时间 (默认值 1000ms)
|
| | | singleWaitTime: 1000,
|
| | | // 是否开启 rem 度量
|
| | | isRemUnit: false,
|
| | | // 开启数据更新监听
|
| | | isWatch: true,
|
| | | // 动画时间
|
| | | delay: 0,
|
| | | // 动画方式
|
| | | ease: "ease-in",
|
| | | // 动画循环次数,-1 表示一直动画
|
| | | count: -1,
|
| | | // 拷贝几份滚动列表
|
| | | copyNum: 1,
|
| | | // 开启鼠标悬停时支持滚轮滚动
|
| | | wheel: false,
|
| | | // 启用单行滚动
|
| | | singleLine: false,
|
| | | });
|
| | | interface Emits {
|
| | | (event: "count", _count: number): void;
|
| | | (event: "stop", _count: number): void;
|
| | | }
|
| | | const emit = defineEmits<Emits>();
|
| | | const scrollRef = ref(null);
|
| | | const slotListRef = ref<HTMLDivElement | null>(null);
|
| | | const realBoxRef = ref<HTMLDivElement | null>(null);
|
| | | const reqFrame = ref<number | null>(null);
|
| | | const singleWaitTimeout = ref<TimeProp | null>(null);
|
| | | const realBoxWidth = ref(0);
|
| | | const realBoxHeight = ref(0);
|
| | | const xPos = ref(0);
|
| | | const yPos = ref(0);
|
| | | const isHover = ref(false);
|
| | | const _count = ref(0);
|
| | | const isScroll = computed(() =>
|
| | | props.list ? props.list.length >= props.limitScrollNum : false
|
| | | );
|
| | | const realBoxStyle = computed(() => {
|
| | | return {
|
| | | width: realBoxWidth.value ? `${realBoxWidth.value}px` : "auto",
|
| | | transform: `translate(${xPos.value}px,${yPos.value}px)`,
|
| | | transition: `all ${
|
| | | typeof props.ease === "string"
|
| | | ? props.ease
|
| | | : "cubic-bezier(" +
|
| | | props.ease.x1 +
|
| | | "," +
|
| | | props.ease.y1 +
|
| | | "," +
|
| | | props.ease.x2 +
|
| | | "," +
|
| | | props.ease.y2 +
|
| | | ")"
|
| | | } ${props.delay}ms`,
|
| | | overflow: "hidden",
|
| | | display: props.singleLine ? "flex" : "block",
|
| | | };
|
| | | });
|
| | | const isHorizontal = computed(
|
| | | () => props.direction == "left" || props.direction == "right"
|
| | | );
|
| | |
|
| | | function dataWarm(list: any) {
|
| | | if (list && typeof list !== "boolean" && list.length > 100) {
|
| | | console.warn(
|
| | | `数据达到了${list.length}条有点多哦~,可能会造成部分老旧浏览器卡顿。`
|
| | | );
|
| | | }
|
| | | }
|
| | | const floatStyle = computed<CSSProperties>(() => {
|
| | | return isHorizontal.value
|
| | | ? {
|
| | | float: "left",
|
| | | overflow: "hidden",
|
| | | display: props.singleLine ? "flex" : "block",
|
| | | flexShrink: props.singleLine ? 0 : 1,
|
| | | }
|
| | | : { overflow: "hidden" };
|
| | | });
|
| | | const baseFontSize = computed(() => {
|
| | | return props.isRemUnit
|
| | | ? parseInt(
|
| | | globalThis.window.getComputedStyle(
|
| | | globalThis.document.documentElement,
|
| | | null
|
| | | ).fontSize
|
| | | )
|
| | | : 1;
|
| | | });
|
| | | const realSingleStopWidth = computed(
|
| | | () => props.singleWidth * baseFontSize.value
|
| | | );
|
| | |
|
| | | const realSingleStopHeight = computed(
|
| | | () => props.singleHeight * baseFontSize.value
|
| | | );
|
| | |
|
| | | const step = computed(() => {
|
| | | let singleStep: number;
|
| | | let _step = props.step;
|
| | | if (isHorizontal.value) {
|
| | | singleStep = realSingleStopWidth.value;
|
| | | } else {
|
| | | singleStep = realSingleStopHeight.value;
|
| | | }
|
| | | if (singleStep > 0 && singleStep % _step > 0) {
|
| | | console.error(
|
| | | "如果设置了单步滚动,step 需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确。~~~~~"
|
| | | );
|
| | | }
|
| | | return _step;
|
| | | });
|
| | |
|
| | | const cancle = () => {
|
| | | cancelAnimationFrame(reqFrame.value as number);
|
| | | reqFrame.value = null;
|
| | | };
|
| | | const animation = (
|
| | | _direction: "up" | "down" | "left" | "right",
|
| | | _step: number,
|
| | | isWheel?: boolean
|
| | | ) => {
|
| | | // console.log("animation",_direction,_step,isWheel);
|
| | | reqFrame.value = requestAnimationFrame(function () {
|
| | | const h = realBoxHeight.value / 2;
|
| | | const w = realBoxWidth.value / 2;
|
| | | if (_direction === "up") {
|
| | | if (Math.abs(yPos.value) >= h) {
|
| | | yPos.value = 0;
|
| | | _count.value += 1;
|
| | | emit("count", _count.value);
|
| | | }
|
| | | yPos.value -= _step;
|
| | | } else if (_direction === "down") {
|
| | | if (yPos.value >= 0) {
|
| | | yPos.value = h * -1;
|
| | | _count.value += 1;
|
| | | emit("count", _count.value);
|
| | | }
|
| | | yPos.value += _step;
|
| | | } else if (_direction === "left") {
|
| | | if (Math.abs(xPos.value) >= w) {
|
| | | xPos.value = 0;
|
| | | _count.value += 1;
|
| | | emit("count", _count.value);
|
| | | }
|
| | | xPos.value -= _step;
|
| | | } else if (_direction === "right") {
|
| | | if (xPos.value >= 0) {
|
| | | xPos.value = w * -1;
|
| | | _count.value += 1;
|
| | | emit("count", _count.value);
|
| | | }
|
| | | xPos.value += _step;
|
| | | }
|
| | | if (isWheel) {
|
| | | return;
|
| | | }
|
| | | let { singleWaitTime } = props;
|
| | | if (singleWaitTimeout.value) {
|
| | | clearTimeout(singleWaitTimeout.value);
|
| | | }
|
| | | if (!!realSingleStopHeight.value) {
|
| | | if (Math.abs(yPos.value) % realSingleStopHeight.value < _step) {
|
| | | singleWaitTimeout.value = setTimeout(() => {
|
| | | move();
|
| | | }, singleWaitTime);
|
| | | } else {
|
| | | move();
|
| | | }
|
| | | } else if (!!realSingleStopWidth.value) {
|
| | | if (Math.abs(xPos.value) % realSingleStopWidth.value < _step) {
|
| | | singleWaitTimeout.value = setTimeout(() => {
|
| | | move();
|
| | | }, singleWaitTime);
|
| | | } else {
|
| | | move();
|
| | | }
|
| | | } else {
|
| | | move();
|
| | | }
|
| | | });
|
| | | };
|
| | | const move = () => {
|
| | | cancle();
|
| | | if (isHover.value || !isScroll.value || _count.value === props.count) {
|
| | | emit("stop", _count.value);
|
| | | _count.value = 0;
|
| | | return;
|
| | | }
|
| | | animation(
|
| | | props.direction as "up" | "down" | "left" | "right",
|
| | | step.value,
|
| | | false
|
| | | );
|
| | | };
|
| | | const initMove = () => {
|
| | | dataWarm(props.list);
|
| | | if (isHorizontal.value) {
|
| | | let slotListWidth = (slotListRef.value as HTMLDivElement).offsetWidth;
|
| | | slotListWidth = slotListWidth * 2 + 1;
|
| | | realBoxWidth.value = slotListWidth;
|
| | | }
|
| | | if (isScroll.value) {
|
| | | realBoxHeight.value = (realBoxRef.value as HTMLDivElement).offsetHeight;
|
| | | if (props.modelValue) {
|
| | | move();
|
| | | }
|
| | | } else {
|
| | | cancle();
|
| | | yPos.value = xPos.value = 0;
|
| | | }
|
| | | // console.log("initMove","isHorizontal",isHorizontal.value,"isScroll",isScroll.value,realBoxRef.value?.offsetHeight);
|
| | | };
|
| | | const startMove = () => {
|
| | | isHover.value = false;
|
| | | move();
|
| | | };
|
| | |
|
| | | const stopMove = () => {
|
| | | isHover.value = true;
|
| | | if (singleWaitTimeout.value) {
|
| | | clearTimeout(singleWaitTimeout.value);
|
| | | }
|
| | | cancle();
|
| | | };
|
| | |
|
| | | const hoverStop = computed(
|
| | | () => props.hover && props.modelValue && isScroll.value
|
| | | );
|
| | | const throttleFunc = throttle((e: WheelEvent) => {
|
| | | cancle();
|
| | | const singleHeight = !!realSingleStopHeight.value
|
| | | ? realSingleStopHeight.value
|
| | | : 15;
|
| | | if (e.deltaY < 0) {
|
| | | animation("down", singleHeight, true);
|
| | | }
|
| | | if (e.deltaY > 0) {
|
| | | animation("up", singleHeight, true);
|
| | | }
|
| | | }, 30);
|
| | |
|
| | | const onWheel = (e: WheelEvent) => {
|
| | | throttleFunc(e);
|
| | | };
|
| | | const reset = () => {
|
| | | cancle();
|
| | | isHover.value = false;
|
| | | initMove();
|
| | | };
|
| | | const Reset = () => {
|
| | | reset();
|
| | | };
|
| | | defineExpose({
|
| | | Reset,
|
| | | });
|
| | |
|
| | | watch(
|
| | | () => props.list,
|
| | | () => {
|
| | | if (props.isWatch) {
|
| | | nextTick(() => {
|
| | | reset();
|
| | | });
|
| | | }
|
| | | },
|
| | | {
|
| | | deep: true,
|
| | | }
|
| | | );
|
| | |
|
| | | watch(
|
| | | () => props.modelValue,
|
| | | (newValue) => {
|
| | | if (newValue) {
|
| | | startMove();
|
| | | } else {
|
| | | stopMove();
|
| | | }
|
| | | }
|
| | | );
|
| | |
|
| | | watch(
|
| | | () => props.count,
|
| | | (newValue) => {
|
| | | if (newValue !== 0) {
|
| | | startMove();
|
| | | }
|
| | | }
|
| | | );
|
| | |
|
| | | onBeforeMount(() => {
|
| | | cancle();
|
| | | clearTimeout(singleWaitTimeout.value as unknown as number);
|
| | | });
|
| | |
|
| | | onMounted(() => {
|
| | | if (isScroll.value) {
|
| | | initMove();
|
| | | }
|
| | | });
|
| | | </script>
|
| | |
|
| | | <template>
|
| | | <div
|
| | | v-if="props.wheel && props.hover"
|
| | | ref="realBoxRef"
|
| | | :style="realBoxStyle"
|
| | | @mouseenter="
|
| | | () => {
|
| | | hoverStop && stopMove();
|
| | | }
|
| | | "
|
| | | @mouseleave="
|
| | | () => {
|
| | | hoverStop && startMove();
|
| | | }
|
| | | "
|
| | | @wheel="
|
| | | (e) => {
|
| | | hoverStop && onWheel(e);
|
| | | }
|
| | | "
|
| | | >
|
| | | <div ref="slotListRef" :style="floatStyle">
|
| | | <slot></slot>
|
| | | </div>
|
| | | <div :style="floatStyle">
|
| | | <slot></slot>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <div
|
| | | v-else
|
| | | :style="realBoxStyle"
|
| | | ref="realBoxRef"
|
| | | @mouseenter="
|
| | | () => {
|
| | | hoverStop && stopMove();
|
| | | }
|
| | | "
|
| | | @mouseleave="
|
| | | () => {
|
| | | hoverStop && startMove();
|
| | | }
|
| | | "
|
| | | >
|
| | | <div ref="slotListRef" :style="floatStyle">
|
| | | <slot></slot>
|
| | | </div>
|
| | | <div :style="floatStyle">
|
| | | <slot></slot>
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <style scoped lang="scss"></style>
|
| | |
| | | return a
|
| | | }
|
| | | },
|
| | | //左下
|
| | | {
|
| | | url: "/bigscreen/leftBottom",
|
| | | type: "get",
|
| | | response: () => {
|
| | | const a = Mock.mock({
|
| | | success: true,
|
| | | data: {
|
| | | "list|20": [
|
| | | {
|
| | | provinceName: "@province()",
|
| | | cityName: '@city()',
|
| | | countyName: "@county()",
|
| | | createTime: "@datetime('yyyy-MM-dd HH:mm:ss')",
|
| | | deviceId: "6c512d754bbcd6d7cd86abce0e0cac58",
|
| | | "gatewayno|+1": 10000,
|
| | | "onlineState|1": [0, 1],
|
| | |
|
| | | }
|
| | | ]
|
| | | }
|
| | | })
|
| | | return a
|
| | | }
|
| | | },
|
| | | //右上
|
| | | {
|
| | | url: "/bigscreen/alarmNum",
|
| | |
| | | url: "/bigscreen/ranking",
|
| | | type: "get",
|
| | | response: () => {
|
| | | let num =Mock.mock({"list|80":[{ value:"@integer(50,1000)",name:"@city()"}]}).list
|
| | | let num = Mock.mock({ "list|80": [{ value: "@integer(50,1000)", name: "@city()" }] }).list
|
| | | // console.log("ranking",num);
|
| | | let newNum:any =[],numObj:any ={}
|
| | | num.map((item:any )=>{
|
| | | if(!numObj[item.name] && newNum.length<8){
|
| | | numObj[item.name] =true
|
| | | let newNum: any = [], numObj: any = {}
|
| | | num.map((item: any) => {
|
| | | if (!numObj[item.name] && newNum.length < 8) {
|
| | | numObj[item.name] = true
|
| | | newNum.push(item)
|
| | | }
|
| | | })
|
| | | let arr = newNum.sort((a:any ,b:any )=>{
|
| | | return b.value-a.value
|
| | | })
|
| | | let a ={
|
| | | success:true,
|
| | | data:arr
|
| | | }
|
| | | return a
|
| | | })
|
| | | let arr = newNum.sort((a: any, b: any) => {
|
| | | return b.value - a.value
|
| | | })
|
| | | let a = {
|
| | | success: true,
|
| | | data: arr
|
| | | }
|
| | | return a
|
| | | }
|
| | | },
|
| | | //右下
|
| | | {
|
| | | url: "/bigscreen/rightBottom",
|
| | | type: "get",
|
| | | response: () => {
|
| | | const a = Mock.mock({
|
| | | success: true,
|
| | | data: {
|
| | | "list|40": [{
|
| | | alertdetail: "@csentence(5,10)",
|
| | | "alertname|1": ["水浸告警", "各种报警"],
|
| | | alertvalue: "@float(60, 200)",
|
| | | createtime: "2022-04-19 08:38:33",
|
| | | deviceid: null,
|
| | | "gatewayno|+1": 10000,
|
| | | phase: "A1",
|
| | | sbInfo: "@csentence(10,18)",
|
| | | "terminalno|+1": 100,
|
| | | provinceName: "@province()",
|
| | | cityName: '@city()',
|
| | | countyName: "@county()",
|
| | | }],
|
| | |
|
| | | }
|
| | | })
|
| | | return a
|
| | | }
|
| | | },
|
| | | //安装计划
|
| | |
| | | import { ref, computed } from 'vue'
|
| | | import { ref, computed, reactive } from 'vue'
|
| | | import { defineStore } from 'pinia'
|
| | | // import { storeToRefs } from 'pinia';
|
| | | export const useSettingStore = defineStore('setting', () => {
|
| | | const settingShow = ref(false);//设置弹窗显隐
|
| | | const isScale = ref(false);//是否进行全局适配
|
| | |
|
| | | const setSettingShow = (flag:boolean)=>{
|
| | | settingShow.value=flag
|
| | | const indexConfig = ref({
|
| | | leftBottomSwiper: true,//左轮播
|
| | | rightBottomSwiper: true,//右下轮播
|
| | | })
|
| | | const defaultOption = ref({
|
| | | step: 4, // 数值越大速度滚动越快
|
| | | hover: true, // 是否开启鼠标悬停stop
|
| | | wheel: false,//在开启鼠标悬停的情况下是否开启滚轮滚动,默认不开启
|
| | | openWatch: true, // 开启数据实时监控刷新dom
|
| | | direction: 1, // 0向下 1向上 2向左 3向右
|
| | | limitScrollNum: 4, // 开始无缝滚动的数据量 this.dataList.length
|
| | | singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
|
| | | singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
|
| | | singleWaitTime: 3000 // 单步运动停止的时间(默认值1000ms)
|
| | | })
|
| | | const setSettingShow = (flag: boolean) => {
|
| | | settingShow.value = flag
|
| | | }
|
| | | const setIsScale = (flag:boolean)=>{
|
| | | isScale.value=flag
|
| | | const setIsScale = (flag: boolean) => {
|
| | | isScale.value = flag
|
| | | setSettingData()
|
| | | }
|
| | | const initSetting=()=>{
|
| | | let settingData:any = localStorage.getItem('loftv-settingData')
|
| | | if(settingData){
|
| | | settingData=JSON.parse(settingData)
|
| | | setIsScale(settingData.isScale)
|
| | | const setIndexConfig = (Config: any) => {
|
| | | indexConfig.value = Config
|
| | | localStorage.setItem('loftv-indexConfig', JSON.stringify(indexConfig.value))
|
| | | }
|
| | | const initSetting = () => {
|
| | | let settingData: any = localStorage.getItem('loftv-settingData')
|
| | | if (settingData) {
|
| | | settingData = JSON.parse(settingData)
|
| | | setIsScale(settingData.isScale)
|
| | | }
|
| | | let settingIndexConfig: any = localStorage.getItem('loftv-indexConfig')
|
| | | if (settingIndexConfig) {
|
| | | settingIndexConfig = JSON.parse(settingIndexConfig)
|
| | | setIndexConfig(settingIndexConfig)
|
| | | }
|
| | | }
|
| | | const setSettingData=()=>{
|
| | | localStorage.setItem('loftv-settingData',JSON.stringify({
|
| | | isScale:isScale.value
|
| | | const setSettingData = () => {
|
| | | localStorage.setItem('loftv-settingData', JSON.stringify({
|
| | | isScale: isScale.value
|
| | | }))
|
| | | }
|
| | | return { settingShow, setSettingShow,isScale ,setIsScale,initSetting,setSettingData}
|
| | | return { settingShow, setSettingShow, isScale, setIsScale, initSetting, setSettingData, defaultOption, indexConfig, setIndexConfig }
|
| | | })
|
| | |
| | | import ItemWrap from "@/components/item-wrap";
|
| | | import LeftTop from "./left-top.vue";
|
| | | import LeftCenter from "./left-center.vue";
|
| | | import LeftBottom from "./left-bottom.vue";
|
| | | import CenterMap from "./center-map.vue";
|
| | | import CenterBottom from "./center-bottom.vue";
|
| | | import RightTop from "./right-top.vue";
|
| | |
| | | title="设备提醒"
|
| | | style="padding: 0 10px 16px 10px"
|
| | | >
|
| | | <!-- <LeftBottom /> -->
|
| | | <LeftBottom />
|
| | | </ItemWrap>
|
| | | </div>
|
| | | <div class="contetn_center">
|
New file |
| | |
| | | <script setup lang="ts">
|
| | | import { currentGET } from "@/api";
|
| | | import SeamlessScroll from "@/components/seamless-scroll";
|
| | | import { computed, onMounted, reactive } from "vue";
|
| | | import { useSettingStore } from "@/stores";
|
| | | import { storeToRefs } from "pinia";
|
| | | import EmptyCom from "@/components/empty-com"
|
| | | const settingStore = useSettingStore();
|
| | | const { defaultOption,indexConfig } = storeToRefs(settingStore);
|
| | | const state = reactive<any>({
|
| | | list: [],
|
| | | defaultOption: {
|
| | | ...defaultOption.value,
|
| | | singleHeight: 256,
|
| | | limitScrollNum: 4,
|
| | | },
|
| | | scroll: true,
|
| | | });
|
| | |
|
| | | const getData = () => {
|
| | | currentGET("leftBottom", { limitNum: 20 }).then((res) => {
|
| | | console.log("设备提醒", res);
|
| | | if (res.success) {
|
| | | state.list = res.data.list;
|
| | | } else {
|
| | | window.$message({
|
| | | text: res.msg,
|
| | | type: "warning",
|
| | | });
|
| | | }
|
| | | });
|
| | | };
|
| | | const addressHandle = (item: any) => {
|
| | | let name = item.provinceName;
|
| | | if (item.cityName) {
|
| | | name += "/" + item.cityName;
|
| | | if (item.countyName) {
|
| | | name += "/" + item.countyName;
|
| | | }
|
| | | }
|
| | | return name;
|
| | | };
|
| | | const comName = computed(()=>{
|
| | | if(indexConfig.value.leftBottomSwiper){
|
| | | return SeamlessScroll
|
| | | }else{
|
| | | return EmptyCom
|
| | | }
|
| | | })
|
| | | onMounted(() => {
|
| | | getData();
|
| | | });
|
| | | </script>
|
| | |
|
| | | <template>
|
| | | <div class="left_boottom_wrap beautify-scroll-def" :class="{ 'overflow-y-auto': !indexConfig.leftBottomSwiper }">
|
| | | <component
|
| | | :is="comName"
|
| | | :list="state.list"
|
| | | v-model="state.scroll"
|
| | | :singleHeight="state.defaultOption.singleHeight"
|
| | | :step="state.defaultOption.step"
|
| | | :limitScrollNum="state.defaultOption.limitScrollNum"
|
| | | :hover="state.defaultOption.hover"
|
| | | :singleWaitTime="state.defaultOption.singleWaitTime"
|
| | | :wheel="state.defaultOption.wheel"
|
| | | >
|
| | | <ul class="left_boottom">
|
| | | <li class="left_boottom_item" v-for="(item, i) in state.list" :key="i">
|
| | | <span class="orderNum doudong">{{ i + 1 }}</span>
|
| | | <div class="inner_right">
|
| | | <div class="dibu"></div>
|
| | | <div class="flex">
|
| | | <div class="info">
|
| | | <span class="labels">设备ID:</span>
|
| | | <span class="text-content zhuyao doudong wangguan">
|
| | | {{ item.gatewayno }}</span
|
| | | >
|
| | | </div>
|
| | | <div class="info">
|
| | | <span class="labels">时间:</span>
|
| | | <span class="text-content" style="font-size: 12px">
|
| | | {{ item.createTime }}</span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <span
|
| | | class="types doudong"
|
| | | :class="{
|
| | | typeRed: item.onlineState == 0,
|
| | | typeGreen: item.onlineState == 1,
|
| | | }"
|
| | | >{{ item.onlineState == 1 ? "上线" : "下线" }}</span
|
| | | >
|
| | |
|
| | | <div class="info addresswrap">
|
| | | <span class="labels">地址:</span>
|
| | | <span class="text-content ciyao" style="font-size: 12px">
|
| | | {{ addressHandle(item) }}</span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | | </li>
|
| | | </ul>
|
| | | </component>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <style scoped lang="scss">
|
| | | .left_boottom_wrap {
|
| | | overflow: hidden;
|
| | | width: 100%;
|
| | | height: 100%;
|
| | | }
|
| | |
|
| | | .doudong {
|
| | | overflow: hidden;
|
| | | backface-visibility: hidden;
|
| | | }
|
| | |
|
| | | .overflow-y-auto {
|
| | | overflow-y: auto;
|
| | | }
|
| | |
|
| | | .left_boottom {
|
| | | width: 100%;
|
| | | height: 100%;
|
| | |
|
| | | .left_boottom_item {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | padding: 8px;
|
| | | font-size: 14px;
|
| | | margin: 10px 0;
|
| | | .orderNum {
|
| | | margin: 0 16px 0 -20px;
|
| | | }
|
| | |
|
| | | .info {
|
| | | margin-right: 10px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | color: #fff;
|
| | |
|
| | | .labels {
|
| | | flex-shrink: 0;
|
| | | font-size: 12px;
|
| | | color: rgba(255, 255, 255, 0.6);
|
| | | }
|
| | |
|
| | | .zhuyao {
|
| | | color: $primary-color;
|
| | | font-size: 15px;
|
| | | }
|
| | |
|
| | | .ciyao {
|
| | | color: rgba(255, 255, 255, 0.8);
|
| | | }
|
| | |
|
| | | .warning {
|
| | | color: #e6a23c;
|
| | | font-size: 15px;
|
| | | }
|
| | | }
|
| | |
|
| | | .inner_right {
|
| | | position: relative;
|
| | | height: 100%;
|
| | | width: 380px;
|
| | | flex-shrink: 0;
|
| | | line-height: 1;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: space-between;
|
| | | flex-wrap: wrap;
|
| | | .dibu {
|
| | | position: absolute;
|
| | | height: 2px;
|
| | | width: 104%;
|
| | | background-image: url("@/assets/img/zuo_xuxian.png");
|
| | | bottom: -10px;
|
| | | left: -2%;
|
| | | background-size: cover;
|
| | | }
|
| | | .addresswrap {
|
| | | width: 100%;
|
| | | display: flex;
|
| | | margin-top: 8px;
|
| | | }
|
| | | }
|
| | |
|
| | | .wangguan {
|
| | | color: #1890ff;
|
| | | font-weight: 900;
|
| | | font-size: 15px;
|
| | | width: 80px;
|
| | | flex-shrink: 0;
|
| | | }
|
| | |
|
| | | .time {
|
| | | font-size: 12px;
|
| | | // color: rgba(211, 210, 210,.8);
|
| | | color: #fff;
|
| | | }
|
| | |
|
| | | .address {
|
| | | font-size: 12px;
|
| | | cursor: pointer;
|
| | | // @include text-overflow(1);
|
| | | }
|
| | |
|
| | | .types {
|
| | | width: 30px;
|
| | | flex-shrink: 0;
|
| | | }
|
| | |
|
| | | .typeRed {
|
| | | color: #fc1a1a;
|
| | | }
|
| | |
|
| | | .typeGreen {
|
| | | color: #29fc29;
|
| | | }
|
| | | }
|
| | | }
|
| | | </style>
|
| | |
| | | <script setup lang='ts'>
|
| | | <script setup lang="ts">
|
| | | import { currentGET } from "@/api";
|
| | | import SeamlessScroll from "@/components/seamless-scroll";
|
| | | import { computed, onMounted, reactive } from "vue";
|
| | | import { useSettingStore } from "@/stores";
|
| | | import { storeToRefs } from "pinia";
|
| | | import EmptyCom from "@/components/empty-com";
|
| | | const settingStore = useSettingStore();
|
| | | const { defaultOption, indexConfig } = storeToRefs(settingStore);
|
| | | const state = reactive<any>({
|
| | | list: [],
|
| | | defaultOption: {
|
| | | ...defaultOption.value,
|
| | | singleHeight: 252,
|
| | | limitScrollNum: 3,
|
| | | // step:3
|
| | | },
|
| | | scroll: true,
|
| | |
|
| | | });
|
| | |
|
| | | const getData = () => {
|
| | | currentGET("rightBottom", { limitNum: 20 }).then((res) => {
|
| | | console.log("右下", res);
|
| | | if (res.success) {
|
| | | state.list = res.data.list;
|
| | | } else {
|
| | | window.$message({
|
| | | text: res.msg,
|
| | | type: "warning",
|
| | | });
|
| | | }
|
| | | });
|
| | | };
|
| | |
|
| | | const comName = computed(() => {
|
| | | if (indexConfig.value.rightBottomSwiper) {
|
| | | return SeamlessScroll;
|
| | | } else {
|
| | | return EmptyCom;
|
| | | }
|
| | | });
|
| | | function montionFilter (val:any) {
|
| | | // console.log(val);
|
| | | return val ? Number(val).toFixed(2) : '--'
|
| | | }
|
| | | const handleAddress=(item:any)=>{
|
| | | return `${ item.provinceName }/${item.cityName }/${item.countyName}`
|
| | | }
|
| | | onMounted(() => {
|
| | | getData();
|
| | | });
|
| | | </script>
|
| | |
|
| | | <template>
|
| | | <div class=''>
|
| | | <div
|
| | | class="right_bottom_wrap beautify-scroll-def"
|
| | | :class="{ 'overflow-y-auto': !indexConfig.rightBottomSwiper }"
|
| | | >
|
| | | <component
|
| | | :is="comName"
|
| | | :list="state.list"
|
| | | v-model="state.scroll"
|
| | | :singleHeight="state.defaultOption.singleHeight"
|
| | | :step="state.defaultOption.step"
|
| | | :limitScrollNum="state.defaultOption.limitScrollNum"
|
| | | :hover="state.defaultOption.hover"
|
| | | :singleWaitTime="state.defaultOption.singleWaitTime"
|
| | | :wheel="state.defaultOption.wheel"
|
| | | >
|
| | | <ul class="right_bottom">
|
| | | <li class="right_center_item" v-for="(item, i) in state.list" :key="i">
|
| | | <span class="orderNum">{{ i + 1 }}</span>
|
| | | <div class="inner_right">
|
| | | <div class="dibu"></div>
|
| | | <div class="flex">
|
| | | <div class="info">
|
| | | <span class="labels">设备ID:</span>
|
| | | <span class="text-content zhuyao"> {{ item.gatewayno }}</span>
|
| | | </div>
|
| | | <div class="info">
|
| | | <span class="labels">型号:</span>
|
| | | <span class="text-content"> {{ item.terminalno }}</span>
|
| | | </div>
|
| | | <div class="info">
|
| | | <span class="labels">告警值:</span>
|
| | | <span class="text-content warning">
|
| | | {{ montionFilter(item.alertvalue) }}</span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <div class="flex">
|
| | | <div class="info">
|
| | | <span class="labels shrink-0"> 地址:</span>
|
| | | <span class=" ciyao truncate" style="font-size: 12px;width: 220px;" :title="handleAddress(item)">
|
| | | {{ handleAddress(item)}}</span
|
| | | >
|
| | | </div>
|
| | | <div class="info time shrink-0">
|
| | | <span class="labels">时间:</span>
|
| | | <span class="text-content" style="font-size: 12px">
|
| | | {{ item.createtime }}</span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | | <div class="flex">
|
| | | <div class="info">
|
| | | <span class="labels">报警内容:</span>
|
| | | <span
|
| | | class="text-content ciyao"
|
| | | :class="{ warning: item.alertdetail }"
|
| | | >
|
| | | {{ item.alertdetail || "无" }}</span
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </li>
|
| | | </ul>
|
| | | </component>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <style scoped lang='scss'>
|
| | | <style scoped lang="scss">
|
| | | .right_bottom {
|
| | | width: 100%;
|
| | | height: 100%;
|
| | |
|
| | | </style> |
| | | .right_center_item {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | height: auto;
|
| | | padding: 10px;
|
| | | font-size: 14px;
|
| | | color: #fff;
|
| | |
|
| | | .orderNum {
|
| | | margin: 0 20px 0 -20px;
|
| | | }
|
| | |
|
| | | .inner_right {
|
| | | position: relative;
|
| | | height: 100%;
|
| | | width: 400px;
|
| | | flex-shrink: 0;
|
| | | line-height: 1.5;
|
| | |
|
| | | .dibu {
|
| | | position: absolute;
|
| | | height: 2px;
|
| | | width: 104%;
|
| | | background-image: url("@/assets/img/zuo_xuxian.png");
|
| | | bottom: -12px;
|
| | | left: -2%;
|
| | | background-size: cover;
|
| | | }
|
| | | }
|
| | |
|
| | | .info {
|
| | | margin-right: 10px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | |
|
| | | .labels {
|
| | | flex-shrink: 0;
|
| | | font-size: 12px;
|
| | | color: rgba(255, 255, 255, 0.6);
|
| | | }
|
| | |
|
| | | .zhuyao {
|
| | | color: $primary-color;
|
| | | font-size: 15px;
|
| | | }
|
| | |
|
| | | .ciyao {
|
| | | color: rgba(255, 255, 255, 0.8);
|
| | | }
|
| | |
|
| | | .warning {
|
| | | color: #e6a23c;
|
| | | font-size: 15px;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | .right_bottom_wrap {
|
| | | overflow: hidden;
|
| | | width: 100%;
|
| | | height: 252px;
|
| | | }
|
| | |
|
| | | .overflow-y-auto {
|
| | | overflow-y: auto;
|
| | | }
|
| | | </style>
|
| | |
| | | <script setup lang="ts">
|
| | | import { useSettingStore } from "@/stores/index";
|
| | | import { ref } from "vue";
|
| | | import {storeToRefs} from "pinia"
|
| | | const isScaleRadio = ref(false);
|
| | | const leftBottomRadio=ref(true)
|
| | | const rightBottomRadio=ref(true)
|
| | | const settingStore = useSettingStore();
|
| | | const {indexConfig}=storeToRefs(settingStore)
|
| | |
|
| | | const init = () => {
|
| | | settingStore.initSetting();
|
| | | isScaleRadio.value = settingStore.isScale;
|
| | |
|
| | | leftBottomRadio.value=indexConfig.value.leftBottomSwiper
|
| | | rightBottomRadio.value=indexConfig.value.rightBottomSwiper
|
| | |
|
| | | };
|
| | | init();
|
| | | const handleClose = () => {};
|
| | |
| | | const isScaleChange = (flag: boolean) => {
|
| | | settingStore.setIsScale(flag);
|
| | | };
|
| | | const radiochange = (blag: boolean, type: string) => {
|
| | | console.log(blag, type);
|
| | | const radiochange = (blag: boolean) => {
|
| | | settingStore.setIsScale(blag);
|
| | | // this.$store.commit('setting/updateSwiper', { val, type })
|
| | | };
|
| | | const indexRadioChange=(flag: boolean)=>{
|
| | | settingStore.setIndexConfig({
|
| | | leftBottomSwiper: leftBottomRadio.value,//左轮播
|
| | | rightBottomSwiper:rightBottomRadio.value,//右下轮播
|
| | | });
|
| | | }
|
| | | </script>
|
| | |
|
| | | <template>
|
| | |
| | | </el-radio-group>
|
| | | </div>
|
| | | </div>
|
| | | <div class="left_shu">实时监测</div>
|
| | | <div class="setting_item">
|
| | | <span class="setting_label">
|
| | | 设备提醒自动轮询: <span class="setting_label_tip"></span>
|
| | | </span>
|
| | | <div class="setting_content">
|
| | | <el-radio-group
|
| | | v-model="leftBottomRadio"
|
| | | @change="indexRadioChange"
|
| | | >
|
| | | <el-radio :label="true">是</el-radio>
|
| | | <el-radio :label="false">否</el-radio>
|
| | | </el-radio-group>
|
| | | </div>
|
| | | </div>
|
| | | <div class="setting_item">
|
| | | <span class="setting_label"> 实时预警轮播: </span>
|
| | | <div class="setting_content">
|
| | | <el-radio-group
|
| | | v-model="rightBottomRadio"
|
| | | @change="indexRadioChange"
|
| | | >
|
| | | <el-radio :label="true">是</el-radio>
|
| | | <el-radio :label="false">否</el-radio>
|
| | | </el-radio-group>
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | | <!-- <template #footer>
|
| | | <div style="flex: auto">
|
| | |
| | | interface Window { |
| | | $message: any |
| | | } |
| | | |
| | | type TimeProp= NodeJS.Timeout |