写项目,学习的一个记录:
<script lang="ts" setup>
import { ref } from 'vue'
import { ElConfigProvider } from 'element-plus'
import type { CheckboxValueType } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { useRoute } from 'vue-router'
import { definePage } from 'vue-router/auto'
import { uselineOidListStore } from './uses/linesStore'
import useFetch from '@/apis/useFetch'
definePage({
alias: ['/visualization/dailyWarning', '/visualization/dailyWarning/:id/:type', '/visualization/dailyWarning/:id/:vehicleNumber/:type'],
name: 'dailyWarning',
})
const route = useRoute()
const lineOidListStore = uselineOidListStore()
const routePath = computed(() => route.path.includes('/visualization/dailyWarning'))
const props = computed(() => {
return {
lineOids: lineOidListStore.lineOidList,
lineOid: (route.params as { id: string }).id,
lineType: Number((route.params as { type: number }).type),
lineOrVehicleId: Number((route.params as { type: number }).type) === 0 ? (route.params as { id: string }).id : (route.params as { vehicleNumber: string }).vehicleNumber,
}
})
const isActive = ref(false)
// 表单
const selectForm = ref({
lineOid: [] as string[],
trainNumber: [] as string[],
belongSystem: [] as string[],
faultLevel: [] as string[],
isTrigger: 'all',
operState: 'all',
dataType: 'all',
faultName: '',
faultCode: '',
startTime: '',
endTime: '',
})
const pagerinfo = reactive({
pageNow: 1,
pageSize: 20,
})
function arrayToString(list: (string | number)[]) {
return `${list.map(el => `'${el}'`).join(',')}`
}
const selectQuery = computed(() => {
return {
body: {
querymode: isActive.value ? 'warn' : 'fault',
condition: {
lineOid: arrayToString(selectForm.value.lineOid),
trainNumber: arrayToString(selectForm.value.trainNumber),
belongSystem: arrayToString(selectForm.value.belongSystem),
faultLevel: arrayToString(selectForm.value.faultLevel),
isTrigger: selectForm.value.isTrigger,
operState: selectForm.value.operState,
dataType: selectForm.value.dataType,
faultName: selectForm.value.faultName,
faultCode: selectForm.value.faultCode,
startTime: selectForm.value.startTime,
endTime: selectForm.value.endTime,
},
pagerinfo: {
pageNow: String(pagerinfo.pageNow),
pageSize: String(pagerinfo.pageSize),
},
},
}
})
/**
* 线路lineOid查询参数
*/
const lineOidListQuery = computed(() => {
return {
body: {
lineOidList: `[${arrayToString(selectForm.value.lineOid)}]`,
},
}
})
// (列车/所属系统)关联信息查询接口
const { data: getLinkageData, send: GetLinkageData } = useFetch('/eda/faultwarn/GetLinkageData', 'post', lineOidListQuery, { immediate: false, refetch: true, initialData: [] })
// 列车
const trainNumberList = computed<{ value: string, label: string }[]>(() => {
if (!getLinkageData.value?.VehicleList)
return []
return getLinkageData.value.VehicleList.map(el => ({ value: el, label: el }))
})
// 所属系统
const belongSysList = computed(() => {
if (!getLinkageData.value?.SystemList)
return []
return getLinkageData.value?.SystemList?.map(el => ({ value: el.systemOid, label: el.systemName }))
})
// 故障预警查询 接口
const { data: getFaultWarnData, send: GetFaultWarnData } = useFetch('/eda/faultwarn/GetFaultWarnData', 'post', selectQuery.value, { immediate: false, refetch: true, initialData: [] })
// 故障信息
const faultList = computed(() => {
return getFaultWarnData.value?.RowList
})
// 时间转换格式
function fomatterTime(date: Date) {
return `${date.getFullYear()}-${(`0${date.getMonth() + 1}`).slice(-2)}-${(`0${date.getDate()}`).slice(-2)} ${(`0${date.getHours()}`).slice(-2)}:${(`0${date.getMinutes()}`).slice(-2)}:${(`0${date.getSeconds()}`).slice(-2)}`
}
function initTime() {
const start = new Date()
const end = new Date()
start.setHours(0, 0, 0, 0)
end.setHours(23, 59, 59, 999)
selectForm.value.startTime = fomatterTime(start)
selectForm.value.endTime = fomatterTime(end)
}
initTime()
// 禁选时间段
const disableStartDate: (date: Date) => boolean = (date) => {
const today = new Date()
today.setHours(0, 0, 0, 0)
// return date.getTime() > Number(selectForm.value.endTime)
return date.getTime() > today.getTime()
}
const disabledEndDate: (date: Date) => boolean = (date) => {
const today = new Date()
today.setHours(0, 0, 0, 0)
// return date.getTime() < Number(selectForm.value.startTime)
return date.getTime() < today.getTime()
}
function onReload() {
if (!trainNumberList.value && !belongSysList.value)
return
selectForm.value.lineOid = props.value.lineType === 0 ? [props.value.lineOrVehicleId] : [props.value.lineOid]
selectForm.value.trainNumber = props.value.lineType === 0 ? trainNumberList.value.map(el => el.value) : [props.value.lineOrVehicleId]
selectForm.value.belongSystem = belongSysList.value.map(el => el.value)
selectForm.value.faultLevel = ['1', '2', '3']
selectForm.value.isTrigger = 'all'
selectForm.value.operState = 'all'
selectForm.value.dataType = 'all'
selectForm.value.faultName = ''
selectForm.value.faultCode = ''
pagerinfo.pageNow = 1
pagerinfo.pageSize = 20
initTime()
}
function faultImg(faultLevel: string) {
if (!faultLevel)
return ''
if (faultLevel === '严重故障' || faultLevel === '严重预警') {
return './img/red-warning.png'
}
if (faultLevel === '中等故障' || faultLevel === '中等预警') {
return './img/orange-warning.png'
}
if (faultLevel === '轻微故障' || faultLevel === '轻微预警')
return './img/slight-warning.png'
}
// 修改分页器默认文字
zhCn.el.pagination.total = '共 {total} 条'
zhCn.el.pagination.goto = '前往'
zhCn.el.pagination.pageClassifier = '页'
const background = ref(true)
function onSearch() {
if (selectForm.value.trainNumber.length === 0 || selectForm.value.belongSystem.length === 0)
return
GetFaultWarnData(selectQuery.value)
}
// 列车全选
const checkAllVehicle = ref(false)
const indeterminate = ref(false)
const vehicleValue = ref<CheckboxValueType[]>([])
watch(vehicleValue, (val) => {
if (val.length === 0) {
checkAllVehicle.value = false
indeterminate.value = false
}
else if (val.length === selectForm.value.trainNumber.length) {
checkAllVehicle.value = true
indeterminate.value = false
}
else {
indeterminate.value = true
}
})
function handleCheckAll(val: CheckboxValueType) {
indeterminate.value = false
if (val) {
selectForm.value.trainNumber = trainNumberList.value.map(el => el.value)
vehicleValue.value = selectForm.value.trainNumber.map(el => el)
}
else {
vehicleValue.value = []
selectForm.value.trainNumber = []
}
}
// 所属系统全选
const checkAllSystem = ref(false)
const indetersystem = ref(false)
const systemValue = ref<CheckboxValueType[]>([])
watch(systemValue, (val) => {
if (val.length === 0) {
checkAllSystem.value = false
indetersystem.value = false
}
else if (val.length === selectForm.value.belongSystem.length) {
checkAllSystem.value = true
indetersystem.value = false
}
else {
indetersystem.value = true
}
})
function handleCheckAllSystem(val: CheckboxValueType) {
indetersystem.value = false
if (val) {
selectForm.value.belongSystem = belongSysList.value.map(el => el.value)
systemValue.value = selectForm.value.belongSystem.map(el => el)
}
else {
systemValue.value = []
selectForm.value.belongSystem = []
}
}
watch([() => selectForm.value.lineOid, () => getLinkageData.value], () => {
selectForm.value.trainNumber = props.value.lineType === 0 ? trainNumberList.value.map(el => el.value) : [props.value.lineOrVehicleId]
selectForm.value.belongSystem = belongSysList.value.map(el => el.value)
GetLinkageData(lineOidListQuery.value)
if (props.value.lineType === 0) {
checkAllVehicle.value = true
}
else {
checkAllVehicle.value = false
}
checkAllSystem.value = true
})
// 监听
watch([() => props.value.lineOids, () => !isActive.value], onSearch)
watch(() => pagerinfo.pageNow, onSearch)
onMounted(() => {
if (routePath.value === true && getLinkageData.value !== null) {
onReload()
setTimeout(() => {
onSearch()
}, 2000)
}
})
</script>
<template>
<ElConfigProvider :locale="zhCn">
<div class="dialog-container w-100% h-full flex flex-col justify-between">
<div class="dislog-header flex justify-between items-center h-3.12rem px-0.7rem">
<div class="text-1.25rem color-#ffffff mb-0.3rem">
<span>当日事件</span>
</div>
</div>
<!-- 切换 -->
<div class="dialog-fault-type mx-0.7rem mt-0.81rem mb-0.5rem flex">
<div
:class="!isActive ? 'isActiveBg' : ''"
class="h-2.2rem text-0.875rem px-2.02rem color-#ffffff flex items-center"
@click="isActive = false"
>
故障查询
</div>
<div
:class="isActive ? 'isActiveBg' : ''"
class="h-2.2rem text-0.875rem px-2.02rem color-#ffffff flex items-center"
@click="isActive = true"
>
预警查询
</div>
</div>
<!-- 条件筛选 -->
<div class="dialog-select mx-0.7rem">
<div class="flex w-100% justify-start flex-wrap">
<div class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select
v-model="selectForm.lineOid" filterable collapse-tags :max-collapse-tags="1" multiple
placeholder="线路" popper-class="mySelectStyle"
>
<el-option label="5号线" value="E3E7CE840763E8449827880D2E710DDF" no-data-text />
<el-option label="8号线" value="5A5E69C4259D4340A7F0FC71602A784C" no-data-text />
<el-option label="10号线" value="C0C42CD4B1E2CE4CB73104ED8E3134B1" no-data-text />
</el-select>
</div>
<div class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select
v-model="selectForm.trainNumber" filterable collapse-tags :max-collapse-tags="1" multiple
placeholder="列车" popper-class="mySelectStyle"
>
<template #header>
<el-checkbox
v-model="checkAllVehicle"
:indeterminate="indeterminate"
@change="handleCheckAll"
>
全选
</el-checkbox>
</template>
<el-option
v-for="item in trainNumberList" :key="item.value" :label="item.label" :value="item.value"
no-data-text
>
<span>
<div class="inline-block bg-#00ff2e mr-0.6rem w-0.5rem h-0.5rem line-height-0.5rem rounded-50%">
</div>{{ item.label }}
</span>
</el-option>
</el-select>
</div>
<div class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select
v-model="selectForm.belongSystem" filterable collapse-tags :max-collapse-tags="1" multiple
placeholder="所属系统" popper-class="mySelectStyle"
>
<template #header>
<el-checkbox
v-model="checkAllSystem"
:indetersystem="indetersystem"
@change="handleCheckAllSystem"
>
全选
</el-checkbox>
</template>
<el-option
v-for="item in belongSysList" :key="item.value" :label="item.label" :value="item.value"
no-data-text
/>
</el-select>
</div>
<div class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select
v-model="selectForm.faultLevel" filterable collapse-tags :max-collapse-tags="1" multiple
:placeholder="!isActive ? '故障等级' : '预警等级'" popper-class="mySelectStyle"
>
<el-option label="严重" value="3" no-data-text />
<el-option label="中等" value="2" no-data-text />
<el-option label="轻微" value="1" no-data-text />
</el-select>
</div>
<div class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select v-model="selectForm.isTrigger" filterable placeholder="解除状态" popper-class="mySelectStyle">
<el-option label="全部" value="all" no-data-text />
<el-option label="已解除" value="0" no-data-text />
<el-option label="未解除" value="1" no-data-text />
</el-select>
</div>
<div class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select v-model="selectForm.operState" filterable placeholder="正线库内" popper-class="mySelectStyle">
<el-option label="全部" value="all" no-data-text />
<el-option label="正线" value="RUN" no-data-text />
<el-option label="库内" value="STOP" no-data-text />
</el-select>
</div>
<div v-if="!isActive" class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-select v-model="selectForm.dataType" filterable placeholder="数据来源" popper-class="mySelectStyle">
<el-option label="全部" value="all" no-data-text />
<el-option label="自动生成" value="0" no-data-text />
<el-option label="手工导入" value="1" no-data-text />
</el-select>
</div>
<div v-if="!isActive" class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-input v-model="selectForm.faultName" placeholder="故障名称" />
</div>
<div v-if="!isActive" class="select-input w-15.65% mb-1rem mr-0.8rem">
<el-input v-model="selectForm.faultCode" placeholder="故障代码" />
</div>
<div class="select-input w-15.65% flex justify-between mr-0.8rem">
<el-date-picker
v-model="selectForm.startTime"
type="datetime"
:clearable="false"
:disabled-date="disableStartDate"
/>
</div>
<div class="select-input w-15.65% flex justify-between">
<el-date-picker
v-model="selectForm.endTime"
type="datetime"
:clearable="false"
:disabled-date="disabledEndDate"
/>
</div>
<div class="w-15.65% flex justify-between ml-0.8rem mb-1rem">
<el-button class="w-47%" type="primary" @click="onSearch()">
查询
</el-button>
<el-button class="w-47%" plain @click="onReload()">
重置
</el-button>
</div>
</div>
</div>
<!-- 查询列表 -->
<div class="dialog-content h-39.2rem overflow-scroll px-0.7rem">
<el-table :stripe="true" :data="faultList" style="height:97%;">
<el-table-column fixed type="index" label="序号" />
<el-table-column property="faultLevel_ZH" :label="!isActive ? '故障等级' : '预警等级'">
<template #default="scope">
<div style="display: flex; align-items: center">
<img :src="faultImg(scope.row.faultLevel_ZH)" alt="">
<span style="margin-left: 10px">{{ scope.row.faultLevel_ZH }}</span>
</div>
</template>
</el-table-column>
<el-table-column property="vehicleNumber" label="列车号" />
<el-table-column property="carriage" label="车厢" />
<el-table-column property="faultCode" label="故障代码" />
<el-table-column property="faultName" label="故障名称" show-overflow-tooltip />
<el-table-column property="belongSystem_ZH" label="所属系统" />
<el-table-column property="occurPosition" label="发生位置" />
<el-table-column property="operState_ZH" label="正线库内" />
<el-table-column property="isTrigger_ZH" label="解除状态">
<template #default="scope">
<div class="flex items-center">
<div :class="scope.row.isTrigger_ZH === '已解除' ? 'bg-#00ff2e' : 'bg-#FF4444'" class="mr-0.2rem w-0.5rem h-0.5rem rounded-50%" />
<span>
{{ scope.row.isTrigger_ZH }}
</span>
</div>
</template>
</el-table-column>
<el-table-column property="occurTime" label="发生时间" />
<el-table-column property="relieveTime" label="解除时间" />
<el-table-column property="durationTime" label="持续时长" show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row.durationTime ? `${scope.row.durationTime}` : '-' }}</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="dialog-pages px-0.7rem mb-0.7rem">
<el-pagination
v-model:currentPage="pagerinfo.pageNow" v-model:page-size="pagerinfo.pageSize"
:background="background" layout="total, prev, pager, next, jumper"
:total="parseInt(getFaultWarnData?.RowCount ?? '0')"
/>
</div>
</div>
</ElConfigProvider>
</template>
<style lang="less">
/* 隐藏滚动条 */
::-webkit-scrollbar {
display: none;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.el-popper.is-light {
border: 0;
}
.el-popper {
max-width: 10.8%;
.mySelectStyle {
background-color: #000f30;
}
.el-select-dropdown {
border-radius: 2px;
border: 1px solid rgba(131, 187, 255, 0.5);
.el-select-dropdown__header {
border-bottom: 1px solid rgba(131, 187, 255, 0.5);
padding-left: 1rem;
padding-top: 0.2rem;
padding-bottom: 0.2rem;
}
.el-select-dropdown__list {
padding: 0;
.el-select-dropdown__item {
color: #fff;
}
.el-select-dropdown__item.is-hovering {
background-color: #063c8d;
color: #fff;
}
}
}
.el-checkbox {
--el-checkbox-text-color: #ffffff;
--el-checkbox-input-border: 1px solid rgba(131, 187, 255, 0.5);
--el-checkbox-input-border-color-hover: rgba(131, 187, 255, 0.5);
--el-checkbox-checked-bg-color: #3e81d2;
--el-checkbox-checked-input-border-color: #3e81d2;
--el-checkbox-checked-text-color: #3e81d2;
}
.el-checkbox__inner {
background-color: rgba(0, 0, 0, 0);
}
.el-popper__arrow {
display: none;
}
.el-picker-panel .el-time-panel {
background-color: #000f30;
border: 1px solid rgba(131, 187, 255, 0.5);
}
}
.el-date-picker {
background-color: #000f30;
color: #ffffff;
border: 1px solid rgba(131, 187, 255, 0.5);
.el-date-picker__header-label,
.el-time-spinner__item {
color: #ffffff;
}
.el-date-picker__time-header {
border-bottom: 1px solid rgba(131, 187, 255, 0.5);
}
.el-time-panel__footer {
display: none;
border-top: 1px solid rgba(131, 187, 255, 0.5);
}
.el-time-panel {
background-color: #05224f;
}
.el-picker-panel__footer {
display: none;
}
.el-date-table th {
border-bottom: 1px solid rgba(131, 187, 255, 0.5);
}
.el-time-spinner__item.is-active:not(.is-disabled) {
color: #3e81d2;
background-color: rgba(0, 0, 0, 0) !important;
}
.el-time-spinner__item:hover {
background-color: #3e81d2 !important;
}
.el-time-panel__content:before {
border-bottom: 1px solid rgba(131, 187, 255, 0.5);
border-top: 1px solid rgba(131, 187, 255, 0.5);
}
}
.select-input,
.el-date-picker__editor-wrap {
.el-input {
--el-input-bg-color: #010516 !important;
--el-input-border-radius: 2px !important;
--el-input-border-color: rgba(131, 187, 255, 0.5);
--el-input-hover-border-color: rgba(131, 187, 255, 0.5);
--el-input-focus-border-color: rgba(131, 187, 255, 0.5);
.el-input__inner {
color: #a8abb2;
}
}
}
.el-picker-panel__icon-btn,
.el-date-table th,
.el-year-table td .cell,
.el-month-table td .cell {
color: #ffffff;
}
.el-year-table td.current:not(.disabled) .cell,
.el-month-table td.current:not(.disabled) .cell {
background-color: #3e81d2;
}
.el-date-picker__header--bordered {
border-bottom: 1px solid rgba(131, 187, 255, 0.5);
}
.el-date-table td.disabled .el-date-table-cell {
background-color: rgba(255, 255, 255, 0.1);
}
</style>
<style lang="less" scoped>
.dialog-container {
background-image: url('/img/daily-event-bg.png');
background-size: 100% 100%;
}
.dislog-header {
background-image: url('/img/daily-event-title.png');
background-size: 100% 100%;
}
.custom-select-bg {
background-color: rgba(255, 0, 0, 0) !important;
}
.dialog-fault-type {
border-bottom: 1px solid #0e4388;
}
.isActiveBg {
background: #3e81d2;
}
/**element-plus组件默认样式修改*/
::v-deep(.el-table--striped .el-table__body tr.el-table__row--striped td) {
background: #0b2a5a;
}
::v-deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
background: url(255,255,255);
}
.dialog-container {
--el-fill-color-blank: #010516;
}
::v-deep(.el-select__wrapper) {
border-radius: 2px;
--el-border-color: rgba(131, 187, 255, 0.5);
--el-select-border-color-hover: rgba(131, 187, 255, 0.5);
}
::v-deep(.el-select__wrapper.is-hovering:not(.is-focused)) {
box-shadow: 0 0 0 1px rgba(131, 187, 255, 0.5) inset;
}
::v-deep(.el-select__placeholder) {
color: #a8abb2;
}
::v-deep(.el-table) {
color: #fff;
font-size: 12px;
--el-table-border: 0;
--el-table-header-bg-color: #0e4388;
--el-table-header-text-color: #ffffff;
--el-table-bg-color: #05224f;
--el-table-tr-bg-color: #05224f;
--el-table-border-color: #05224f;
--el-table-row-hover-bg-color: rgba(255, 255, 255, 0);
}
::v-deep(.el-button) {
border-radius: 2px;
}
::v-deep(.el-button--primary) {
--el-button-bg-color: #3e81d2;
}
::v-deep(.el-button.is-plain) {
--el-button-bg-color: #05224f;
--el-button-hover-text-color: #83bbff;
--el-button-hover-bg-color: rgb(0, 0, 0, 0.4);
--el-button-border-color: #83bbff;
color: #83bbff;
}
::v-deep(.el-pagination.is-background .btn-next:disabled),
::v-deep(.el-pagination.is-background .btn-prev:disabled) {
background-color: #05224f;
color: #fff;
}
::v-deep(.el-pagination.is-background .el-pager li.is-active) {
--el-button-bg-color: #3e81d2;
border-radius: 2px;
}
::v-deep(.el-pagination) {
--el-pagination-button-bg-color: #05224f;
--el-pagination-button-color: #ffffff;
}
.dialog-pages::v-deep(.el-input__wrapper) {
background-color: #05224f;
}
::v-deep .el-input {
--el-input-border-color: rgba(131, 187, 255, 0.5);
--el-input-border-radius: 2px;
--el-input-hover-border-color: rgba(131, 187, 255, 0.5);
}
::v-deep(.el-pagination__total),
::v-deep(.el-pagination__jump),
.el-pagination ::v-deep(.el-input__inner) {
color: #fff;
}
::v-deep(.el-date-editor.el-input) {
width: 100%;
}
::v-deep(.el-pagination__total) {
color: #76b6ff;
font-size: 12px;
}
.dialog-container {
.dialog-select {
::v-deep .el-select__wrapper.is-focused,
.el-input__wrapper.isfocus {
box-shadow: 0 0 0 1px rgba(131, 187, 255, 0.5);
}
}
}
:deep(.el-tag.el-tag--info) {
color: #ffffff;
--el-tag-bg-color: rgba(62, 129, 210, 0.2);
--el-tag-border-color: var(--el-color-info-light-8);
--el-tag-hover-color: var(--el-color-info);
}
</style>