UPDATE: 处理控制台警告问题

This commit is contained in:
贾同学
2025-10-10 13:23:40 +08:00
parent 8e0b3be438
commit b319a89501
45 changed files with 6390 additions and 6341 deletions

View File

@@ -4,16 +4,17 @@
<div class="not-detail">
<h2>403</h2>
<h4>抱歉您无权访问该页面~🙅🙅</h4>
<el-button type="primary" @click="router.back"> 返回上一页 </el-button>
<el-button type="primary" @click="router.back">返回上一页</el-button>
</div>
</div>
</template>
<script setup lang="ts" name="403">
import { useRouter } from "vue-router";
const router = useRouter();
import { useRouter } from 'vue-router'
const router = useRouter()
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -4,16 +4,17 @@
<div class="not-detail">
<h2>404</h2>
<h4>抱歉您访问的页面不存在~🤷🤷</h4>
<el-button type="primary" @click="router.back"> 返回上一页 </el-button>
<el-button type="primary" @click="router.back">返回上一页</el-button>
</div>
</div>
</template>
<script setup lang="ts" name="404">
import { useRouter } from "vue-router";
const router = useRouter();
import { useRouter } from 'vue-router'
const router = useRouter()
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -4,16 +4,17 @@
<div class="not-detail">
<h2>500</h2>
<h4>抱歉您的网络不见了~🤦🤦</h4>
<el-button type="primary" @click="router.back"> 返回上一页 </el-button>
<el-button type="primary" @click="router.back">返回上一页</el-button>
</div>
</div>
</template>
<script setup lang="ts" name="500">
import { useRouter } from "vue-router";
const router = useRouter();
import { useRouter } from 'vue-router'
const router = useRouter()
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -9,5 +9,5 @@
<script setup lang="ts" name="Loading"></script>
<style scoped lang="scss">
@import "./index.scss";
@use "./index.scss";;
</style>

View File

@@ -1,49 +1,49 @@
<template>
<div class='icon-box' >
<div class="icon-box">
<el-input
ref='inputRef'
v-model='valueIcon'
v-bind='$attrs'
:placeholder='placeholder'
:clearable='clearable'
@clear='clearIcon'
@click='openDialog'
ref="inputRef"
v-model="valueIcon"
v-bind="$attrs"
:placeholder="placeholder"
:clearable="clearable"
@clear="clearIcon"
@click="openDialog"
>
<template #append>
<el-button :icon='customIcons[iconValue]' />
<el-button :icon="customIcons[iconValue]" />
</template>
</el-input>
<el-dialog v-model='dialogVisible' :title='placeholder' top='5%' width='30%' >
<el-input v-model='inputValue' placeholder='搜索图标' size='large' :prefix-icon='Icons.Search' />
<el-scrollbar v-if='Object.keys(iconsList).length'>
<div class='icon-list'>
<div v-for='item in iconsList' :key='item' class='icon-item' @click='selectIcon(item)'>
<component :is='item'></component>
<el-dialog v-model="dialogVisible" :title="placeholder" top="5%" width="30%">
<el-input v-model="inputValue" placeholder="搜索图标" size="large" :prefix-icon="Icons.Search" />
<el-scrollbar v-if="Object.keys(iconsList).length">
<div class="icon-list">
<div v-for="item in iconsList" :key="item" class="icon-item" @click="selectIcon(item)">
<component :is="item"></component>
<span>{{ item.name }}</span>
</div>
</div>
</el-scrollbar>
<el-empty v-else description='未搜索到您要找的图标~' />
<el-empty v-else description="未搜索到您要找的图标~" />
</el-dialog>
</div>
</template>
<script lang='ts' setup name='SelectIcon'>
<script lang="ts" setup name="SelectIcon">
import * as Icons from '@element-plus/icons-vue'
import { computed, ref } from 'vue';
import { computed, ref } from 'vue'
interface SelectIconProps {
iconValue: string| undefined;
title?: string;
clearable?: boolean;
placeholder?: string;
iconValue: string | undefined
title?: string
clearable?: boolean
placeholder?: string
}
const props = withDefaults(defineProps<SelectIconProps>(), {
iconValue: '',
title: '请选择图标',
clearable: true,
placeholder: '请选择图标',
placeholder: '请选择图标'
})
// 重新接收一下,防止打包后 clearable 报错
@@ -55,7 +55,7 @@ const openDialog = () => (dialogVisible.value = true)
// 选择图标(触发更新父组件数据)
const emit = defineEmits<{
'update:iconValue': [value: string];
'update:iconValue': [value: string]
}>()
const selectIcon = (item: any) => {
dialogVisible.value = false
@@ -83,9 +83,8 @@ const iconsList = computed((): { [key: string]: any } => {
}
return result
})
</script>
<style scoped lang='scss'>
@import "./index.scss";
<style scoped lang="scss">
@use './index.scss';
</style>

View File

@@ -1,97 +1,84 @@
<template>
<div class='time-control'>
<el-select
class='select'
v-model='timeUnit'
placeholder='选择时间单位'
@change='handleChange'
>
<div class="time-control">
<el-select class="select" v-model="timeUnit" placeholder="选择时间单位" @change="handleChange">
<!-- 采用 v-for 动态渲染 -->
<el-option
v-for='unit in timeUnits'
:key='unit.value'
:label='unit.label'
:value='unit.value'
></el-option>
<el-option v-for="unit in timeUnits" :key="unit.value" :label="unit.label" :value="unit.value"></el-option>
</el-select>
<!-- 禁用时间选择器 -->
<div class='date-display'>
<div class="date-display">
<el-date-picker
class='date-picker'
v-model='startDate'
type='date'
placeholder='起始时间'
@change='emitDateChange'
:disabled-date='disableStartDate'
class="date-picker"
v-model="startDate"
type="date"
placeholder="起始时间"
@change="emitDateChange"
:disabled-date="disableStartDate"
:readonly="timeUnit != '自定义'"
></el-date-picker>
<el-text>~</el-text>
<el-date-picker
class='date-picker'
v-model='endDate'
type='date'
placeholder='结束时间'
@change='emitDateChange'
:disabled-date='disableEndDate'
class="date-picker"
v-model="endDate"
type="date"
placeholder="结束时间"
@change="emitDateChange"
:disabled-date="disableEndDate"
:readonly="timeUnit !== '自定义'"
></el-date-picker>
</div>
<div class='date-display' v-if="timeUnit !== '自定义'">
<div class="date-display" v-if="timeUnit !== '自定义'">
<el-button
style='width: 10px;'
class='triangle-button'
type='primary'
@click='prevPeriod'
@change='emitDateChange'
style="width: 10px"
class="triangle-button"
type="primary"
@click="prevPeriod"
@change="emitDateChange"
>
<div class='left_triangle'></div>
</el-button>
<el-button class='triangle-button' type='primary' @click='goToCurrent'>
当前
<div class="left_triangle"></div>
</el-button>
<el-button class="triangle-button" type="primary" @click="goToCurrent">当前</el-button>
<el-button
style='width: 10px;'
class='triangle-button'
type='primary'
@click='nextPeriod'
:disabled='isNextDisabled'
style="width: 10px"
class="triangle-button"
type="primary"
@click="nextPeriod"
:disabled="isNextDisabled"
>
<div class='right_triangle'></div>
<div class="right_triangle"></div>
</el-button>
</div>
</div>
</template>
<script setup lang='ts'>
import { ref, onMounted, defineProps, defineEmits } from 'vue'
<script setup lang="ts">
import { onMounted, ref } from 'vue'
// 定义时间单位的类型
interface TimeUnit {
label: string;
value: string;
label: string
value: string
}
// 定义组件的props包含包括和排除的时间单位
const props = defineProps({
include: {
type: Array as () => string[],
default: () => ['日', '周', '月', '季度', '年', '自定义'],
default: () => ['日', '周', '月', '季度', '年', '自定义']
},
exclude: {
type: Array as () => string[],
default: () => [],
default: () => []
},
default: {
type: String,
default: '月',
},
default: '月'
}
})
// 定义事件
const emit = defineEmits<{
(e: 'update-dates', startDate: string, endDate: string): void;
(e: 'update-dates', startDate: string, endDate: string): void
}>()
const timeUnit = ref<string>(props.default) // 默认选择
const startDate = ref<Date>(new Date()) // 起始日期
@@ -100,16 +87,17 @@ const isNextDisabled = ref<boolean>(false) // 控制下一周期按钮的禁用
const today = ref<Date>(new Date()) // 当前日期
// 过滤出可用的时间单位
const timeUnits = ref<TimeUnit[]>(
props.include.filter(unit => !props.exclude.includes(unit)).map(unit => ({
props.include
.filter(unit => !props.exclude.includes(unit))
.map(unit => ({
label: unit,
value: unit,
})),
value: unit
}))
)
// 发出日期变化事件
const emitDateChange = () => {
emit('update-dates', formatDate(startDate.value), formatDate(endDate.value))
}
// 在组件挂载时更新日期范围
@@ -139,7 +127,6 @@ const handleChange = (unit: string) => {
updateNextButtonStatus()
}
const updateDateRange = () => {
// 根据选择的时间单位计算起始和结束日期
if (timeUnit.value === '日') {
startDate.value = today.value
@@ -147,32 +134,29 @@ const updateDateRange = () => {
} else if (timeUnit.value === '周') {
startDate.value = getStartOfWeek(today.value)
endDate.value = getEndOfWeek(today.value)
} else if (timeUnit.value === '月') {
// 获取本月的开始和结束日期
startDate.value = new Date(today.value.getFullYear(), today.value.getMonth(), 1);
endDate.value = new Date(today.value.getFullYear(), today.value.getMonth() + 1, 0);
// // 确保结束日期不超过今天
// if (endDate.value > today.value) {
// endDate.value = new Date(today.value);
// endDate.value.setHours(23, 59, 59, 999); // 设置结束时间为今天的23:59:59.999
// }
} else if (timeUnit.value === '季度') {
const quarter = Math.floor(today.value.getMonth() / 3);
startDate.value = new Date(today.value.getFullYear(), quarter * 3, 1);
endDate.value = new Date(today.value.getFullYear(), quarter * 3 + 3, 0);
startDate.value = new Date(today.value.getFullYear(), today.value.getMonth(), 1)
endDate.value = new Date(today.value.getFullYear(), today.value.getMonth() + 1, 0)
// // 确保结束日期不超过今天
// if (endDate.value > today.value) {
// endDate.value = new Date(today.value);
// endDate.value.setHours(23, 59, 59, 999); // 设置结束时间为今天的23:59:59.999
// }
} else if (timeUnit.value === '季度') {
const quarter = Math.floor(today.value.getMonth() / 3)
startDate.value = new Date(today.value.getFullYear(), quarter * 3, 1)
endDate.value = new Date(today.value.getFullYear(), quarter * 3 + 3, 0)
} else if (timeUnit.value === '年') {
startDate.value = new Date(today.value.getFullYear(), 0, 1);
endDate.value = new Date(today.value.getFullYear(), 11, 31);
// // 确保结束日期不超过今天
// if (endDate.value > today.value) {
// endDate.value = new Date(today.value);
// endDate.value.setHours(23, 59, 59, 999); // 设置结束时间为今天的23:59:59.999
// }
} else if (timeUnit.value === '年') {
startDate.value = new Date(today.value.getFullYear(), 0, 1)
endDate.value = new Date(today.value.getFullYear(), 11, 31)
// // 确保结束日期不超过今天
// if (endDate.value > today.value) {
@@ -180,7 +164,7 @@ const updateDateRange = () => {
// endDate.value = new Date(today.value);
// endDate.value.setHours(23, 59, 59, 999); // 设置结束时间为今天的23:59:59.999
// }
}
}
// 确保开始时间和结束时间不为空
if (!startDate.value) {
startDate.value = new Date()
@@ -205,8 +189,8 @@ const getEndOfWeek = (date: Date) => {
endOfWeek.setDate(endOfWeek.getDate() + diff)
// 获取今天的日期
const today = new Date();
today.setHours(23, 59, 59, 999); // 设置今天的结束时间23:59:59.999
const today = new Date()
today.setHours(23, 59, 59, 999) // 设置今天的结束时间23:59:59.999
// 返回不超过今天的结束时间
//return endOfWeek > today ? today : endOfWeek;
@@ -223,13 +207,8 @@ const prevPeriod = () => {
prevStartDate.setDate(prevStartDate.getDate() - 7)
prevEndDate.setDate(prevEndDate.getDate() - 7)
} else if (timeUnit.value === '月') {
prevStartDate.setMonth(prevStartDate.getMonth() - 1)
prevEndDate.setMonth(prevEndDate.getMonth() - 1)
} else if (timeUnit.value === '季度') {
prevStartDate.setMonth(prevStartDate.getMonth() - 3)
prevEndDate.setMonth(prevEndDate.getMonth() - 3)
@@ -273,7 +252,6 @@ const nextPeriod = () => {
updateNextButtonStatus()
}
const updateNextButtonStatus = () => {
// 更新下一个按钮的禁用状态
const maxDate = new Date() // 假设最新日期为今天
// 将 maxDate 设置为当天的开始时间
@@ -286,7 +264,6 @@ const updateNextButtonStatus = () => {
emitDateChange() // 变化时也发出更新事件
}
// 限制开始日期不能选择超过当前日期
const disableStartDate = (date: Date) => {
return date > today.value
@@ -298,21 +275,18 @@ const disableEndDate = (date: Date) => {
return date > today.value || (start && date <= start)
}
// 格式化日期yyyy-mm-dd
function formatDate(date: Date | null): string {
if (!date) {
return '';
return ''
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
</script>
<style scoped lang='scss'>
@import "./index.scss";
<style scoped lang="scss">
@use './index.scss';
</style>

View File

@@ -5,7 +5,7 @@
</template>
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, defineExpose, watch, nextTick } from 'vue'
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
// import echarts from './echarts'
import * as echarts from 'echarts' // 全引入
// import 'echarts/lib/component/dataZoom'

View File

@@ -1,7 +1,6 @@
<!-- 经典布局 -->
<template>
<el-container class="layout">
<el-header>
<div class="header-lf mask-image">
<div class="logo flx-center">
@@ -38,26 +37,26 @@
</template>
<script setup lang="ts" name="layoutClassic">
import { computed } from "vue";
import { useRoute } from "vue-router";
import { useAuthStore } from "@/stores/modules/auth";
import { useGlobalStore } from "@/stores/modules/global";
import Main from "@/layouts/components/Main/index.vue";
import SubMenu from "@/layouts/components/Menu/SubMenu.vue";
import ToolBarLeft from "@/layouts/components/Header/ToolBarLeft.vue";
import ToolBarRight from "@/layouts/components/Header/ToolBarRight.vue";
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/modules/auth'
import { useGlobalStore } from '@/stores/modules/global'
import Main from '@/layouts/components/Main/index.vue'
import SubMenu from '@/layouts/components/Menu/SubMenu.vue'
import ToolBarLeft from '@/layouts/components/Header/ToolBarLeft.vue'
import ToolBarRight from '@/layouts/components/Header/ToolBarRight.vue'
const title = import.meta.env.VITE_GLOB_APP_TITLE;
const title = import.meta.env.VITE_GLOB_APP_TITLE
const route = useRoute();
const authStore = useAuthStore();
const globalStore = useGlobalStore();
const accordion = computed(() => globalStore.accordion);
const isCollapse = computed(() => globalStore.isCollapse);
const menuList = computed(() => authStore.showMenuListGet);
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string);
const route = useRoute()
const authStore = useAuthStore()
const globalStore = useGlobalStore()
const accordion = computed(() => globalStore.accordion)
const isCollapse = computed(() => globalStore.isCollapse)
const menuList = computed(() => authStore.showMenuListGet)
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string)
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -11,7 +11,9 @@
v-for="item in menuList"
:key="item.path"
class="split-item"
:class="{ 'split-active': splitActive === item.path || `/${splitActive.split('/')[1]}` === item.path }"
:class="{
'split-active': splitActive === item.path || `/${splitActive.split('/')[1]}` === item.path
}"
@click="changeSubMenu(item)"
>
<el-icon>
@@ -24,7 +26,7 @@
</div>
<el-aside :class="{ 'not-aside': !subMenuList.length }" :style="{ width: isCollapse ? '65px' : '210px' }">
<div class="logo flx-center">
<span v-show="subMenuList.length" class="logo-text">{{ isCollapse ? "G" : title }}</span>
<span v-show="subMenuList.length" class="logo-text">{{ isCollapse ? 'G' : title }}</span>
</div>
<el-scrollbar>
<el-menu
@@ -49,55 +51,55 @@
</template>
<script setup lang="ts" name="layoutColumns">
import { ref, computed, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useAuthStore } from "@/stores/modules/auth";
import { useGlobalStore } from "@/stores/modules/global";
import Main from "@/layouts/components/Main/index.vue";
import ToolBarLeft from "@/layouts/components/Header/ToolBarLeft.vue";
import ToolBarRight from "@/layouts/components/Header/ToolBarRight.vue";
import SubMenu from "@/layouts/components/Menu/SubMenu.vue";
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/modules/auth'
import { useGlobalStore } from '@/stores/modules/global'
import Main from '@/layouts/components/Main/index.vue'
import ToolBarLeft from '@/layouts/components/Header/ToolBarLeft.vue'
import ToolBarRight from '@/layouts/components/Header/ToolBarRight.vue'
import SubMenu from '@/layouts/components/Menu/SubMenu.vue'
const title = import.meta.env.VITE_GLOB_APP_TITLE;
const title = import.meta.env.VITE_GLOB_APP_TITLE
const route = useRoute();
const router = useRouter();
const authStore = useAuthStore();
const globalStore = useGlobalStore();
const accordion = computed(() => globalStore.accordion);
const isCollapse = computed(() => globalStore.isCollapse);
const menuList = computed(() => authStore.showMenuListGet);
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string);
const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()
const globalStore = useGlobalStore()
const accordion = computed(() => globalStore.accordion)
const isCollapse = computed(() => globalStore.isCollapse)
const menuList = computed(() => authStore.showMenuListGet)
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string)
const subMenuList = ref<Menu.MenuOptions[]>([]);
const splitActive = ref("");
const subMenuList = ref<Menu.MenuOptions[]>([])
const splitActive = ref('')
watch(
() => [menuList, route],
() => {
// 当前菜单没有数据直接 return
if (!menuList.value.length) return;
splitActive.value = route.path;
if (!menuList.value.length) return
splitActive.value = route.path
const menuItem = menuList.value.filter((item: Menu.MenuOptions) => {
return route.path === item.path || `/${route.path.split("/")[1]}` === item.path;
});
if (menuItem[0].children?.length) return (subMenuList.value = menuItem[0].children);
subMenuList.value = [];
return route.path === item.path || `/${route.path.split('/')[1]}` === item.path
})
if (menuItem[0].children?.length) return (subMenuList.value = menuItem[0].children)
subMenuList.value = []
},
{
deep: true,
immediate: true
}
);
)
// change SubMenu
const changeSubMenu = (item: Menu.MenuOptions) => {
splitActive.value = item.path;
if (item.children?.length) return (subMenuList.value = item.children);
subMenuList.value = [];
router.push(item.path);
};
splitActive.value = item.path
if (item.children?.length) return (subMenuList.value = item.children)
subMenuList.value = []
router.push(item.path)
}
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -4,12 +4,8 @@
<el-header>
<div class="logo flx-center">
<!-- <img class="logo-img" src="@/assets/images/logo.svg" alt="logo" /> -->
<img
class="logo-img"
src="@/assets/images/cn_pms9100_logo.png"
alt="logo"
/>
<span class="logo-text">{{ title }} </span>
<img class="logo-img" src="@/assets/images/cn_pms9100_logo.png" alt="logo" />
<span class="logo-text">{{ title }}</span>
</div>
<el-menu v-if="showMenuFlag" trigger="click" mode="horizontal" :router="false" :default-active="activeMenu">
<!-- 不能直接使用 SubMenu 组件无法触发 el-menu 隐藏省略功能 -->
@@ -45,38 +41,35 @@
<ToolBarRight />
</el-header>
<Main />
</el-container>
</template>
<script setup lang="ts" name="layoutTransverse">
import { computed } from "vue";
import { useAuthStore } from "@/stores/modules/auth";
import { useRoute, useRouter } from "vue-router";
import Main from "@/layouts/components/Main/index.vue";
import ToolBarRight from "@/layouts/components/Header/ToolBarRight.vue";
import SubMenu from "@/layouts/components/Menu/SubMenu.vue";
import { computed } from 'vue'
import { useAuthStore } from '@/stores/modules/auth'
import { useRoute, useRouter } from 'vue-router'
import Main from '@/layouts/components/Main/index.vue'
import ToolBarRight from '@/layouts/components/Header/ToolBarRight.vue'
import SubMenu from '@/layouts/components/Menu/SubMenu.vue'
const title = import.meta.env.VITE_GLOB_APP_TITLE;
const title = import.meta.env.VITE_GLOB_APP_TITLE
const route = useRoute();
const router = useRouter();
const authStore = useAuthStore();
const menuList = computed(() => authStore.showMenuListGet);
const showMenuFlag=computed(()=>authStore.showMenuFlagGet)
const activeMenu = computed(
() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string
);
const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()
const menuList = computed(() => authStore.showMenuListGet)
const showMenuFlag = computed(() => authStore.showMenuFlagGet)
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string)
const handleClickMenu = (subItem: Menu.MenuOptions) => {
if (subItem.meta.isLink) return window.open(subItem.meta.isLink, "_blank");
router.push(subItem.path);
};
if (subItem.meta.isLink) return window.open(subItem.meta.isLink, '_blank')
router.push(subItem.path)
}
</script>
<style scoped lang="scss">
@import "./index.scss";
.logo{
@use './index.scss';
.logo {
margin-right: 0 !important;
}
.logo-text {

View File

@@ -31,26 +31,26 @@
</template>
<script setup lang="ts" name="layoutVertical">
import { computed } from "vue";
import { useRoute } from "vue-router";
import { useAuthStore } from "@/stores/modules/auth";
import { useGlobalStore } from "@/stores/modules/global";
import Main from "@/layouts/components/Main/index.vue";
import ToolBarLeft from "@/layouts/components/Header/ToolBarLeft.vue";
import ToolBarRight from "@/layouts/components/Header/ToolBarRight.vue";
import SubMenu from "@/layouts/components/Menu/SubMenu.vue";
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/modules/auth'
import { useGlobalStore } from '@/stores/modules/global'
import Main from '@/layouts/components/Main/index.vue'
import ToolBarLeft from '@/layouts/components/Header/ToolBarLeft.vue'
import ToolBarRight from '@/layouts/components/Header/ToolBarRight.vue'
import SubMenu from '@/layouts/components/Menu/SubMenu.vue'
const title = import.meta.env.VITE_GLOB_APP_TITLE;
const title = import.meta.env.VITE_GLOB_APP_TITLE
const route = useRoute();
const authStore = useAuthStore();
const globalStore = useGlobalStore();
const accordion = computed(() => globalStore.accordion);
const isCollapse = computed(() => globalStore.isCollapse);
const menuList = computed(() => authStore.showMenuListGet);
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string);
const route = useRoute()
const authStore = useAuthStore()
const globalStore = useGlobalStore()
const accordion = computed(() => globalStore.accordion)
const isCollapse = computed(() => globalStore.isCollapse)
const menuList = computed(() => authStore.showMenuListGet)
const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string)
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -10,62 +10,51 @@
<!-- <el-button dictType="primary"> -->
<div class="change_mode">
{{ title }}
<el-icon class="el-icon--right change_mode_down"
><arrow-down
/></el-icon>
<el-icon class="el-icon--right change_mode_down"><arrow-down /></el-icon>
<el-icon class="el-icon--right change_mode_up"><arrow-up /></el-icon>
</div>
<!-- </el-button> -->
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handelOpen('模拟式')"
>模拟式模块</el-dropdown-item
>
<el-dropdown-item @click="handelOpen('数字式')"
>数字式模块</el-dropdown-item
>
<el-dropdown-item @click="handelOpen('比对式')"
>比对式模块</el-dropdown-item
>
<el-dropdown-item @click="handelOpen('模拟式')">模拟式模块</el-dropdown-item>
<el-dropdown-item @click="handelOpen('数字式')">数字式模块</el-dropdown-item>
<el-dropdown-item @click="handelOpen('比对式')">比对式模块</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<p style="margin: 0;" >
<a href="http://www.shining-electric.com/" target="_blank">
2024 © 南京灿能电力自动化股份有限公司
</a>
<p style="margin: 0">
<a href="http://www.shining-electric.com/" target="_blank">2024 © 南京灿能电力自动化股份有限公司</a>
</p>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, onMounted, watch } from "vue";
import { useAuthStore } from "@/stores/modules/auth";
import { useModeStore } from '@/stores/modules/mode'; // 引入模式 store
import { useRouter } from "vue-router";
const router = useRouter();
const authStore = useAuthStore();
const modeStore = useModeStore();
import { computed } from 'vue'
import { useAuthStore } from '@/stores/modules/auth'
import { useModeStore } from '@/stores/modules/mode' // 引入模式 store
import { useRouter } from 'vue-router'
const router = useRouter()
const authStore = useAuthStore()
const modeStore = useModeStore()
const title = computed(() => {
return modeStore.currentMode=== ''? '模拟式模块' : modeStore.currentMode+'模块';
});
return modeStore.currentMode === '' ? '模拟式模块' : modeStore.currentMode + '模块'
})
const handelOpen = async (item: string) => {
await authStore.setShowMenu();
modeStore.setCurrentMode(item); // 将模式code存入 store
await authStore.setShowMenu()
modeStore.setCurrentMode(item) // 将模式code存入 store
//if (router.currentRoute.value.path === '/home/index') {
// 强制刷新页面
window.location.reload();
window.location.reload()
//} else {
// router.push({ path: '/home/index' });
//}
};
}
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
.footer {
position: relative;
background-color: var(--el-color-primary);

View File

@@ -2,10 +2,10 @@
<Maximize v-show="maximize" />
<Tabs v-if="tabs && showMenuFlag" />
<el-main>
<router-view v-slot="{ Component, route }" style="height:100%;">
<router-view v-slot="{ Component, route }" style="height: 100%">
<!-- {{ keepAliveName}} -->
<!-- <transition name="slide-right" mode="out-in"> -->
<keep-alive :include="tabsMenuList" >
<keep-alive :include="tabsMenuList">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
<!-- </transition> -->
@@ -17,67 +17,65 @@
</template>
<script setup lang="ts">
import { ref, onBeforeUnmount, provide, watch, computed } from "vue";
import { storeToRefs } from "pinia";
import { useDebounceFn } from "@vueuse/core";
import { useGlobalStore } from "@/stores/modules/global";
import { useKeepAliveStore } from "@/stores/modules/keepAlive";
import Maximize from "./components/Maximize.vue";
import Tabs from "@/layouts/components/Tabs/index.vue";
import Footer from "@/layouts/components/Footer/index.vue";
import { useAuthStore } from "@/stores/modules/auth";
import { computed, onBeforeUnmount, provide, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useDebounceFn } from '@vueuse/core'
import { useGlobalStore } from '@/stores/modules/global'
import { useKeepAliveStore } from '@/stores/modules/keepAlive'
import Maximize from './components/Maximize.vue'
import Tabs from '@/layouts/components/Tabs/index.vue'
import Footer from '@/layouts/components/Footer/index.vue'
import { useAuthStore } from '@/stores/modules/auth'
import { useTabsStore } from '@/stores/modules/tabs'
const tabStore = useTabsStore()
const globalStore = useGlobalStore();
const globalStore = useGlobalStore()
const tabsMenuList = computed(() => tabStore.tabsMenuList.map(item => item.name))
const authStore = useAuthStore();
const { maximize, isCollapse, layout, tabs, footer } = storeToRefs(globalStore);
const keepAliveStore = useKeepAliveStore();
const { keepAliveName } = storeToRefs(keepAliveStore);
const authStore = useAuthStore()
const { maximize, isCollapse, layout, tabs, footer } = storeToRefs(globalStore)
const keepAliveStore = useKeepAliveStore()
const { keepAliveName } = storeToRefs(keepAliveStore)
//是否显示导航栏
const showMenuFlag = computed(() => authStore.showMenuFlagGet);
const showMenuFlag = computed(() => authStore.showMenuFlagGet)
// 注入刷新页面方法
const isRouterShow = ref(true);
const refreshCurrentPage = (val: boolean) => (isRouterShow.value = val);
provide("refresh", refreshCurrentPage);
const isRouterShow = ref(true)
const refreshCurrentPage = (val: boolean) => (isRouterShow.value = val)
provide('refresh', refreshCurrentPage)
// 监听当前页面是否最大化,动态添加 class
watch(
() => maximize.value,
() => {
const app = document.getElementById("app") as HTMLElement;
if (maximize.value) app.classList.add("main-maximize");
else app.classList.remove("main-maximize");
const app = document.getElementById('app') as HTMLElement
if (maximize.value) app.classList.add('main-maximize')
else app.classList.remove('main-maximize')
},
{ immediate: true }
);
)
// 监听布局变化,在 body 上添加相对应的 layout class
watch(
() => layout.value,
() => {
const body = document.body as HTMLElement;
body.setAttribute("class", layout.value);
const body = document.body as HTMLElement
body.setAttribute('class', layout.value)
},
{ immediate: true }
);
)
// 监听窗口大小变化,折叠侧边栏
const screenWidth = ref(0);
const screenWidth = ref(0)
const listeningWindow = useDebounceFn(() => {
screenWidth.value = document.body.clientWidth;
if (!isCollapse.value && screenWidth.value < 1200)
globalStore.setGlobalState("isCollapse", true);
if (isCollapse.value && screenWidth.value > 1200)
globalStore.setGlobalState("isCollapse", false);
}, 100);
window.addEventListener("resize", listeningWindow, false);
screenWidth.value = document.body.clientWidth
if (!isCollapse.value && screenWidth.value < 1200) globalStore.setGlobalState('isCollapse', true)
if (isCollapse.value && screenWidth.value > 1200) globalStore.setGlobalState('isCollapse', false)
}, 100)
window.addEventListener('resize', listeningWindow, false)
onBeforeUnmount(() => {
window.removeEventListener("resize", listeningWindow);
});
window.removeEventListener('resize', listeningWindow)
})
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -6,25 +6,32 @@
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="refresh">
<el-icon><Refresh /></el-icon>{{ $t("tabs.refresh") }}
<el-icon><Refresh /></el-icon>
{{ $t('tabs.refresh') }}
</el-dropdown-item>
<el-dropdown-item @click="maximize">
<el-icon><FullScreen /></el-icon>{{ $t("tabs.maximize") }}
<el-icon><FullScreen /></el-icon>
{{ $t('tabs.maximize') }}
</el-dropdown-item>
<el-dropdown-item divided @click="closeCurrentTab">
<el-icon><Remove /></el-icon>{{ $t("tabs.closeCurrent") }}
<el-icon><Remove /></el-icon>
{{ $t('tabs.closeCurrent') }}
</el-dropdown-item>
<el-dropdown-item @click="tabStore.closeTabsOnSide(route.fullPath, 'left')">
<el-icon><DArrowLeft /></el-icon>{{ $t("tabs.closeLeft") }}
<el-icon><DArrowLeft /></el-icon>
{{ $t('tabs.closeLeft') }}
</el-dropdown-item>
<el-dropdown-item @click="tabStore.closeTabsOnSide(route.fullPath, 'right')">
<el-icon><DArrowRight /></el-icon>{{ $t("tabs.closeRight") }}
<el-icon><DArrowRight /></el-icon>
{{ $t('tabs.closeRight') }}
</el-dropdown-item>
<el-dropdown-item divided @click="tabStore.closeMultipleTab(route.fullPath)">
<el-icon><CircleClose /></el-icon>{{ $t("tabs.closeOther") }}
<el-icon><CircleClose /></el-icon>
{{ $t('tabs.closeOther') }}
</el-dropdown-item>
<el-dropdown-item @click="closeAllTab">
<el-icon><FolderDelete /></el-icon>{{ $t("tabs.closeAll") }}
<el-icon><FolderDelete /></el-icon>
{{ $t('tabs.closeAll') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
@@ -32,50 +39,50 @@
</template>
<script setup lang="ts">
import { inject, nextTick } from "vue";
import { HOME_URL } from "@/config";
import { useTabsStore } from "@/stores/modules/tabs";
import { useGlobalStore } from "@/stores/modules/global";
import { useKeepAliveStore } from "@/stores/modules/keepAlive";
import { useRoute, useRouter } from "vue-router";
import { inject, nextTick } from 'vue'
import { HOME_URL } from '@/config'
import { useTabsStore } from '@/stores/modules/tabs'
import { useGlobalStore } from '@/stores/modules/global'
import { useKeepAliveStore } from '@/stores/modules/keepAlive'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute();
const router = useRouter();
const tabStore = useTabsStore();
const globalStore = useGlobalStore();
const keepAliveStore = useKeepAliveStore();
const route = useRoute()
const router = useRouter()
const tabStore = useTabsStore()
const globalStore = useGlobalStore()
const keepAliveStore = useKeepAliveStore()
// refresh current page
const refreshCurrentPage: Function = inject("refresh") as Function;
const refreshCurrentPage: Function = inject('refresh') as Function
const refresh = () => {
setTimeout(() => {
keepAliveStore.removeKeepAliveName(route.name as string);
refreshCurrentPage(false);
keepAliveStore.removeKeepAliveName(route.name as string)
refreshCurrentPage(false)
nextTick(() => {
keepAliveStore.addKeepAliveName(route.name as string);
refreshCurrentPage(true);
});
}, 0);
};
keepAliveStore.addKeepAliveName(route.name as string)
refreshCurrentPage(true)
})
}, 0)
}
// maximize current page
const maximize = () => {
globalStore.setGlobalState("maximize", true);
};
globalStore.setGlobalState('maximize', true)
}
// Close Current
const closeCurrentTab = () => {
if (route.meta.isAffix) return;
tabStore.removeTabs(route.fullPath);
};
if (route.meta.isAffix) return
tabStore.removeTabs(route.fullPath)
}
// Close All
const closeAllTab = () => {
tabStore.closeMultipleTab();
router.push(HOME_URL);
};
tabStore.closeMultipleTab()
router.push(HOME_URL)
}
</script>
<style scoped lang="scss">
@import "../index.scss";
@use '../index.scss';
</style>

View File

@@ -24,12 +24,12 @@
<script setup lang="ts">
import Sortable from 'sortablejs'
import { ref, computed, watch, onMounted } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useGlobalStore } from '@/stores/modules/global'
import { useTabsStore } from '@/stores/modules/tabs'
import { useAuthStore } from '@/stores/modules/auth'
import { TabsPaneContext, TabPaneName } from 'element-plus'
import { TabPaneName, TabsPaneContext } from 'element-plus'
import MoreButton from './components/MoreButton.vue'
const route = useRoute()
@@ -110,12 +110,10 @@ const tabClick = (tabItem: TabsPaneContext) => {
// Remove Tab
const tabRemove = (fullPath: TabPaneName) => {
tabStore.removeTabs(fullPath as string, fullPath == route.fullPath || '/machine/testScriptAdd' == route.fullPath)
}
</script>
<style scoped lang="scss">
@import './index.scss';
@use './index.scss';
</style>

View File

@@ -7,7 +7,10 @@
</el-divider>
<div class="layout-box">
<el-tooltip effect="dark" content="纵向" placement="top" :show-after="200">
<div :class="['layout-item layout-vertical', { 'is-active': layout == 'vertical' }]" @click="setLayout('vertical')">
<div
:class="['layout-item layout-vertical', { 'is-active': layout == 'vertical' }]"
@click="setLayout('vertical')"
>
<div class="layout-dark"></div>
<div class="layout-container">
<div class="layout-light"></div>
@@ -19,7 +22,10 @@
</div>
</el-tooltip>
<el-tooltip effect="dark" content="经典" placement="top" :show-after="200">
<div :class="['layout-item layout-classic', { 'is-active': layout == 'classic' }]" @click="setLayout('classic')">
<div
:class="['layout-item layout-classic', { 'is-active': layout == 'classic' }]"
@click="setLayout('classic')"
>
<div class="layout-dark"></div>
<div class="layout-container">
<div class="layout-light"></div>
@@ -31,7 +37,10 @@
</div>
</el-tooltip>
<el-tooltip effect="dark" content="横向" placement="top" :show-after="200">
<div :class="['layout-item layout-transverse', { 'is-active': layout == 'transverse' }]" @click="setLayout('transverse')">
<div
:class="['layout-item layout-transverse', { 'is-active': layout == 'transverse' }]"
@click="setLayout('transverse')"
>
<div class="layout-dark"></div>
<div class="layout-content"></div>
<el-icon v-if="layout == 'transverse'">
@@ -40,7 +49,10 @@
</div>
</el-tooltip>
<el-tooltip effect="dark" content="分栏" placement="top" :show-after="200">
<div :class="['layout-item layout-columns', { 'is-active': layout == 'columns' }]" @click="setLayout('columns')">
<div
:class="['layout-item layout-columns', { 'is-active': layout == 'columns' }]"
@click="setLayout('columns')"
>
<div class="layout-dark"></div>
<div class="layout-light"></div>
<div class="layout-content"></div>
@@ -128,18 +140,18 @@
</template>
<script setup lang="ts">
import { ref } from "vue";
import { storeToRefs } from "pinia";
import { useTheme } from "@/hooks/useTheme";
import { useGlobalStore } from "@/stores/modules/global";
import { LayoutType } from "@/stores/interface";
import { DEFAULT_PRIMARY } from "@/config";
import mittBus from "@/utils/mittBus";
import SwitchDark from "@/components/SwitchDark/index.vue";
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useTheme } from '@/hooks/useTheme'
import { useGlobalStore } from '@/stores/modules/global'
import { LayoutType } from '@/stores/interface'
import { DEFAULT_PRIMARY } from '@/config'
import mittBus from '@/utils/mittBus'
import SwitchDark from '@/components/SwitchDark/index.vue'
const { changePrimary, changeGreyOrWeak, setAsideTheme, setHeaderTheme } = useTheme();
const { changePrimary, changeGreyOrWeak, setAsideTheme, setHeaderTheme } = useTheme()
const globalStore = useGlobalStore();
const globalStore = useGlobalStore()
const {
layout,
primary,
@@ -154,33 +166,33 @@ const {
tabs,
tabsIcon,
footer
} = storeToRefs(globalStore);
} = storeToRefs(globalStore)
// 预定义主题颜色
const colorList = [
DEFAULT_PRIMARY,
"#daa96e",
"#0c819f",
"#409eff",
"#27ae60",
"#ff5c93",
"#e74c3c",
"#fd726d",
"#f39c12",
"#9b59b6"
];
'#daa96e',
'#0c819f',
'#409eff',
'#27ae60',
'#ff5c93',
'#e74c3c',
'#fd726d',
'#f39c12',
'#9b59b6'
]
// 设置布局方式
const setLayout = (val: LayoutType) => {
globalStore.setGlobalState("layout", val);
setAsideTheme();
};
globalStore.setGlobalState('layout', val)
setAsideTheme()
}
// 打开主题设置
const drawerVisible = ref(false);
mittBus.on("openThemeDrawer", () => (drawerVisible.value = true));
const drawerVisible = ref(false)
mittBus.on('openThemeDrawer', () => (drawerVisible.value = true))
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -1,6 +1,6 @@
<template>
<el-dialog :title="dialogTitle" :model-value="dialogVisible" @close="close" v-bind="dialogMiddle" align-center>
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' class="form-two">
<el-form :model="formContent" ref="dialogFormRef" :rules="rules" class="form-two">
<el-form-item label="上级菜单" prop="pid" :label-width="100">
<el-tree-select
v-model="displayPid"
@@ -14,29 +14,29 @@
/>
</el-form-item>
<el-form-item label="名称" prop="name" :label-width="100">
<el-input v-model="formContent.name" maxlength="32" show-word-limit/>
<el-input v-model="formContent.name" maxlength="32" show-word-limit />
</el-form-item>
<el-form-item label="编码" prop="code" :label-width="100">
<el-input v-model="formContent.code" maxlength="32" show-word-limit/>
<el-input v-model="formContent.code" maxlength="32" show-word-limit />
</el-form-item>
<el-form-item v-if="!formContent.type" label="图标" prop="icon" :label-width="100">
<IconSelect
v-model="formContent.icon"
:iconValue="formContent.icon"
@update:icon-value="iconValue => formContent.icon = iconValue"
@update:icon-value="iconValue => (formContent.icon = iconValue)"
placeholder="选择一个图标"
/>
</el-form-item>
<el-form-item v-if="!formContent.type" label="路由地址" prop="path" :label-width="100" >
<el-input v-model="formContent.path" maxlength="32" show-word-limit/>
<el-form-item v-if="!formContent.type" label="路由地址" prop="path" :label-width="100">
<el-input v-model="formContent.path" maxlength="32" show-word-limit />
</el-form-item>
<el-form-item v-if="!formContent.type" label="组件地址" prop="component" :label-width="100">
<el-input v-model="formContent.component" maxlength="32" show-word-limit/>
<el-input v-model="formContent.component" maxlength="32" show-word-limit />
</el-form-item>
<el-form-item label="排序" prop="sort" :label-width="100">
<el-input-number v-model="formContent.sort" :min='1' :max='999' />
<el-input-number v-model="formContent.sort" :min="1" :max="999" />
</el-form-item>
<el-form-item label='类型' prop='type' :label-width="100">
<el-form-item label="类型" prop="type" :label-width="100">
<el-select v-model="formContent.type" clearable placeholder="请选择资源类型">
<el-option label="菜单" :value="0"></el-option>
<el-option label="按钮" :value="1"></el-option>
@@ -45,7 +45,7 @@
</el-select>
</el-form-item>
<el-form-item label="描述" prop="remark" :label-width="100">
<el-input v-model="formContent.remark" :rows="2" type="textarea"/>
<el-input v-model="formContent.remark" :rows="2" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
@@ -55,155 +55,156 @@
</div>
</template>
</el-dialog>
</template>
</template>
<script lang="ts" setup name="ResourceDialog">
import { defineProps, defineEmits,watch,ref, type Ref, computed } from 'vue';
import { dialogMiddle } from '@/utils/elementBind'
import { ElMessage, type FormInstance, type FormItemRule } from 'element-plus'
import { useDictStore } from '@/stores/modules/dict'
import type { Function } from "@/api/user/interface/function"
import {addFunction,updateFunction,getFunctionListNoButton} from '@/api/user/function/index'
import IconSelect from '@/components/SelectIcon/index.vue'
const value = ref()
// 树形节点配置
const defaultProps = {
<script lang="ts" setup name="ResourceDialog">
import { computed, type Ref, ref, watch } from 'vue'
import { dialogMiddle } from '@/utils/elementBind'
import { ElMessage, type FormInstance, type FormItemRule } from 'element-plus'
import { useDictStore } from '@/stores/modules/dict'
import type { Function } from '@/api/user/interface/function'
import { addFunction, getFunctionListNoButton, updateFunction } from '@/api/user/function/index'
import IconSelect from '@/components/SelectIcon/index.vue'
const value = ref()
// 树形节点配置
const defaultProps = {
children: 'children',
label: 'name',
value: 'id'
};
const functionList = ref<Function.ResFunction[]>([])
const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
function useMetaInfo() {
}
const functionList = ref<Function.ResFunction[]>([])
const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = ref<Function.ResFunction>({
id: '',//资源表Id
pid:'',//节点0为根节点
pids:'',//节点上层所有节点
name: '',//名称
code:'',//资源标识
path:'',//路径
component:'',
icon:undefined as string | undefined, // 图标
sort:100,//排序
type:0,//资源类型0-菜单、1-按钮、2-公共资源、3-服务间调用资源
remark: '',//权限资源描述
state:1,//权限资源状态
id: '', //资源表Id
pid: '', //节点0为根节点
pids: '', //节点上层所有节点
name: '', //名称
code: '', //资源标识
path: '', //路径
component: '',
icon: undefined as string | undefined, // 图标
sort: 100, //排序
type: 0, //资源类型0-菜单、1-按钮、2-公共资源、3-服务间调用资源
remark: '', //权限资源描述
state: 1 //权限资源状态
})
return { dialogVisible, titleType, formContent }
}
}
const { dialogVisible, titleType, formContent } = useMetaInfo()
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
formContent.value = {
id: '',//资源表Id
pid:'',//节点0为根节点
pids:'',//节点上层所有节点
name: '',//名称
code:'',//资源标识
path:'',//路径
component:'',
icon:undefined,//图标
sort:100,//排序
type:0,//资源类型0-菜单、1-按钮、2-公共资源、3-服务间调用资源
remark:'',//权限资源描述
state:1,//权限资源状态
}
id: '', //资源表Id
pid: '', //节点0为根节点
pids: '', //节点上层所有节点
name: '', //名称
code: '', //资源标识
path: '', //路径
component: '',
icon: undefined, //图标
sort: 100, //排序
type: 0, //资源类型0-菜单、1-按钮、2-公共资源、3-服务间调用资源
remark: '', //权限资源描述
state: 1 //权限资源状态
}
}
let dialogTitle = computed(() => {
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增菜单' : '编辑菜单'
})
})
// 定义规则
const formRuleRef = ref<FormInstance>()
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
name: [{ required: true, trigger: 'blur', message: '菜单名称必填!' }],
code: [{ required: true, trigger: 'blur', message: '编码必填!' }]
})
// 定义规则
const formRuleRef = ref<FormInstance>()
const rules : Ref<Record<string, Array<FormItemRule>>> = ref({
name :[{required:true,trigger:'blur',message:'菜单名称必填!'}],
code :[{required:true,trigger:'blur',message:'编码必填!'}]
})
watch(() => formContent.value.type, (newVal) => {
watch(
() => formContent.value.type,
newVal => {
if (newVal === 1) {
// 选择按钮时,路由地址和组件地址无需校验
rules.value.path = [];
rules.value.component = [];
rules.value.path = []
rules.value.component = []
} else {
// 其他情况下,路由地址和组件地址需要校验
rules.value.path = [{ required: true, trigger: 'blur', message: '路由地址必填!' }];
rules.value.component = [{ required: true, trigger: 'blur', message: '组件地址必填!' }];
rules.value.path = [{ required: true, trigger: 'blur', message: '路由地址必填!' }]
rules.value.component = [{ required: true, trigger: 'blur', message: '组件地址必填!' }]
}
});
}
)
// 关闭弹窗
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
}
}
// 计算属性,用于控制显示的 pid
const displayPid = computed({
get: () => {
return formContent.value.pid === '0' ? '' : formContent.value.pid;
return formContent.value.pid === '0' ? '' : formContent.value.pid
},
set: (value) => {
formContent.value.pid = value;
set: value => {
formContent.value.pid = value
}
});
})
// 保存数据
const save = () => {
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (formContent.value.pid === undefined || formContent.value.pid === null || formContent.value.pid === '') {
formContent.value.pid = '0';
formContent.value.pid = '0'
}
if (formContent.value.pids === undefined || formContent.value.pids === null || formContent.value.pids === '') {
formContent.value.pids = '0';
if (
formContent.value.pids === undefined ||
formContent.value.pids === null ||
formContent.value.pids === ''
) {
formContent.value.pids = '0'
}
if (valid) {
if (formContent.value.id) {
await updateFunction(formContent.value);
await updateFunction(formContent.value)
} else {
await addFunction(formContent.value);
await addFunction(formContent.value)
}
ElMessage.success({ message: `${dialogTitle.value}成功!` })
close()
// 刷新表格
await props.refreshTable!()
}
})
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: Function.ResFunction) => {
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: Function.ResFunction) => {
// 重置表单
dialogFormRef.value?.resetFields()
const response = await getFunctionListNoButton()
functionList.value = response.data as unknown as Function.ResFunction[]
titleType.value = sign
dialogVisible.value = true
rules.value.path = [{ required: true, trigger: 'blur', message: '路由地址必填!' }];
rules.value.component = [{ required: true, trigger: 'blur', message: '组件地址必填!' }];
rules.value.path = [{ required: true, trigger: 'blur', message: '路由地址必填!' }]
rules.value.component = [{ required: true, trigger: 'blur', message: '组件地址必填!' }]
if (formContent.value.pid ==='0') {
formContent.value.pid = '';
if (formContent.value.pid === '0') {
formContent.value.pid = ''
}
if (data.id) {
@@ -211,12 +212,11 @@ const displayPid = computed({
} else {
resetFormContent()
}
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined
}>()
</script>

View File

@@ -1,18 +1,20 @@
<template>
<div class="table-container table-main">
<el-table :data="tableData"
:header-cell-style="{ textAlign: 'center' } "
<el-table
:data="tableData"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
max-height="400px"
:span-method="objectSpanMethod">
<el-table-column prop="monitorNum" label="监测点序号" width="80"/>
<el-table-column prop="desc" label="描述" width="90"/>
<el-table-column label="电压通道" >
:span-method="objectSpanMethod"
>
<el-table-column prop="monitorNum" label="监测点序号" width="80" />
<el-table-column prop="desc" label="描述" width="90" />
<el-table-column label="电压通道">
<el-table-column prop="Ua" label="A相">
<el-table-column prop="aVuData" label="被检值(V)" width="100px">
<template #default="scope">
<el-icon v-if="scope.row.aVuData === '—'&& scope.row.loading" class="loading-box">
<el-icon v-if="scope.row.aVuData === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
@@ -29,8 +31,12 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
误差值{{ scope.row.aV + 'V'}}
误差范围
{{
(-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'
}}
<br />
误差值{{ scope.row.aV + 'V' }}
</template>
<el-tag type="danger" class="tooltip-content">
{{ scope.row.aVuXi }}
@@ -43,15 +49,19 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
误差值{{ scope.row.aV + 'V'}}
误差范围
{{
(-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'
}}
<br />
误差值{{ scope.row.aV + 'V' }}
</template>
<el-tag type="success" class="tooltip-content">{{ scope.row.aVuXi }}</el-tag>
</el-tooltip>
<!-- <el-tag type="danger" v-if="scope.row.aVuXi === '不合格'">
{{ scope.row.aVuXi }}
</el-tag> -->
<el-icon v-else-if="scope.row.aVuXi === '—'&& scope.row.loading" class="loading-box">
<el-icon v-else-if="scope.row.aVuXi === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<!-- <span v-else>
@@ -63,7 +73,7 @@
<el-table-column prop="Ub" label="B相">
<el-table-column prop="bVuData" label="被检值(V)" width="100px">
<template #default="scope">
<el-icon v-if="scope.row.bVuData === '—'&& scope.row.loading" class="loading-box">
<el-icon v-if="scope.row.bVuData === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
@@ -80,8 +90,12 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
误差值{{ scope.row.bV + 'V'}}
误差范围
{{
(-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'
}}
<br />
误差值{{ scope.row.bV + 'V' }}
</template>
<el-tag type="danger" class="tooltip-content">
{{ scope.row.bVuXi }}
@@ -94,12 +108,16 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
误差值{{ scope.row.bV + 'V'}}
误差范围
{{
(-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'
}}
<br />
误差值{{ scope.row.bV + 'V' }}
</template>
<el-tag type="success" class="tooltip-content">{{ scope.row.bVuXi }}</el-tag>
</el-tooltip>
<el-icon v-else-if="scope.row.bVuXi === '—'&& scope.row.loading" class="loading-box">
<el-icon v-else-if="scope.row.bVuXi === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
</template>
@@ -108,7 +126,7 @@
<el-table-column prop="Uc" label="C相">
<el-table-column prop="cVuData" label="被检值(V)" width="100px">
<template #default="scope">
<el-icon v-if="scope.row.cVuData === '—'&& scope.row.loading" class="loading-box">
<el-icon v-if="scope.row.cVuData === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
@@ -125,8 +143,12 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4)+ 'V'}}<br/>
误差值{{ scope.row.cV + 'V'}}
误差范围
{{
(-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'
}}
<br />
误差值{{ scope.row.cV + 'V' }}
</template>
<el-tag type="danger" class="tooltip-content">
{{ scope.row.cVuXi }}
@@ -139,23 +161,27 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ (-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'}}<br/>
误差值{{ scope.row.cV + 'V'}}
误差范围
{{
(-0.001 * props.curV).toFixed(4) + 'V~' + (0.001 * props.curV).toFixed(4) + 'V'
}}
<br />
误差值{{ scope.row.cV + 'V' }}
</template>
<el-tag type="success" class="tooltip-content">{{ scope.row.cVuXi }}</el-tag>
</el-tooltip>
<el-icon v-else-if="scope.row.cVuXi === '—'&& scope.row.loading" class="loading-box">
<el-icon v-else-if="scope.row.cVuXi === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
</template>
</el-table-column>
</el-table-column>
</el-table-column>
<el-table-column label="电流通道" >
<el-table-column label="电流通道">
<el-table-column prop="Ia" label="A相">
<el-table-column prop="aIeData" label="被检值(A)" width="100px">
<template #default="scope">
<el-icon v-if="scope.row.aIeData === '—'&& scope.row.loading" class="loading-box">
<el-icon v-if="scope.row.aIeData === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
@@ -172,8 +198,9 @@
placement="bottom-start"
>
<template #content>
误差范围 {{-0.5 + "%~" +0.5 + "%" }}<br/>
误差值{{ scope.row.aI + '%'}}
误差范围 {{ -0.5 + '%~' + 0.5 + '%' }}
<br />
误差值{{ scope.row.aI + '%' }}
</template>
<el-tag type="danger" class="tooltip-content">
{{ scope.row.aIeXi }}
@@ -186,12 +213,13 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ -0.5 + "%~" +0.5 + "%" }}<br/>
误差值{{ scope.row.aI + '%'}}
误差范围 {{ -0.5 + '%~' + 0.5 + '%' }}
<br />
误差值{{ scope.row.aI + '%' }}
</template>
<el-tag type="success" class="tooltip-content">{{ scope.row.aIeXi }}</el-tag>
</el-tooltip>
<el-icon v-else-if="scope.row.aIeXi === '—'&& scope.row.loading" class="loading-box">
<el-icon v-else-if="scope.row.aIeXi === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
</template>
@@ -200,7 +228,7 @@
<el-table-column prop="Ib" label="B相">
<el-table-column prop="bIeData" label="被检值(A)" width="100px">
<template #default="scope">
<el-icon v-if="scope.row.bIeData === '—'&& scope.row.loading" class="loading-box">
<el-icon v-if="scope.row.bIeData === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
@@ -217,8 +245,9 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ -0.5 + "%~" +0.5 + "%" }}<br/>
误差值{{ scope.row.bI + '%'}}
误差范围 {{ -0.5 + '%~' + 0.5 + '%' }}
<br />
误差值{{ scope.row.bI + '%' }}
</template>
<el-tag type="danger" class="tooltip-content">
{{ scope.row.bIeXi }}
@@ -231,12 +260,13 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ -0.5 + "%~" +0.5 + "%" }}<br/>
误差值{{ scope.row.bI + '%'}}
误差范围 {{ -0.5 + '%~' + 0.5 + '%' }}
<br />
误差值{{ scope.row.bI + '%' }}
</template>
<el-tag type="success" class="tooltip-content">{{ scope.row.bIeXi }}</el-tag>
</el-tooltip>
<el-icon v-else-if="scope.row.bIeXi === '—'&& scope.row.loading" class="loading-box">
<el-icon v-else-if="scope.row.bIeXi === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
</template>
@@ -245,7 +275,7 @@
<el-table-column prop="Ic" label="C相">
<el-table-column prop="cIeData" label="被检值(A)" width="100px">
<template #default="scope">
<el-icon v-if="scope.row.cIeData === '—'&& scope.row.loading" class="loading-box">
<el-icon v-if="scope.row.cIeData === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
@@ -262,8 +292,9 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ -0.5 + "%~" +0.5 + "%" }}<br/>
误差值{{ scope.row.cI + '%'}}
误差范围 {{ -0.5 + '%~' + 0.5 + '%' }}
<br />
误差值{{ scope.row.cI + '%' }}
</template>
<el-tag type="danger" class="tooltip-content">
{{ scope.row.cIeXi }}
@@ -276,12 +307,13 @@
placement="bottom-start"
>
<template #content>
误差范围 {{ -0.5 + "%~" +0.5 + "%" }}<br/>
误差值{{ scope.row.cI + '%'}}
误差范围 {{ -0.5 + '%~' + 0.5 + '%' }}
<br />
误差值{{ scope.row.cI + '%' }}
</template>
<el-tag type="success" class="tooltip-content">{{ scope.row.cIeXi }}</el-tag>
</el-tooltip>
<el-icon v-else-if="scope.row.cIeXi === '—'&& scope.row.loading" class="loading-box">
<el-icon v-else-if="scope.row.cIeXi === '—' && scope.row.loading" class="loading-box">
<el-icon-loading />
</el-icon>
</template>
@@ -292,57 +324,63 @@
</div>
</template>
<script lang="ts" setup name="ErrorSystemDialog">
import { defineProps, type PropType } from 'vue';
import { ElIcon, ElLoading, ElTag } from 'element-plus';
import type { ChannelsTest } from '@/api/home/interface/channelsTest';
import { number } from 'echarts';
<script lang="ts" setup name="ErrorSystemDialog">
import { ElIcon, ElTag } from 'element-plus'
import type { ChannelsTest } from '@/api/home/interface/channelsTest'
interface Props {
tableData: ChannelsTest.CoefficientVO[];
big_V_loading: boolean;
curV: number;
tableData: ChannelsTest.CoefficientVO[]
big_V_loading: boolean
curV: number
}
const props = withDefaults(defineProps<Props>(), {
tableData: () => [],
big_V_loading: false,
curV: 0,
});
curV: 0
})
function objectSpanMethod({ row, column, rowIndex, columnIndex }: { row: any, column: any, rowIndex: number, columnIndex: number }) {
function objectSpanMethod({
row,
column,
rowIndex,
columnIndex
}: {
row: any
column: any
rowIndex: number
columnIndex: number
}) {
if (columnIndex === 0) {
if (rowIndex % 4 === 0) {
return {
rowspan: 4,
colspan: 1,
};
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0,
};
colspan: 0
}
}
}
if (columnIndex === 1) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1,
};
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0,
};
colspan: 0
}
}
}
}
</script>
</script>
<style scoped>
<style scoped>
.form-grid {
display: flex;
flex-direction: row; /* 横向排列 */
@@ -364,7 +402,8 @@ const props = withDefaults(defineProps<Props>(), {
margin-bottom: 20px; /* 添加底部边距 */
}
.el-table th, .el-table td {
.el-table th,
.el-table td {
text-align: center; /* 所有单元格文字居中 */
}
@@ -391,7 +430,6 @@ const props = withDefaults(defineProps<Props>(), {
cursor: pointer;
}
@keyframes rotate {
from {
transform: rotate(0deg);

View File

@@ -39,8 +39,13 @@
<el-option v-for="item in chnList" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="检测次数" >
<el-select v-model="formContent.num" clearable @change="handleNumChange" :disabled="sourceKey == 1">
<el-form-item label="检测次数">
<el-select
v-model="formContent.num"
clearable
@change="handleNumChange"
:disabled="sourceKey == 1"
>
<el-option
v-for="item in chnMapList[formContent.chnNum]"
:key="item"
@@ -67,9 +72,7 @@
node-key="id"
ref="treeRef"
@node-click="handleNodeClick"
>
</el-tree>
></el-tree>
</div>
<div class="content-right">
<div class="content-right-title">
@@ -93,17 +96,19 @@
<span v-else style="color: var(--el-color-primary)">{{ rowList.scriptName }}</span>
</div>
<el-form-item
style="margin: 0 auto; margin-bottom: 0px !important; width: 200px; position: absolute; left: 50%; transform: translateX(-50%);"
style="
margin: 0 auto;
margin-bottom: 0px !important;
width: 200px;
position: absolute;
left: 50%;
transform: translateX(-50%);
"
label="录波次数"
v-if="isWaveData"
>
<el-select v-model="waveNumber" @change="handleWaveNumberChange">
<el-option
v-for="i in waveNumCount"
:key="i"
:label="i"
:value="i"
/>
<el-option v-for="i in waveNumCount" :key="i" :label="i" :value="i" />
</el-select>
</el-form-item>
<el-form-item
@@ -128,7 +133,6 @@
:currentCheckItem="currentCheckItem"
:currentScriptTypeName="currentScriptTypeName"
v-if="activeTab === 'resultTab'"
/>
</el-tab-pane>
<el-tab-pane label="原始数据" name="rawDataTab">
@@ -148,7 +152,7 @@
</template>
<script setup lang="ts">
import { dialogBig } from '@/utils/elementBind'
import { reactive, ref, watch, computed, nextTick } from 'vue'
import { computed, reactive, ref } from 'vue'
import CompareDataCheckResultTable from './compareDataCheckResultTable.vue'
import CompareDataCheckRawDataTable from './compareDataCheckRawDataTable.vue'
import { CheckData } from '@/api/check/interface'
@@ -157,16 +161,20 @@ import { Histogram, Postcard } from '@element-plus/icons-vue'
import { getPqErrSysList } from '@/api/plan/plan'
import { useModeStore } from '@/stores/modules/mode' // 引入模式 store
import { useDictStore } from '@/stores/modules/dict'
import { getContrastFormContent, getContrastResult, getScriptList,reCalculate ,changeErrorSystem,deleteTempTable} from '@/api/check/test'
import {
changeErrorSystem,
deleteTempTable,
getContrastFormContent,
getContrastResult,
getScriptList,
reCalculate
} from '@/api/check/test'
import { ElMessage } from 'element-plus'
import {ResultEnum} from "@/enums/httpEnum";
import { ResultEnum } from '@/enums/httpEnum'
const { appendToBody } = withDefaults(
defineProps<{
const { appendToBody = true } = defineProps<{
appendToBody: boolean
}>(),
{ appendToBody: true }
)
}>()
const checkStore = useCheckStore()
const modeStore = useModeStore()
@@ -192,7 +200,7 @@ const selectedScriptName = ref('')
const pattern = ref('')
// 添加以下内容
const isWaveData = ref(false)
const scriptNameOptions = ref<{label: string, value: string}[]>([])
const scriptNameOptions = ref<{ label: string; value: string }[]>([])
// 表单数据
const formContent = reactive<CheckData.DataCheck>({
@@ -230,10 +238,9 @@ const currentRawTableData = computed(() => {
return Array.isArray(data) ? data : []
})
const open = async (row: any, chnNum: string, deviceId: string | null, source: number) => {
isWaveData.value = false
pattern.value = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''//获取数据字典中对应的id
pattern.value = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? '' //获取数据字典中对应的id
rowList.value = {}
formContent.deviceId = deviceId || ''
formContent.chnNum = chnNum
@@ -261,13 +268,13 @@ const open = async (row: any, chnNum: string, deviceId: string | null, source: n
Object.assign(pqErrorList, resPqErrorList)
initGetResult()
}
const initGetResult = async () => {
// 判断是否为录波数据
const isLuoboData = (sourceKey.value == 1 && rowList.value.scriptName == "录波数据") ||
(sourceKey.value == 2 && scriptData.value[0]?.code == "wave_data");
const isLuoboData =
(sourceKey.value == 1 && rowList.value.scriptName == '录波数据') ||
(sourceKey.value == 2 && scriptData.value[0]?.code == 'wave_data')
if (isLuoboData) {
isWaveData.value = true
// 设置录波数据相关的选项
@@ -292,7 +299,6 @@ const initGetResult = async () => {
}
}
// 查询大项树
const initScriptData = async () => {
let response: any = await getScriptList({
@@ -313,11 +319,10 @@ const initScriptData = async () => {
scriptData.value = temp
// 查找code为"录波"的项
let luoboItem = response.data.find((item: any) => item.code === 'wave_data');
let luoboItem = response.data.find((item: any) => item.code === 'wave_data')
// 如果找到了"录波"项则使用其subitems否则使用空数组
let temp2 = [];
let temp2 = []
if (luoboItem && luoboItem.subItems) {
// 格式化脚本数据
temp2 = luoboItem.subItems.map((item: any) => {
return {
@@ -328,10 +333,8 @@ const initScriptData = async () => {
}
selectScript.value = temp2
// 只有在sourceKey == 2时才设置rowList和tree相关属性
if (sourceKey.value === 2 && temp.length > 0) {
rowList.value.scriptName = temp[0].scriptName
rowList.value.scriptType = temp[0].id
selectedScriptName.value = temp[0].scriptName
@@ -339,8 +342,6 @@ const initScriptData = async () => {
treeRef.value?.setCurrentKey(temp[0].id)
}, 0)
}
}
// 获取基本信息
@@ -349,9 +350,9 @@ const getBasicInformation = async (scriptType: any) => {
rawTableData.value = []
const scriptType2 = ref('')
if(sourceKey.value == 1){
if (sourceKey.value == 1) {
scriptType2.value = scriptType
}else{
} else {
scriptType2.value = ''
}
@@ -389,8 +390,6 @@ const getBasicInformation = async (scriptType: any) => {
formContent.num = numList[numList.length - 1]
}
waveNumCount.value = res.data.waveNumTotal
} catch (error) {
console.error('获取基本信息失败:', error)
}
@@ -431,7 +430,7 @@ const handleCommonChange = async () => {
const tempNode = {
scriptName: rowList.value.scriptName,
id: rowList.value.scriptType,
code: rowList.value.scriptName === "录波数据" ? 'wave_data' : ''
code: rowList.value.scriptName === '录波数据' ? 'wave_data' : ''
}
handleNodeClick(tempNode)
}
@@ -464,7 +463,6 @@ const handleNodeClick = (data: any) => {
// 每次选中录波数据时都重置为第一个选项并触发getResults
if (scriptNameOptions.value.length > 0) {
selectedScriptName.value = scriptNameOptions.value[0].value
// 更新rowList并触发getResults
rowList.value.scriptName = selectedScriptName.value
@@ -476,7 +474,6 @@ const handleNodeClick = (data: any) => {
}
}
} else {
isWaveData.value = false
getResults(data.code)
}
@@ -496,7 +493,7 @@ const getResults = async (code: any) => {
chnNum: formContent.chnNum,
num: formContent.num == '' ? null : formContent.num,
waveNum: isWaveDataRequest ? waveNumber.value : null,
isWave: isWaveDataRequest ,
isWave: isWaveDataRequest,
patternId: pattern.value
}).then((res: any) => {
let list: string[] = []
@@ -507,8 +504,6 @@ const getResults = async (code: any) => {
tesList.value = list
checkResultData.value = res.data.resultMap
rawTableData.value = res.data.rawDataMap
})
}
@@ -547,8 +542,8 @@ const handleErrorSysChange = async () => {
errorSysId: formContent.errorSysId,
deviceId: formContent.deviceId,
code: checkStore.plan.code + '',
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? '',
}).then((res) => {
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
}).then(res => {
if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('切换误差体系成功')
handleChnNumChange(formContent.chnNum)
@@ -556,8 +551,6 @@ const handleErrorSysChange = async () => {
})
}
const handleReCalculate = async () => {
reCalculate({
planId: checkStore.plan.id,
@@ -565,14 +558,12 @@ const handleReCalculate = async () => {
errorSysId: formContent.errorSysId,
deviceId: formContent.deviceId,
code: checkStore.plan.code + '',
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? '',
}).then((res) => {
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
}).then(res => {
if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('重新计算成功!')
handleChnNumChange(formContent.chnNum)
}
})
}

View File

@@ -81,8 +81,8 @@
<RealTimeData ref="realTimeDataRef" />
</template>
<script lang="tsx" setup name="preTest">
import {ElMessage, ElMessageBox, StepProps} from "element-plus";
import {computed, defineExpose, PropType, ref, toRef, watch} from 'vue';
import { ElMessage, ElMessageBox, StepProps } from 'element-plus'
import { computed, PropType, ref, toRef, watch } from 'vue'
import RealTimeData from './realTimeDataAlign.vue'
const realTimeDataRef = ref()

View File

@@ -134,30 +134,17 @@
</template>
<script lang="tsx" setup name="testPopup">
import { nextTick, PropType, reactive, ref, watch } from 'vue'
import { nextTick, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
Coin,
Edit,
Key,
Switch,
Refresh,
Right,
SuccessFilled,
UploadFilled,
VideoPause,
VideoPlay
} from '@element-plus/icons-vue'
import { Coin, Edit, Key, Refresh, Right, SuccessFilled, Switch, VideoPause, VideoPlay } from '@element-plus/icons-vue'
import ComparePreTest from './comparePreTest.vue'
import ChannelPairing from './channelPairing.vue'
import { Device } from '@/api/device/interface/device'
import CompareTest from './compareTest.vue'
import socketClient from '@/utils/webSocketClient'
import { useCheckStore } from '@/stores/modules/check'
import { pauseTest, resumeTest, startPreTest, contrastTest } from '@/api/socket/socket'
import { contrastTest, pauseTest, resumeTest, startPreTest } from '@/api/socket/socket'
import { useUserStore } from '@/stores/modules/user'
import { JwtUtil } from '@/utils/jwtUtil'
import { StandardDevice } from '@/api/device/interface/standardDevice'
const userStore = useUserStore()
const checkStore = useCheckStore()
@@ -242,8 +229,8 @@ const standardDevIds = ref<[]>()
const pairs = ref<any>()
const testAgain = ref(false) //重新检测按钮是否显示
const checkNumber = ref(0) //检测次数
const deviceMonitor2= ref<Map<string, any[]>>();
const onlyWave = ref(false);//计划数据源是否只有录波
const deviceMonitor2 = ref<Map<string, any[]>>()
const onlyWave = ref(false) //计划数据源是否只有录波
const open = async (
title: string,
mapping: any,
@@ -252,14 +239,14 @@ const open = async (
devIdsArray: [],
standardDevIdsArray: [],
pair: any,
deviceMonitor:Map<string, any[]>,
deviceMonitor: Map<string, any[]>,
planIsOnlyWave: boolean
) => {
if (checkStore.selectTestItems.preTest && !checkStore.selectTestItems.test) {
testAgain.value = true
}
deviceMonitor2.value = deviceMonitor;
onlyWave.value = planIsOnlyWave;
deviceMonitor2.value = deviceMonitor
onlyWave.value = planIsOnlyWave
checkStore.setNodesConnectable(true)
dialogTitle.value = title
channelMapping.value = mapping
@@ -588,7 +575,6 @@ const nextStep = () => {
}
const handleStepClick = (step: number) => {
if (step > stepsActive.value) {
return
} else {
@@ -636,7 +622,7 @@ defineExpose({ open })
<style scoped lang="scss">
.test-head-steps {
::v-deep .el-step {
:deep(.el-step) {
.el-step__head.is-success {
color: #91cc75;
}

View File

@@ -1,21 +1,26 @@
<template>
<div class="table-main">
<el-table v-if="tableData.length > 0" :data="tableData" height="357px" :header-cell-style="{ textAlign: 'center' } "
:cell-style="{ textAlign: 'center' }">
<el-table
v-if="tableData.length > 0"
:data="tableData"
height="357px"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
>
<!-- <el-table-column prop="chnNum" label="通道号" width="80">-->
<!-- <template #default="{row}">-->
<!-- {{ '通道' + row.chnNum }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="A相" v-if="phaseA === 1">
<el-table-column prop="stdA" :label="'标准值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="dataA" :label="'被检值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="stdA" :label="'标准值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="dataA" :label="'被检值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="isDataA" label="检测结果">
<template #default="scope">
<el-tooltip effect="dark" placement="bottom">
<template #content>
误差范围{{ scope.row.maxErrorA }} <br/>
误差范围{{ scope.row.maxErrorA }}
<br />
误差值{{ scope.row.errorA }} {{ scope.row.errorA !== '/' ? innerUnitA : '' }}
</template>
<el-tag type="success" v-if="scope.row.isDataA === 1">符合</el-tag>
@@ -27,13 +32,14 @@
</el-table-column>
</el-table-column>
<el-table-column label="B相" v-if="phaseB === 1">
<el-table-column prop="stdB" :label="'标准值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="dataB" :label="'被检值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="stdB" :label="'标准值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="dataB" :label="'被检值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="isDataB" label="检测结果">
<template #default="scope">
<el-tooltip effect="dark" placement="bottom">
<template #content>
误差范围{{ scope.row.maxErrorB }}<br/>
误差范围{{ scope.row.maxErrorB }}
<br />
误差值{{ scope.row.errorB }} {{ scope.row.errorB !== '/' ? innerUnitB : '' }}
</template>
<el-tag type="success" v-if="scope.row.isDataB === 1">符合</el-tag>
@@ -45,13 +51,14 @@
</el-table-column>
</el-table-column>
<el-table-column label="C相" v-if="phaseC === 1">
<el-table-column prop="stdC" :label="'标准值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="dataC" :label="'被检值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="stdC" :label="'标准值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="dataC" :label="'被检值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="isDataC" label="检测结果">
<template #default="scope">
<el-tooltip effect="dark" placement="bottom">
<template #content>
误差范围 {{ scope.row.maxErrorC }}<br/>
误差范围 {{ scope.row.maxErrorC }}
<br />
误差值{{ scope.row.errorC }} {{ scope.row.errorC !== '/' ? innerUnitC : '' }}
</template>
<el-tag type="success" v-if="scope.row.isDataC === 1">符合</el-tag>
@@ -64,13 +71,14 @@
</el-table-column>
<el-table-column :label="tableHeader" v-if="phaseT === 1">
<el-table-column prop="stdT" :label="'标准值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="dataT" :label="'被检值'+(outerUnit==''?'':''+outerUnit+'')"/>
<el-table-column prop="stdT" :label="'标准值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="dataT" :label="'被检值' + (outerUnit == '' ? '' : '' + outerUnit + '')" />
<el-table-column prop="isDataT" label="检测结果">
<template #default="scope">
<el-tooltip effect="dark" placement="bottom">
<template #content>
误差范围 {{ scope.row.maxErrorT }}<br/>
误差范围 {{ scope.row.maxErrorT }}
<br />
误差值{{ scope.row.errorT }} {{ scope.row.errorT !== '/' ? innerUnitT : '' }}
</template>
<el-tag type="success" v-if="scope.row.isDataT === 1">符合</el-tag>
@@ -83,54 +91,52 @@
</el-table-column>
</el-table>
</div>
</template>
<script lang="tsx" setup>
import {computed, defineProps} from 'vue';
import {CheckData} from "@/api/check/interface";
import { computed } from 'vue'
import { CheckData } from '@/api/check/interface'
const {tableData, currentScriptTypeName} = defineProps<{
tableData: CheckData.CheckResult[],
const { tableData, currentScriptTypeName } = defineProps<{
tableData: CheckData.CheckResult[]
currentScriptTypeName: string
}>();
}>()
const outerUnit = computed(() => {
return tableData.length > 0 ? tableData[0].unit : '';
return tableData.length > 0 ? tableData[0].unit : ''
})
const innerUnitA = computed(() => {
return tableData.length > 0 ? tableData[0].unitA : '';
return tableData.length > 0 ? tableData[0].unitA : ''
})
const innerUnitB = computed(() => {
return tableData.length > 0 ? tableData[0].unitB : '';
return tableData.length > 0 ? tableData[0].unitB : ''
})
const innerUnitC = computed(() => {
return tableData.length > 0 ? tableData[0].unitC : '';
return tableData.length > 0 ? tableData[0].unitC : ''
})
const innerUnitT = computed(() => {
return tableData.length > 0 ? tableData[0].unitT : '';
return tableData.length > 0 ? tableData[0].unitT : ''
})
const phaseA = computed(() => {
return tableData.length <= 0 || tableData[0].dataA == null || tableData[0].dataA == "/" ? 0 : 1
return tableData.length <= 0 || tableData[0].dataA == null || tableData[0].dataA == '/' ? 0 : 1
})
const phaseB = computed(() => {
return tableData.length <= 0 || tableData[0].dataB == null || tableData[0].dataB == "/" ? 0 : 1
return tableData.length <= 0 || tableData[0].dataB == null || tableData[0].dataB == '/' ? 0 : 1
})
const phaseC = computed(() => {
return tableData.length <= 0 || tableData[0].dataC == null || tableData[0].dataC == "/" ? 0 : 1
return tableData.length <= 0 || tableData[0].dataC == null || tableData[0].dataC == '/' ? 0 : 1
})
const phaseT = computed(() => {
return tableData.length <= 0 || tableData[0].dataT == null || tableData[0].dataT == "/" ? 0 : 1
return tableData.length <= 0 || tableData[0].dataT == null || tableData[0].dataT == '/' ? 0 : 1
})
const tableHeader = computed(() => {
if (phaseT.value === 1) {
let index = currentScriptTypeName.indexOf('=');
return currentScriptTypeName.substring(0, index);
let index = currentScriptTypeName.indexOf('=')
return currentScriptTypeName.substring(0, index)
}
return currentScriptTypeName
})
@@ -143,11 +149,9 @@ const tableHeader = computed(() => {
// }
// return result;
// })
</script>
<style scoped>
.form-grid {
display: flex;
flex-direction: row; /* 横向排列 */
@@ -173,8 +177,8 @@ const tableHeader = computed(() => {
margin-bottom: 20px; /* 添加底部边距 */
}
.el-table th, .el-table td {
.el-table th,
.el-table td {
text-align: center; /* 所有单元格文字居中 */
}
</style>

View File

@@ -1,38 +1,56 @@
<template>
<el-dialog :append-to-body="appendToBody" class="dialog" title="数据查询" :model-value='visible' @close="close"
v-bind="dialogBig" :draggable="false" width="1400px">
<el-dialog
:append-to-body="appendToBody"
class="dialog"
title="数据查询"
:model-value="visible"
@close="close"
v-bind="dialogBig"
:draggable="false"
width="1400px"
>
<div class="data-check-dialog">
<div class="data-check-head">
<el-form :model='formContent' label-width="auto" class="form-three ">
<el-form :model="formContent" label-width="auto" class="form-three">
<el-form-item label="检测脚本">
<el-input v-model='formContent.scriptName' :disabled="true"/>
<el-input v-model="formContent.scriptName" :disabled="true" />
</el-form-item>
<el-form-item label="误差体系">
<el-select :disabled="checkStore.showDetailType===2 || checkStore.showDetailType===0" v-model="formContent.errorSysId" placeholder="请选择误差体系"
<el-select
:disabled="checkStore.showDetailType === 2 || checkStore.showDetailType === 0"
v-model="formContent.errorSysId"
placeholder="请选择误差体系"
autocomplete="off"
@change="handleErrorSysChange">
@change="handleErrorSysChange"
>
<el-option
v-for="(option) in pqErrorList"
v-for="option in pqErrorList"
:key="option.id"
:label="option.name"
:value="option.id"/>
:value="option.id"
/>
</el-select>
</el-form-item>
<el-form-item label="数据原则">
<el-input v-model='formContent.dataRule' :disabled="true"/>
<el-input v-model="formContent.dataRule" :disabled="true" />
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model='formContent.deviceName' :disabled="true"/>
<el-input v-model="formContent.deviceName" :disabled="true" />
</el-form-item>
<el-form-item label='通道号'>
<el-form-item label="通道号">
<el-select v-model="formContent.chnNum">
<el-option v-for="item in chnList" :key="item.value" :label="item.label" :value="item.value"/>
<el-option
v-for="item in chnList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="checkStore.showDetailType===1">
<el-form-item v-if="checkStore.showDetailType === 1">
<el-button type="primary" :icon="Postcard" @click="handleGenerateReport">报告生成</el-button>
</el-form-item>
<el-form-item v-if="checkStore.showDetailType===0">
<el-form-item v-if="checkStore.showDetailType === 0">
<el-button type="primary" :icon="Histogram" @click="handleReCalculate">重新计算</el-button>
</el-form-item>
</el-form>
@@ -40,24 +58,31 @@
<div class="data-check-body">
<div class="content-left-tree">
<div style="width: 99%;">
<el-input
placeholder='请输入测试项名称'
clearable
v-model='searchValue'
></el-input>
<div style="width: 99%">
<el-input placeholder="请输入测试项名称" clearable v-model="searchValue"></el-input>
</div>
<div class="content-tree">
<el-tree :filter-node-method='filterNode' :highlight-current="true" :default-expanded-keys="defaultExpandedKeys"
<el-tree
:filter-node-method="filterNode"
:highlight-current="true"
:default-expanded-keys="defaultExpandedKeys"
node-key="index"
:data="treeDataAll"
:props="defaultProps"
@node-click="handleNodeClick" class="custom-tree" ref="treeRef">
@node-click="handleNodeClick"
class="custom-tree"
ref="treeRef"
>
<template #default="{ node, data }">
<el-tooltip effect="dark" :content="data.scriptTypeName" placement="right">
<span class="custom-tree-node" :style="data.fly===2? 'color: #F56C6C;':data.fly===4? 'color: #e6a23c;':''">{{
data.scriptTypeName
}}</span>
<span
class="custom-tree-node"
:style="
data.fly === 2 ? 'color: #F56C6C;' : data.fly === 4 ? 'color: #e6a23c;' : ''
"
>
{{ data.scriptTypeName }}
</span>
</el-tooltip>
</template>
</el-tree>
@@ -66,22 +91,27 @@
<div class="content-right">
<div class="content-right-title">
<div style="width: 840px;">
<span class="content-right-title-text">当前检测项目
<div style="width: 840px">
<span class="content-right-title-text">
当前检测项目
<el-popover trigger="hover" :content="currentDesc" width="500px" placement="right">
<template #reference>
<el-button type="text" style="font-size: 14px;">
<el-button type="text" style="font-size: 14px">
{{ currentScriptTypeName }}
</el-button>
</template>
</el-popover>
</span>
</div>
<el-form-item style="margin-left: 0px;margin-bottom:0px !important;width: 280px;" v-if="checkListLevel.length" label='测试项'>
<el-form-item
style="margin-left: 0px; margin-bottom: 0px !important; width: 280px"
v-if="checkListLevel.length"
label="测试项"
>
<el-cascader
v-model="currentCheckItem"
:options="checkListLevel"
:props="{expandTrigger: 'click' as const}"
:props="{ expandTrigger: 'click' as const }"
placement="bottom-end"
/>
</el-form-item>
@@ -89,10 +119,17 @@
<div class="content-right-Tabs">
<el-tabs type="border-card" v-model="activeTab">
<el-tab-pane label="检测结果" name="resultTab">
<DataCheckResultTable :tableData="checkResultData" :currentScriptTypeName="currentScriptTypeName"/>
<DataCheckResultTable
:tableData="checkResultData"
:currentScriptTypeName="currentScriptTypeName"
/>
</el-tab-pane>
<el-tab-pane label="原始数据" name="rawDataTab">
<DataCheckRawDataTable :tableData="rawTableData" :currentScriptTypeName="currentScriptTypeName" @exportRawDataHandler="exportRawDataHandler"/>
<DataCheckRawDataTable
:tableData="rawTableData"
:currentScriptTypeName="currentScriptTypeName"
@exportRawDataHandler="exportRawDataHandler"
/>
</el-tab-pane>
</el-tabs>
</div>
@@ -100,48 +137,54 @@
</div>
</div>
</el-dialog>
</template>
<script setup lang='ts'>
import {dialogBig} from '@/utils/elementBind'
import {reactive, ref, watch} from 'vue'
<script setup lang="ts">
import { dialogBig } from '@/utils/elementBind'
import { reactive, ref, watch } from 'vue'
import DataCheckResultTable from './dataCheckResultTable.vue'
import DataCheckRawDataTable from './dataCheckRawDataTable.vue'
import {CheckData} from "@/api/check/interface";
import {useCheckStore} from "@/stores/modules/check";
import {changeErrorSystem, deleteTempTable, exportRawData, getFormData, getTableData, getTreeData, reCalculate} from "@/api/check/test";
import {generateDevReport, getPqErrSysList} from '@/api/plan/plan'
import {useDownload} from "@/hooks/useDownload";
import {Histogram, Postcard} from "@element-plus/icons-vue";
import {ResultEnum} from "@/enums/httpEnum";
import {ElMessage} from "element-plus";
import {useDictStore} from "@/stores/modules/dict";
import {useModeStore} from "@/stores/modules/mode";
import { CheckData } from '@/api/check/interface'
import { useCheckStore } from '@/stores/modules/check'
import {
changeErrorSystem,
deleteTempTable,
exportRawData,
getFormData,
getTableData,
getTreeData,
reCalculate
} from '@/api/check/test'
import { generateDevReport, getPqErrSysList } from '@/api/plan/plan'
import { useDownload } from '@/hooks/useDownload'
import { Histogram, Postcard } from '@element-plus/icons-vue'
import { ResultEnum } from '@/enums/httpEnum'
import { ElMessage } from 'element-plus'
import { useDictStore } from '@/stores/modules/dict'
import { useModeStore } from '@/stores/modules/mode'
const dictStore = useDictStore()
const modeStore = useModeStore()
const {appendToBody} = withDefaults(defineProps<{
const { appendToBody = true } = defineProps<{
appendToBody: boolean
}>(), {appendToBody: true})
}>()
const defaultProps = {
label: "scriptTypeName",
children: "children",
};
label: 'scriptTypeName',
children: 'children'
}
const checkStore = useCheckStore()
const visible = ref(false)
const treeRef = ref()
const searchValue = ref<string>('')
const pqErrorList = reactive<{ id: string; name: string; }[]>([])
watch(searchValue, (val) => {
const pqErrorList = reactive<{ id: string; name: string }[]>([])
watch(searchValue, val => {
treeRef.value!.filter(val)
})
// 格式化数字
const fixed = 4;
const fixed = 4
// 表单数据
const formContent = reactive<CheckData.DataCheck>({
@@ -149,7 +192,7 @@ const formContent = reactive<CheckData.DataCheck>({
errorSysId: '',
dataRule: '',
deviceName: '',
chnNum: '',
chnNum: ''
})
// 原始误差体系id
let originErrorSysId: string = ''
@@ -161,7 +204,7 @@ const currentCheckItem = ref<any>()
// 检测项列表
// const checkList = reactive<{ value: string, label: string }[]>([])
// 带有层级的检测项列表
const checkListLevel = reactive<{ value: string, label: string, children: { value: string, label: string }[] }[]>([])
const checkListLevel = reactive<{ value: string; label: string; children: { value: string; label: string }[] }[]>([])
let deviceId: string = ''
let originScriptType: string | null = null
@@ -170,7 +213,6 @@ let scriptType: string | null = null
// 通道下拉列表
let chnList: any[] = []
// 左侧树数据
const treeDataAll = reactive<CheckData.TreeItem[]>([])
@@ -180,12 +222,15 @@ const checkIndex = ref<string>('')
// 当前检测项目名称
const currentScriptTypeName = ref('')
// 当前检测项目描述
const currentDesc = ref('');
const currentDesc = ref('')
// 右侧Tab选中项
const activeTab = ref<string>('resultTab')
//存放相应的表格数据
const resTableData = reactive<{ resultData: Map<string, any>, rawData: Map<string, any> }>({resultData: new Map(), rawData: new Map()})
const resTableData = reactive<{ resultData: Map<string, any>; rawData: Map<string, any> }>({
resultData: new Map(),
rawData: new Map()
})
// 检测结果表格数据
const checkResultData = reactive<CheckData.CheckResult[]>([])
@@ -194,7 +239,6 @@ const popoverWidth: ComputedRef<string> = computed(() => {
return `${1140 - (currentScriptTypeName.value.length + 7 + 3) * 14 - (checkListLevel.length ? 280 : 0)}px`
})
// 原始数据表格数据
const rawTableData = reactive<CheckData.RawDataItem[]>([])
@@ -214,28 +258,28 @@ const handleNodeClick = async (data: any) => {
currentDesc.value = data.sourceDesc
scriptType = data.scriptType ?? scriptType
console.log("点击左侧树节点触发事件handleNodeClick", checkIndex.value)
console.log('点击左侧树节点触发事件handleNodeClick', checkIndex.value)
if (checkIndex.value !== '') {
await updateTableData()
activeTab.value = 'resultTab'
}
}
};
}
const handleErrorSysChange = async () => {
console.log("切换误差体系", formContent.errorSysId);
console.log('切换误差体系', formContent.errorSysId)
changeErrorSystem({
planId: checkStore.plan.id,
scriptId: checkStore.plan.scriptId,
errorSysId: formContent.errorSysId,
deviceId: deviceId,
code: checkStore.plan.code + '',
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? '',
}).then((res) => {
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
}).then(res => {
if (res.code === ResultEnum.SUCCESS) {
ElMessage.success('切换误差体系成功')
if (originErrorSysId != formContent.errorSysId) {
planCode = checkStore.plan.code + "_temp"
planCode = checkStore.plan.code + '_temp'
} else {
planCode = checkStore.plan.code + ''
}
@@ -248,18 +292,20 @@ const handleErrorSysChange = async () => {
})
}
watch(() => formContent.chnNum, async (newVal, oldVal) => {
watch(
() => formContent.chnNum,
async (newVal, oldVal) => {
// console.log("通道号", newVal);
if (newVal != '') {
handleChnNumChange()
}
})
}
)
const handleChnNumChange = async () => {
console.log("通道号", formContent.chnNum);
console.log('通道号', formContent.chnNum)
// 发起请求,查询该测试项的检测结果
const {data: resTreeDataTemp}: { data: CheckData.TreeItem[] } = await getTreeData({
const { data: resTreeDataTemp }: { data: CheckData.TreeItem[] } = await getTreeData({
scriptId: checkStore.plan.scriptId,
devId: deviceId,
devNum: formContent.chnNum + '',
@@ -278,14 +324,13 @@ const handleChnNumChange = async () => {
activeTab.value = 'resultTab'
}
watch(currentCheckItem, (newVal, oldVal) => {
if (newVal !== '') {
let key = newVal[0]
if (newVal.length == 2) {
key += "_" + newVal[1]
key += '_' + newVal[1]
}
console.log("当前检测项", key);
console.log('当前检测项', key)
doCurrentCheckItemUpdate(key)
} else {
activeTab.value = 'resultTab'
@@ -302,7 +347,7 @@ const defaultOperate = () => {
checkIndex.value = node.index
defaultExpandedKeys = [node.index]
treeRef.value?.setCurrentKey(node.index);
treeRef.value?.setCurrentKey(node.index)
scriptType = node.scriptType ?? scriptType
} else {
currentScriptTypeName.value = ''
@@ -313,9 +358,8 @@ const defaultOperate = () => {
}
const updateTableData = async () => {
console.log("左侧树被选中的叶子节点checkIndex", checkIndex.value);
console.log('左侧树被选中的叶子节点checkIndex', checkIndex.value)
if (checkIndex.value !== '') {
checkListLevel.length = 0
checkResultData.length = 0
rawTableData.length = 0
@@ -323,13 +367,13 @@ const updateTableData = async () => {
// console.log("更新表格数据");
// 发起请求,查询该测试项的检测结果
const {data} = await getTableData({
const { data } = await getTableData({
scriptType,
scriptId: checkStore.plan.scriptId,
devId: deviceId,
devNum: formContent.chnNum + '',
code: planCode,
index: parseInt(checkIndex.value),
index: parseInt(checkIndex.value)
})
let keys1 = Object.keys(data.resultData)
@@ -340,15 +384,29 @@ const updateTableData = async () => {
if ((key.includes('谐波') || key.includes('简谐波')) && key !== '谐波有功功率') {
for (let item of data.resultData[key]) {
let num = formatHarmNum(item.harmNum + '')
label = item.isData === 1 ? `${num}` : item.isData === 4 ? `${num}/` : item.isData === 5 ? `${num}-` : `${num}(不符合)`
children.push({label: label, value: num})
resultData.set(key + "_" + num, item)
label =
item.isData === 1
? `${num}`
: item.isData === 4
? `${num}/`
: item.isData === 5
? `${num}-`
: `${num}(不符合)`
children.push({ label: label, value: num })
resultData.set(key + '_' + num, item)
}
checkListLevel.push({label: key, value: key, children: children})
checkListLevel.push({ label: key, value: key, children: children })
} else {
label = data.resultData[key][0].isData === 1 ? `${key}` : data.resultData[key][0].isData === 4 ? `${key}/` : data.resultData[key][0].isData === 5 ? `${key}-` : `${key}(不符合)`
label =
data.resultData[key][0].isData === 1
? `${key}`
: data.resultData[key][0].isData === 4
? `${key}/`
: data.resultData[key][0].isData === 5
? `${key}-`
: `${key}(不符合)`
resultData.set(key, data.resultData[key][0])
checkListLevel.push({label: label, value: key, children: []})
checkListLevel.push({ label: label, value: key, children: [] })
let temp = checkListLevel.find(item => item.label.includes('电压幅值'))
if (temp) {
checkListLevel.splice(checkListLevel.indexOf(temp), 1)
@@ -357,16 +415,15 @@ const updateTableData = async () => {
}
}
let keys2 = Object.keys(data.rawData)
let rawData = new Map()
for (let key of keys2) {
if ((key.includes('谐波') || key.includes('简谐波')) && key !== '谐波有功功率') {
for (let item of data.rawData[key]) {
let num = formatHarmNum(item.harmNum + '')
let value = rawData.get(key + "_" + num)
let value = rawData.get(key + '_' + num)
if (!value) {
rawData.set(key + "_" + num, [item])
rawData.set(key + '_' + num, [item])
} else {
value.push(item)
}
@@ -376,7 +433,6 @@ const updateTableData = async () => {
}
}
resTableData.resultData = resultData
resTableData.rawData = rawData
@@ -389,8 +445,6 @@ const updateTableData = async () => {
currentCheckItem.value = [checkListLevel[0].value + '']
}
}
} else {
checkResultData.length = 0
rawTableData.length = 0
@@ -418,14 +472,14 @@ const open = async (_deviceId: string, chnNum: string, _scriptType: string | nul
scriptType = _scriptType
// 发起后端请求,查询详细信息 当chnNum为-1时查询所有通道号
const {data: resFormContent}: { data: any } = await getFormData({
const { data: resFormContent }: { data: any } = await getFormData({
planId: checkStore.plan.id,
deviceId,
chnNum,
scriptType
})
chnList = resFormContent.chnList.map((item: { value: string, label: string }) => ({
chnList = resFormContent.chnList.map((item: { value: string; label: string }) => ({
value: item.value,
label: item.value
//label: item.label == '1' ? `${item.value}` : item.label == '2' ? `${item.value}(不符合)` : `${item.value}`
@@ -433,20 +487,25 @@ const open = async (_deviceId: string, chnNum: string, _scriptType: string | nul
Object.assign(formContent, {
...resFormContent,
chnNum: chnList.length > 0 ? chnList[0].value : '',
chnNum: chnList.length > 0 ? chnList[0].value : ''
})
originErrorSysId = formContent.errorSysId
pqErrorList.length = 0
let {data: resPqErrorList} = await getPqErrSysList()
let { data: resPqErrorList } = await getPqErrSysList()
Object.assign(pqErrorList, resPqErrorList)
visible.value = true;
visible.value = true
}
const handleGenerateReport = async () => {
await generateDevReport({'planId': checkStore.plan.id, 'devIdList': [deviceId], 'scriptId': checkStore.plan.scriptId, 'planCode': planCode})
ElMessage.success({message: `报告生成成功!`})
await generateDevReport({
planId: checkStore.plan.id,
devIdList: [deviceId],
scriptId: checkStore.plan.scriptId,
planCode: planCode
})
ElMessage.success({ message: `报告生成成功!` })
}
const handleReCalculate = async () => {
@@ -456,8 +515,8 @@ const handleReCalculate = async () => {
errorSysId: formContent.errorSysId,
deviceId: deviceId,
code: checkStore.plan.code + '',
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? '',
}).then((res) => {
patternId: dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''
}).then(res => {
ElMessage.success('重新计算成功!')
// if (originErrorSysId != formContent.errorSysId) {
// planCode = checkStore.plan.code + "_temp"
@@ -479,7 +538,7 @@ const close = async () => {
errorSysName: '',
dataRule: '',
deviceName: '',
chnNum: '',
chnNum: ''
})
treeDataAll.length = 0
// harmNumList.length = 0
@@ -496,12 +555,12 @@ const close = async () => {
pqErrorList.length = 0
planCode = ''
visible.value = false;
visible.value = false
if (checkStore.showDetailType === 1) {
await deleteTempTable(checkStore.plan.code + '')
}
};
}
const setCheckResultData = (data: CheckData.ResCheckResult | null) => {
let result: CheckData.CheckResult[] = []
@@ -538,7 +597,7 @@ const setCheckResultData = (data: CheckData.ResCheckResult | null) => {
maxError: data.radius,
unit: data.unit,
result: data.isData,
result: data.isData
})
}
@@ -555,22 +614,28 @@ const setCheckResultData = (data: CheckData.ResCheckResult | null) => {
maxError: data.radius,
unit: data.unit,
result: data.isData,
result: data.isData
})
}
Object.assign(checkResultData, result)
console.log("检测结果", checkResultData);
console.log('检测结果', checkResultData)
}
const exportRawDataHandler = () => {
useDownload(exportRawData, '原始数据', {
useDownload(
exportRawData,
'原始数据',
{
scriptType,
scriptId: checkStore.plan.scriptId,
devId: deviceId,
devNum: formContent.chnNum + '',
code: checkStore.plan.code + '',
index: parseInt(checkIndex.value),
}, false, '.xlsx')
index: parseInt(checkIndex.value)
},
false,
'.xlsx'
)
}
const formatHarmNum = (num: string) => {
@@ -596,7 +661,7 @@ const setRawData = (data: CheckData.RawDataItem[]) => {
})
rawTableData.length = 0
Object.assign(rawTableData, data)
console.log("原始数据", rawTableData)
console.log('原始数据', rawTableData)
}
const dataToShow = (num: number): string => {
if (num == null || num == undefined) {
@@ -605,14 +670,13 @@ const dataToShow = (num: number): string => {
return num + ''
}
const numberToFixed = (num: number): string => {
if (num == null || num == undefined) {
return '/'
} else {
let result = num.toFixed(fixed)
if (result === "-0.0000") {
return result.replace(/-/g, "")
if (result === '-0.0000') {
return result.replace(/-/g, '')
}
return result
}
@@ -627,8 +691,8 @@ const stringToFixed = (str: string): string => {
return '/'
} else {
let result = num.toFixed(fixed)
if (result === "-0.0000") {
return result.replace(/-/g, "")
if (result === '-0.0000') {
return result.replace(/-/g, '')
}
return result
}
@@ -644,30 +708,30 @@ const getError = (num1: number, num2: number): string => {
const toMaxErrorStr = (oldMaxErroe: any, unit: any) => {
let result = oldMaxErroe ?? '/'
let idx = result.indexOf('~');
let idx = result.indexOf('~')
if (idx > 0) {
let left = result.substring(0, idx)
let right = result.substring(idx, result.length)
result = left + unit + right + unit;
result = left + unit + right + unit
}
return result;
return result
}
const findFirstLeafNode = (node: any): any => {
if (!node.children || node.children.length === 0) {
return node;
return node
}
return findFirstLeafNode(node.children[0]);
return findFirstLeafNode(node.children[0])
}
const getDefaultNode = (data: any[]) => {
if (!data || data.length === 0) {
return null;
return null
}
const firstElement = data[0];
const firstElement = data[0]
return findFirstLeafNode(firstElement);
return findFirstLeafNode(firstElement)
}
const toAngleLast = () => {
@@ -702,7 +766,7 @@ const filter = (treeData: any[], fly: number) => {
filter(node.children, fly)
// 检查 children 是否被全部移除
if (node.children.length === 0) {
treeData.splice(i, 1);
treeData.splice(i, 1)
}
} else {
treeData.splice(i, 1)
@@ -719,34 +783,33 @@ const updateTreeFly = (treeData: any[], fly: number) => {
// 如果当前节点是叶子节点且 fly 字段等于 targetFly
if (!node.children || node.children.length === 0) {
if (node.fly === targetFly) {
node.fly = targetFly; // 确保叶子节点的 fly 字段被设置为 targetFly
return true; // 返回 true 表示找到并更新了
node.fly = targetFly // 确保叶子节点的 fly 字段被设置为 targetFly
return true // 返回 true 表示找到并更新了
}
return false; // 否则返回 false
return false // 否则返回 false
}
// 递归更新子节点
let updated = false;
let updated = false
for (let child of node.children) {
if (recursiveUpdate(child, targetFly)) {
updated = true;
updated = true
}
}
// 如果有子节点被更新了,则更新当前节点的 fly 字段
if (updated) {
node.fly = targetFly;
node.fly = targetFly
}
return updated;
return updated
}
for (let i = 0; i < treeData.length; i++) {
// 调用递归函数从根节点开始更新
recursiveUpdate(treeData[i], fly);
recursiveUpdate(treeData[i], fly)
}
}
defineExpose({
open
})
@@ -759,7 +822,6 @@ defineExpose({
overflow-y: hidden;
overflow-x: hidden;
.data-check-dialog {
display: flex;
flex-direction: column;

View File

@@ -74,8 +74,8 @@
* 3. 协议校验 - 进行ICD报告触发测试
* 4. 相序校验 - 判断装置接线是否正确
*/
import {ElMessage, ElMessageBox} from "element-plus";
import {defineExpose, ref, toRef, watch} from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'
import { ref, toRef, watch } from 'vue'
// ==================== 日志数据存储 ====================
// 各步骤的日志数据,用于在右侧折叠面板中显示实时日志

View File

@@ -3,19 +3,28 @@
<div class="result-dialog">
<div class="result-title">
<el-row>
<el-form-item label="检测脚本" >
<el-input v-model='testScriptName' :disabled="true"/>
<el-form-item label="检测脚本">
<el-input v-model="testScriptName" :disabled="true" />
</el-form-item>
<el-form-item label="误差体系" >
<el-input v-model='errorSysName' :disabled="true"/>
<el-form-item label="误差体系">
<el-input v-model="errorSysName" :disabled="true" />
</el-form-item>
<el-form-item label="数据原则" >
<el-input v-model='dataRule' :disabled="true"/>
<el-form-item label="数据原则">
<el-input v-model="dataRule" :disabled="true" />
</el-form-item>
</el-row>
</div>
<div class="result-content">
<el-table :data="resultData" stripe max-height="350" :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" border v-on:cell-click="handleClick">
<el-table
:data="resultData"
stripe
max-height="350"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
border
v-on:cell-click="handleClick"
>
<el-table-column prop="deviceName" label="被检设备" />
<el-table-column prop="result_1" label="通道1" />
<el-table-column prop="result_2" label="通道2" />
@@ -23,9 +32,7 @@
<el-table-column prop="result_4" label="通道4" />
</el-table>
</div>
<div class="result-footer">
你可以停留在本页查看数据或返回首页进行复检报告生成和归档
</div>
<div class="result-footer">你可以停留在本页查看数据或返回首页进行复检报告生成和归档</div>
</div>
<DataCheckPopup
:visible="DataCheckDialogVisible"
@@ -34,79 +41,71 @@
</el-dialog>
</template>
<script lang="ts" setup name="testPopup">
import{ElMessage, ElSelectV2, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument,Edit, Picture, UploadFilled, SuccessFilled,VideoPlay,Right,Refresh,Close} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
import preTest from './preTest.vue'
import timeTest from './timeTest.vue'
import DataCheckPopup from './dataCheckPopup.vue';
import { log } from 'console';
<script lang="ts" setup name="testPopup">
import { ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
import DataCheckPopup from './dataCheckPopup.vue'
const props = defineProps<{
visible: boolean;
}>();
const props = defineProps<{
visible: boolean
}>()
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'submit', data: any): void;
}>();
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void
(e: 'submit', data: any): void
}>()
const testScriptName = ref('Q/GDW 10650.4-2021 模拟式');
const errorSysName = ref('Q/GDW 10650.2-2021');
const dataRule = ref('所有值');
const DataCheckDialogVisible = ref(false);
const testScriptName = ref('Q/GDW 10650.4-2021 模拟式')
const errorSysName = ref('Q/GDW 10650.2-2021')
const dataRule = ref('所有值')
const DataCheckDialogVisible = ref(false)
const resultData = ref([
{
deviceName: "被检设备1",
result_1: "合格",
result_2: "合格",
result_3: "合格",
result_4: "合格",
deviceName: '被检设备1',
result_1: '合格',
result_2: '合格',
result_3: '合格',
result_4: '合格'
},
{
deviceName: "被检设备2",
result_1: "合格",
result_2: "合格",
result_3: "—",
result_4: "—",
deviceName: '被检设备2',
result_1: '合格',
result_2: '合格',
result_3: '—',
result_4: '—'
},
{
deviceName: "被检设备3",
result_1: "不合格",
result_2: "合格",
result_3: "—",
result_4: "—",
},
]);
deviceName: '被检设备3',
result_1: '不合格',
result_2: '合格',
result_3: '—',
result_4: '—'
}
])
const handleClick = (row:any) => {
const handleClick = (row: any) => {
console.log(111)
DataCheckDialogVisible.value = true;
};
DataCheckDialogVisible.value = true
}
const handleCancel = () => {
emit('update:visible', false); // 关闭对话框
};
const handleCancel = () => {
emit('update:visible', false) // 关闭对话框
}
</script>
</script>
<style scoped>
.result-dialog{
<style scoped>
.result-dialog {
display: flex;
flex-direction: column;
}
.result-title{
.result-title {
/* display: flex;
flex-direction: row; */
}
.result-footer{
}
.result-footer {
text-align: right;
margin-top: 10px;
}

View File

@@ -1,117 +1,155 @@
<template>
<!-- 检测流程弹窗容器 -->
<el-dialog :title='dialogTitle' width='1550px' :model-value='dialogVisible' :before-close='beforeClose'
@close='handleClose' height='1000px' draggable>
<el-dialog
:title="dialogTitle"
width="1550px"
:model-value="dialogVisible"
:before-close="beforeClose"
@close="handleClose"
height="1000px"
draggable
>
<!-- 步骤指示器容器 -->
<div class='steps-container'>
<div class="steps-container">
<!-- 检测步骤进度条根据选择的检测项动态显示步骤 -->
<!-- 注意Element Plus的active属性从0开始但业务逻辑从1开始所以需要减1 -->
<el-steps v-if='showSteps' class='test-head-steps' simple :active='stepsActiveIndex - 1' process-status='finish'
finish-status='success'>
<el-steps
v-if="showSteps"
class="test-head-steps"
simple
:active="stepsActiveIndex - 1"
process-status="finish"
finish-status="success"
>
<!-- 预检测步骤 -->
<el-step v-if='preTestSelected' title='预检测'
:icon='stepsActive > 1 || stepsActiveIndex > stepsTotalNum-1? SuccessFilled :Edit'
@click='handleStepClick(1)' />
<el-step
v-if="preTestSelected"
title="预检测"
:icon="stepsActive > 1 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Edit"
@click="handleStepClick(1)"
/>
<!-- 守时检测步骤 -->
<el-step v-if='timeTestSelected' title='守时检测'
:icon='stepsActive > 2 || stepsActiveIndex > stepsTotalNum-1? SuccessFilled :UploadFilled'
@click='handleStepClick(2)' />
<el-step
v-if="timeTestSelected"
title="守时检测"
:icon="stepsActive > 2 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : UploadFilled"
@click="handleStepClick(2)"
/>
<!-- 系数校准步骤 -->
<el-step v-if='channelsTestSelected' title='系数校准'
:icon='stepsActive > 3 || stepsActiveIndex > stepsTotalNum-1? SuccessFilled :Odometer'
@click='handleStepClick(3)' />
<el-step
v-if="channelsTestSelected"
title="系数校准"
:icon="stepsActive > 3 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Odometer"
@click="handleStepClick(3)"
/>
<!-- 正式检测步骤 -->
<el-step v-if='testSelected' title='正式检测'
:icon='stepsActive > 4 || stepsActiveIndex > stepsTotalNum-1? SuccessFilled :Coin'
@click='handleStepClick(4)' />
<el-step
v-if="testSelected"
title="正式检测"
:icon="stepsActive > 4 || stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Coin"
@click="handleStepClick(4)"
/>
<!-- 检测完成步骤 -->
<el-step title='检测完成' :icon='stepsActiveIndex > stepsTotalNum-1 ? SuccessFilled :Key' />
<el-step title="检测完成" :icon="stepsActiveIndex > stepsTotalNum - 1 ? SuccessFilled : Key" />
</el-steps>
</div>
<!-- 检测组件容器 - 根据当前步骤显示对应的检测组件 -->
<!-- 预检测组件 -->
<preTest v-if='showComponent&&preTestSelected' v-show='preTestSelected && stepsActiveView==1' ref='preTestRef'
v-model:testStatus='preTestStatus'
:webMsgSend='webMsgSend' />
<preTest
v-if="showComponent && preTestSelected"
v-show="preTestSelected && stepsActiveView == 1"
ref="preTestRef"
v-model:testStatus="preTestStatus"
:webMsgSend="webMsgSend"
/>
<!-- 守时检测组件 -->
<timeTest v-if='showComponent&&timeTestSelected' v-show='timeTestSelected && stepsActiveView==2'
v-model:testStatus='timeTestStatus' />
<timeTest
v-if="showComponent && timeTestSelected"
v-show="timeTestSelected && stepsActiveView == 2"
v-model:testStatus="timeTestStatus"
/>
<!-- 系数校准检测组件 -->
<factorTest v-if='showComponent&&channelsTestSelected' v-show='channelsTestSelected && stepsActiveView==3'
v-model:testStatus='channelsTestStatus'
:webMsgSend='webMsgSend' />
<factorTest
v-if="showComponent && channelsTestSelected"
v-show="channelsTestSelected && stepsActiveView == 3"
v-model:testStatus="channelsTestStatus"
:webMsgSend="webMsgSend"
/>
<!-- 正式检测组件 -->
<test v-if='showComponent&&testSelected' ref='testRef' v-show='testSelected && stepsActiveView==4'
v-model:testStatus='TestStatus' :webMsgSend='webMsgSend'
@update:webMsgSend='webMsgSend=$event' @sendPause='sendPause' @sendResume='sendResume'
@closeWebSocket='closeWebSocket'
:stepsActive='stepsActive' />
<test
v-if="showComponent && testSelected"
ref="testRef"
v-show="testSelected && stepsActiveView == 4"
v-model:testStatus="TestStatus"
:webMsgSend="webMsgSend"
@update:webMsgSend="webMsgSend = $event"
@sendPause="sendPause"
@sendResume="sendResume"
@closeWebSocket="closeWebSocket"
:stepsActive="stepsActive"
/>
<!-- 弹窗底部操作按钮区域 -->
<template #footer>
<div>
<!-- 开始检测按钮 - 当前状态为等待时显示 -->
<el-button type='primary' :icon='VideoPlay' v-if="ActiveStatue === 'waiting'" @click='handleSubmitFast'>
<el-button type="primary" :icon="VideoPlay" v-if="ActiveStatue === 'waiting'" @click="handleSubmitFast">
开始检测
</el-button>
<!-- 初始化中按钮 - 禁用状态显示加载动画 -->
<el-button type='primary' v-if="TestStatus === 'test_init'" disabled>
<el-icon class='loading-box' style='color: #fff;margin-right: 8px;'>
<component :is='Refresh' />
<el-button type="primary" v-if="TestStatus === 'test_init'" disabled>
<el-icon class="loading-box" style="color: #fff; margin-right: 8px">
<component :is="Refresh" />
</el-icon>
初始化中
</el-button>
<!-- 停止检测按钮 - 检测进行中时显示 -->
<el-button
type='primary'
v-if="TestStatus=='process'"
:icon='VideoPause'
@click='handlePause()'>停止检测
<el-button type="primary" v-if="TestStatus == 'process'" :icon="VideoPause" @click="handlePause()">
停止检测
</el-button>
<!-- 暂停中按钮 - 禁用状态显示加载动画 -->
<el-button type='warning' v-if="TestStatus === 'paused_ing'" disabled>
<el-icon class='loading-box' style='color: #fff;margin-right: 8px;'>
<component :is='Refresh' />
<el-button type="warning" v-if="TestStatus === 'paused_ing'" disabled>
<el-icon class="loading-box" style="color: #fff; margin-right: 8px">
<component :is="Refresh" />
</el-icon>
暂停中
</el-button>
<!-- 继续检测按钮 - 检测已暂停时显示 -->
<el-button
type='warning'
v-if="(TestStatus =='paused')"
:icon='VideoPlay'
@click='sendResume'
>继续检测
<el-button type="warning" v-if="TestStatus == 'paused'" :icon="VideoPlay" @click="sendResume">
继续检测
</el-button>
<!-- 下一步/完成/错误状态按钮 -->
<el-button :type="ActiveStatue==='success'?'primary':'danger'" :icon='Right'
v-if="nextStepText !== '下一步' && (ActiveStatue === 'success'||ActiveStatue==='error'||ActiveStatue==='connect_timeout'||ActiveStatue==='pause_timeout')"
@click='nextStep'>
<el-button
:type="ActiveStatue === 'success' ? 'primary' : 'danger'"
:icon="Right"
v-if="
nextStepText !== '下一步' &&
(ActiveStatue === 'success' ||
ActiveStatue === 'error' ||
ActiveStatue === 'connect_timeout' ||
ActiveStatue === 'pause_timeout')
"
@click="nextStep"
>
{{ nextStepText }}
</el-button>
<!-- 退出检测按钮 - 默认显示 -->
<el-button type='primary' @click='handleQuit' v-else>
退出检测
</el-button>
<el-button type="primary" @click="handleQuit" v-else>退出检测</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang='tsx' setup name='testPopup'>
<script lang="tsx" setup name="testPopup">
// ====================== 导入依赖 ======================
import { reactive, ref, watch, onBeforeUnmount } from 'vue'
import { onBeforeUnmount, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
Coin,
@@ -123,7 +161,7 @@ import {
SuccessFilled,
UploadFilled,
VideoPause,
VideoPlay,
VideoPlay
} from '@element-plus/icons-vue'
import preTest from './preTest.vue'
import timeTest from './timeTest.vue'
@@ -166,7 +204,7 @@ const webMsgSend = ref() // webSocket推送的数据用于组件间通信
const dataSocket = reactive<{
socketServe: typeof socketClient.Instance | null
}>({
socketServe: socketClient.Instance, // WebSocket客户端实例
socketServe: socketClient.Instance // WebSocket客户端实例
})
// ====================== 检测项选择状态 ======================
@@ -262,7 +300,7 @@ const open = (title: string) => {
dataSocket.socketServe = socketClient.Instance
// 注册新的回调
dataSocket.socketServe.registerCallBack('aaa', (res) => {
dataSocket.socketServe.registerCallBack('aaa', res => {
// 将接收到的数据传递给子组件
webMsgSend.value = res
})
@@ -278,7 +316,7 @@ const open = (title: string) => {
*/
const handleSubmitFast = () => {
// 获取设备ID列表和计划ID
let deviceIds = checkStore.devices.map((item) => item.deviceId)
let deviceIds = checkStore.devices.map(item => item.deviceId)
let planId = checkStore.plan.id
// 检查WebSocket连接状态
@@ -303,12 +341,16 @@ const handleSubmitFast = () => {
userId: userStore.userInfo.id,
temperature: checkStore.temperature,
humidity: checkStore.humidity,
testItemList: [checkStore.selectTestItems.preTest, checkStore.selectTestItems.channelsTest, checkStore.selectTestItems.test],
testItemList: [
checkStore.selectTestItems.preTest,
checkStore.selectTestItems.channelsTest,
checkStore.selectTestItems.test
]
}).then(res => {
if (res.code !== 'A0000') {
ElMessageBox.alert('预检测失败', '检测失败', {
confirmButtonText: '确定',
type: 'error',
type: 'error'
})
preTestStatus.value = 'error'
}
@@ -332,12 +374,16 @@ const handleSubmitFast = () => {
userId: userStore.userInfo.id,
temperature: checkStore.temperature,
humidity: checkStore.humidity,
testItemList: [checkStore.selectTestItems.preTest, checkStore.selectTestItems.channelsTest, checkStore.selectTestItems.test],
testItemList: [
checkStore.selectTestItems.preTest,
checkStore.selectTestItems.channelsTest,
checkStore.selectTestItems.test
]
}).then(res => {
if (res.code !== 'A0000') {
ElMessageBox.alert('系数校准失败', '检测失败', {
confirmButtonText: '确定',
type: 'error',
type: 'error'
})
channelsTestStatus.value = 'error'
}
@@ -349,7 +395,11 @@ const handleSubmitFast = () => {
case 4: // 正式检测步骤
if (TestStatus.value == 'waiting') {
// 如果没有预检测和系数校准,直接进行正式检测需要先初始化
if (!checkStore.selectTestItems.preTest && !checkStore.selectTestItems.channelsTest && checkStore.selectTestItems.test) {
if (
!checkStore.selectTestItems.preTest &&
!checkStore.selectTestItems.channelsTest &&
checkStore.selectTestItems.test
) {
startPreTest({
userPageId: JwtUtil.getLoginName(),
devIds: deviceIds,
@@ -358,12 +408,16 @@ const handleSubmitFast = () => {
userId: userStore.userInfo.id,
temperature: checkStore.temperature,
humidity: checkStore.humidity,
testItemList: [checkStore.selectTestItems.preTest, checkStore.selectTestItems.channelsTest, checkStore.selectTestItems.test],
testItemList: [
checkStore.selectTestItems.preTest,
checkStore.selectTestItems.channelsTest,
checkStore.selectTestItems.test
]
}).then(res => {
if (res.code !== 'A0000') {
ElMessageBox.alert('正式检测失败', '检测失败', {
confirmButtonText: '确定',
type: 'error',
type: 'error'
})
TestStatus.value = 'error'
}
@@ -380,36 +434,35 @@ const handleSubmitFast = () => {
}
}
// ====================== 事件定义 ======================
const emit = defineEmits<{
(e: 'quitClicked'): void; // 退出检测事件
(e: 'quitClicked'): void // 退出检测事件
}>()
// ====================== 状态监听器 ======================
// 监听各个检测步骤的状态变化,并同步到总体状态
watch(preTestStatus, function(newValue, oldValue) {
watch(preTestStatus, function (newValue, oldValue) {
console.log('预检测状态变化:', newValue, oldValue)
ActiveStatue.value = newValue // 同步到总体状态
})
watch(timeTestStatus, function(newValue, oldValue) {
watch(timeTestStatus, function (newValue, oldValue) {
console.log('守时检测状态变化:', newValue, oldValue)
ActiveStatue.value = newValue // 同步到总体状态
})
watch(channelsTestStatus, function(newValue, oldValue) {
watch(channelsTestStatus, function (newValue, oldValue) {
console.log('系数校准状态变化:', newValue, oldValue)
ActiveStatue.value = newValue // 同步到总体状态
})
watch(TestStatus, function(newValue, oldValue) {
watch(TestStatus, function (newValue, oldValue) {
console.log('正式检测状态变化:', newValue, oldValue)
ActiveStatue.value = newValue // 同步到总体状态
})
// 监听总体状态变化,处理步骤切换和错误状态
watch(ActiveStatue, function(newValue, oldValue) {
watch(ActiveStatue, function (newValue, oldValue) {
console.log('总体状态变化:', newValue, oldValue)
// 处理错误状态
@@ -504,17 +557,17 @@ const sendResume = () => {
// 调用继续检测API
resumeTest({
userPageId: JwtUtil.getLoginName(),
devIds: checkStore.devices.map((item) => item.deviceId),
devIds: checkStore.devices.map(item => item.deviceId),
planId: checkStore.plan.id,
reCheckType: '2', // 操作类型0-系数校验1-预检测2-正式检测8-不合格项复检
userId: userStore.userInfo.id,
temperature: checkStore.temperature,
humidity: checkStore.humidity,
humidity: checkStore.humidity
})
// 发送继续成功消息给子组件
Object.assign(webMsgSend.value, {
requestId: 'Resume_Success',
requestId: 'Resume_Success'
})
}
@@ -548,7 +601,12 @@ const closeWebSocket = () => {
*/
const nextStep = () => {
// 如果已到最后或遇到错误状态,直接关闭弹窗
if (stepsActiveIndex.value == stepsTotalNum.value + 1 || ActiveStatue.value === 'error' || ActiveStatue.value === 'connect_timeout' || ActiveStatue.value === 'pause_timeout') {
if (
stepsActiveIndex.value == stepsTotalNum.value + 1 ||
ActiveStatue.value === 'error' ||
ActiveStatue.value === 'connect_timeout' ||
ActiveStatue.value === 'pause_timeout'
) {
handleClose()
return
}
@@ -562,13 +620,19 @@ const nextStep = () => {
// 遍历检测项,找到下一个需要执行的步骤
for (let selectTestItemsKey in checkStore.selectTestItems) {
if (tempStep == 0 && checkStore.selectTestItems[selectTestItemsKey as keyof typeof checkStore.selectTestItems]) {
if (
tempStep == 0 &&
checkStore.selectTestItems[selectTestItemsKey as keyof typeof checkStore.selectTestItems]
) {
// 找到下一个要执行的检测项
stepsActiveView.value = idx // 设置显示的组件
stepsActive.value = idx // 设置业务逻辑步骤
return
}
if (checkStore.selectTestItems[selectTestItemsKey as keyof typeof checkStore.selectTestItems] && tempStep != 0) {
if (
checkStore.selectTestItems[selectTestItemsKey as keyof typeof checkStore.selectTestItems] &&
tempStep != 0
) {
tempStep-- // 跳过已选择的检测项
}
idx++
@@ -613,9 +677,8 @@ const beforeClose = () => {
ElMessageBox.confirm('检测未完成,是否退出当前检测流程?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
},
).then(() => {
type: 'warning'
}).then(() => {
handleClose() // 用户确认后关闭
})
} else {
@@ -649,10 +712,9 @@ onBeforeUnmount(() => {
defineExpose({ open }) // 只暴露open方法供父组件调用
</script>
<style scoped lang='scss'>
<style scoped lang="scss">
.test-head-steps {
::v-deep .el-step {
:deep(.el-step) {
.el-step__head.is-success {
color: #91cc75;
}
@@ -705,6 +767,4 @@ defineExpose({ open }) // 只暴露open方法供父组件调用
transform: rotate(360deg);
}
}
</style>

View File

@@ -1,76 +1,57 @@
<template>
<el-form
ref='loginFormRef'
:model='loginForm'
:rules='loginRules'
size='large'
>
<el-form-item prop='username'>
<el-input v-model='loginForm.username' placeholder='用户名'>
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" size="large">
<el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="用户名">
<template #prefix>
<el-icon class='el-input__icon'>
<user/>
<el-icon class="el-input__icon">
<user />
</el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop='password'>
<el-form-item prop="password">
<el-input
v-model='loginForm.password'
type='password'
placeholder='密码'
v-model="loginForm.password"
type="password"
placeholder="密码"
show-password
autocomplete='new-password'
autocomplete="new-password"
>
<template #prefix>
<el-icon class='el-input__icon'>
<lock/>
<el-icon class="el-input__icon">
<lock />
</el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop='checked'>
<el-form-item prop="checked">
<el-checkbox v-model="loginForm.checked">记住我</el-checkbox>
</el-form-item>
</el-form>
<div class='login-btn'>
<el-button
:icon='UserFilled'
round
size='large'
type='primary'
:loading='loading'
@click='login(loginFormRef)'
>
<div class="login-btn">
<el-button :icon="UserFilled" round size="large" type="primary" :loading="loading" @click="login(loginFormRef)">
登录
</el-button>
<el-button
:icon='CircleClose'
round
size='large'
@click='resetForm(loginFormRef)'
>
重置
</el-button>
<el-button :icon="CircleClose" round size="large" @click="resetForm(loginFormRef)">重置</el-button>
</div>
</template>
<script setup lang='ts'>
import {useRouter} from 'vue-router'
import {HOME_URL} from '@/config'
import {getTimeState} from '@/utils'
import {type Dict} from '@/api/interface'
import {type Login} from '@/api/user/interface/user'
import type {ElForm} from 'element-plus'
import {ElNotification} from 'element-plus'
import {getDictList, getPublicKey, loginApi} from '@/api/user/login'
import {useUserStore} from '@/stores/modules/user'
import {useTabsStore} from '@/stores/modules/tabs'
import {useKeepAliveStore} from '@/stores/modules/keepAlive'
import {initDynamicRouter} from '@/routers/modules/dynamicRouter'
import {CircleClose, UserFilled} from '@element-plus/icons-vue'
import {useAuthStore} from '@/stores/modules/auth'
import {useDictStore} from "@/stores/modules/dict";
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { HOME_URL } from '@/config'
import { getTimeState } from '@/utils'
import { type Dict } from '@/api/interface'
import { type Login } from '@/api/user/interface/user'
import type { ElForm } from 'element-plus'
import { ElNotification } from 'element-plus'
import { getDictList, getPublicKey, loginApi } from '@/api/user/login'
import { useUserStore } from '@/stores/modules/user'
import { useTabsStore } from '@/stores/modules/tabs'
import { useKeepAliveStore } from '@/stores/modules/keepAlive'
import { initDynamicRouter } from '@/routers/modules/dynamicRouter'
import { CircleClose, UserFilled } from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/modules/auth'
import { useDictStore } from '@/stores/modules/dict'
import forge from 'node-forge'
const authStore = useAuthStore()
@@ -80,44 +61,45 @@ const tabsStore = useTabsStore()
const keepAliveStore = useKeepAliveStore()
const dictStore = useDictStore()
let publicKey: any = null;
let publicKey: any = null
type FormInstance = InstanceType<typeof ElForm>;
type FormInstance = InstanceType<typeof ElForm>
const loginFormRef = ref<FormInstance>()
const loginRules = reactive({
username: [{required: true, message: '请输入用户名', trigger: 'blur'}],
password: [{required: true, message: '请输入密码', trigger: 'blur'}],
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
})
const loading = ref(false)
const loginForm = reactive<Login.ReqLoginForm>({
username: '',
password: '',
checked: false,
checked: false
})
// login
const login = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.validate(async (valid) => {
formEl.validate(async valid => {
if (!valid) return
loading.value = true
try {
let {data: publicKeyBase64}: { data: string } = await getPublicKey(loginForm.username)
let { data: publicKeyBase64 }: { data: string } = await getPublicKey(loginForm.username)
//将base64格式的公钥转换为Forge可以使用的格式
const publicKeyDer = forge.util.decode64(publicKeyBase64);
publicKey = forge.pki.publicKeyFromPem(forge.pki.publicKeyToPem(forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyDer))));
const publicKeyDer = forge.util.decode64(publicKeyBase64)
publicKey = forge.pki.publicKeyFromPem(
forge.pki.publicKeyToPem(forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyDer)))
)
// 1.执行登录接口
const {data} = await loginApi({
const { data } = await loginApi({
username: forge.util.encode64(loginForm.username),
password: encryptPassword(loginForm.password),
password: encryptPassword(loginForm.password)
})
userStore.setAccessToken(data.accessToken)
userStore.setRefreshToken(data.refreshToken)
userStore.setUserInfo(data.userInfo)
if(loginForm.checked){
if (loginForm.checked) {
userStore.setExp(Date.now() + 1000 * 60 * 60 * 24 * 30)
}
const response = await getDictList()
@@ -138,7 +120,7 @@ const login = (formEl: FormInstance | undefined) => {
title: getTimeState(),
message: '登录成功',
type: 'success',
duration: 3000,
duration: 3000
})
} finally {
loading.value = false
@@ -164,13 +146,12 @@ onMounted(() => {
})
const encryptPassword = (password: string) => {
const encrypted = publicKey.encrypt(password, 'RSAES-PKCS1-V1_5');
const encrypted = publicKey.encrypt(password, 'RSAES-PKCS1-V1_5')
// 将加密后的数据转换为base64格式以便传输
return forge.util.encode64(encrypted);
return forge.util.encode64(encrypted)
}
</script>
<style scoped lang='scss'>
@import "../index.scss";
<style scoped lang="scss">
@use '../index.scss';
</style>

View File

@@ -18,11 +18,11 @@
</template>
<script setup lang="ts" name="login">
import LoginForm from "./components/LoginForm.vue";
const title = import.meta.env.VITE_GLOB_APP_TITLE;
import LoginForm from './components/LoginForm.vue'
const title = import.meta.env.VITE_GLOB_APP_TITLE
</script>
<style scoped lang="scss">
@import "./index.scss";
@use './index.scss';
</style>

View File

@@ -6,7 +6,7 @@
</div>
<div class="data-check-content">
<div class="content-tree">
<Tree ref="treeRef" :treeData="treeData" @setTab="setTab" />
<MachineTree ref="treeRef" :treeData="treeData" @setTab="setTab" />
</div>
<div class="content-right-Tabs" style="height: calc(100vh - 315px); width: 100px">
@@ -204,33 +204,22 @@
</template>
<script setup lang="ts">
import { type PropType, ref, nextTick, onMounted, watch } from 'vue'
import Tree from './tree.vue'
import { nextTick, onMounted, type PropType, ref, watch } from 'vue'
import MachineTree from './machineTree.vue'
import Commun from '@/views/machine/testScript/components//communication.vue'
import { type CascaderOption, ElMessage } from 'element-plus'
import { ElMessage } from 'element-plus'
import { getTreeData } from '@/api/check/test'
import {
CirclePlus,
Delete,
Check,
CopyDocument,
View,
EditPen,
VideoPlay,
VideoPause,
Loading
} from '@element-plus/icons-vue'
import { VideoPause, VideoPlay, View } from '@element-plus/icons-vue'
import type { TestScript } from '@/api/device/interface/testScript'
import TestProjectPopup from '@/views/machine/testScript/components/testProjectPopup.vue'
import { CheckData } from '@/api/check/interface'
import { dlsDetails, deleteDtls, updateDtls, addScriptDtls, checkDataList } from '@/api/device/testScript'
import { dlsDetails } from '@/api/device/testScript'
import { useDictStore } from '@/stores/modules/dict'
import { useHandleData } from '@/hooks/useHandleData'
import { scriptDtlsCheckDataList } from '@/api/device/testScript/index'
import ViewRow from '@/views/machine/testScript/components/viewRow.vue'
import { startSimulateTest, closeSimulateTest } from '@/api/device/controlSource/index.ts'
import { closeSimulateTest, startSimulateTest } from '@/api/device/controlSource/index.ts'
import { controlSource } from '@/api/device/interface/controlSource'
import {JwtUtil} from "@/utils/jwtUtil";
import { JwtUtil } from '@/utils/jwtUtil'
interface TabOption {
label?: string
name?: string

View File

@@ -1,101 +1,128 @@
<!-- components/MonitorPointTable.vue -->
<template>
<div class='table-box'>
<div class="table-box">
<ProTable
ref='proTable'
ref="proTable"
:pagination="false"
:toolButton="false"
:columns='columns'
:columns="columns"
:data="tableData"
:style="{ height: tableHeight + 'px',overflow:'hidden'}"
:style="{ height: tableHeight + 'px', overflow: 'hidden' }"
>
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button type='primary' :icon='CirclePlus' @click="openDialog('add')" :disabled="props.DevFormContent.importFlag == 1">新增</el-button>
<el-button v-auth.device="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
<template #tableHeader="scope">
<el-button
type="primary"
:icon="CirclePlus"
@click="openDialog('add')"
:disabled="props.DevFormContent.importFlag == 1"
>
新增
</el-button>
<el-button
v-auth.device="'delete'"
type="danger"
:icon="Delete"
plain
:disabled="!scope.isSelected"
@click="batchDelete(scope.selectedListIds)"
>
删除
</el-button>
</template>
<!-- 表格操作 -->
<template #operation="scope">
<el-button v-auth.device="'edit'" type='primary' link :icon='EditPen' :model-value='false' :disabled="props.DevFormContent.importFlag == 1"
@click="openDialog('edit', scope.row)">编辑
<el-button
v-auth.device="'edit'"
type="primary"
link
:icon="EditPen"
:model-value="false"
:disabled="props.DevFormContent.importFlag == 1"
@click="openDialog('edit', scope.row)"
>
编辑
</el-button>
<el-button v-auth.device="'delete'" type='primary' link :icon='Delete' @click='handleDelete(scope.row.id)' >删除
<el-button
v-auth.device="'delete'"
type="primary"
link
:icon="Delete"
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template>
</ProTable>
</div>
<MonitorPopup @getParameter="getParameter" ref='monitorPopup'/>
</template>
<MonitorPopup @getParameter="getParameter" ref="monitorPopup" />
</template>
<script setup lang="ts">
import { ref, defineProps, reactive, watch } from 'vue';
import ProTable from '@/components/ProTable/index.vue'; // 假设 ProTable 是自定义组件
import { CirclePlus, Delete, EditPen, MessageBox } from '@element-plus/icons-vue';
import MonitorPopup from '@/views/machine/device/components/monitorPopup.vue'
import { ProTableInstance, type ColumnProps } from '@/components/ProTable/interface'
import { type Monitor } from '@/api/device/interface/monitor'
import { useDictStore } from '@/stores/modules/dict';
import { useHandleData } from '@/hooks/useHandleData';
import { Device } from '@/api/device/interface/device';
import { ElMessage, ElMessageBox } from 'element-plus';
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import ProTable from '@/components/ProTable/index.vue' // 假设 ProTable 是自定义组件
import { CirclePlus, Delete, EditPen } from '@element-plus/icons-vue'
import MonitorPopup from '@/views/machine/device/components/monitorPopup.vue'
import { type ColumnProps, ProTableInstance } from '@/components/ProTable/interface'
import { type Monitor } from '@/api/device/interface/monitor'
import { useDictStore } from '@/stores/modules/dict'
import { Device } from '@/api/device/interface/device'
import { ElMessage, ElMessageBox } from 'element-plus'
// 定义 props
const props = defineProps<{
DevFormContent:Device.ResPqDev,
tableHeight?: number, // 接收外部传入的高度
selectOptions: Record<string, Device.SelectOption[]>,
}>();
// 定义 props
const props = defineProps<{
DevFormContent: Device.ResPqDev
tableHeight?: number // 接收外部传入的高度
selectOptions: Record<string, Device.SelectOption[]>
}>()
// ProTable 实例
const proTable = ref<ProTableInstance>()
const dictStore = useDictStore()
const monitorPopup = ref()
const tableData = ref<any[]>([])
const title_Type = ref('add')
// ProTable 实例
const proTable = ref<ProTableInstance>()
const dictStore = useDictStore()
const monitorPopup = ref()
const tableData = ref<any[]>([])
const title_Type = ref('add')
// 表格配置项
// 表格配置项
const columns = reactive<ColumnProps<Monitor.ResPqMon>[]>([
{ type: 'selection', fixed: 'left', width: 70 },
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '名称',
width: 200,
width: 200
},
{
prop: 'busbar',
label: '所属母线',
width: 200,
width: 200
},
{
prop: 'num',
label: '线路号',
width: 200,
width: 200
},
{
prop: 'pt',
label: 'PT变比',
width: 110,
width: 110
},
{
prop: 'ct',
label: 'CT变比',
width: 130,
width: 130
},
{
prop: 'connection',
label: '接线方式',
enum: dictStore.getDictData('Dev_Connect'),
fieldNames: {label: 'name', value: 'id'},
width: 130,
fieldNames: { label: 'name', value: 'id' },
width: 130
},
{
prop: 'statInterval',
label: '统计间隔',
width: 130,
width: 130
},
{
prop: 'checkFlag',
@@ -103,12 +130,11 @@ const columns = reactive<ColumnProps<Monitor.ResPqMon>[]>([
render: (scope: any) => {
return scope.row.checkFlag === 1 ? '是' : '否'
},
width: 130,
width: 130
},
{ prop: 'operation', label: '操作', fixed: 'right', width: 200 },
{ prop: 'operation', label: '操作', fixed: 'right', width: 200 }
])
const emit = defineEmits(['get-parameter'])
const getParameter = (data: Monitor.ResPqMon) => {
@@ -117,83 +143,68 @@ const getParameter = (data: Monitor.ResPqMon) => {
// 编辑:替换已有的数据
const index = tableData.value.findIndex(item => item.id === data.id)
if (index > -1) {
tableData.value = [
...tableData.value.slice(0, index),
data,
...tableData.value.slice(index + 1)
]
tableData.value = [...tableData.value.slice(0, index), data, ...tableData.value.slice(index + 1)]
}
} else {
// 新增:追加数据
tableData.value = [...tableData.value, data]
}
emit('get-parameter', tableData.value)
}
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<Monitor.ResPqMon> = {}) => {
if(props.DevFormContent.devType == '' || props.DevFormContent.devType == undefined){
ElMessageBox.confirm(
'请先选择被检设备类型',
'提示',
{
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<Monitor.ResPqMon> = {}) => {
if (props.DevFormContent.devType == '' || props.DevFormContent.devType == undefined) {
ElMessageBox.confirm('请先选择被检设备类型', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
},
)
type: 'warning'
})
return
}
title_Type.value = titleType
monitorPopup.value?.open(titleType, row,props.DevFormContent,tableData.value,props.selectOptions)
}
monitorPopup.value?.open(titleType, row, props.DevFormContent, tableData.value, props.selectOptions)
}
// 批量删除监测点台账
const batchDelete = (ids: string[]) => {
ElMessageBox.confirm(`是否批量删除监测点?`, "温馨提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
// 批量删除监测点台账
const batchDelete = (ids: string[]) => {
ElMessageBox.confirm(`是否批量删除监测点?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
draggable: true
}).then(async () => {
tableData.value = tableData.value.filter(item => !ids.includes(item.id));
tableData.value = tableData.value.filter(item => !ids.includes(item.id))
proTable.value?.clearSelection()
emit('get-parameter', tableData.value)
ElMessage({
type: "success",
type: 'success',
message: `批量删除监测点成功!`
});
});
})
})
}
}
// 删除监测点台账
// 删除监测点台账
const handleDelete = (id: string) => {
ElMessageBox.confirm(`是否删除监测点?`, "温馨提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
ElMessageBox.confirm(`是否删除监测点?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
draggable: true
}).then(async () => {
tableData.value = tableData.value.filter(item => item.id !== id)
proTable.value?.clearSelection()
emit('get-parameter', tableData.value)
ElMessage({
type: "success",
type: 'success',
message: `删除监测点成功!`
});
});
})
})
}
watch(
() => props.DevFormContent.monitorList,
(newVal) => {
tableData.value = newVal|| []
newVal => {
tableData.value = newVal || []
},
{ immediate: true }
)
</script>
</script>

View File

@@ -1,8 +1,8 @@
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" align-center>
<el-dialog :title="dialogTitle" v-model="dialogVisible" @close="close" v-bind="dialogBig" align-center>
<div class="table-container">
<el-table :data="errorData.value"
<el-table
:data="errorData.value"
height="500"
:header-cell-style="rowClass"
:cell-style="{ textAlign: 'center' }"
@@ -12,34 +12,38 @@
class="custom-table"
>
<el-table-column label="被测量">
<el-table-column prop="col1" width="150"/>
<el-table-column prop="col2" width="120"/>
<el-table-column prop="col1" width="150" />
<el-table-column prop="col2" width="120" />
</el-table-column>
<el-table-column prop="deviceLevel" label="检测装置级别" width="120"/>
<el-table-column prop="measurementType" label="测量类型"/>
<el-table-column prop="condition" label="测量条件"/>
<el-table-column prop="maxErrorValue" label="最大误差"/>
<el-table-column prop="deviceLevel" label="检测装置级别" width="120" />
<el-table-column prop="measurementType" label="测量类型" />
<el-table-column prop="condition" label="测量条件" />
<el-table-column prop="maxErrorValue" label="最大误差" />
</el-table>
</div>
<div>
<label class="left-align-label">注1UN测量的标称电压IN测量仪器的标称电流Uh和Ih测量值h表示谐波次数</label>
<label class="left-align-label">
注1UN测量的标称电压IN测量仪器的标称电流Uh和Ih测量值h表示谐波次数
</label>
</div>
<div>
<label class="left-align-label">注2对于数字式接入监测终端与电能质量信号采集单元联合准确度需满足本表要求</label>
<label class="left-align-label">
注2对于数字式接入监测终端与电能质量信号采集单元联合准确度需满足本表要求
</label>
</div>
</el-dialog>
</template>
<script lang="ts" setup name="IndicatorTypeDialog">
import {computed, type CSSProperties, defineProps, ref} from 'vue';
import {dialogBig} from '@/utils/elementBind'
import type {ErrorSystem} from '@/api/device/interface/error'
import { computed, type CSSProperties, ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
import type { ErrorSystem } from '@/api/device/interface/error'
import errorDataList from '@/api/device/error/errorData'
import type {TableColumnCtx} from 'element-plus'
import {useDictStore} from '@/stores/modules/dict'
import type { TableColumnCtx } from 'element-plus'
import { useDictStore } from '@/stores/modules/dict'
const dictStore = useDictStore()
const errorData = ref<ErrorSystem.Error_detail[]>([]);
const errorData = ref<ErrorSystem.Error_detail[]>([])
const dialogTitle = ref()
const devLevelName = ref<string>('') // 假设 devLevelName 是一个 ref
function useMetaInfo() {
@@ -51,12 +55,12 @@ function useMetaInfo() {
standardTime: '',
devLevel: '',
enable: 1,
state: 1,
state: 1
})
return {dialogVisible, formContent}
return { dialogVisible, formContent }
}
const {dialogVisible, formContent} = useMetaInfo()
const { dialogVisible, formContent } = useMetaInfo()
interface SpanMethodProps {
row: ErrorSystem.ErrorSystemDetail
@@ -65,149 +69,186 @@ interface SpanMethodProps {
columnIndex: number
}
const rowClass = ({row, column, rowIndex, columnIndex}: { row: any; column: any; rowIndex: number; columnIndex: number }): CSSProperties => {
const rowClass = ({
row,
column,
rowIndex,
columnIndex
}: {
row: any
column: any
rowIndex: number
columnIndex: number
}): CSSProperties => {
let res: CSSProperties = {
textAlign: 'center' as CSSProperties['textAlign'],
backgroundColor: 'var(--el-color-primary)',
color: '#fff'
}
if (rowIndex === 1) {
res = {...res, display: 'none'}
res = { ...res, display: 'none' }
}
return res
}
const spanMethod = computed(() => {
return devLevelName.value === 'A级' ? spanAMethod : spanSMethod
})
const spanAMethod = ({
row,
column,
rowIndex,
columnIndex,
}: SpanMethodProps) => {
const spanAMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0) {
if (rowIndex <= 1 || rowIndex === 7 || rowIndex == 20) {//0电压偏差1频率偏差7闪变20功率简单的跨两列
if (rowIndex <= 1 || rowIndex === 7 || rowIndex == 20) {
//0电压偏差1频率偏差7闪变20功率简单的跨两列
return {
rowspan: 1,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 2) {//2三相不平衡跨三行两列
if (rowIndex === 2) {
//2三相不平衡跨三行两列
return {
rowspan: 3,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 3 || rowIndex === 4 || rowIndex === 6 ||
rowIndex >= 9 && rowIndex <= 15 ||
rowIndex >= 17 && rowIndex <= 19 ||
rowIndex === 22 || rowIndex === 24) {//这些行不显示
if (
rowIndex === 3 ||
rowIndex === 4 ||
rowIndex === 6 ||
(rowIndex >= 9 && rowIndex <= 15) ||
(rowIndex >= 17 && rowIndex <= 19) ||
rowIndex === 22 ||
rowIndex === 24
) {
//这些行不显示
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
if (rowIndex === 5 || rowIndex === 23) {//5电压波动23电压暂降暂升中断跨两列
if (rowIndex === 5 || rowIndex === 23) {
//5电压波动23电压暂降暂升中断跨两列
return {
rowspan: 2,
colspan: 1,
colspan: 1
}
}
if (rowIndex === 8) {//谐波和间谐波跨八行两列
if (rowIndex === 8) {
//谐波和间谐波跨八行两列
return {
rowspan: 8,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 16) {//高频次谐波跨八行两列
if (rowIndex === 16) {
//高频次谐波跨八行两列
return {
rowspan: 4,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 21 || rowIndex === 22) {//电流跨两行两列
if (rowIndex === 21 || rowIndex === 22) {
//电流跨两行两列
return {
rowspan: 2,
colspan: 2,
colspan: 2
}
}
}
if (columnIndex === 1) {
if (rowIndex <= 4 || rowIndex >= 7 && rowIndex <= 22) {
if (rowIndex <= 4 || (rowIndex >= 7 && rowIndex <= 22)) {
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
}
if (columnIndex === 2 || columnIndex === 3) {
if (rowIndex === 2 || rowIndex === 8 || rowIndex === 10 ||
rowIndex === 12 || rowIndex === 14 || rowIndex === 16 ||
rowIndex === 18 || rowIndex === 21) {
if (
rowIndex === 2 ||
rowIndex === 8 ||
rowIndex === 10 ||
rowIndex === 12 ||
rowIndex === 14 ||
rowIndex === 16 ||
rowIndex === 18 ||
rowIndex === 21
) {
return {
rowspan: 2,
colspan: 1,
colspan: 1
}
}
if (rowIndex === 3 || rowIndex === 9 || rowIndex === 11 ||
rowIndex === 13 || rowIndex === 15 || rowIndex === 17 ||
rowIndex === 19 || rowIndex === 22) {
if (
rowIndex === 3 ||
rowIndex === 9 ||
rowIndex === 11 ||
rowIndex === 13 ||
rowIndex === 15 ||
rowIndex === 17 ||
rowIndex === 19 ||
rowIndex === 22
) {
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
}
};
}
const spanSMethod = ({
row,
column,
rowIndex,
columnIndex,
}: SpanMethodProps) => {
const spanSMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0) {
if (rowIndex <= 1 || rowIndex === 8 || rowIndex == 17) {//0电压偏差1频率偏差7闪变20功率简单的跨两列
if (rowIndex <= 1 || rowIndex === 8 || rowIndex == 17) {
//0电压偏差1频率偏差7闪变20功率简单的跨两列
return {
rowspan: 1,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 2) {//2三相不平衡跨三行两列
if (rowIndex === 2) {
//2三相不平衡跨三行两列
return {
rowspan: 3,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 3 || rowIndex === 4 || rowIndex === 6 || rowIndex === 7 ||
rowIndex >= 10 && rowIndex <= 12 ||
rowIndex >= 14 && rowIndex <= 16 ||
rowIndex === 19 || rowIndex === 21 || rowIndex === 22) {//这些行不显示
if (
rowIndex === 3 ||
rowIndex === 4 ||
rowIndex === 6 ||
rowIndex === 7 ||
(rowIndex >= 10 && rowIndex <= 12) ||
(rowIndex >= 14 && rowIndex <= 16) ||
rowIndex === 19 ||
rowIndex === 21 ||
rowIndex === 22
) {
//这些行不显示
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
if (rowIndex === 5 || rowIndex === 20) {//5电压波动23电压暂降暂升中断跨两行
if (rowIndex === 5 || rowIndex === 20) {
//5电压波动23电压暂降暂升中断跨两行
return {
rowspan: 3,
colspan: 1,
colspan: 1
}
}
if (rowIndex === 9 || rowIndex === 13) {//谐波和间谐波跨八行两列
if (rowIndex === 9 || rowIndex === 13) {
//谐波和间谐波跨八行两列
return {
rowspan: 4,
colspan: 2,
colspan: 2
}
}
if (rowIndex === 18) {//电流跨两行两列
if (rowIndex === 18) {
//电流跨两行两列
return {
rowspan: 2,
colspan: 2,
colspan: 2
}
}
}
@@ -215,54 +256,81 @@ const spanSMethod = ({
if (rowIndex === 6 || rowIndex === 21) {
return {
rowspan: 2,
colspan: 1,
colspan: 1
}
}
if (rowIndex <= 4 || rowIndex >= 7 && rowIndex <= 19 || rowIndex === 22) {
if (rowIndex <= 4 || (rowIndex >= 7 && rowIndex <= 19) || rowIndex === 22) {
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
}
if (columnIndex === 2) {
if (rowIndex === 2 || rowIndex === 6 || rowIndex === 9 ||
rowIndex === 11 || rowIndex === 13 || rowIndex === 15 ||
rowIndex === 18 || rowIndex === 21) {
if (
rowIndex === 2 ||
rowIndex === 6 ||
rowIndex === 9 ||
rowIndex === 11 ||
rowIndex === 13 ||
rowIndex === 15 ||
rowIndex === 18 ||
rowIndex === 21
) {
return {
rowspan: 2,
colspan: 1,
colspan: 1
}
}
if (rowIndex === 3 || rowIndex === 7 ||
rowIndex === 10 || rowIndex === 12 ||
rowIndex === 14 || rowIndex === 16 ||
rowIndex === 19 || rowIndex === 22) {
if (
rowIndex === 3 ||
rowIndex === 7 ||
rowIndex === 10 ||
rowIndex === 12 ||
rowIndex === 14 ||
rowIndex === 16 ||
rowIndex === 19 ||
rowIndex === 22
) {
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
}
if (columnIndex === 3) {
if (rowIndex === 2 || rowIndex === 6 || rowIndex === 9 ||
rowIndex === 11 || rowIndex === 13 || rowIndex === 15 ||
rowIndex === 18 || rowIndex === 21) {
if (
rowIndex === 2 ||
rowIndex === 6 ||
rowIndex === 9 ||
rowIndex === 11 ||
rowIndex === 13 ||
rowIndex === 15 ||
rowIndex === 18 ||
rowIndex === 21
) {
return {
rowspan: 2,
colspan: 1,
colspan: 1
}
}
if (rowIndex === 3 || rowIndex === 7 || rowIndex === 10 ||
rowIndex === 12 || rowIndex === 14 || rowIndex === 16 ||
rowIndex === 19 || rowIndex === 22) {
if (
rowIndex === 3 ||
rowIndex === 7 ||
rowIndex === 10 ||
rowIndex === 12 ||
rowIndex === 14 ||
rowIndex === 16 ||
rowIndex === 19 ||
rowIndex === 22
) {
return {
rowspan: 0,
colspan: 0,
colspan: 0
}
}
}
};
}
// 关闭弹窗
const close = () => {
@@ -275,22 +343,21 @@ const open = async (sign: string, data: ErrorSystem.ErrorSystemList) => {
dialogVisible.value = true
if (data.id) {
formContent.value = data as ErrorSystem.ErrorSystemList;
devLevelName.value = dictStore.getDictData('Dev_Level').find(item => item.id === data.devLevel)?.name || '';
formContent.value = data as ErrorSystem.ErrorSystemList
devLevelName.value = dictStore.getDictData('Dev_Level').find(item => item.id === data.devLevel)?.name || ''
if (devLevelName.value === 'A级' || data.devLevel === 'A级') {
errorData.value = errorDataList.errorADetail as unknown as ErrorSystem.Error_detail[];
errorData.value = errorDataList.errorADetail as unknown as ErrorSystem.Error_detail[]
} else {
errorData.value = errorDataList.errorSDetail as unknown as ErrorSystem.Error_detail[];
errorData.value = errorDataList.errorSDetail as unknown as ErrorSystem.Error_detail[]
}
}
}
// 对外映射
defineExpose({open})
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
refreshTable: (() => Promise<void>) | undefined
}>()
</script>
<style>
@@ -313,6 +380,4 @@ const props = defineProps<{
display: block; /* 使每个label标签上下排列 */
margin-bottom: 10px; /* 调整两个label之间的间距 */
}
</style>

View File

@@ -1,35 +1,43 @@
<template>
<div class="dialog-footer">
<el-button :icon='CirclePlus' type="primary" @click="openAddDialog">新增</el-button>
<el-button :icon='Delete' type="danger" plain :disabled='!multipleSelection.length' @click="deleteSelectedRows">删除</el-button>
<el-button :icon="CirclePlus" type="primary" @click="openAddDialog">新增</el-button>
<el-button :icon="Delete" type="danger" plain :disabled="!multipleSelection.length" @click="deleteSelectedRows">
删除
</el-button>
</div>
<div class="table-container">
<el-table :data="tableData"
:header-cell-style="{ textAlign: 'center',backgroundColor: 'var(--el-color-primary)',color: '#fff' } "
<el-table
:data="tableData"
:header-cell-style="{ textAlign: 'center', backgroundColor: 'var(--el-color-primary)', color: '#fff' }"
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
:style="{ height: '400px',maxHeight: '400px',overflow:'hidden'}"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"/>
<el-table-column prop="sort" label="序号" width="60"/>
:style="{ height: '400px', maxHeight: '400px', overflow: 'hidden' }"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="sort" label="序号" width="60" />
<el-table-column prop="type" label="误差类型" min-width="180">
<template #default="{ row }">
<el-cascader style="min-width: 180px;"
<el-cascader
style="min-width: 180px"
:options="errorOptions"
v-model="row.errorType"
:props="{ checkStrictly: false, emitPath: false }"
placeholder="请选择误差类型"
@change="handleErrorTypeChange($event, row)"/>
@change="handleErrorTypeChange($event, row)"
/>
</template>
</el-table-column>
<el-table-column prop="type" label="脚本类型" min-width="230">
<template #default="{ row }">
<el-cascader style="min-width: 230px;"
<el-cascader
style="min-width: 230px"
:options="scriptOptions"
v-model="row.scriptType"
:props="{ checkStrictly: false, emitPath: false }"
placeholder="请选择脚本类型"
@change="handleScriptTypeChange(row)"/>
@change="handleScriptTypeChange(row)"
/>
</template>
</el-table-column>
<el-table-column label="起止范围">
@@ -37,14 +45,22 @@
<template #default="{ row }">
<el-row type="flex" :gutter="24">
<el-col :span="12">
<el-select v-model="row.startFlag" placeholder="选择起始值" style="width: 70px;" @change="(value) => handleStartFlagChange(row, value)">
<el-select
v-model="row.startFlag"
placeholder="选择起始值"
style="width: 70px"
@change="value => handleStartFlagChange(row, value)"
>
<el-option label="无" :value="2"></el-option>
<el-option label=">=" :value="1"></el-option>
<el-option label=">" :value="0"></el-option>
</el-select>
</el-col>
<el-col :span="12">
<el-input v-model="row.startValue" style="width: 60px;" :disabled="isStartValueDisabled[row.sort]"
<el-input
v-model="row.startValue"
style="width: 60px"
:disabled="isStartValueDisabled[row.sort]"
/>
</el-col>
</el-row>
@@ -54,14 +70,23 @@
<template #default="{ row }">
<el-row type="flex" :gutter="24">
<el-col :span="12">
<el-select v-model="row.endFlag" placeholder="选择结束值" style="width: 70px;" @change="(value) => handleEndFlagChange(row, value)">
<el-select
v-model="row.endFlag"
placeholder="选择结束值"
style="width: 70px"
@change="value => handleEndFlagChange(row, value)"
>
<el-option label="无" :value="2"></el-option>
<el-option label="<=" :value="1"></el-option>
<el-option label="<" :value="0"></el-option>
</el-select>
</el-col>
<el-col :span="12">
<el-input v-model="row.endValue" style="width: 60px;" :disabled="isEndValueDisabled[row.sort]"/>
<el-input
v-model="row.endValue"
style="width: 60px"
:disabled="isEndValueDisabled[row.sort]"
/>
</el-col>
</el-row>
</template>
@@ -82,14 +107,16 @@
<el-table-column label="最大误差">
<el-table-column prop="maxErrorValue" label="最大误差值" width="100">
<template #default="{ row }">
<el-input v-model="row.maxErrorValue" style="width: 70px;"/>
<el-input v-model="row.maxErrorValue" style="width: 70px" />
</template>
</el-table-column>
<el-table-column label="误差类型" width="170">
<template #default="{ row }">
<el-cascader :options="errorValueTypeOptions"
<el-cascader
:options="errorValueTypeOptions"
v-model="row.errorValueType"
@change="handleErrorValueTypeChange(row)"/>
@change="handleErrorValueTypeChange(row)"
/>
</template>
</el-table-column>
<el-table-column label="误差单位" width="100" prop="errorUnit">
@@ -100,8 +127,8 @@
</el-table-column>
<el-table-column label="操作" min-width="150">
<template #default="{ row }">
<el-button type="primary" link :icon='CopyDocument' @click="copyRow(row)">复制</el-button>
<el-button type='primary' link :icon='Delete' @click="deleteRow(row)">删除</el-button>
<el-button type="primary" link :icon="CopyDocument" @click="copyRow(row)">复制</el-button>
<el-button type="primary" link :icon="Delete" @click="deleteRow(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -109,17 +136,17 @@
</template>
<script setup lang="ts">
import {type ErrorSystem} from '@/api/device/interface/error';
import {useDictStore,} from '@/stores/modules/dict'
import {CirclePlus, CopyDocument, Delete} from '@element-plus/icons-vue'
import {type CascaderOption} from 'element-plus';
import {defineEmits, type PropType, reactive, ref, watch} from 'vue';
import { type ErrorSystem } from '@/api/device/interface/error'
import { useDictStore } from '@/stores/modules/dict'
import { CirclePlus, CopyDocument, Delete } from '@element-plus/icons-vue'
import { type CascaderOption } from 'element-plus'
import { type PropType, reactive, ref, watch } from 'vue'
const emit = defineEmits(['updateTableData']);
const emit = defineEmits(['updateTableData'])
const multipleSelection = ref<number[]>([])
const dictStore = useDictStore()
const isStartValueDisabled = ref<{ [key: number]: boolean }>({});
const isEndValueDisabled = ref<{ [key: number]: boolean }>({});
const isStartValueDisabled = ref<{ [key: number]: boolean }>({})
const isEndValueDisabled = ref<{ [key: number]: boolean }>({})
const props = defineProps({
errorOptions: {
type: Array as PropType<CascaderOption[]>,
@@ -135,14 +162,15 @@ const props = defineProps({
type: Array as PropType<ErrorSystem.ErrorSystemDetail[]>,
default: () => []
}
});
})
const errorValueTypeOptions = reactive<{ value: number, label: string, children: { value: number, label: string }[] }[]>([])
const errorValueTypeOptions = reactive<
{ value: number; label: string; children: { value: number; label: string }[] }[]
>([])
const conditionTypes = dictStore.getDictData('Condition_Type')
const errorValueTypes = dictStore.getDictData('Error_Value_Type')
const valueTypes = dictStore.getDictData('Script_Value_Type')
onBeforeMount(() => {
valueTypes.forEach(item1 => {
let children = []
@@ -150,13 +178,12 @@ onBeforeMount(() => {
if (item1.value === '2' && errorValueTypes[i].value === '2') {
continue
}
children.push({label: errorValueTypes[i].name, value: Number(errorValueTypes[i].value)})
children.push({ label: errorValueTypes[i].name, value: Number(errorValueTypes[i].value) })
}
errorValueTypeOptions.push({label: item1.name, value: Number(item1.value), children: children})
errorValueTypeOptions.push({ label: item1.name, value: Number(item1.value), children: children })
})
})
const handleErrorTypeChange = (value: any, row: any) => {
// const matchedRow = findRowById(row.errorType, props.errorOptions);//选中误差id找对应结构中的含chilren的code
// console.log('matchedRow.code',matchedRow.code)
// const code = errSysAndScriptMap.get(matchedRow?.code || '') || ''; // 确保 code 不为 undefined
@@ -188,103 +215,101 @@ const handleErrorValueTypeChange = (row: any) => {
case 1: // 绝对值
row.valueType = 1
row.errorUnit = scriptType.remark
break;
break
case 2: // 相对值
row.valueType = 2
row.errorUnit = "%"
break;
row.errorUnit = '%'
break
default:
break;
break
}
}
}
// 假设 props.errorOptions 是一个数组,每个元素可能包含 children 属性
const findRowById = (id: string, options: any[]): any | null => {
for (const option of options) {
if (option.value === id) {
return option;
return option
}
if (option.children && option.children.length > 0) {
const result = findRowById(id, option.children);
const result = findRowById(id, option.children)
if (result) {
return result;
return result
}
}
}
return null;
};
return null
}
// 假设 props.errorOptions 是一个数组,每个元素可能包含 children 属性
const findRowByCode = (code: string, options: any[]): any | null => {
for (const option of options) {
if (option.code === code) {
return option;
return option
}
if (option.children && option.children.length > 0) {
const result = findRowByCode(code, option.children);
const result = findRowByCode(code, option.children)
if (result) {
return result;
return result
}
}
}
return null;
};
return null
}
// 监听 props.tableData 的变化,确保每次数据变化时都重新设置 sort
watch(() => props.tableData, async (newTableData) => {
watch(
() => props.tableData,
async newTableData => {
for (let i = 0; i < newTableData.length; i++) {
newTableData[i].sort = i + 1;
newTableData[i].sort = i + 1
if (newTableData[i].startFlag === 2) {
newTableData[i].startValue = null; // 设置 startValue 为 null
newTableData[i].startValue = null // 设置 startValue 为 null
}
if (newTableData[i].endFlag === 2) {
newTableData[i].endValue = null; // 设置 endValue 为 null
newTableData[i].endValue = null // 设置 endValue 为 null
}
}
// 重新设置 isStartValueDisabled 和 isEndValueDisabled,并清空输入框
props.tableData.forEach(row => {
isStartValueDisabled.value[row.sort] = row.startFlag === 2;
});
isStartValueDisabled.value[row.sort] = row.startFlag === 2
})
props.tableData.forEach(row => {
isEndValueDisabled.value[row.sort] = row.endFlag === 2;
});
}, {immediate: true});
isEndValueDisabled.value[row.sort] = row.endFlag === 2
})
},
{ immediate: true }
)
// 处理 startFlag 变化的方法
const handleStartFlagChange = (row: ErrorSystem.ErrorSystemDetail, value: number) => {
if (value === 2) {
row.startValue = null; // 清空输入框
isStartValueDisabled.value[row.sort] = true; // 禁用输入框
row.startValue = null // 清空输入框
isStartValueDisabled.value[row.sort] = true // 禁用输入框
} else {
isStartValueDisabled.value[row.sort] = false; // 启用输入框
isStartValueDisabled.value[row.sort] = false // 启用输入框
}
};
}
// 处理 endFlag 变化的方法
const handleEndFlagChange = (row: ErrorSystem.ErrorSystemDetail, value: number) => {
if (value === 2) {
row.endValue = null; // 清空输入框
isEndValueDisabled.value[row.sort] = true; // 禁用输入框
row.endValue = null // 清空输入框
isEndValueDisabled.value[row.sort] = true // 禁用输入框
} else {
isEndValueDisabled.value[row.sort] = false; // 启用输入框
isEndValueDisabled.value[row.sort] = false // 启用输入框
}
};
}
//选中
const handleSelectionChange = (selection: ErrorSystem.ErrorSystemDetail[]) => {
multipleSelection.value = selection.map(row => row.sort); // 更新选中的行
};
multipleSelection.value = selection.map(row => row.sort) // 更新选中的行
}
//新增
const openAddDialog = () => {
// 获取字典数据
const newRow = {
sort: props.tableData.length + 1,
id: '',
@@ -293,41 +318,37 @@ const openAddDialog = () => {
conditionType: conditionTypes.length > 0 ? Number(conditionTypes[0].value) : 0, // 设置默认值为第一个选项的值
valueType: valueTypes.length > 0 ? Number(valueTypes[0].value) : 1,
errorValueType: [errorValueTypeOptions[0].value, errorValueTypeOptions[0].children[0].value],
errorSysId: "",
errorType: "",
scriptType: "",
errorSysId: '',
errorType: '',
scriptType: '',
maxErrorValue: 0
};
}
emit('updateTableData', [...props.tableData, newRow]);
};
emit('updateTableData', [...props.tableData, newRow])
}
const copyRow = (row: ErrorSystem.ErrorSystemDetail) => {
// 深拷贝行数据
const newRow = {...row};
const maxNextId = Math.max(...props.tableData.map(item => item.sort), 0);
newRow.sort = maxNextId + 1;
emit('updateTableData', [...props.tableData, newRow]);
};
const newRow = { ...row }
const maxNextId = Math.max(...props.tableData.map(item => item.sort), 0)
newRow.sort = maxNextId + 1
emit('updateTableData', [...props.tableData, newRow])
}
//删除行
const deleteRow = (row: ErrorSystem.ErrorSystemDetail) => {
const index = props.tableData.indexOf(row);
const index = props.tableData.indexOf(row)
if (index !== -1) {
const newTableData = [...props.tableData];
newTableData.splice(index, 1);
emit('updateTableData', newTableData);
const newTableData = [...props.tableData]
newTableData.splice(index, 1)
emit('updateTableData', newTableData)
}
};
}
//批量删除选中行
const deleteSelectedRows = () => {
const newTableData = props.tableData.filter(row => !multipleSelection.value.includes(row.sort));
multipleSelection.value = []; // 清空已选择的行
emit('updateTableData', newTableData);
};
const newTableData = props.tableData.filter(row => !multipleSelection.value.includes(row.sort))
multipleSelection.value = [] // 清空已选择的行
emit('updateTableData', newTableData)
}
</script>
<style scoped>
@@ -338,7 +359,8 @@ const deleteSelectedRows = () => {
margin-top: 10px;
}
.el-table th, .el-table td {
.el-table th,
.el-table td {
text-align: center; /* 所有单元格文字居中 */
}

View File

@@ -1,30 +1,49 @@
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" width="1660px" align-center>
<el-dialog
:title="dialogTitle"
v-model="dialogVisible"
@close="close"
v-bind="dialogBig"
width="1660px"
align-center
>
<el-tabs type="border-card">
<el-tab-pane label="基础信息">
<div>
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' label-width="auto" class="form-four">
<el-form-item label="标准号" prop="standardName" >
<el-input v-model='formContent.standardName' placeholder="请填写标准号" maxlength="32" show-word-limit/>
<el-form
:model="formContent"
ref="dialogFormRef"
:rules="rules"
label-width="auto"
class="form-four"
>
<el-form-item label="标准号" prop="standardName">
<el-input
v-model="formContent.standardName"
placeholder="请填写标准号"
maxlength="32"
show-word-limit
/>
</el-form-item>
<el-form-item label="标准推行年份" prop="standardTime" >
<el-form-item label="标准推行年份" prop="standardTime">
<el-date-picker
v-model="formContent.standardTime"
type="year"
placeholder="请选择标准推行年份"
/>
</el-form-item>
<el-form-item label="适用设备等级" prop="devLevel" >
<el-select v-model='formContent.devLevel' placeholder="请选择设备等级">
<el-form-item label="适用设备等级" prop="devLevel">
<el-select v-model="formContent.devLevel" placeholder="请选择设备等级">
<el-option
v-for="item in dictStore.getDictData('Dev_Level')"
:key="item.id"
:label="item.name"
:value="item.id"/>
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="enable" >
<el-select v-model='formContent.enable' placeholder="请选择状态">
<el-form-item label="状态" prop="enable">
<el-select v-model="formContent.enable" placeholder="请选择状态">
<el-option label="启用" :value="1"></el-option>
<el-option label="停用" :value="0"></el-option>
</el-select>
@@ -34,43 +53,44 @@
</el-tab-pane>
</el-tabs>
<ErrorSystemDetailTable :tableData="tableData" :errorOptions="errorOptions" :scriptOptions="scriptOptions" @updateTableData="handleTableDataUpdate" />
<ErrorSystemDetailTable
:tableData="tableData"
:errorOptions="errorOptions"
:scriptOptions="scriptOptions"
@updateTableData="handleTableDataUpdate"
/>
<template #footer>
<div >
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>保存</el-button>
<div>
<el-button @click="close()"> </el-button>
<el-button type="primary" @click="save()">保存</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup name="ErrorSystemDialog">
import{type CascaderOption, ElMessage, type FormInstance,type FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, type Ref, computed } from 'vue';
import { dialogBig} from '@/utils/elementBind'
import { addPqErrSys,updatePqErrSys,getPqErrSysListById} from '@/api/device/error/index'
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
import { type ErrorSystem } from '@/api/device/interface/error';
import ErrorSystemDetailTable from '@/views/machine/errorSystem/components/errorSystemDetailTable.vue';
import {getDictTreeByCode} from '@/api/system/dictionary/dictTree'
import { type Dict } from '@/api/system/dictionary/interface';
// 定义弹出组件元信息
const dialogFormRef = ref()
const dictStore = useDictStore()
const tableData = ref<ErrorSystem.ErrorSystemDetail[]>([]);
const errorOptions: Ref<CascaderOption[]> = ref([]); // 修改这里
const scriptOptions: Ref<CascaderOption[]> = ref([]); // 修改这里
<script lang="ts" setup name="ErrorSystemDialog">
import { type CascaderOption, ElMessage, type FormItemRule } from 'element-plus'
import { computed, type Ref, ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
import { addPqErrSys, getPqErrSysListById, updatePqErrSys } from '@/api/device/error/index'
import { useDictStore } from '@/stores/modules/dict'
import { type ErrorSystem } from '@/api/device/interface/error'
import ErrorSystemDetailTable from '@/views/machine/errorSystem/components/errorSystemDetailTable.vue'
import { getDictTreeByCode } from '@/api/system/dictionary/dictTree'
import { type Dict } from '@/api/system/dictionary/interface'
// 定义弹出组件元信息
const dialogFormRef = ref()
const dictStore = useDictStore()
const tableData = ref<ErrorSystem.ErrorSystemDetail[]>([])
const errorOptions: Ref<CascaderOption[]> = ref([]) // 修改这里
const scriptOptions: Ref<CascaderOption[]> = ref([]) // 修改这里
const handleTableDataUpdate = (newTableData: ErrorSystem.ErrorSystemDetail[]) => {
tableData.value = newTableData;
};
tableData.value = newTableData
}
function useMetaInfo() {
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = ref<ErrorSystem.ErrorSystemList>({
@@ -80,15 +100,15 @@ const handleTableDataUpdate = (newTableData: ErrorSystem.ErrorSystemDetail[]) =>
standardTime: '',
devLevel: '',
enable: 1,
state:1,
pqErrSysDtlsList:[]
state: 1,
pqErrSysDtlsList: []
})
return { dialogVisible, titleType, formContent }
}
}
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
formContent.value = {
id: '',
name: '',
@@ -96,71 +116,69 @@ const handleTableDataUpdate = (newTableData: ErrorSystem.ErrorSystemDetail[]) =>
standardTime: '',
devLevel: '',
enable: 1,
state:1,
pqErrSysDtlsList:[]
}
tableData.value =[]
state: 1,
pqErrSysDtlsList: []
}
tableData.value = []
}
let dialogTitle = computed(() => {
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增误差体系' : '编辑误差体系'
})
})
// 定义规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
// 定义规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
name: [{ required: true, message: '误差体系名称必填!', trigger: 'blur' }],
standardName: [{ required: true, message: '参照标准名称必填!', trigger: 'blur' }],
standardTime: [{ required: true, message: '标准推行年份必选!', trigger: 'blur' }],
devLevel:[{ required: true, message: '请选择一项设备等级', trigger: 'change' },],
enable:[{ required: true, message: '请选择一项状态', trigger: 'change '},]
});
devLevel: [{ required: true, message: '请选择一项设备等级', trigger: 'change' }],
enable: [{ required: true, message: '请选择一项状态', trigger: 'change ' }]
})
// 关闭弹窗
const close = () => {
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
}
}
// 保存数据
const save = () => {
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 确保 standardTime 是 Date 对象
if (formContent.value.standardTime) {
const date = new Date(formContent.value.standardTime);
formContent.value.standardTime = date.getFullYear().toString();
const date = new Date(formContent.value.standardTime)
formContent.value.standardTime = date.getFullYear().toString()
}
formContent.value.pqErrSysDtlsList = tableData.value
formContent.value.pqErrSysDtlsList.forEach((item) => {
item.errorValueType=item.errorValueType[1]
formContent.value.pqErrSysDtlsList.forEach(item => {
item.errorValueType = item.errorValueType[1]
})
if (formContent.value.id) {
await updatePqErrSys(formContent.value);
await updatePqErrSys(formContent.value)
ElMessage.success({ message: `${dialogTitle.value}成功!` })
} else {
await addPqErrSys(formContent.value);
await addPqErrSys(formContent.value)
ElMessage.success({ message: `${dialogTitle.value}成功!` })
}
close()
// 刷新表格
await props.refreshTable!()
}
})
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
// 封装提取第二层节点的逻辑
}
// 封装提取第二层节点的逻辑
const loadSecondLevelOptions = async () => {
const dictCode = 'Err_Sys_Items'; // 替换为实际需要的字典代码
const dictCode2 = 'Script_Error'; // 替换为实际需要的字典代码
const dictCode = 'Err_Sys_Items' // 替换为实际需要的字典代码
const dictCode2 = 'Script_Error' // 替换为实际需要的字典代码
const resDictTree: Dict.ResDictTree = {
name: '',
@@ -169,7 +187,7 @@ const loadSecondLevelOptions = async () => {
pids: '',
code: dictCode,
sort: 0
};
}
const resDictTree2: Dict.ResDictTree = {
name: '',
@@ -178,82 +196,74 @@ const loadSecondLevelOptions = async () => {
pids: '',
code: dictCode2,
sort: 0
};
}
// 并行请求两个字典树列表
const [result, result2] = await Promise.all([
getDictTreeByCode(resDictTree),
getDictTreeByCode(resDictTree2)
]);
const [result, result2] = await Promise.all([getDictTreeByCode(resDictTree), getDictTreeByCode(resDictTree2)])
const allOptions = convertToOptions(result.data as Dict.ResDictTree[]);
const allOptions2 = convertToOptions(result2.data as Dict.ResDictTree[]);
const allOptions = convertToOptions(result.data as Dict.ResDictTree[])
const allOptions2 = convertToOptions(result2.data as Dict.ResDictTree[])
// 提取第二层节点
const secondLevelOptions: any[] = [];
const secondLevelOptions: any[] = []
allOptions.forEach(option => {
if (option.children && option.children.length > 0) {
secondLevelOptions.push(...option.children);
secondLevelOptions.push(...option.children)
}
});
})
const secondLevelOptions2: any[] = [];
const secondLevelOptions2: any[] = []
allOptions2.forEach(option => {
if (option.children && option.children.length > 0) {
secondLevelOptions2.push(...option.children);
secondLevelOptions2.push(...option.children)
}
});
})
// 将第二层节点赋值给 options.value
errorOptions.value = secondLevelOptions;
scriptOptions.value = secondLevelOptions2;
};
errorOptions.value = secondLevelOptions
scriptOptions.value = secondLevelOptions2
}
// 转换函数
const convertToOptions = (dictTree: Dict.ResDictTree[]): CascaderOption[] => {
// 转换函数
const convertToOptions = (dictTree: Dict.ResDictTree[]): CascaderOption[] => {
return dictTree.map(item => ({
value: item.id,
label: item.name,
code: item.code,
children: item.children ? convertToOptions(item.children) : undefined,
remark: item.remark
}));
};
}))
}
// 打开弹窗,可能是新增,也可能是编辑
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: ErrorSystem.ErrorSystemList) => {
titleType.value = sign;
titleType.value = sign
// 并行执行两个异步操作
const loadOptionsPromise = loadSecondLevelOptions();
const fetchDataPromise = data.id ? getPqErrSysListById(data) : Promise.resolve(null);
const loadOptionsPromise = loadSecondLevelOptions()
const fetchDataPromise = data.id ? getPqErrSysListById(data) : Promise.resolve(null)
const [_, result] = await Promise.all([loadOptionsPromise, fetchDataPromise]);
const [_, result] = await Promise.all([loadOptionsPromise, fetchDataPromise])
if (result && result.data) {
formContent.value = result.data as ErrorSystem.ErrorSystemList;
tableData.value = formContent.value.pqErrSysDtlsList || [];
tableData.value.forEach((item) => {
item.errorValueType=[item.valueType,item.errorValueType]
formContent.value = result.data as ErrorSystem.ErrorSystemList
tableData.value = formContent.value.pqErrSysDtlsList || []
tableData.value.forEach(item => {
item.errorValueType = [item.valueType, item.errorValueType]
})
} else {
resetFormContent();
resetFormContent()
}
// 重置表单
dialogFormRef.value?.resetFields();
dialogVisible.value = true;
};
dialogFormRef.value?.resetFields()
dialogVisible.value = true
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
refreshTable: (() => Promise<void>) | undefined
}>()
</script>
<style>
</style>
<style></style>

View File

@@ -7,7 +7,7 @@
</div>
<div class="data-check-content">
<div class="content-tree" :style="{ height: `calc(100vh - ${props.shrink ? '370px' : '315px'})` }">
<Tree :treeData="treeData" @setTab="setTab" />
<TestScriptTree :treeData="treeData" @setTab="setTab" />
</div>
<div
@@ -19,7 +19,8 @@
<el-tab-pane v-for="tab in tabData" :key="tab.value" :label="tab.label" :name="tab.value">
<div v-if="activeName == tab.value">
<div class="dialog-footer">
<el-switch v-model="value1"
<el-switch
v-model="value1"
inline-prompt
:active-value="1"
:inactive-value="0"
@@ -28,7 +29,7 @@
@change="enableScript"
size="large"
width="80px"
style="margin-right: 10px;"
style="margin-right: 10px"
/>
<el-button :icon="CirclePlus" type="primary" @click="openDialog('add')">新增</el-button>
</div>
@@ -215,20 +216,21 @@
</template>
<script setup lang="ts">
import { type PropType, ref, nextTick } from 'vue'
import Tree from './tree.vue'
import { type PropType, ref } from 'vue'
import TestScriptTree from './testScriptTree.vue'
import Commun from './communication.vue'
import { type CascaderOption, ElMessageBox } from 'element-plus'
import { ElMessageBox } from 'element-plus'
import { getTreeData } from '@/api/check/test'
import { CirclePlus, Delete, Check, CopyDocument, View, EditPen } from '@element-plus/icons-vue'
import { CirclePlus, CopyDocument, Delete, EditPen, View } from '@element-plus/icons-vue'
import type { TestScript } from '@/api/device/interface/testScript'
import TestProjectPopup from '@/views/machine/testScript/components/testProjectPopup.vue'
import { CheckData } from '@/api/check/interface'
import { dlsDetails, deleteDtls, updateDtls, addScriptDtls, checkDataList } from '@/api/device/testScript'
import { addScriptDtls, deleteDtls, dlsDetails, updateDtls } from '@/api/device/testScript'
import { useDictStore } from '@/stores/modules/dict'
import { useHandleData } from '@/hooks/useHandleData'
import { scriptDtlsCheckDataList } from '@/api/device/testScript/index'
import ViewRow from '@/views/machine/testScript/components/viewRow.vue'
interface TabOption {
label?: string
name?: string
@@ -370,8 +372,6 @@ const inquireTable = () => {
value1.value = tableData.value.some(item => item.enable === 1) ? 1 : 0
}
})
}
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<TestScript.ResTestScript> = {}) => {
@@ -466,7 +466,6 @@ const enableRow = async (row: any) => {
})
}
// 启用/禁用脚本的方法
const enableScript = async () => {
const willEnable = value1.value === 1
@@ -496,7 +495,6 @@ const enableScript = async () => {
}
}
// 获取左边树数据
// 新增保存
const addTab = (row: any) => {
@@ -537,7 +535,6 @@ onMounted(() => {
overflow-x: hidden;
}
/* 确保 el-tree 内容可以超出容器宽度 */
.el-tree {
width: fit-content; /* 根据内容自适应宽度 */
@@ -553,7 +550,6 @@ onMounted(() => {
margin-bottom: 10px;
}
.divider-container {
display: flex;
}

View File

@@ -1,6 +1,5 @@
<template>
<el-dialog v-model="dialogVisible" :title="dialogTitle"
v-bind="dialogSmall" @close="close" align-center>
<el-dialog v-model="dialogVisible" :title="dialogTitle" v-bind="dialogSmall" @close="close" align-center>
<div>
<el-form :model="formContent" ref="dialogFormRef" :rules="rules">
<el-form-item label="参数所属" prop="pId" :label-width="100">
@@ -16,36 +15,33 @@
/>
</el-form-item>
<el-form-item label="源参数描述" :label-width="100" prop="desc">
<el-input v-model="formContent.desc" autocomplete="off" maxlength="32" show-word-limit/>
<el-input v-model="formContent.desc" autocomplete="off" maxlength="32" show-word-limit />
</el-form-item>
<el-form-item label="源参数类型" :label-width="100" prop="type">
<el-input v-model="formContent.type" autocomplete="off" maxlength="32" show-word-limit/>
<el-input v-model="formContent.type" autocomplete="off" maxlength="32" show-word-limit />
</el-form-item>
<el-form-item label="源参数值" :label-width="100"
prop="value">
<el-input v-model="formContent.value" autocomplete="off"/>
<el-form-item label="源参数值" :label-width="100" prop="value">
<el-input v-model="formContent.value" autocomplete="off" />
</el-form-item>
<el-form-item label="排序" :label-width="100">
<el-input-number v-model="formContent.sort" :min='1' :max='999'/>
<el-input-number v-model="formContent.sort" :min="1" :max="999" />
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="close()">取消</el-button>
<el-button type="primary" @click="save()">
保存
</el-button>
<el-button type="primary" @click="save()">保存</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {computed, defineEmits, reactive, watch} from 'vue'
import {dialogSmall} from "@/utils/elementBind"
import {TestSource} from "@/api/device/interface/testSource"
import {ElMessage, FormItemRule} from "element-plus"
import { computed, reactive } from 'vue'
import { dialogSmall } from '@/utils/elementBind'
import { type TestSource } from '@/api/device/interface/testSource'
import { type FormItemRule } from 'element-plus'
defineProps<{
tableData: TestSource.ParameterType[]
@@ -56,46 +52,49 @@ const emit = defineEmits(['get-parameter'])
// 计算属性,用于控制显示的 pid
const displayPid = computed({
get: () => {
return formContent.pId === '0' ? '' : formContent.pId;
return formContent.pId === '0' ? '' : formContent.pId
},
set: (value) => {
formContent.pId = value;
set: value => {
formContent.pId = value
}
});
})
// 树形节点配置
const defaultProps = {
children: 'children',
label: 'desc',
value: 'id'
};
}
const dialogFormRef = ref()
const {dialogVisible, titleType, formContent} = useMetaInfo()
const { dialogVisible, titleType, formContent } = useMetaInfo()
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = reactive<TestSource.ParameterType>({
id: "",
type: "",
id: '',
type: '',
value: null,
desc: "",
desc: '',
sort: 100,
pId: "0",
pId: '0'
})
return {dialogVisible, titleType, formContent}
return { dialogVisible, titleType, formContent }
}
const rules: reactive<Record<string, Array<FormItemRule>>> = reactive({
desc: [{required: true, message: '源参数描述必填!', trigger: 'blur'},{min: 1, max: 32, message: '长度为1~32个字符', trigger: 'blur'}],
type: [{required: true, message: '源参数类型必填!', trigger: 'blur'},{min: 1, max: 32, message: '长度为1~32个字符', trigger: 'blur'}],
sort: [{required: true, message: '排序必填!', trigger: 'blur'}]
desc: [
{ required: true, message: '源参数描述必填!', trigger: 'blur' },
{ min: 1, max: 32, message: '长度为1~32个字符', trigger: 'blur' }
],
type: [
{ required: true, message: '源参数类型必填!', trigger: 'blur' },
{ min: 1, max: 32, message: '长度为1~32个字符', trigger: 'blur' }
],
sort: [{ required: true, message: '排序必填!', trigger: 'blur' }]
})
// watch(() => formContent.pId, (newVal, oldVal) => {
@@ -113,12 +112,12 @@ let dialogTitle = computed(() => {
const resetFormContent = () => {
Object.assign(formContent, {
id: "",
type: "",
id: '',
type: '',
value: null,
desc: "",
desc: '',
sort: 100,
pId: "0",
pId: '0'
})
}
const open = (sign: string, data: TestSource.ParameterType) => {
@@ -137,7 +136,7 @@ const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
let newUpdateParameter = toRaw({...formContent})
let newUpdateParameter = toRaw({ ...formContent })
delete newUpdateParameter.children
emit('get-parameter', newUpdateParameter)
close()
@@ -153,9 +152,7 @@ const close = () => {
dialogFormRef.value?.resetFields()
}
defineExpose({open})
defineExpose({ open })
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -1,76 +1,97 @@
<template>
<div class='table-box' >
<div class="table-box">
<ProTable
ref='proTable'
:columns='columns'
ref="proTable"
:columns="columns"
:pagination="false"
:toolButton="false"
:data="tableData"
row-key="id"
:style="{ height: '250px',maxHeight: '400px',overflow:'hidden'}"
:style="{ height: '250px', maxHeight: '400px', overflow: 'hidden' }"
:expand-row-keys="defaultExpandRowKeys"
>
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button :disabled="isDisable" v-auth.testSource="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增
<template #tableHeader="scope">
<el-button
:disabled="isDisable"
v-auth.testSource="'add'"
type="primary"
:icon="CirclePlus"
@click="openDialog('add')"
>
新增
</el-button>
<el-button v-auth.testSource="'delete'" type='danger' :icon='Delete'
plain :disabled='isDisable || !scope.isSelected' @click='batchDelete(scope.selectedListIds)'>
<el-button
v-auth.testSource="'delete'"
type="danger"
:icon="Delete"
plain
:disabled="isDisable || !scope.isSelected"
@click="batchDelete(scope.selectedListIds)"
>
删除
</el-button>
</template>
<!-- 表格操作 -->
<template #operation='scope'>
<template #operation="scope">
<!-- <el-button type="primary" link :icon='CopyDocument' @click="copyRow(scope.row)">复制</el-button> -->
<el-button :disabled="isDisable" type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button :disabled="isDisable" type='primary' link :icon='Delete' @click='handleDelete(scope.row.id)'>删除</el-button>
<el-button
:disabled="isDisable"
type="primary"
link
:icon="EditPen"
@click="openDialog('edit', scope.row)"
>
编辑
</el-button>
<el-button :disabled="isDisable" type="primary" link :icon="Delete" @click="handleDelete(scope.row.id)">
删除
</el-button>
</template>
</ProTable>
</div>
<ParameterPopup @getParameter="getParameter" ref='parameterPopup' :tableData="tableData"/>
<ParameterPopup @getParameter="getParameter" ref="parameterPopup" :tableData="tableData" />
</template>
<script setup lang='tsx' name='useRole'>
import {type TestSource} from '@/api/device/interface/testSource'
<script setup lang="tsx" name="useRole">
import { type TestSource } from '@/api/device/interface/testSource'
import ProTable from '@/components/ProTable/index.vue'
import type {ColumnProps, ProTableInstance} from '@/components/ProTable/interface'
import {CirclePlus, CopyDocument, Delete, EditPen} from '@element-plus/icons-vue'
import {useDictStore} from '@/stores/modules/dict'
import ParameterPopup from '@/views/machine/testSource/components/parameterPopup.vue';
import {reactive, ref, watch} from 'vue'
import {generateUUID} from "@/styles";
import {defineEmits} from "vue/dist/vue";
import type { ColumnProps, ProTableInstance } from '@/components/ProTable/interface'
import { CirclePlus, Delete, EditPen } from '@element-plus/icons-vue'
import ParameterPopup from '@/views/machine/testSource/components/parameterPopup.vue'
import { reactive, ref, watch } from 'vue'
import { generateUUID } from '@/styles'
import { ElMessage, ElMessageBox } from 'element-plus'
const parameterPopup = ref()
const dictStore = useDictStore()
const btnDelete = ref(false)
// ProTable 实例
const proTable = ref<ProTableInstance>()
const tableData = ref<any[]>([])
const props = defineProps({
const props = defineProps({
parameterStr: {
type: String,
required: true,
required: true
},
isDisable: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['change-parameter'])
let originalParameterArr=reactive<TestSource.ParameterType[]>([])
watch(() => props.parameterStr, (newData) => {
if (newData) {
getTableList()
default: false
}
})
const defaultExpandRowKeys =computed(() => {
const emit = defineEmits(['change-parameter'])
let originalParameterArr = reactive<TestSource.ParameterType[]>([])
watch(
() => props.parameterStr,
newData => {
if (newData) {
getTableList()
}
}
)
const defaultExpandRowKeys = computed(() => {
return getDefaultKeyArray(tableData.value)
})
@@ -81,7 +102,7 @@ const getDefaultKeyArray = (data: any[]) => {
const firstElement = data[0]
let result: any[] = []
recursion(firstElement,result)
recursion(firstElement, result)
return result
}
@@ -98,24 +119,23 @@ const getTableList = () => {
originalParameterArr = JSON.parse(props.parameterStr)
tableData.value = getTreeData(originalParameterArr)
}
};
}
const getTreeData = (data: TestSource.ParameterType[]): TestSource.ParameterType[] => {
const result: TestSource.ParameterType[] = []// 最终返回的树形结构数据
const result: TestSource.ParameterType[] = [] // 最终返回的树形结构数据
//不能修改原数组,所以需要深拷贝
const copyData = JSON.parse(JSON.stringify(data))
const map = new Map<string, TestSource.ParameterType>();
const map = new Map<string, TestSource.ParameterType>()
copyData.forEach(item => {
map.set(item.id, item)
});
})
for (const item of copyData) {
let parent = map.get(item.pId);
let parent = map.get(item.pId)
if (parent) {
if (!parent.children) {
parent.children = [];
parent.children = []
}
parent.children.push(item);
parent.children.push(item)
parent.children.sort((a, b) => {
if (a.sort && b.sort) {
return a.sort - b.sort
@@ -138,104 +158,106 @@ const getTreeData = (data: TestSource.ParameterType[]): TestSource.ParameterType
}
const columns = reactive<ColumnProps<any>[]>([
{type: 'selection', fixed: 'left', width: 70,
{
type: 'selection',
fixed: 'left',
width: 70,
selectable(row, index) {
if (props.isDisable) {
return false;
return false
}
return true
}
return true;
},
},
{type: 'index', fixed: 'left', width: 70, label: '序号'},
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'type',
label: '参数类型',
minWidth: 180,
align: 'left',
headerAlign:'center'
headerAlign: 'center'
},
{
prop: 'desc',
label: '参数描述',
minWidth: 220,
minWidth: 220
},
{
prop: 'value',
label: '值',
minWidth: 150,
minWidth: 150
},
{prop: 'operation', label: '操作', fixed: 'right', width: 250},
{ prop: 'operation', label: '操作', fixed: 'right', width: 250 }
])
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<TestSource.ParameterType> = {}) => {
parameterPopup.value?.open(titleType, row)
}
// 批量删除源参数
const batchDelete = async (ids: string[]) => {
ElMessageBox.confirm(`是否批量删除检测源?`, "温馨提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
ElMessageBox.confirm(`是否批量删除检测源?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
draggable: true
}).then(async () => {
let parentIds = originalParameterArr.map(item => item.pId);
let parentIds = originalParameterArr.map(item => item.pId)
if (parentIds.some(item => ids.includes(item))) {
ElMessage.error('不能删除父节点');
return;
ElMessage.error('不能删除父节点')
return
}
// 直接过滤掉需要删除的项
originalParameterArr = originalParameterArr.filter(item => !ids.includes(item.id));
emit('change-parameter', originalParameterArr);
tableData.value = getTreeData(originalParameterArr);
originalParameterArr = originalParameterArr.filter(item => !ids.includes(item.id))
emit('change-parameter', originalParameterArr)
tableData.value = getTreeData(originalParameterArr)
ElMessage({
type: "success",
type: 'success',
message: `批量删除检测源成功!`
});
});
})
})
}
// 删除源参数
const handleDelete = (id: string) => {
ElMessageBox.confirm(`是否删除检测源?`, "温馨提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
ElMessageBox.confirm(`是否删除检测源?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
draggable: true
}).then(async () => {
let parentIds = originalParameterArr.map(item => item.pId);
let parentIds = originalParameterArr.map(item => item.pId)
if (parentIds.includes(id)) {
ElMessage.error('不能删除父节点');
return;
ElMessage.error('不能删除父节点')
return
}
originalParameterArr = originalParameterArr.filter(item => item.id !== id);
emit('change-parameter', originalParameterArr);
tableData.value = getTreeData(originalParameterArr);
originalParameterArr = originalParameterArr.filter(item => item.id !== id)
emit('change-parameter', originalParameterArr)
tableData.value = getTreeData(originalParameterArr)
ElMessage({
type: "success",
type: 'success',
message: `删除检测源成功!`
});
});
})
})
}
// 复制源参数
const copyRow = (row) => {
const copyRow = row => {
delete row.children
let parentIds = originalParameterArr.map(item => item.pId)
if (parentIds.includes(row.id)) {
let newParameterId = generateUUID().replaceAll("-","")
let children = originalParameterArr.filter(item => item.pId == row.id).map(item => ({
let newParameterId = generateUUID().replaceAll('-', '')
let children = originalParameterArr
.filter(item => item.pId == row.id)
.map(item => ({
...item,
id: generateUUID().replaceAll("-",""),
id: generateUUID().replaceAll('-', ''),
pId: newParameterId
}))
originalParameterArr.push({...row, id: newParameterId})
originalParameterArr.push({ ...row, id: newParameterId })
originalParameterArr.push(...children)
} else {
originalParameterArr.push({...row, id: generateUUID().replaceAll("-",""), pId: row.pId})
originalParameterArr.push({ ...row, id: generateUUID().replaceAll('-', ''), pId: row.pId })
}
emit('change-parameter', originalParameterArr)
tableData.value = getTreeData(originalParameterArr)
@@ -248,16 +270,15 @@ const getParameter = (data: TestSource.ParameterType) => {
// }
let index = originalParameterArr.findIndex(item => item.id === data.id)
if (index === -1) {
data.id = generateUUID().replaceAll("-","")
data.id = generateUUID().replaceAll('-', '')
// 新增
originalParameterArr.push(data)
ElMessage.success({message: '新增成功!'})
ElMessage.success({ message: '新增成功!' })
} else {
// 编辑
originalParameterArr[index] = data
ElMessage.success({message: '编辑成功!'})
ElMessage.success({ message: '编辑成功!' })
}
emit('change-parameter', originalParameterArr)
tableData.value = getTreeData(originalParameterArr)
@@ -274,7 +295,4 @@ defineExpose({
})
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -1,9 +1,16 @@
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" align-center>
<div >
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' :disabled="tableIsDisable" label-width="auto" class="form-three">
<el-form-item label="设备类型" prop="devType" >
<el-select v-model='formContent.devType' placeholder="请选择源型号">
<el-dialog :title="dialogTitle" v-model="dialogVisible" @close="close" v-bind="dialogBig" align-center>
<div>
<el-form
:model="formContent"
ref="dialogFormRef"
:rules="rules"
:disabled="tableIsDisable"
label-width="auto"
class="form-three"
>
<el-form-item label="设备类型" prop="devType">
<el-select v-model="formContent.devType" placeholder="请选择源型号">
<el-option
v-for="item in dictStore.getDictData(dictTypeCode)"
:key="item.id"
@@ -12,8 +19,8 @@
/>
</el-select>
</el-form-item>
<el-form-item label="检测源类型" prop="type" >
<el-select v-model='formContent.type' placeholder="请选择检测源类型">
<el-form-item label="检测源类型" prop="type">
<el-select v-model="formContent.type" placeholder="请选择检测源类型">
<el-option
v-for="item in dictStore.getDictData('Pq_Source_Type')"
:key="item.id"
@@ -25,25 +32,28 @@
</el-form>
</div>
<ParameterTable :parameterStr="formContent.parameter" @change-parameter="changeParameter" ref="parameterTable" :is-disable="tableIsDisable"/>
<ParameterTable
:parameterStr="formContent.parameter"
@change-parameter="changeParameter"
ref="parameterTable"
:is-disable="tableIsDisable"
/>
<template #footer>
<div>
<el-button :disabled="tableIsDisable" @click='close()'> </el-button>
<el-button :disabled="tableIsDisable" type="primary" @click='save()'>保存</el-button>
<el-button :disabled="tableIsDisable" @click="close()"> </el-button>
<el-button :disabled="tableIsDisable" type="primary" @click="save()">保存</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup name="ErrorSystemDialog">
import {ElMessage, type FormItemRule} from 'element-plus'
import {computed, defineProps, Ref, ref} from 'vue';
import {dialogBig} from '@/utils/elementBind'
import {addTestSource, getTestSourceById, updateTestSource} from '@/api/device/testSource/index'
import {useDictStore} from '@/stores/modules/dict'
import {type TestSource} from '@/api/device/interface/testSource';
import { ElMessage, type FormItemRule } from 'element-plus'
import { computed, Ref, ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
import { addTestSource, getTestSourceById, updateTestSource } from '@/api/device/testSource/index'
import { useDictStore } from '@/stores/modules/dict'
import { type TestSource } from '@/api/device/interface/testSource'
// 定义弹出组件元信息
const dialogFormRef = ref()
const dictStore = useDictStore()
@@ -61,12 +71,12 @@ function useMetaInfo() {
parameter: '',
type: '',
devType: '',
state: 1,
state: 1
})
return {dialogVisible, titleType, formContent}
return { dialogVisible, titleType, formContent }
}
const {dialogVisible, titleType, formContent} = useMetaInfo()
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
formContent.value = {
@@ -75,7 +85,7 @@ const resetFormContent = () => {
parameter: '',
type: '',
devType: '',
state: 1,
state: 1
}
}
@@ -83,28 +93,27 @@ let dialogTitle = computed(() => {
switch (titleType.value) {
case 'add':
tableIsDisable.value = false
return '新增检测源';
return '新增检测源'
case 'edit':
tableIsDisable.value = false
return '编辑检测源';
return '编辑检测源'
case 'view':
tableIsDisable.value = true
return '查看检测源';
return '查看检测源'
default:
return ''; // 默认情况,可选
return '' // 默认情况,可选
}
});
})
let dictTypeCode = computed(() => {
return 'S_Dev_Type_' + dictStore.getDictData('Pattern').find(item => item.id === modeId.value)?.code
})
// 定义规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
name: [{required: true, message: '检测源名称必填!', trigger: 'blur'}],
devType: [{required: true, message: '请选择一项设备类型', trigger: 'change'},],
type: [{required: true, message: '请选择一项检测源类型', trigger: 'change '},]
});
name: [{ required: true, message: '检测源名称必填!', trigger: 'blur' }],
devType: [{ required: true, message: '请选择一项设备类型', trigger: 'change' }],
type: [{ required: true, message: '请选择一项检测源类型', trigger: 'change ' }]
})
// 关闭弹窗
const close = () => {
@@ -120,14 +129,13 @@ const close = () => {
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (formContent.value.id) {
await updateTestSource(formContent.value);
ElMessage.success({message: `${dialogTitle.value}成功!`})
await updateTestSource(formContent.value)
ElMessage.success({ message: `${dialogTitle.value}成功!` })
} else {
await addTestSource(formContent.value);
ElMessage.success({message: `${dialogTitle.value}成功!`})
await addTestSource(formContent.value)
ElMessage.success({ message: `${dialogTitle.value}成功!` })
}
close()
// 刷新表格
@@ -144,11 +152,11 @@ const open = async (sign: string, data: TestSource.ResTestSource, currentMode: s
titleType.value = sign
dialogVisible.value = true
mode.value = currentMode
modeId.value = dictStore.getDictData('Pattern').find(item => item.name === currentMode)?.id;
modeId.value = dictStore.getDictData('Pattern').find(item => item.name === currentMode)?.id
if (data.id) {
const result = await getTestSourceById(data);
const result = await getTestSourceById(data)
if (result && result.data) {
formContent.value = result.data as TestSource.ResTestSource;
formContent.value = result.data as TestSource.ResTestSource
}
} else {
resetFormContent()
@@ -157,18 +165,14 @@ const open = async (sign: string, data: TestSource.ResTestSource, currentMode: s
dialogFormRef.value?.resetFields()
}
const changeParameter = (parameterArr: any) => {
formContent.value.parameter = JSON.stringify(parameterArr)
}
// 对外映射
defineExpose({open})
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
refreshTable: (() => Promise<void>) | undefined
}>()
</script>
<style>
</style>
<style></style>

View File

@@ -0,0 +1,527 @@
<template>
<div class="table_info">
<ProTable
ref="proTable"
:columns="columns"
:request-api="getTableList"
:init-param="initParam"
:data-callback="dataCallback"
@drag-sort="sortTable"
:height="tableHeight"
:stripe="true"
>
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<el-form :model="form" label-width="80px" :inline="true">
<el-form-item label="检测状态" v-if="form.activeTabs != 5">
<el-select v-model="form.checkStatus">
<el-option
v-for="(item, index) in checkStatusList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="报告状态" v-if="form.activeTabs != 5">
<el-select v-model="form.checkReportStatus">
<el-option
v-for="(item, index) in checkReportStatusList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="检测结果" v-if="form.activeTabs != 5">
<el-select v-model="form.checkResult">
<el-option
v-for="(item, index) in checkResultList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="绑定状态" v-if="form.activeTabs == 5">
<el-select v-model="form.deviceBindStatus">
<el-option
v-for="(item, index) in deviceBindStatusList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="设备类型" v-if="form.activeTabs == 5">
<el-select v-model="form.deviceType">
<el-option
v-for="(item, index) in deviceTypeList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="制造厂商" v-if="form.activeTabs == 5">
<el-select v-model="form.manufacturer">
<el-option
v-for="(item, index) in manufacturerList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
<el-button type="primary" @click="handleTest" v-if="form.activeTabs === 0">
启动自动检测
</el-button>
<el-button type="primary" @click="handleTest" v-if="form.activeTabs === 1">
启动手动检测
</el-button>
<el-button type="primary" v-if="form.activeTabs === 2">报告生成</el-button>
<el-button type="primary" v-if="form.activeTabs === 5">设备导入</el-button>
</el-form-item>
</el-form>
</template>
<!-- 表格操作 -->
<!-- <template #operation="scope">
<el-button
dictType="primary"
link
:icon="View"
@click="openDrawer('查看', scope.row)"
>查看</el-button
>
<el-button
dictType="primary"
link
:icon="EditPen"
@click="openDrawer('编辑', scope.row)"
>导出</el-button
>
<el-button
dictType="primary"
link
:icon="Delete"
@click="deleteAccount(scope.row)"
>删除</el-button
>
</template> -->
</ProTable>
</div>
</template>
<script setup lang="tsx" name="useProTable">
import { onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { User } from '@/api/interface'
import { useHandleData } from '@/hooks/useHandleData'
import { ElMessage } from 'element-plus'
import ProTable from '@/components/ProTable/index.vue'
import { Search } from '@element-plus/icons-vue'
import { getPlanList } from '@/api/plan/planList'
const router = useRouter()
const value1 = ref('')
const value2 = ref('')
const tableHeight = ref(0)
console.log(window.innerHeight, '+++++++++')
tableHeight.value = window.innerHeight - 630
//下拉框数据
//检测状态数据
const checkStatusList = [
{
label: '未检',
value: 0
},
{
label: '检测中',
value: 1
},
{
label: '检测完成',
value: 2
},
{
label: '归档',
value: 3
}
]
//检测报告状态数据
const checkReportStatusList = [
{
label: '未生成报告',
value: 0
},
{
label: '已生成报告',
value: 1
}
]
//检测结果数组
const checkResultList = [
{
label: '/',
value: null
},
{
label: '不合格',
value: 0
},
{
label: '合格',
value: 1
}
]
//绑定状态数组
const deviceBindStatusList = [
{
label: '未绑定',
value: 0
},
{
label: '已绑定',
value: 1
}
]
//设备类型数组
const deviceTypeList = [
{
label: 'PQS882A',
value: 0
},
{
label: 'PQS882B4',
value: 1
},
{
label: 'PQS882B5',
value: 2
},
{
label: 'PQS882B6',
value: 3
},
{
label: 'PQS882B7',
value: 4
},
{
label: 'PQS882B8',
value: 5
}
]
//制造厂商数组
const manufacturerList = [
{
label: '南京灿能电力',
value: 0
},
{
label: '南瑞继保',
value: 1
},
{
label: '中电',
value: 2
}
]
//查询条件
const form: any = ref({
activeTabs: 0, //功能选择
checkStatus: 0, //检测状态
checkReportStatus: 0, //检测报告状态
checkResult: 0, //检测结果
deviceBindStatus: 0, //绑定状态
deviceType: 0, //设备类型
manufacturer: 0 //制造厂商
})
const searchForm = ref({
intervalType: 0,
time: ['2024-08-20', '2024-08-27'],
searchBeginTime: '',
searchEndTime: '',
checkStatus: 0,
checkReportStatus: 0,
checkResult: 0
})
// ProTable 实例
const proTable = ref<ProTableInstance>()
// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
const initParam = reactive({ type: 1, pageNum: 1, pageSize: 10 })
// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
const tableList = ref([])
const dataCallback = (data: any) => {
return {
list: data || data.data || data.list,
total: data.length || data.total //total
}
}
// 如果你想在请求之前对当前请求参数做一些操作可以自定义如下函数params 为当前所有的请求参数(包括分页),最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
const getTableList = (params: any) => {
let newParams = JSON.parse(JSON.stringify(params))
newParams.createTime && (newParams.startTime = newParams.createTime[0])
newParams.createTime && (newParams.endTime = newParams.createTime[1])
delete newParams.createTime
return getPlanList(newParams)
}
// 表格配置项
const columns = reactive<ColumnProps<User.ResUserList>[]>([
{ type: 'selection', fixed: 'left', width: 70 },
{
prop: 'checkMode',
label: '设备序列号',
width: 140,
render: scope => {
return scope.row.checkMode == 0
? '设备1'
: scope.row.checkMode == 1
? '设备2'
: scope.row.checkMode == 2
? '设备3'
: scope.row.checkMode
}
},
{
prop: 'checkMode',
label: '设备类型',
width: 140,
render: scope => {
return scope.row.checkMode == 0
? 'PQS991'
: scope.row.checkMode == 1
? 'PQS882'
: scope.row.checkMode == 2
? 'PQS6666'
: scope.row.checkMode
}
},
{
prop: 'checkFrom',
label: '制造厂商',
width: 140,
render: scope => {
return scope.row.checkFrom == 0
? '南京灿能'
: scope.row.checkFrom == 1
? '南瑞继保'
: scope.row.checkFrom == 2
? '/'
: scope.row.checkFrom
}
},
{
prop: 'numberFromName',
label: 'MAC/IP',
render: scope => {
return scope.row.numberFromName == 0
? '192.168.0.1'
: scope.row.numberFromName == 1
? '192.168.0.2'
: scope.row.numberFromName == 2
? '192.168.0.3'
: scope.row.numberFromName
}
}
// {
// prop: "checkExe",
// label: "检测脚本",
// render: (scope) => {
// return scope.row.checkExe == 0
// ? "国网入网检测脚本(单影响量-模拟式)"
// : scope.row.checkExe == 1
// ? "国网入网检测脚本"
// : scope.row.checkExe == 2
// ? "/"
// : scope.row.checkExe;
// },
// },
// {
// prop: "wctx",
// label: "误差体系",
// render: (scope) => {
// return scope.row.wctx == 0
// ? "Q/GDW 1650.2- 2016"
// : scope.row.wctx == 1
// ? "Q/GDW 10650.2 - 2021"
// : scope.row.wctx == 2
// ? "/"
// : scope.row.wctx;
// },
// },
// {
// prop: "checkStatus",
// label: "检测状态",
// width: 120,
// render: (scope) => {
// return scope.row.checkStatus == 1
// ? "未检"
// : scope.row.checkStatus == 2
// ? "检测中"
// : scope.row.checkStatus == 3
// ? "检测完成"
// : scope.row.checkStatus;
// },
// },
// {
// prop: "checkReport",
// label: "检测报告",
// width: 120,
// render: (scope) => {
// return scope.row.checkReport == 1
// ? "未生成"
// : scope.row.checkReport == 2
// ? "部分生成"
// : scope.row.checkReport == 3
// ? "全部生成"
// : scope.row.checkReport;
// },
// },
// {
// prop: "checkResult",
// label: "检测结果",
// width: 120,
// render: (scope) => {
// return scope.row.checkReport == 1
// ? "/"
// : scope.row.checkReport == 2
// ? "符合"
// : scope.row.checkReport == 3
// ? "不符合"
// : scope.row.checkReport;
// },
// },
// {
// prop: "parentNode",
// label: "父节点",
// width: 90,
// render: (scope) => {
// return scope.row.checkReport == 0
// ? "/"
// : scope.row.checkReport == 1
// ? "检测计划1"
// : scope.row.checkReport == 2
// ? "检测计划2"
// : scope.row.checkReport == 3
// ? "检测计划3"
// : scope.row.checkReport;
// },
// },
// { prop: "operation", label: "操作", fixed: "right", width: 250 },
])
// 跳转详情页
const toDetail = () => {
router.push(`/proTable/useProTable/detail/${Math.random().toFixed(3)}?params=detail-page`)
}
//重置查询条件
const resetSearchForm = () => {
searchForm.value = {
intervalType: 0,
time: ['2024-08-20', '2024-08-27'],
searchBeginTime: '',
searchEndTime: '',
checkStatus: 0,
checkReportStatus: 0,
checkResult: 0
}
}
//查询
const handleSearch = () => {
proTable.value?.getTableList()
}
//重置
const handleRefresh = () => {
proTable.value?.getTableList()
}
// 表格拖拽排序
const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
console.log(newIndex, oldIndex)
console.log(proTable.value?.tableData)
ElMessage.success('修改列表排序成功')
}
// 删除用户信息
const deleteAccount = async (params: User.ResUserList) => {
await useHandleData(deleteUser, { id: [params.id] }, `删除【${params.username}`)
proTable.value?.getTableList()
}
// 批量删除用户信息
const batchDelete = async (id: string[]) => {
await useHandleData(deleteUser, { id }, '删除所选用户信息')
proTable.value?.clearSelection()
proTable.value?.getTableList()
}
// 重置用户密码
const resetPass = async (params: User.ResUserList) => {
await useHandleData(resetUserPassWord, { id: params.id }, `重置【${params.username}】用户密码`)
proTable.value?.getTableList()
}
// 切换用户状态
const changeStatus = async (row: User.ResUserList) => {
await useHandleData(
changeUserStatus,
{ id: row.id, status: row.status == 1 ? 0 : 1 },
`切换【${row.username}】用户状态`
)
proTable.value?.getTableList()
}
//顶部功能切换时修改activeTabs
const changeActiveTabs = (val: number) => {
form.value.activeTabs = val
}
//启动自动检测/手动检测
const handleTest = () => {
//自动检测
if (form.value.activeTabs === 0) {
ElMessage.success('自动检测')
router.push({
path: '/plan/autoTest'
})
} else {
ElMessage.warning('手动检测')
}
}
onMounted(() => {
console.log(proTable.value?.tableData)
})
defineExpose({ changeActiveTabs })
</script>
<style lang="scss" scoped>
/* 当屏幕宽度小于或等于1300像素时 */
@media screen and (max-width: 1300px) {
.el-select {
width: 130px !important;
}
}
@media screen and (min-width: 1300px) {
.el-select {
width: 150px !important;
}
}
.el-form {
width: 100%;
display: flex;
flex-wrap: wrap;
.el-form-item {
display: flex;
align-items: center;
justify-content: space-between;
.el-button {
margin: 0 !important;
margin-right: 10px !important;
}
}
}
</style>

View File

@@ -1,568 +0,0 @@
<template>
<div class="table_info">
<ProTable
ref="proTable"
:columns="columns"
:request-api="getTableList"
:init-param="initParam"
:data-callback="dataCallback"
@drag-sort="sortTable"
:height="tableHeight"
:stripe="true"
>
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<el-form :model="form" label-width="80px" :inline="true">
<el-form-item label="检测状态" v-if="form.activeTabs != 5">
<el-select v-model="form.checkStatus">
<el-option
v-for="(item, index) in checkStatusList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="报告状态" v-if="form.activeTabs != 5">
<el-select v-model="form.checkReportStatus">
<el-option
v-for="(item, index) in checkReportStatusList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="检测结果" v-if="form.activeTabs != 5">
<el-select v-model="form.checkResult">
<el-option
v-for="(item, index) in checkResultList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="绑定状态" v-if="form.activeTabs == 5">
<el-select v-model="form.deviceBindStatus">
<el-option
v-for="(item, index) in deviceBindStatusList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="设备类型" v-if="form.activeTabs == 5">
<el-select v-model="form.deviceType">
<el-option
v-for="(item, index) in deviceTypeList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="制造厂商" v-if="form.activeTabs == 5">
<el-select v-model="form.manufacturer">
<el-option
v-for="(item, index) in manufacturerList"
:label="item.label"
:value="item.value"
:key="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="handleSearch"
>查询</el-button
>
<el-button
type="primary"
@click="handleTest"
v-if="form.activeTabs === 0"
>启动自动检测</el-button
>
<el-button
type="primary"
@click="handleTest"
v-if="form.activeTabs === 1"
>启动手动检测</el-button
>
<el-button type="primary" v-if="form.activeTabs === 2"
>报告生成</el-button
>
<el-button type="primary" v-if="form.activeTabs === 5"
>设备导入</el-button
>
</el-form-item>
</el-form>
</template>
<!-- 表格操作 -->
<!-- <template #operation="scope">
<el-button
dictType="primary"
link
:icon="View"
@click="openDrawer('查看', scope.row)"
>查看</el-button
>
<el-button
dictType="primary"
link
:icon="EditPen"
@click="openDrawer('编辑', scope.row)"
>导出</el-button
>
<el-button
dictType="primary"
link
:icon="Delete"
@click="deleteAccount(scope.row)"
>删除</el-button
>
</template> -->
</ProTable>
</div>
</template>
<script setup lang="tsx" name="useProTable">
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { User } from "@/api/interface";
import { useHandleData } from "@/hooks/useHandleData";
import { useDownload } from "@/hooks/useDownload";
import { ElMessage, ElMessageBox } from "element-plus";
import ProTable from "@/components/ProTable/index.vue";
import ImportExcel from "@/components/ImportExcel/index.vue";
import {
CirclePlus,
Delete,
EditPen,
Download,
Upload,
View,
Refresh,
Search,
} from "@element-plus/icons-vue";
import { getPlanList } from "@/api/plan/planList";
const router = useRouter();
const value1 = ref("");
const value2 = ref("");
const tableHeight = ref(0);
console.log(window.innerHeight, "+++++++++");
tableHeight.value = window.innerHeight - 630;
//下拉框数据
//检测状态数据
const checkStatusList = [
{
label: "未检",
value: 0,
},
{
label: "检测中",
value: 1,
},
{
label: "检测完成",
value: 2,
},
{
label: "归档",
value: 3,
},
];
//检测报告状态数据
const checkReportStatusList = [
{
label: "未生成报告",
value: 0,
},
{
label: "已生成报告",
value: 1,
},
];
//检测结果数组
const checkResultList = [
{
label: "/",
value: null,
},
{
label: "不合格",
value: 0,
},
{
label: "合格",
value: 1,
},
];
//绑定状态数组
const deviceBindStatusList = [
{
label: "未绑定",
value: 0,
},
{
label: "已绑定",
value: 1,
},
];
//设备类型数组
const deviceTypeList = [
{
label: "PQS882A",
value: 0,
},
{
label: "PQS882B4",
value: 1,
},
{
label: "PQS882B5",
value: 2,
},
{
label: "PQS882B6",
value: 3,
},
{
label: "PQS882B7",
value: 4,
},
{
label: "PQS882B8",
value: 5,
},
];
//制造厂商数组
const manufacturerList = [
{
label: "南京灿能电力",
value: 0,
},
{
label: "南瑞继保",
value: 1,
},
{
label: "中电",
value: 2,
},
];
//查询条件
const form: any = ref({
activeTabs: 0, //功能选择
checkStatus: 0, //检测状态
checkReportStatus: 0, //检测报告状态
checkResult: 0, //检测结果
deviceBindStatus: 0, //绑定状态
deviceType: 0, //设备类型
manufacturer: 0, //制造厂商
});
const searchForm = ref({
intervalType: 0,
time: ["2024-08-20", "2024-08-27"],
searchBeginTime: "",
searchEndTime: "",
checkStatus: 0,
checkReportStatus: 0,
checkResult: 0,
});
// ProTable 实例
const proTable = ref<ProTableInstance>();
// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
const initParam = reactive({ type: 1, pageNum: 1, pageSize: 10 });
// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
const tableList = ref([]);
const dataCallback = (data: any) => {
return {
list: data || data.data || data.list,
total: data.length || data.total, //total
};
};
// 如果你想在请求之前对当前请求参数做一些操作可以自定义如下函数params 为当前所有的请求参数(包括分页),最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
const getTableList = (params: any) => {
let newParams = JSON.parse(JSON.stringify(params));
newParams.createTime && (newParams.startTime = newParams.createTime[0]);
newParams.createTime && (newParams.endTime = newParams.createTime[1]);
delete newParams.createTime;
return getPlanList(newParams);
};
// 表格配置项
const columns = reactive<ColumnProps<User.ResUserList>[]>([
{ type: "selection", fixed: "left", width: 70 },
{
prop: "checkMode",
label: "设备序列号",
width: 140,
render: (scope) => {
return scope.row.checkMode == 0
? "设备1"
: scope.row.checkMode == 1
? "设备2"
: scope.row.checkMode == 2
? "设备3"
: scope.row.checkMode;
},
},
{
prop: "checkMode",
label: "设备类型",
width: 140,
render: (scope) => {
return scope.row.checkMode == 0
? "PQS991"
: scope.row.checkMode == 1
? "PQS882"
: scope.row.checkMode == 2
? "PQS6666"
: scope.row.checkMode;
},
},
{
prop: "checkFrom",
label: "制造厂商",
width: 140,
render: (scope) => {
return scope.row.checkFrom == 0
? "南京灿能"
: scope.row.checkFrom == 1
? "南瑞继保"
: scope.row.checkFrom == 2
? "/"
: scope.row.checkFrom;
},
},
{
prop: "numberFromName",
label: "MAC/IP",
render: (scope) => {
return scope.row.numberFromName == 0
? "192.168.0.1"
: scope.row.numberFromName == 1
? "192.168.0.2"
: scope.row.numberFromName == 2
? "192.168.0.3"
: scope.row.numberFromName;
},
},
// {
// prop: "checkExe",
// label: "检测脚本",
// render: (scope) => {
// return scope.row.checkExe == 0
// ? "国网入网检测脚本(单影响量-模拟式)"
// : scope.row.checkExe == 1
// ? "国网入网检测脚本"
// : scope.row.checkExe == 2
// ? "/"
// : scope.row.checkExe;
// },
// },
// {
// prop: "wctx",
// label: "误差体系",
// render: (scope) => {
// return scope.row.wctx == 0
// ? "Q/GDW 1650.2- 2016"
// : scope.row.wctx == 1
// ? "Q/GDW 10650.2 - 2021"
// : scope.row.wctx == 2
// ? "/"
// : scope.row.wctx;
// },
// },
// {
// prop: "checkStatus",
// label: "检测状态",
// width: 120,
// render: (scope) => {
// return scope.row.checkStatus == 1
// ? "未检"
// : scope.row.checkStatus == 2
// ? "检测中"
// : scope.row.checkStatus == 3
// ? "检测完成"
// : scope.row.checkStatus;
// },
// },
// {
// prop: "checkReport",
// label: "检测报告",
// width: 120,
// render: (scope) => {
// return scope.row.checkReport == 1
// ? "未生成"
// : scope.row.checkReport == 2
// ? "部分生成"
// : scope.row.checkReport == 3
// ? "全部生成"
// : scope.row.checkReport;
// },
// },
// {
// prop: "checkResult",
// label: "检测结果",
// width: 120,
// render: (scope) => {
// return scope.row.checkReport == 1
// ? "/"
// : scope.row.checkReport == 2
// ? "符合"
// : scope.row.checkReport == 3
// ? "不符合"
// : scope.row.checkReport;
// },
// },
// {
// prop: "parentNode",
// label: "父节点",
// width: 90,
// render: (scope) => {
// return scope.row.checkReport == 0
// ? "/"
// : scope.row.checkReport == 1
// ? "检测计划1"
// : scope.row.checkReport == 2
// ? "检测计划2"
// : scope.row.checkReport == 3
// ? "检测计划3"
// : scope.row.checkReport;
// },
// },
// { prop: "operation", label: "操作", fixed: "right", width: 250 },
]);
// 跳转详情页
const toDetail = () => {
router.push(
`/proTable/useProTable/detail/${Math.random().toFixed(3)}?params=detail-page`
);
};
//重置查询条件
const resetSearchForm = () => {
searchForm.value = {
intervalType: 0,
time: ["2024-08-20", "2024-08-27"],
searchBeginTime: "",
searchEndTime: "",
checkStatus: 0,
checkReportStatus: 0,
checkResult: 0,
};
};
//查询
const handleSearch = () => {
proTable.value?.getTableList();
};
//重置
const handleRefresh = () => {
proTable.value?.getTableList();
};
// 表格拖拽排序
const sortTable = ({
newIndex,
oldIndex,
}: {
newIndex?: number;
oldIndex?: number;
}) => {
console.log(newIndex, oldIndex);
console.log(proTable.value?.tableData);
ElMessage.success("修改列表排序成功");
};
// 删除用户信息
const deleteAccount = async (params: User.ResUserList) => {
await useHandleData(
deleteUser,
{ id: [params.id] },
`删除【${params.username}`
);
proTable.value?.getTableList();
};
// 批量删除用户信息
const batchDelete = async (id: string[]) => {
await useHandleData(deleteUser, { id }, "删除所选用户信息");
proTable.value?.clearSelection();
proTable.value?.getTableList();
};
// 重置用户密码
const resetPass = async (params: User.ResUserList) => {
await useHandleData(
resetUserPassWord,
{ id: params.id },
`重置【${params.username}】用户密码`
);
proTable.value?.getTableList();
};
// 切换用户状态
const changeStatus = async (row: User.ResUserList) => {
await useHandleData(
changeUserStatus,
{ id: row.id, status: row.status == 1 ? 0 : 1 },
`切换【${row.username}】用户状态`
);
proTable.value?.getTableList();
};
//顶部功能切换时修改activeTabs
const changeActiveTabs = (val: number) => {
form.value.activeTabs = val;
};
//启动自动检测/手动检测
const handleTest = () => {
//自动检测
if (form.value.activeTabs === 0) {
ElMessage.success("自动检测");
router.push({
path:"/plan/autoTest"
})
}else{
ElMessage.warning("手动检测");
}
};
onMounted(() => {
console.log(proTable.value?.tableData);
});
defineExpose({ changeActiveTabs });
</script>
<style lang="scss" scoped>
/* 当屏幕宽度小于或等于1300像素时 */
@media screen and (max-width: 1300px) {
.el-select {
width: 130px !important;
}
}
@media screen and (min-width: 1300px) {
.el-select {
width: 150px !important;
}
}
// ::v-deep .el-select {
// width: 150px !important;
// }
.el-form {
width: 100%;
display: flex;
flex-wrap: wrap;
.el-form-item {
display: flex;
align-items: center;
justify-content: space-between;
.el-button {
margin: 0 !important;
margin-right: 10px !important;
}
}
}
</style>

View File

@@ -11,14 +11,11 @@
v-model="item.selected"
:key="index"
:label="item.name"
></el-checkbox
>
></el-checkbox>
<el-button type="primary" @click="handlePreTest">预检测</el-button>
<el-button type="primary" @click="handleAutoTest">正式检测</el-button>
<el-button type="primary" @click="handleBackDeviceList"
>返回首页</el-button
>
<el-button type="primary" @click="handleBackDeviceList">返回首页</el-button>
<!-- <el-select v-model="currentErrSysID" placeholder="请选择误差体系" autocomplete="off">
<el-option
@@ -33,44 +30,24 @@
</div>
<div class="test_bot">
<div class="test_left">
<Tree ref="treeRef"></Tree>
<AutoTestTree ref="treeRef"></AutoTestTree>
</div>
<div class="test_right">
<el-descriptions
style="
width: 100%;
border-radius: 6px;
margin-bottom: 10px;
background-color: #fff;
padding: 10px;
"
style="width: 100%; border-radius: 6px; margin-bottom: 10px; background-color: #fff; padding: 10px"
:column="3"
border
>
<template #extra>
<el-progress
style="width: 80%"
:percentage="percentage"
:color="customColors"
/>
<el-progress style="width: 80%" :percentage="percentage" :color="customColors" />
<div class="test_button">
<el-button
type="primary"
v-if="!isPause"
:icon="VideoPause"
@click="handlePauseTest"
>暂停检测</el-button
>
<el-button
type="warning"
v-if="isPause"
:icon="Refresh"
@click="handlePauseTest"
>继续检测</el-button
>
<el-button type="danger" :icon="Close" @click="handleFinishTest"
>停止检测</el-button
>
<el-button type="primary" v-if="!isPause" :icon="VideoPause" @click="handlePauseTest">
暂停检测
</el-button>
<el-button type="warning" v-if="isPause" :icon="Refresh" @click="handlePauseTest">
继续检测
</el-button>
<el-button type="danger" :icon="Close" @click="handleFinishTest">停止检测</el-button>
<!-- <el-button
type="danger"
v-if="!isPause"
@@ -134,7 +111,7 @@
:key="vvs"
:type="vv.type"
text
@click="handleClick(item,index,vvs)"
@click="handleClick(item, index, vvs)"
>
{{ vv.label }}
</el-button>
@@ -148,82 +125,69 @@
</div>
<div class="right_status" ref="statusRef" v-if="!beforeTest">
<!-- ,fontSize:index%5===0?'16px':'14px' -->
<p v-for="(item, index) in statusList" :key="index" :style="{color:index%5===0?'#F56C6C':'var(--el-text-color-regular)'}">
输入{{ item.remark }} -{{
item.status == 0 ? "输出完毕" : "输入中请稍后"
}}<br />
<p
v-for="(item, index) in statusList"
:key="index"
:style="{ color: index % 5 === 0 ? '#F56C6C' : 'var(--el-text-color-regular)' }"
>
输入{{ item.remark }} -{{ item.status == 0 ? '输出完毕' : '输入中,请稍后!' }}
<br />
<span v-if="index == statusList.length - 1">...</span>
</p>
</div>
</div>
</div>
</div>
<ShowDataPopup ref='showDataPopup'/>
<ShowDataPopup ref="showDataPopup" />
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, nextTick } from "vue";
import Tree from "./components/tree.vue";
import { data } from "@/api/plan/autoTest.json";
import { useTransition } from "@vueuse/core";
import { getPlanList } from "@/api/plan/planList";
import { ElMessage, ElMessageBox } from "element-plus";
import { nextTick, onMounted, ref } from 'vue'
import AutoTestTree from './components/autoTestTree.vue'
import { data } from '@/api/plan/autoTest.json'
import { ElMessage, ElMessageBox } from 'element-plus'
import ShowDataPopup from './components/ShowDataPopup.vue'
import {
CirclePlus,
Delete,
EditPen,
Download,
Upload,
View,
Check,
Plus,
Refresh,
Search,
Close,
VideoPause,
} from "@element-plus/icons-vue";
import {dictPattern,dictTestState,dictReportState,dictResult,testPlanDataList,testSoureDataList,testScriptDataList,testErrSystDataList,planData,testFatherPlanList} from '@/api/plan/planData'
import { Close, Refresh, VideoPause } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const currentErrSysID = ref("2")
const treeRef = ref<any>();
const currentErrSysID = ref('2')
const treeRef = ref<any>()
const PopupVisible = ref(false)
const showDataPopup = ref()
const beforeTest = ref(true)
const testModel = ref("")
const testModel = ref('')
//定义与预检测配置数组
const detectionOptions = ref([
{
id: 0,
name: "标准源通讯检测",//判断源通讯是否正常
selected: true,
name: '标准源通讯检测', //判断源通讯是否正常
selected: true
},
{
id: 1,
name: "设备通讯检测",//判断设备的IP、Port、识别码、秘钥是否正常
selected: true,
name: '设备通讯检测', //判断设备的IP、Port、识别码、秘钥是否正常
selected: true
},
{
id: 2,
name: "协议校验",//ICD报告触发测试
selected: true,
name: '协议校验', //ICD报告触发测试
selected: true
},
{
id: 3,
name: "相序校验",//判断装置的接线是否正确
selected: true,
name: '相序校验', //判断装置的接线是否正确
selected: true
},
{
id: 4,
name: "守时校验",//判断装置24小时内的守时误差是否小于1s
selected: true,
name: '守时校验', //判断装置24小时内的守时误差是否小于1s
selected: true
},
{
id: 5,
name: "通道系数校准",//通过私有协议与装置进行通讯,校准三相电压电流的通道系数
selected: true,
},
name: '通道系数校准', //通过私有协议与装置进行通讯,校准三相电压电流的通道系数
selected: true
}
// {
// id: 6,
// name: "实时数据比对",
@@ -232,7 +196,7 @@ const detectionOptions = ref([
// id: 7,
// name: "录波数据比对",
// },
]);
])
const leftDeviceData = ref<any>([
// {
@@ -265,86 +229,86 @@ const leftDeviceData = ref<any>([
// name: "设备6-预检测",
// status: 0,
// },
]);
])
const initLeftDeviceData = () => {
leftDeviceData.value.map((item, index) => {
// handlePrintText(item.name, index);
});
};
})
}
const preTestData = [
{
"id": 0,
"name": "预检测项目",
"children": [
id: 0,
name: '预检测项目',
children: [
{
"scriptIdx":1,
"isChildNode":true,
"pid": "0-2",
"id": "0-2-2",
"name": "标准源通讯检测"
scriptIdx: 1,
isChildNode: true,
pid: '0-2',
id: '0-2-2',
name: '标准源通讯检测'
},
{
"scriptIdx":2,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "设备通讯检测"
scriptIdx: 2,
isChildNode: true,
pid: '0-3',
id: '0-3-1',
name: '设备通讯检测'
},
{
"scriptIdx":3,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "协议校验"
scriptIdx: 3,
isChildNode: true,
pid: '0-3',
id: '0-3-1',
name: '协议校验'
},
{
"scriptIdx":4,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "相序校验"
scriptIdx: 4,
isChildNode: true,
pid: '0-3',
id: '0-3-1',
name: '相序校验'
},
{
"scriptIdx":5,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "守时校验"
scriptIdx: 5,
isChildNode: true,
pid: '0-3',
id: '0-3-1',
name: '守时校验'
},
{
"scriptIdx":6,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "通道系数校准"
scriptIdx: 6,
isChildNode: true,
pid: '0-3',
id: '0-3-1',
name: '通道系数校准'
}
]
}
]
]
// 弹出数据查询页面
const handleClick = (item,index,vvs) => {
const handleClick = (item, index, vvs) => {
//const data = "检测脚本为:"+item.name+";被检设备为:"+item.children.value.devID+";被检通道序号为:"+ item.children.monitorIndex;
console.log(vvs,index,item.name,item.children)
console.log(vvs, index, item.name, item.children)
PopupVisible.value = true
showDataPopup.value.open()
};
let currentIndex = 0;
let totalNum = 0;
}
let currentIndex = 0
let totalNum = 0
//启动预检测
const handlePreTest = () => {
ElMessage.success("启动预检测");
currentIndex = 0;
percentage.value = 0;
statusList.value = [];
deviceTestList.value = [];
statusId.value = 0;
testModel.value = "preTest"
beforeTest.value = false;
ElMessage.success('启动预检测')
currentIndex = 0
percentage.value = 0
statusList.value = []
deviceTestList.value = []
statusId.value = 0
testModel.value = 'preTest'
beforeTest.value = false
getTreeData(preTestData)
totalNum = preTestData[0].children.length;
interValTest();
totalNum = preTestData[0].children.length
interValTest()
// let count = 0;
// if (timer) {
@@ -368,37 +332,37 @@ const handlePreTest = () => {
// });
// }, 2000);
// }
};
}
//进入检测流程
const handleAutoTest = () => {
ElMessage.success("启动正式检测");
currentIndex = 0;
percentage.value = 0;
statusList.value = [];
deviceTestList.value = [];
statusId.value = 0;
testModel.value = "Test"
beforeTest.value = false;
ElMessage.success('启动正式检测')
currentIndex = 0
percentage.value = 0
statusList.value = []
deviceTestList.value = []
statusId.value = 0
testModel.value = 'Test'
beforeTest.value = false
getTreeData(data)
// totalNum = data.length;
totalNum = 10;
totalNum = 10
interValTest();
};
interValTest()
}
//返回设备列表
const handleBackDeviceList = () => {
router.push({
path: "/home/index",
});
};
path: '/home/index'
})
}
const getTreeData = (val) => {
treeRef.value && treeRef.value.getTreeData(val);
};
const getTreeData = val => {
treeRef.value && treeRef.value.getTreeData(val)
}
const tableList = ref([]);
const tableList = ref([])
const percentage = ref(0);
const percentage = ref(0)
const customColors = [
// { color: "red", percentage: 0 },
@@ -411,182 +375,161 @@ const customColors = [
// { color: "#e6a23c", percentage: 70 }, //黄
// { color: "#e6a23c", percentage: 80 }, //1989fa
// { color: "#e6a23c", percentage: 90 }, //1989fa
{ color: "#5cb87a", percentage: 100 }, //绿
];
{ color: '#5cb87a', percentage: 100 } //绿
]
//加载进度条
const refreshProgress = () => {
console.log(currentIndex,totalNum,percentage.value)
console.log(currentIndex, totalNum, percentage.value)
if (percentage.value < 100) {
percentage.value = Math.trunc(currentIndex/totalNum * 100);
percentage.value = Math.trunc((currentIndex / totalNum) * 100)
} else {
clearInterval(timer.value)
clearInterval(statusTimer.value)
let strTemp = ""
if(testModel.value === "preTest")
strTemp = "预检测过程全部结束"
else if(testModel.value === "Test")
strTemp = "正式检测全部结束"
let strTemp = ''
if (testModel.value === 'preTest') strTemp = '预检测过程全部结束'
else if (testModel.value === 'Test') strTemp = '正式检测全部结束'
statusId.value++;
statusId.value++
statusList.value.push({
id: statusId.value,
remark: strTemp,
status: 0,
});
status: 0
})
console.log("检测结束")
if(testModel.value === "preTest")
ElMessage.success("预检测过程全部结束")
else if(testModel.value === "Test")
console.log('检测结束')
if (testModel.value === 'preTest') ElMessage.success('预检测过程全部结束')
else if (testModel.value === 'Test')
//ElMessage.success("正式检测全部结束,你可以停留在此页面查看检测结果,或返回首页进行复检、报告生成和归档等操作")
ElMessageBox.confirm(
ElMessageBox.confirm(
'检测全部结束,你可以停留在此页面查看检测结果,或返回首页进行复检、报告生成和归档等操作',
'检测完成',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'success',
type: 'success'
}
)
.then()
).then()
// percentage.value = 0;
// statusList.value = [];
// deviceTestList.value = [];
// statusId.value = 0;
}
};
}
let timer: any = ref("");
const statusTimer: any = ref("");
let timer: any = ref('')
const statusTimer: any = ref('')
//检测列表数据
const deviceTestList = ref<any>([]);
const deviceTestList = ref<any>([])
//检测结果数据
const deviceList = ref<any>([]);
const deviceList = ref<any>([])
//前一个页面带过来的设备数据
// const deviceData = ref<any>([]);
const deviceData = ref([
{
id: 0,
name: "设备1通道1",
name: '设备1通道1',
status: Math.floor(Math.random() * 4),
type:"info",
label:"/",
devID:"dev1",
monitorIndex:1,
type: 'info',
label: '/',
devID: 'dev1',
monitorIndex: 1
},
{
id: 1,
name: "设备1通道2",
name: '设备1通道2',
status: Math.floor(Math.random() * 4),
type:"success",
label:"√",
devID:"dev1",
monitorIndex:2,
type: 'success',
label: '√',
devID: 'dev1',
monitorIndex: 2
},
{
id: 2,
name: "设备2通道1",
name: '设备2通道1',
status: Math.floor(Math.random() * 4),
type:"danger",
label:"×",
devID:"dev2",
monitorIndex:1,
type: 'danger',
label: '×',
devID: 'dev2',
monitorIndex: 1
},
{
id: 3,
name: "设备3通道1",
name: '设备3通道1',
status: Math.floor(Math.random() * 4),
type:"success",
label:"√",
devID:"dev3",
monitorIndex:1,
},
]);
type: 'success',
label: '√',
devID: 'dev3',
monitorIndex: 1
}
])
const interValTest = () => {
timer.value = setInterval(() => {
deviceTestList.value.push({
id: 0,
name: `频率 ${statusId.value}Hz`,
children: deviceData.value,
children: deviceData.value
// status: Math.floor(Math.random() * 4),
});
currentIndex++;
})
currentIndex++
treeRef.value && treeRef.value.getCurrentIndex(currentIndex)
refreshProgress();
}, 2000);
refreshProgress()
}, 2000)
statusTimer.value = setInterval(() => {
getStatusList();
getStatusList()
statusList.value.map((item: any, index: any) => {
if (index == statusList.value.length - 1) {
item.status = 1;
item.status = 1
} else {
item.status = 0;
item.status = 0
}
});
}, 2000);
};
})
}, 2000)
}
//暂停检测
const isPause = ref<boolean>(false);
const isPause = ref<boolean>(false)
const handlePauseTest = () => {
if (!isPause.value) {
clearInterval(timer.value);
clearInterval(statusTimer.value);
clearInterval(timer.value)
clearInterval(statusTimer.value)
} else {
interValTest();
interValTest()
}
isPause.value = !isPause.value;
};
isPause.value = !isPause.value
}
//完成检测
const handleFinishTest = () => {
ElMessage.success("完成检测");
};
ElMessage.success('完成检测')
}
// 表格拖拽排序
const sortTable = ({
newIndex,
oldIndex,
}: {
newIndex?: number;
oldIndex?: number;
}) => {
console.log(newIndex, oldIndex);
ElMessage.success("修改列表排序成功");
};
const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
console.log(newIndex, oldIndex)
ElMessage.success('修改列表排序成功')
}
const statusList: any = ref([]);
let statusId = ref(0);
const statusRef = ref();
const statusList: any = ref([])
let statusId = ref(0)
const statusRef = ref()
const getStatusList = () => {
statusId.value++;
statusId.value++
statusList.value.push({
id: statusId.value,
remark: `频率 ${statusId.value}Hz`,
status: 0,
});
status: 0
})
// console.log(statusRef.value.offsetHeight);
nextTick(() => {
if (statusRef.value)
statusRef.value.scrollTop = statusRef.value.scrollHeight;
});
};
if (statusRef.value) statusRef.value.scrollTop = statusRef.value.scrollHeight
})
}
onMounted(() => {
});
onMounted(() => {})
</script>
<style lang="scss" scoped>
.empty__div {
position: absolute;
left: 50%;
@@ -741,11 +684,11 @@ onMounted(() => {
}
}
::v-deep .header-button-lf {
:deep(.header-button-lf) {
clear: both !important;
}
::v-deep .el-descriptions__extra {
:deep(.el-descriptions__extra) {
width: 100%;
display: flex;
justify-content: space-between;

View File

@@ -383,7 +383,7 @@
<script lang="ts" setup>
import { type CascaderOption, ElMessage, type FormItemRule } from 'element-plus'
import { computed, defineProps, reactive, ref } from 'vue'
import { computed, reactive, ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
import { type Plan } from '@/api/plan/interface'
import {

View File

@@ -12,10 +12,7 @@
<template #tableHeader>
<el-form :model="searchForm">
<el-form-item label="检测时间">
<el-select
v-model="searchForm.intervalType"
style="width: 80px !important"
>
<el-select v-model="searchForm.intervalType" style="width: 80px !important">
<el-option :value="0" label="按周">按周</el-option>
<el-option :value="1" label="按月">按月</el-option>
<el-option :value="2" label="按日">按日</el-option>
@@ -58,30 +55,20 @@
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="handleSearch"
>查询</el-button
>
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
<el-button :icon="Refresh" @click="handleRefresh">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Upload" @click="handleRefresh"
>导入</el-button
>
<el-button type="primary" :icon="Upload" @click="handleRefresh">导入</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Check" @click="handleRefresh"
>合并</el-button
>
<el-button type="primary" :icon="Check" @click="handleRefresh">合并</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Plus" @click="handleRefresh"
>新增</el-button
>
<el-button type="primary" :icon="Plus" @click="handleRefresh">新增</el-button>
</el-form-item>
<el-form-item>
<el-button type="danger" :icon="Delete" @click="handleRefresh"
>删除</el-button
>
<el-button type="danger" :icon="Delete" @click="handleRefresh">删除</el-button>
</el-form-item>
</el-form>
<!-- <el-button
@@ -126,27 +113,9 @@
</template> -->
<!-- 表格操作 -->
<template #operation="scope">
<el-button
type="primary"
link
:icon="View"
@click="handleDetails('查看', scope.row)"
>查看</el-button
>
<el-button
type="primary"
link
:icon="EditPen"
@click="openDrawer('编辑', scope.row)"
>导出</el-button
>
<el-button
type="primary"
link
:icon="Delete"
@click="deleteAccount(scope.row)"
>删除</el-button
>
<el-button type="primary" link :icon="View" @click="handleDetails('查看', scope.row)">查看</el-button>
<el-button type="primary" link :icon="EditPen" @click="openDrawer('编辑', scope.row)">导出</el-button>
<el-button type="primary" link :icon="Delete" @click="deleteAccount(scope.row)">删除</el-button>
</template>
</ProTable>
</div>
@@ -154,292 +123,263 @@
</template>
<script setup lang="tsx" name="useProTable">
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { User } from "@/api/interface";
import { useHandleData } from "@/hooks/useHandleData";
import { useDownload } from "@/hooks/useDownload";
import { ElMessage, ElMessageBox } from "element-plus";
import ProTable from "@/components/ProTable/index.vue";
import ImportExcel from "@/components/ImportExcel/index.vue";
import planDetails from "./components/details.vue";
import {
CirclePlus,
Delete,
EditPen,
Download,
Upload,
View,
Check,
Plus,
Refresh,
Search,
} from "@element-plus/icons-vue";
import { getPlanList } from "@/api/plan/planList";
import { onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { User } from '@/api/interface'
import { useHandleData } from '@/hooks/useHandleData'
import { ElMessage } from 'element-plus'
import ProTable from '@/components/ProTable/index.vue'
import planDetails from './components/details.vue'
import { Check, Delete, EditPen, Plus, Refresh, Search, Upload, View } from '@element-plus/icons-vue'
import { getPlanList } from '@/api/plan/planList'
const router = useRouter();
const value1 = ref("");
const value2 = ref("");
const router = useRouter()
const value1 = ref('')
const value2 = ref('')
const shortcuts = [
{
text: "最近一周",
text: '最近一周',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
},
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start, end]
}
},
{
text: "最近一个月",
text: '最近一个月',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
},
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start, end]
}
},
{
text: "最近三个月",
text: '最近三个月',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
},
},
];
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
return [start, end]
}
}
]
// 跳转详情页
const toDetail = () => {
router.push(
`/proTable/useProTable/detail/${Math.random().toFixed(3)}?params=detail-page`
);
};
router.push(`/proTable/useProTable/detail/${Math.random().toFixed(3)}?params=detail-page`)
}
const searchForm = ref({
intervalType: 0,
time: ["2024-08-20", "2024-08-27"],
searchBeginTime: "",
searchEndTime: "",
time: ['2024-08-20', '2024-08-27'],
searchBeginTime: '',
searchEndTime: '',
checkStatus: 0,
checkReportStatus: 0,
checkResult: 0,
});
checkResult: 0
})
// ProTable 实例
const proTable = ref<ProTableInstance>();
const proTable = ref<ProTableInstance>()
// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
const initParam = reactive({ type: 1, pageNum: 1, pageSize: 10 });
const initParam = reactive({ type: 1, pageNum: 1, pageSize: 10 })
// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
const tableList = ref([]);
const tableList = ref([])
const dataCallback = (data: any) => {
return {
list: data || data.data || data.list,
total: data.length || data.total,
};
};
total: data.length || data.total
}
}
// 如果你想在请求之前对当前请求参数做一些操作可以自定义如下函数params 为当前所有的请求参数(包括分页),最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
const getTableList = (params: any) => {
let newParams = JSON.parse(JSON.stringify(params));
newParams.createTime && (newParams.startTime = newParams.createTime[0]);
newParams.createTime && (newParams.endTime = newParams.createTime[1]);
delete newParams.createTime;
return getPlanList(newParams);
};
let newParams = JSON.parse(JSON.stringify(params))
newParams.createTime && (newParams.startTime = newParams.createTime[0])
newParams.createTime && (newParams.endTime = newParams.createTime[1])
delete newParams.createTime
return getPlanList(newParams)
}
//查看详情
const detailsRef: any = ref();
const detailsRef: any = ref()
const handleDetails = () => {
console.log(detailsRef.value, "+++++++++++++++");
detailsRef.value.open("查看计划");
};
console.log(detailsRef.value, '+++++++++++++++')
detailsRef.value.open('查看计划')
}
// 表格配置项
const columns = reactive<ColumnProps<User.ResUserList>[]>([
{ type: "selection", fixed: "left", width: 70 },
{ type: "sort", label: "Sort", width: 80 },
{ type: "expand", label: "Expand", width: 85 },
{ type: 'selection', fixed: 'left', width: 70 },
{ type: 'sort', label: 'Sort', width: 80 },
{ type: 'expand', label: 'Expand', width: 85 },
{
prop: "planName",
label: "计划名称",
width: 120,
prop: 'planName',
label: '计划名称',
width: 120
},
{
prop: "checkMode",
label: "检测模式",
prop: 'checkMode',
label: '检测模式',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.checkMode == 0
? "模拟式"
? '模拟式'
: scope.row.checkMode == 1
? "比对式"
? '比对式'
: scope.row.checkMode == 2
? "数字式"
: scope.row.checkMode;
},
? '数字式'
: scope.row.checkMode
}
},
{
prop: "checkFrom",
label: "检测源",
prop: 'checkFrom',
label: '检测源',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.checkFrom == 0
? "标准源-福禄克-6100A"
? '标准源-福禄克-6100A'
: scope.row.checkFrom == 1
? "标准源-昂立-PF2"
? '标准源-昂立-PF2'
: scope.row.checkFrom == 2
? "高精度设备-PQS882-1"
: scope.row.checkFrom;
},
? '高精度设备-PQS882-1'
: scope.row.checkFrom
}
},
{
prop: "numberFromName",
label: "源名称",
render: (scope) => {
prop: 'numberFromName',
label: '源名称',
render: scope => {
return scope.row.numberFromName == 0
? "分钟统计数据最大值"
? '分钟统计数据最大值'
: scope.row.numberFromName == 1
? "分钟统计数据最小值"
? '分钟统计数据最小值'
: scope.row.numberFromName == 2
? "分钟统计数据CP95值"
: scope.row.numberFromName;
},
? '分钟统计数据CP95值'
: scope.row.numberFromName
}
},
{
prop: "checkExe",
label: "检测脚本",
prop: 'checkExe',
label: '检测脚本',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.checkExe == 0
? "国网入网检测脚本(单影响量-模拟式)"
? '国网入网检测脚本(单影响量-模拟式)'
: scope.row.checkExe == 1
? "国网入网检测脚本"
? '国网入网检测脚本'
: scope.row.checkExe == 2
? "/"
: scope.row.checkExe;
},
? '/'
: scope.row.checkExe
}
},
{
prop: "wctx",
label: "误差体系",
prop: 'wctx',
label: '误差体系',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.wctx == 0
? "Q/GDW 1650.2- 2016"
? 'Q/GDW 1650.2- 2016'
: scope.row.wctx == 1
? "Q/GDW 10650.2 - 2021"
? 'Q/GDW 10650.2 - 2021'
: scope.row.wctx == 2
? "/"
: scope.row.wctx;
},
? '/'
: scope.row.wctx
}
},
{
type: "tag",
prop: "checkStatus",
label: "检测状态",
type: 'tag',
prop: 'checkStatus',
label: '检测状态',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.checkStatus == 1
? "未检"
? '未检'
: scope.row.checkStatus == 2
? "检测中"
? '检测中'
: scope.row.checkStatus == 3
? "检测完成"
: scope.row.checkStatus;
},
? '检测完成'
: scope.row.checkStatus
}
},
{
prop: "checkReport",
label: "检测报告",
prop: 'checkReport',
label: '检测报告',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.checkReport == 1
? "未生成"
? '未生成'
: scope.row.checkReport == 2
? "部分生成"
? '部分生成'
: scope.row.checkReport == 3
? "全部生成"
: scope.row.checkReport;
},
? '全部生成'
: scope.row.checkReport
}
},
{
prop: "checkResult",
label: "检测结果",
prop: 'checkResult',
label: '检测结果',
width: 120,
render: (scope) => {
render: scope => {
return scope.row.checkReport == 1
? "/"
? '/'
: scope.row.checkReport == 2
? "符合"
? '符合'
: scope.row.checkReport == 3
? "不符合"
: scope.row.checkReport;
? '不符合'
: scope.row.checkReport
}
},
},
{ prop: "operation", label: "操作", fixed: "right", width: 250 },
]);
{ prop: 'operation', label: '操作', fixed: 'right', width: 250 }
])
//重置查询条件
const resetSearchForm = () => {
searchForm.value = {
intervalType: 0,
time: ["2024-08-20", "2024-08-27"],
searchBeginTime: "",
searchEndTime: "",
time: ['2024-08-20', '2024-08-27'],
searchBeginTime: '',
searchEndTime: '',
checkStatus: 0,
checkReportStatus: 0,
checkResult: 0,
};
};
checkResult: 0
}
}
//查询
const handleSearch = () => {
proTable.value?.getTableList();
};
proTable.value?.getTableList()
}
//重置
const handleRefresh = () => {
proTable.value?.getTableList();
};
proTable.value?.getTableList()
}
// 表格拖拽排序
const sortTable = ({
newIndex,
oldIndex,
}: {
newIndex?: number;
oldIndex?: number;
}) => {
const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
// console.log(newIndex, oldIndex);
//console.log(proTable.value?.tableData);
ElMessage.success("修改列表排序成功");
};
ElMessage.success('修改列表排序成功')
}
// 删除用户信息
const deleteAccount = async (params: User.ResUserList) => {
await useHandleData(
deleteUser,
{ id: [params.id] },
`删除【${params.username}`
);
proTable.value?.getTableList();
};
await useHandleData(deleteUser, { id: [params.id] }, `删除【${params.username}`)
proTable.value?.getTableList()
}
// 批量删除用户信息
const batchDelete = async (id: string[]) => {
await useHandleData(deleteUser, { id }, "删除所选用户信息");
proTable.value?.clearSelection();
proTable.value?.getTableList();
};
await useHandleData(deleteUser, { id }, '删除所选用户信息')
proTable.value?.clearSelection()
proTable.value?.getTableList()
}
// 重置用户密码
const resetPass = async (params: User.ResUserList) => {
await useHandleData(
resetUserPassWord,
{ id: params.id },
`重置【${params.username}】用户密码`
);
proTable.value?.getTableList();
};
await useHandleData(resetUserPassWord, { id: params.id }, `重置【${params.username}】用户密码`)
proTable.value?.getTableList()
}
// 切换用户状态
const changeStatus = async (row: User.ResUserList) => {
@@ -447,12 +387,12 @@ const changeStatus = async (row: User.ResUserList) => {
changeUserStatus,
{ id: row.id, status: row.status == 1 ? 0 : 1 },
`切换【${row.username}】用户状态`
);
proTable.value?.getTableList();
};
)
proTable.value?.getTableList()
}
onMounted(() => {
console.log(proTable.value?.tableData);
});
console.log(proTable.value?.tableData)
})
</script>
<style lang="scss" scoped>
.planList {
@@ -460,7 +400,7 @@ onMounted(() => {
// height: calc(100vh - 165px);
height: 100%;
}
::v-deep .el-select {
:deep(.el-select) {
width: 150px !important;
}