Commit 6024505a authored by Cai Wei's avatar Cai Wei

feat(*): 添加cypress测试流程

parents effe56e8 ba8db0cc
......@@ -13,6 +13,7 @@
"crypto-js": "^4.2.0",
"echarts": "^5.6.0",
"element-plus": "^2.9.10",
"gsap": "^3.13.0",
"js-cookie": "^3.0.5",
"moment": "^2.30.1",
"nprogress": "^0.2.0",
......@@ -1698,6 +1699,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gsap": {
"version": "3.13.0",
"resolved": "https://registry.npmmirror.com/gsap/-/gsap-3.13.0.tgz",
"integrity": "sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw=="
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
......@@ -3452,6 +3458,11 @@
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
},
"gsap": {
"version": "3.13.0",
"resolved": "https://registry.npmmirror.com/gsap/-/gsap-3.13.0.tgz",
"integrity": "sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw=="
},
"has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
......
......@@ -10,8 +10,8 @@
@toggleClick="toggleSideBar"
:is-active="sidebar"
/>
<h3>DC-TOM管理平台</h3>
<div class="go-tom" @click="goTom">EcoTOM 三流合一</div>
<h3>E-Core / DC-TOM 管理平台</h3>
<div class="go-tom" @click="goTom" v-if="!currentDomain.includes('screen.bmetech.com')">EcoTOM 三流合一</div>
<div class="right-block">
<el-dropdown class="right-menu-item" trigger="click">
<div class="user-info">
......@@ -90,6 +90,9 @@ export default {
const route = useRoute();
const breadcrumbList = ref([]);
const currentDomain = window.location.hostname;
// 获取当前路由的面包屑数据
const getBreadcrumbData = () => {
breadcrumbList.value = [];
......@@ -151,6 +154,7 @@ export default {
sidebar,
toggleSideBar,
goTom,
currentDomain,
};
},
created() {},
......
import * as echarts from "echarts";
// 设置图表主题颜色
const chartColors = {
// 设置图表主题颜色
const chartColors = {
background: '#181d21',
textColor: '#8a9199',
axisLineColor: '#2a2f33',
......@@ -12,10 +12,10 @@ import * as echarts from "echarts";
yellow: '#f5b83d',
red: '#ff4d4d',
purple: '#6366f1'
};
};
// 通用图表配置
const commonConfig = {
// 通用图表配置
const commonConfig = {
backgroundColor: chartColors.background,
textStyle: {
color: chartColors.textColor
......@@ -68,7 +68,7 @@ import * as echarts from "echarts";
color: '#fff'
}
}
};
};
export const getLineOption = (xData = [], seriesData = []) => ({
tooltip: {
......@@ -283,7 +283,7 @@ export const getBagMonitoringChartOption = (xData = [], seriesData = []) => ({
],
});
export const getLineOption2 = (xData = [], seriesData = [], legendDesc = "健康度指数(%)") => ({
export const getLineOption2 = (xData = [], seriesData = [], legendDesc = "健康度指数", unit = '') => ({
tooltip: {
trigger: "axis",
backgroundColor: 'rgba(24, 29, 33, 0.9)',
......@@ -291,6 +291,21 @@ export const getLineOption2 = (xData = [], seriesData = [], legendDesc = "健康
borderWidth: 2,
textStyle: {
color: '#fff'
},
formatter: function (params) {
// 展示保留圆点
const icon = '<span style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #399DFA; margin-right: 5px;"></span>';
return `第${params[0].name}天<br/> ${icon} ${params[0].seriesName}: ${params[0].value} ${unit}`;
}
},
// 添加子标题
title: {
text: legendDesc === '除尘器健康度指数' ? '根据除尘器日维度告警数据计算' : '',
right: "20",
top: "0%",
textStyle: {
color: '#909399',
fontSize: 12,
}
},
grid: {
......@@ -312,6 +327,11 @@ export const getLineOption2 = (xData = [], seriesData = [], legendDesc = "健康
},
xAxis: {
type: "category",
name: "天",
nameTextStyle: {
color: '#909399',
fontSize: 12,
},
axisTick: {
show: false,
},
......@@ -327,6 +347,11 @@ export const getLineOption2 = (xData = [], seriesData = [], legendDesc = "健康
},
yAxis: {
type: "value",
name: unit,
nameTextStyle: {
color: '#909399',
fontSize: 12,
},
axisLabel: {
color: "#909399",
},
......@@ -359,14 +384,73 @@ export const getGaugeOption = (option) => {
radius: "90%",
min: option.min || 0,
max: option.max || 100,
splitNumber: 8,
splitNumber: 5,
axisLine: {
lineStyle: {
width: 30,
width: 20,
color: [
[0.2, "#fd666d"],
[0.8, "#48cd4d"],
[1, "#fd666d"],
[
0,
new echarts.graphic.LinearGradient(
1,
0,
0,
0,
[
{
offset: 1,
color: "#13d2a9", // 0% 处的颜色
},
{
offset: 0,
color: "#13d2a9", // 100% 处的颜色
},
],
false
),
],
[
0.4,
new echarts.graphic.LinearGradient(
1,
0,
0,
0,
[
{
offset: 1,
color: "#13d2a9", // 0% 处的颜色
},
{
offset: 0,
color: "#9ad8c9", // 100% 处的颜色
},
],
false
),
],
[
1,
new echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 1,
color: "#9ad8c9", // 0% 处的颜色
},
{
offset: 0,
color: "#dadb1b", // 100% 处的颜色
},
],
false
),
],
],
},
},
......@@ -376,7 +460,7 @@ export const getGaugeOption = (option) => {
}
},
axisTick: {
distance: -30,
distance: -20,
length: 10,
lineStyle: {
color: "#909399",
......@@ -384,8 +468,8 @@ export const getGaugeOption = (option) => {
},
},
splitLine: {
distance: -30,
length: 38,
distance: -20,
length: 24,
lineStyle: {
color: '#909399',
width: 2
......
<template>
<div class="gsap-number-container">
<div :class="['value', colorClass]" ref="numberElement">{{ isStringMode ? stringValue : displayValue }}</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch, defineProps, defineEmits, onUnmounted, computed } from 'vue';
import gsap from 'gsap';
const props = defineProps({
// 要显示的目标数字或字符串
value: {
type: [Number, String],
required: true,
default: 0
},
// 数字的初始值
startValue: {
type: Number,
default: 0
},
// 动画持续时间(秒)
duration: {
type: Number,
default: 1
},
// 是否启用颜色变化
enableColorChange: {
type: Boolean,
default: false
},
// 数字的小数位数
decimals: {
type: Number,
default: 0
},
// 数字的前缀
prefix: {
type: String,
default: ''
},
// 数字的后缀
suffix: {
type: String,
default: ''
},
// 是否在组件挂载时自动开始动画
autoStart: {
type: Boolean,
default: true
},
// 动画类型
animationType: {
type: String,
default: 'count', // 'count', 'bounce', 'color'
validator: (value) => ['count', 'bounce', 'color'].includes(value)
},
// 颜色阈值(用于颜色变化)
colorThresholds: {
type: Object,
default: () => ({
low: { value: 30, color: '#e74c3c' }, // 红色
medium: { value: 70, color: '#f39c12' }, // 橙色
high: { value: 100, color: '#36f1cd' } // 绿色
})
},
// 动画触发间隔(毫秒),默认为0表示不自动触发
animationInterval: {
type: Number,
default: 0
}
});
const emit = defineEmits(['animation-complete']);
const displayValue = ref(props.startValue);
const stringValue = ref('');
const numberElement = ref(null);
const colorClass = ref('blue'); // 默认颜色类
const intervalTimer = ref(null);
// 判断是否为字符串模式
const isStringMode = computed(() => typeof props.value === 'string');
// 格式化数字显示
const formatNumber = (num) => {
// 判断传入的值有多少位小数
const numStr = String(num);
const decimalParts = numStr.split('.');
const decimalPlaces = decimalParts.length > 1 ? decimalParts[1].length : 0;
// 使用传入值的小数位数,而不是props.decimals
const formattedNum = parseFloat(num).toFixed(decimalPlaces);
return `${props.prefix}${formattedNum}${props.suffix}`;
};
// 根据值确定颜色
const determineColor = (value) => {
const { low, medium, high } = props.colorThresholds;
if (value <= low.value) return 'red';
if (value <= medium.value) return 'orange';
return 'green';
};
// 执行计数动画
const animateCount = () => {
// 如果是字符串模式,直接设置值并执行弹跳动画
if (isStringMode.value) {
stringValue.value = props.value;
animateBounceForString();
return;
}
const obj = { value: props.startValue };
// 保存目标值的小数位数
const targetValueStr = String(props.value);
const decimalParts = targetValueStr.split('.');
const targetDecimalPlaces = decimalParts.length > 1 ? decimalParts[1].length : 0;
gsap.to(obj, {
value: props.value,
duration: props.duration,
ease: "power2.inOut",
onUpdate: function() {
// 动画过程中使用整数递增
const intValue = Math.floor(obj.value);
displayValue.value = `${props.prefix}${intValue}${props.suffix}`;
if (props.enableColorChange) {
colorClass.value = determineColor(obj.value);
}
},
onComplete: () => {
// 动画完成时显示原始值的完整格式(包含小数)
displayValue.value = formatNumber(props.value);
emit('animation-complete');
}
});
};
// 执行弹跳动画
const animateBounce = () => {
// 如果是字符串模式,使用字符串弹跳动画
if (isStringMode.value) {
stringValue.value = props.value;
animateBounceForString();
return;
}
// 首先更新值
displayValue.value = formatNumber(props.value);
// 然后添加弹跳动画
const tl = gsap.timeline();
tl.from(numberElement.value, {
scale: 0.5,
duration: 0.5,
ease: "back.out(1.7)"
});
tl.to(numberElement.value, {
scale: 1.2,
duration: 0.3,
ease: "power2.inOut"
});
tl.to(numberElement.value, {
scale: 1,
duration: 0.3,
ease: "power2.inOut",
onComplete: () => {
emit('animation-complete');
}
});
};
// 字符串的弹跳动画
const animateBounceForString = () => {
const tl = gsap.timeline();
tl.from(numberElement.value, {
scale: 0.5,
duration: 0.5,
ease: "back.out(1.7)"
});
tl.to(numberElement.value, {
scale: 1.1,
duration: 0.3,
ease: "power2.inOut"
});
tl.to(numberElement.value, {
scale: 1,
duration: 0.3,
ease: "power2.inOut",
onComplete: () => {
emit('animation-complete');
}
});
};
// 执行颜色变化动画
const animateColor = () => {
// 如果是字符串模式,使用字符串弹跳动画
if (isStringMode.value) {
stringValue.value = props.value;
animateBounceForString();
return;
}
// 首先执行计数动画
const obj = { value: props.startValue };
// 确定目标颜色
const targetColor = props.enableColorChange
? props.colorThresholds[determineColor(props.value)].color
: '#36f1cd';
gsap.to(obj, {
value: props.value,
duration: props.duration,
ease: "power2.inOut",
onUpdate: function() {
// 动画过程中使用整数递增
const intValue = Math.floor(obj.value);
displayValue.value = `${props.prefix}${intValue}${props.suffix}`;
},
onComplete: () => {
// 动画完成时显示原始值的完整格式(包含小数)
displayValue.value = formatNumber(props.value);
}
});
// 同时执行颜色变化
gsap.to(numberElement.value, {
color: targetColor,
duration: props.duration,
ease: "power2.inOut",
onComplete: () => {
emit('animation-complete');
}
});
};
// 开始动画
const startAnimation = () => {
switch (props.animationType) {
case 'bounce':
animateBounce();
break;
case 'color':
animateColor();
break;
case 'count':
default:
animateCount();
break;
}
};
// 设置定时器
const setupIntervalTimer = () => {
// 清除之前的定时器
if (intervalTimer.value) {
clearInterval(intervalTimer.value);
intervalTimer.value = null;
}
// 如果设置了有效的间隔时间,则创建新的定时器
if (props.animationInterval > 0) {
intervalTimer.value = setInterval(() => {
startAnimation();
}, props.animationInterval);
}
};
// 监听值变化
watch(() => props.value, (newValue) => {
// 如果是字符串,直接设置值
if (typeof newValue === 'string') {
stringValue.value = newValue;
}
startAnimation();
});
// 监听间隔时间变化
watch(() => props.animationInterval, () => {
setupIntervalTimer();
});
// 组件挂载时
onMounted(() => {
// 如果初始值是字符串,直接设置
if (typeof props.value === 'string') {
stringValue.value = props.value;
}
if (props.autoStart) {
startAnimation();
}
// 设置定时器(如果有指定间隔)
setupIntervalTimer();
});
// 组件卸载时清除定时器
onUnmounted(() => {
if (intervalTimer.value) {
clearInterval(intervalTimer.value);
intervalTimer.value = null;
}
});
</script>
<style scoped>
.gsap-number-container {
width: 100%;
}
.value {
transition: color 0.3s ease;
}
.blue {
color: #fff;
}
.green {
color: #fff;
}
.orange {
color: #fff;
}
.red {
color: #fff;
}
</style>
\ No newline at end of file
This diff is collapsed.
......@@ -24,10 +24,10 @@ const iframeRef = ref(null);
const url = computed(() => {
const currentDomain = window.location.hostname;
if (currentDomain.includes('screen.bmetech.com')) {
return `https://screen.bmetech.com/steelmakingScreen/#/robotNew`;
return `http://screen.bmetech.com/steelmakingScreen/#/robotNew`;
}
// Default URL or alternative URL for other domains
return `http://172.16.20.227/admin/ecoTom/#/robotNew`;
return `http://172.16.20.199/admin/ecoTom/#/robotNew`;
});
......
......@@ -1082,7 +1082,7 @@ export default {
)
.then((result) => {
localStorage.setItem("menuList", JSON.stringify(result.data));
this.$router.push('/dashboard');
this.$router.push('/monitor');
})
.catch((e) => {
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment