feat: 首页大屏模块开发

dev-deviceSetting
JINGYJ 1 year ago
parent 130131aea4
commit 1017acbbde

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 174 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 188 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 194 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 194 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.0 MiB

@ -0,0 +1,27 @@
<svg width="210" height="96" viewBox="0 0 210 96" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 94V95H2H207H208V94V64.8393V64.3732L207.643 64.0735L201.886 59.2393V36.35L207.643 31.5158L208 31.2161V30.75V2V1H207H2H1V2V94Z" fill="#071D46" stroke="#1F4885" stroke-width="2"/>
<path d="M17 1H1V17" stroke="#20A0FD" stroke-width="2"/>
<path d="M17 95H1V79" stroke="#20A0FD" stroke-width="2"/>
<path opacity="0.8" d="M77 94V2H208V30.75L200.971 35.8839V59.7054L208 64.8393V94H77Z" fill="url(#paint0_linear_8677_101011)"/>
<path d="M192 1H208V17" stroke="#20A0FD" stroke-width="2"/>
<path d="M193 95H209V79" stroke="#20A0FD" stroke-width="2"/>
<path d="M209 62V33L204 37V57.5L209 62Z" fill="#0A7CFE"/>
<path opacity="0.3" d="M93 12H143.443L166.103 28H192" stroke="url(#paint1_linear_8677_101011)" stroke-width="1.5"/>
<path opacity="0.3" d="M93 84H143.443L166.103 68H192" stroke="url(#paint2_linear_8677_101011)" stroke-width="1.5"/>
<defs>
<linearGradient id="paint0_linear_8677_101011" x1="97.5" y1="2" x2="97.5" y2="94" gradientUnits="userSpaceOnUse">
<stop stop-color="#084BA1"/>
<stop offset="1" stop-color="#071E49"/>
</linearGradient>
<linearGradient id="paint1_linear_8677_101011" x1="99" y1="12" x2="194" y2="12" gradientUnits="userSpaceOnUse">
<stop stop-color="#20A0FD" stop-opacity="0"/>
<stop offset="0.48" stop-color="#20A0FD"/>
<stop offset="1" stop-color="#20A0FD" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_8677_101011" x1="90" y1="84" x2="190" y2="84" gradientUnits="userSpaceOnUse">
<stop stop-color="#20A0FD" stop-opacity="0"/>
<stop offset="0.48" stop-color="#20A0FD"/>
<stop offset="1" stop-color="#20A0FD" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,7 @@
import reSeamlessScroll from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
/** 无缝滚动组件 */
export const ReSeamlessScroll = withInstall(reSeamlessScroll);
export default ReSeamlessScroll;

@ -0,0 +1,532 @@
<script setup lang="ts">
import { computed, ref, unref, nextTick } from "vue";
import type { CSSProperties, PropType } from "vue";
import {
tryOnMounted,
tryOnUnmounted,
templateRef,
useDebounceFn
} from "@vueuse/core";
import * as utilsMethods from "./utils";
const { animationFrame, copyObj } = utilsMethods;
animationFrame();
defineOptions({
name: "ReSeamlessScroll"
});
const props = defineProps({
data: {
type: Array as PropType<unknown>
},
classOption: {
type: Object as PropType<unknown>
}
});
const emit = defineEmits<{
(e: "scrollEnd"): void;
}>();
const xPos = ref<number>(0);
const yPos = ref<number>(0);
const delay = ref<number>(0);
const height = ref<number>(0);
//
const width = ref<number>(0);
//
const realBoxWidth = ref<number>(0);
const realBoxHeight = ref<number>(0);
const copyHtml = ref("");
// single
let singleWaitTime = null;
// moveanimationFrame
let reqFrame = null;
let startPos = null;
//touchStartposY
let startPosY = null;
//touchStartposX
let startPosX = null;
// mouseenter mouseleave scrollMove()
let isHover = false;
let ease = "ease-in";
if (props.classOption["key"] === undefined) {
// eslint-disable-next-line vue/no-mutating-props
props.classOption["key"] = 0;
}
const wrap = templateRef<HTMLElement | null>(
`wrap${props.classOption["key"]}`,
null
);
const slotList = templateRef<HTMLElement | null>(
`slotList${props.classOption["key"]}`,
null
);
const realBox = templateRef<HTMLElement | null>(
`realBox${props.classOption["key"]}`,
null
);
const leftSwitchState = computed(() => {
return unref(xPos) < 0;
});
const rightSwitchState = computed(() => {
return Math.abs(unref(xPos)) < unref(realBoxWidth) - unref(width);
});
const defaultOption = computed(() => {
return {
//
step: 1,
//
limitMoveNum: 5,
//hover
hoverStop: true,
// bottom top () left right
direction: "top",
//touch
openTouch: true,
//hoverStop
singleHeight: 0,
//hoverStop
singleWidth: 0,
//
waitTime: 1000,
switchOffset: 30,
autoPlay: true,
navigation: false,
switchSingleStep: 134,
switchDelay: 400,
switchDisabledClass: "disabled",
// singleWidth/singleHeight rem
isSingleRemUnit: false
};
});
const options = computed(() => {
// @ts-expect-error
return copyObj({}, unref(defaultOption), props.classOption);
});
const leftSwitchClass = computed(() => {
return unref(leftSwitchState) ? "" : unref(options).switchDisabledClass;
});
const rightSwitchClass = computed(() => {
return unref(rightSwitchState) ? "" : unref(options).switchDisabledClass;
});
const leftSwitch = computed((): CSSProperties => {
return {
position: "absolute",
margin: `${unref(height) / 2}px 0 0 -${unref(options).switchOffset}px`,
transform: "translate(-100%,-50%)"
};
});
const rightSwitch = computed((): CSSProperties => {
return {
position: "absolute",
margin: `${unref(height) / 2}px 0 0 ${
unref(width) + unref(options).switchOffset
}px`,
transform: "translateY(-50%)"
};
});
const isHorizontal = computed(() => {
return (
unref(options).direction !== "bottom" && unref(options).direction !== "top"
);
});
const float = computed((): CSSProperties => {
return unref(isHorizontal)
? { float: "left", overflow: "hidden" }
: { overflow: "hidden" };
});
const pos = computed(() => {
return {
transform: `translate(${unref(xPos)}px,${unref(yPos)}px)`,
transition: `all ${ease} ${unref(delay)}ms`,
overflow: "hidden"
};
});
const navigation = computed(() => {
return unref(options).navigation;
});
const autoPlay = computed(() => {
if (unref(navigation)) return false;
return unref(options).autoPlay;
});
const scrollSwitch = computed(() => {
// props .
return (props.data as any).length >= unref(options).limitMoveNum;
});
const hoverStopSwitch = computed(() => {
return unref(options).hoverStop && unref(autoPlay) && unref(scrollSwitch);
});
const canTouchScroll = computed(() => {
return unref(options).openTouch;
});
const baseFontSize = computed(() => {
return unref(options).isSingleRemUnit
? parseInt(window.getComputedStyle(document.documentElement, null).fontSize)
: 1;
});
const realSingleStopWidth = computed(() => {
return unref(options).singleWidth * unref(baseFontSize);
});
const realSingleStopHeight = computed(() => {
return unref(options).singleHeight * unref(baseFontSize);
});
const step = computed(() => {
let singleStep;
const step = unref(options).step;
if (unref(isHorizontal)) {
singleStep = unref(realSingleStopWidth);
} else {
singleStep = unref(realSingleStopHeight);
}
if (singleStep > 0 && singleStep % step > 0) {
throw "如果设置了单步滚动step需是单步大小的约数否则无法保证单步滚动结束的位置是否准确";
}
return step;
});
function reset() {
xPos.value = 0;
yPos.value = 0;
scrollCancle();
scrollInitMove();
}
function leftSwitchClick() {
if (!unref(leftSwitchState)) return;
//
if (Math.abs(unref(xPos)) < unref(options).switchSingleStep) {
xPos.value = 0;
return;
}
xPos.value += unref(options).switchSingleStep;
}
function rightSwitchClick() {
if (!unref(rightSwitchState)) return;
//
if (
unref(realBoxWidth) - unref(width) + unref(xPos) <
unref(options).switchSingleStep
) {
xPos.value = unref(width) - unref(realBoxWidth);
return;
}
xPos.value -= unref(options).switchSingleStep;
}
function scrollCancle() {
cancelAnimationFrame(reqFrame || "");
}
function touchStart(e) {
if (!unref(canTouchScroll)) return;
let timer;
//touchestouchtouch
const touch = e.targetTouches[0];
const { waitTime, singleHeight, singleWidth } = unref(options);
//touch
startPos = {
x: touch.pageX,
y: touch.pageY
};
//touchStartposY
startPosY = unref(yPos);
//touchStartposX
startPosX = unref(xPos);
if (!!singleHeight && !!singleWidth) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
scrollCancle();
}, waitTime + 20);
} else {
scrollCancle();
}
}
function touchMove(e) {
//touchmove
if (
!unref(canTouchScroll) ||
e.targetTouches.length > 1 ||
(e.scale && e.scale !== 1)
)
return;
const touch = e.targetTouches[0];
const { direction } = unref(options);
const endPos = {
x: touch.pageX - startPos.x,
y: touch.pageY - startPos.y
};
//
e.preventDefault();
//dir10
const dir = Math.abs(endPos.x) < Math.abs(endPos.y) ? 1 : 0;
if (
(dir === 1 && direction === "bottom") ||
(dir === 1 && direction === "top")
) {
// &&
yPos.value = startPosY + endPos.y;
} else if (
(dir === 0 && direction === "left") ||
(dir === 0 && direction === "right")
) {
// &&
xPos.value = startPosX + endPos.x;
}
}
function touchEnd() {
if (!unref(canTouchScroll)) return;
// eslint-disable-next-line prefer-const
let timer: any;
const direction = unref(options).direction;
delay.value = 50;
if (direction === "top") {
if (unref(yPos) > 0) yPos.value = 0;
} else if (direction === "bottom") {
const h = (unref(realBoxHeight) / 2) * -1;
if (unref(yPos) < h) yPos.value = h;
} else if (direction === "left") {
if (unref(xPos) > 0) xPos.value = 0;
} else if (direction === "right") {
const w = unref(realBoxWidth) * -1;
if (unref(xPos) < w) xPos.value = w;
}
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
delay.value = 0;
scrollMove();
}, unref(delay));
}
function enter() {
if (unref(hoverStopSwitch)) scrollStopMove();
}
function leave() {
if (unref(hoverStopSwitch)) scrollStartMove();
}
function scrollMove() {
// scrollMove()
if (isHover) return;
//move touchMove
// scrollCancle();
reqFrame = requestAnimationFrame(function () {
//
const h = unref(realBoxHeight) / 2;
//
const w = unref(realBoxWidth) / 2;
const { direction, waitTime } = unref(options);
if (direction === "top") {
//
if (Math.abs(unref(yPos)) >= h) {
emit("scrollEnd");
yPos.value = 0;
}
yPos.value -= step.value;
} else if (direction === "bottom") {
//
if (unref(yPos) >= 0) {
emit("scrollEnd");
yPos.value = h * -1;
}
yPos.value += step.value;
} else if (direction === "left") {
//
if (Math.abs(unref(xPos)) >= w) {
emit("scrollEnd");
xPos.value = 0;
}
xPos.value -= step.value;
} else if (direction === "right") {
//
if (unref(xPos) >= 0) {
emit("scrollEnd");
xPos.value = w * -1;
}
xPos.value += step.value;
}
if (singleWaitTime) clearTimeout(singleWaitTime);
if (unref(realSingleStopHeight)) {
//
if (Math.abs(unref(yPos)) % unref(realSingleStopHeight) < unref(step)) {
// waitTime
singleWaitTime = setTimeout(() => {
scrollMove();
}, waitTime);
} else {
scrollMove();
}
} else if (unref(realSingleStopWidth)) {
if (Math.abs(unref(xPos)) % unref(realSingleStopWidth) < unref(step)) {
// waitTime
singleWaitTime = setTimeout(() => {
scrollMove();
}, waitTime);
} else {
scrollMove();
}
} else {
scrollMove();
}
});
}
function scrollInitMove() {
nextTick(() => {
const { switchDelay } = unref(options);
//copy
copyHtml.value = "";
if (unref(isHorizontal)) {
height.value = unref(wrap).offsetHeight;
width.value = unref(wrap).offsetWidth;
let slotListWidth = unref(slotList).offsetWidth;
// warp width
if (unref(autoPlay)) {
// offsetWidth
slotListWidth = slotListWidth * 2 + 1;
}
unref(realBox).style.width = slotListWidth + "px";
realBoxWidth.value = slotListWidth;
}
if (unref(autoPlay)) {
ease = "ease-in";
delay.value = 0;
} else {
ease = "linear";
delay.value = switchDelay;
return;
}
//
if (unref(scrollSwitch)) {
let timer;
if (timer) clearTimeout(timer);
copyHtml.value = unref(slotList).innerHTML;
setTimeout(() => {
realBoxHeight.value = unref(realBox)?.offsetHeight;
scrollMove();
}, 0);
} else {
scrollCancle();
yPos.value = xPos.value = 0;
}
});
}
function scrollStartMove() {
//scrollMove
isHover = false;
scrollMove();
}
function scrollStopMove() {
//scrollMove
isHover = true;
// hover,
if (singleWaitTime) clearTimeout(singleWaitTime);
scrollCancle();
}
//
function wheel(e) {
if (
unref(options).direction === "left" ||
unref(options).direction === "right"
)
return;
useDebounceFn(() => {
e.deltaY > 0 ? (yPos.value -= step.value) : (yPos.value += step.value);
}, 50)();
}
// watchEffect(() => {
// const watchData = data;
// if (!watchData) return;
// nextTick(() => {
// reset();
// });
// const watchAutoPlay = unref(autoPlay);
// if (watchAutoPlay) {
// reset();
// } else {
// scrollStopMove();
// }
// });
tryOnMounted(() => {
scrollInitMove();
});
tryOnUnmounted(() => {
scrollCancle();
clearTimeout(singleWaitTime);
});
defineExpose({
reset
});
</script>
<template>
<div :ref="'wrap' + props.classOption['key']">
<div
:style="leftSwitch"
v-if="navigation"
:class="leftSwitchClass"
@click="leftSwitchClick"
>
<slot name="left-switch" />
</div>
<div
:style="rightSwitch"
v-if="navigation"
:class="rightSwitchClass"
@click="rightSwitchClick"
>
<slot name="right-switch" />
</div>
<div
:ref="'realBox' + props.classOption['key']"
:style="pos"
@mouseenter="enter"
@mouseleave="leave"
@touchstart.passive="touchStart"
@touchmove.passive="touchMove"
@touchend="touchEnd"
@mousewheel.passive="wheel"
>
<div :ref="'slotList' + props.classOption['key']" :style="float">
<slot />
</div>
<div v-html="copyHtml" :style="float" />
</div>
</div>
</template>

@ -0,0 +1,117 @@
/**
* @desc AnimationFramehack
*/
export const animationFrame = () => {
window.cancelAnimationFrame = (() => {
return (
window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
window.msCancelAnimationFrame ||
function (id) {
return window.clearTimeout(id);
}
);
})();
window.requestAnimationFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000 / 60);
}
);
})();
};
/**
* @desc
* @return {Boolean}
* @param arr1
* @param arr2
*/
export const arrayEqual = (arr1: Array<any>, arr2: Array<any>) => {
if (arr1 === arr2) return true;
if (arr1.length !== arr2.length) return false;
for (let i = 0; i < arr1.length; ++i) {
if (arr1[i] !== arr2[i]) return false;
}
return true;
};
/**
* @desc
*/
export function copyObj() {
if (!Array.isArray) {
// @ts-expect-error
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
}
let name,
options,
src,
copy,
copyIsArray,
clone,
i = 1,
// eslint-disable-next-line prefer-rest-params
target = arguments[0] || {}, // 使用||运算符排除隐式强制类型转换为false的数据类型
deep = false,
// eslint-disable-next-line prefer-const
len = arguments.length;
if (typeof target === "boolean") {
deep = target;
// eslint-disable-next-line prefer-rest-params
target = arguments[1] || {};
i++;
}
if (typeof target !== "object" && typeof target !== "function") {
target = {};
}
// 如果arguments.length === 1 或typeof arguments[0] === 'boolean',且存在arguments[1]则直接返回target对象
if (i === len) {
return target;
}
for (; i < len; i++) {
//所以如果源对象中数据类型为Undefined或Null那么就会跳过本次循环接着循环下一个源对象
// eslint-disable-next-line prefer-rest-params
if ((options = arguments[i]) != null) {
// 如果遇到源对象的数据类型为Boolean, Number for in循环会被跳过不执行for in循环// src用于判断target对象是否存在name属性
for (name in options) {
// src用于判断target对象是否存在name属性
src = target[name];
// 需要复制的属性当前源对象的name属性
copy = options[name];
// 判断copy是否是数组
copyIsArray = Array.isArray(copy);
// 如果是深复制且copy是一个对象或数组则需要递归直到copy成为一个基本数据类型为止
if (deep && copy && (typeof copy === "object" || copyIsArray)) {
if (copyIsArray) {
copyIsArray = false;
// 如果目标对象存在name属性且是一个数组
// 则使用目标对象的name属性否则重新创建一个数组用于复制
clone = src && Array.isArray(src) ? src : [];
} else {
// 如果目标对象存在name属性且是一个对象则使用目标对象的name属性否则重新创建一个对象用于复制
clone = src && typeof src === "object" ? src : {};
}
// 深复制所以递归调用copyObject函数
// 返回值为target对象即clone对象
// copy是一个源对象
// @ts-expect-error
target[name] = copyObj(deep, clone, copy);
} else if (copy !== undefined) {
// 浅复制直接复制到target对象上
target[name] = copy;
}
}
}
}
return target;
}

@ -0,0 +1,252 @@
<script setup lang="ts">
import { ref, computed, watch, type Ref } from "vue";
import { useAppStoreHook } from "@/store/modules/app";
import {
delay,
useDark,
useECharts,
type EchartOptions
} from "@pureadmin/utils";
import * as echarts from "echarts/core";
const { isDark } = useDark();
const theme: EchartOptions["theme"] = computed(() => {
return isDark.value ? "dark" : "light";
});
const alarmLineChartRef = ref<HTMLDivElement | null>(null);
const { setOptions, resize } = useECharts(
alarmLineChartRef as Ref<HTMLDivElement>,
{
theme
}
);
setOptions(
{
title: {
show: false,
text: "缺陷监测数据",
left: "left",
textStyle: {
fontSize: 14,
color: "#333"
}
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
bottom: "60px",
right: "20px",
left: "60px",
top: "30px"
},
legend: {
// show: true,
bottom: "10px",
textStyle: {
color: "rgba(255, 255, 255, 0.65)", //
fontSize: 14, // 14px
fontWeight: "bold" //
},
data: [
{
name: "间隙告警",
icon: "bar" //
},
{
name: "表面缺陷",
icon: "bar"
},
{
name: "厚度达标",
icon: "bar"
}
]
},
xAxis: [
{
type: "category",
axisLine: {
// 线
show: false // 线
},
axisTick: { alignWithLabel: true }, // XY
axisLabel: {
// textStyle: {
color: "#737A85", //
fontSize: 12 //
// }
},
data: ["10.15", "10.16", "10.17", "10.18", "10.19"]
}
],
yAxis: [
{
type: "value",
// name: "",
axisLabel: {
// textStyle: {
color: "#737A85"
// }
},
nameTextStyle: {
color: "#737A85",
fontSize: 12,
lineHeight: 40
},
splitLine: {
lineStyle: {
type: "dashed",
color: "rgba(255,255,255,0.2)"
}
},
axisLine: {
show: false
},
axisTick: {
show: false
}
}
],
series: [
// {
// name: "",
// type: "bar",
// barWidth: "20%",
// itemStyle: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: "#0F00B3"
// },
// {
// offset: 1,
// color: "#0F00B3"
// }
// ])
// },
// data: [3620, 7500, 1450, 3620, 7500]
// },
{
//线()
name: "间隙告警",
type: "line",
yAxisIndex: 0,
data: [246, 246, 246, 180, 160],
smooth: true,
// showSymbol: false,/
symbolSize: 8,
zlevel: 3,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(255,207,95,0.4)"
},
{
offset: 1,
color: "rgba(255,207,95,0)"
}
])
},
itemStyle: {
//线
color: "#FFCF5F",
opacity: 0.4
},
emphasis: {
focus: "series"
}
},
{
//线()
name: "表面缺陷",
type: "line",
yAxisIndex: 0,
data: [160, 246, 450, 100, 246],
smooth: true,
// showSymbol: false,/
symbolSize: 8,
zlevel: 3,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(92,242,197,0.6)"
},
{
offset: 1,
color: "rgba(92,242,197,0)"
}
])
},
itemStyle: {
//线
color: "#5CF2C5"
},
emphasis: {
focus: "series"
}
},
{
//线()
name: "厚度达标",
type: "line",
yAxisIndex: 0,
data: [100, 200, 400, 150, 306],
smooth: true,
// showSymbol: false,/
symbolSize: 8,
zlevel: 3,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(252,194,106,1)"
},
{
offset: 1,
color: "rgba(252,194,106,0)"
}
])
},
itemStyle: {
//线
color: "#FB9907"
},
emphasis: {
focus: "series"
}
}
],
addTooltip: true
},
{
name: "click",
callback: params => {
console.log("click", params);
}
}
);
watch(
() => useAppStoreHook().getSidebarStatus,
() => {
delay(600).then(() => resize());
}
);
</script>
<template>
<div ref="alarmLineChartRef" style="width: 100%; height: 100%" />
</template>

@ -0,0 +1,172 @@
<script setup lang="ts">
import { ref, computed, watch, type Ref } from "vue";
import { useAppStoreHook } from "@/store/modules/app";
import {
delay,
useDark,
useECharts,
type EchartOptions
} from "@pureadmin/utils";
import * as echarts from "echarts/core";
const { isDark } = useDark();
const theme: EchartOptions["theme"] = computed(() => {
return isDark.value ? "dark" : "light";
});
const defectLineChartRef = ref<HTMLDivElement | null>(null);
const { setOptions, resize } = useECharts(
defectLineChartRef as Ref<HTMLDivElement>,
{
theme
}
);
setOptions(
{
title: {
show: false,
text: "缺陷监测数据",
left: "left",
textStyle: {
fontSize: 14,
color: "#333"
}
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
bottom: "60px",
right: "20px",
left: "60px",
top: "30px"
},
legend: {
show: false,
bottom: "10px",
textStyle: {
color: "rgba(255, 255, 255, 0.65)", //
fontSize: 14, // 14px
fontWeight: "bold" //
},
data: [
{
name: "缺陷总数",
icon: "bar" //
},
{
name: "表面缺陷",
icon: "bar"
},
{
name: "厚度达标",
icon: "bar"
}
]
},
xAxis: [
{
type: "category",
axisLine: {
// 线
show: false // 线
},
axisTick: { alignWithLabel: true }, // XY
axisLabel: {
// textStyle: {
color: "#737A85", //
fontSize: 12 //
// }
},
data: ["1.15", "1.16", "1.17", "1.18", "1.19"]
}
],
yAxis: [
{
type: "value",
// name: "",
axisLabel: {
// textStyle: {
color: "#737A85"
// }
},
nameTextStyle: {
color: "#737A85",
fontSize: 12,
lineHeight: 40
},
splitLine: {
lineStyle: {
type: "dashed",
color: "rgba(255,255,255,0.2)"
}
},
axisLine: {
show: false
},
axisTick: {
show: false
}
}
],
series: [
{
//线()
name: "缺陷总数",
type: "line",
yAxisIndex: 0,
data: [46, 460, 100, 300, 20],
smooth: true,
// showSymbol: false,/
symbolSize: 8,
zlevel: 3,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(71,123,255,0.2)"
},
{
offset: 1,
color: "rgba(71,123,255,0.2)"
}
])
},
itemStyle: {
//线
color: "#477BFF",
opacity: 0.4
},
emphasis: {
focus: "series"
}
}
],
addTooltip: true
},
{
name: "click",
callback: params => {
console.log("click", params);
}
}
);
watch(
() => useAppStoreHook().getSidebarStatus,
() => {
delay(600).then(() => resize());
}
);
</script>
<template>
<div ref="defectLineChartRef" style="width: 100%; height: 100%" />
</template>

@ -2,4 +2,91 @@
width: 430px;
height: 288px;
background: url("@/assets/svg/screenBgCommon.svg") no-repeat;
.warp {
box-sizing: border-box;
padding: 12px;
width: 100%;
height: 100%;
// margin: 0 auto;
overflow: hidden;
color: #ffffff;
ul {
padding: 0;
margin: 0 auto;
list-style: none;
li,
a {
display: flex;
// justify-content: space-between;
justify-content: flex-start;
height: 30px;
font-size: 15px;
line-height: 30px;
}
}
}
}
.mid {
width: 880px;
height: 94px;
display: flex;
justify-content: space-between;
.mid_box {
display: flex;
justify-content: flex-start;
width: 205px;
height: 94px;
background: url("@/assets/svg/screenSmallBgCommon.svg") no-repeat;
.mid_box_icon {
width: 76px;
height: 94px;
background: url("@/assets/svg/dataScreen/abnormal.svg") no-repeat center
center;
}
.mid_box_info {
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 12px;
height: 100%;
.mid_box_info_top {
font-weight: bold;
font-size: 20px;
color: #ffffff;
}
.mid_box_info_bottom {
font-weight: 500;
font-size: 16px;
color: rgba(255, 255, 255, 0.8);
}
}
}
.mid_box:nth-of-type(2) {
.mid_box_icon {
width: 76px;
height: 94px;
background: url("@/assets/svg/dataScreen/device.svg") no-repeat center
center;
}
}
.mid_box:nth-of-type(3) {
.mid_box_icon {
width: 76px;
height: 94px;
background: url("@/assets/svg/dataScreen/workshop.svg") no-repeat center
center;
}
}
.mid_box:nth-of-type(4) {
.mid_box_icon {
width: 76px;
height: 94px;
background: url("@/assets/svg/dataScreen/resource.svg") no-repeat center
center;
}
}
}
.ds_home_wrap {
background: url("@/assets/svg/screenHomeBg.svg") no-repeat center center;
}

@ -6,17 +6,121 @@
* @FilePath: \General-AI-Platform-Web-Client\src\pages\dataScreen\views\home\homeIndex.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { reactive, ref, unref } from "vue";
import AlarmLine from "./components/AlarmLine.vue";
import DefectLine from "./components/DefectLine.vue";
import SeamlessScroll from "@/components/ReSeamlessScroll";
const scroll = ref();
const listData = ref([
{
title: "无缝滚动第一行无缝滚动第一行"
},
{
title: "无缝滚动第二行无缝滚动第二行"
},
{
title: "无缝滚动第三行无缝滚动第三行"
},
{
title: "无缝滚动第四行无缝滚动第四行"
},
{
title: "无缝滚动第五行无缝滚动第五行"
},
{
title: "无缝滚动第六行无缝滚动第六行"
},
{
title: "无缝滚动第七行无缝滚动第七行"
},
{
title: "无缝滚动第八行无缝滚动第八行"
},
{
title: "无缝滚动第九行无缝滚动第九行"
}
]);
const classOption = reactive({
direction: "top"
});
// function changeDirection(val) {
// (unref(scroll) as any).reset();
// unref(classOption).direction = val;
// }
</script>
<template>
<div class="flex justify-between w-full ds_home_wrap">
<div class="left">
<div class="left_box_1">
<div class="box_header" style="height: 50px">分类告警</div>
<div style="height: 238px; width: 100%">
<AlarmLine />
</div>
</div>
<div class="left_box_1">
<div class="box_header" style="height: 50px">总缺陷数</div>
<div style="height: 238px; width: 100%">
<DefectLine />
</div>
</div>
<div class="left_box_1">123</div>
<div class="left_box_1">123</div>
<div class="left_box_1">123</div>
</div>
<div class="mid">
<div class="mid_box">
<div class="mid_box_icon" />
<div class="mid_box_info">
<span class="mid_box_info_top">1102</span>
<span class="mid_box_info_bottom">异常总量</span>
</div>
</div>
<div class="mid_box">
<div class="mid_box_icon" />
<div class="mid_box_info">
<span class="mid_box_info_top">467</span>
<span class="mid_box_info_bottom">设备总量</span>
</div>
</div>
<div class="mid_box">
<div class="mid_box_icon" />
<div class="mid_box_info">
<span class="mid_box_info_top">3048</span>
<span class="mid_box_info_bottom">覆盖车间</span>
</div>
</div>
<div class="mid_box">
<div class="mid_box_icon" />
<div class="mid_box_info">
<span class="mid_box_info_top">893</span>
<span class="mid_box_info_bottom">资源使用</span>
</div>
</div>
</div>
<div class="right">
<div class="left_box_1">123</div>
<div class="left_box_1">123</div>
<div class="left_box_1">123</div>
<div class="left_box_1">
<div class="box_header" style="height: 50px">总缺陷数</div>
<div style="height: 238px; width: 100%">
<SeamlessScroll
ref="scroll"
:data="listData"
:class-option="classOption"
class="warp"
>
<ul class="item">
<li v-for="(item, index) in listData" :key="index">
<span class="type">紧急</span>
<span class="title" v-text="item.title" />
<span class="time">今天10:03:01</span>
</li>
</ul>
</SeamlessScroll>
</div>
</div>
</div>
</div>
</template>

Loading…
Cancel
Save