Files
CN_Tool_client/frontend/src/views/components/TimePeriodSearch/index.vue
yexb 055e69fff7 feat(steady): 完善稳态数据视图功能
- 更新纵坐标刻度算法,优化小数趋势图范围显示
- 添加稳态趋势图全屏模式和共享工具组件
- 实现多图联动的鼠标悬停竖线同步功能
- 调整主线线宽分档策略,降低最大线宽限制
- 重构稳态趋势工具栏,优化谐波次数选择逻辑
- 添加周时间周期搜索支持和自定义时间范围选择
- 完善稳态数据表格和指示器浮动面板功能
- 优化稳态趋势图性能,添加LTB采样和动画控制
- 修复数据表格打开前的趋势数据验证问题
- 统一时间轴标签格式化和网格对齐处理
2026-05-27 08:06:12 +08:00

157 lines
4.1 KiB
Vue

<template>
<div class="time-period-search">
<el-select class="time-period-search__unit" :model-value="unit" @update:model-value="handleUnitChange">
<el-option
v-for="item in visibleTimePeriodUnitOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button
v-if="!isCustomUnit"
class="time-period-search__button"
:icon="ArrowLeft"
:title="`上一个${unitLabel}`"
@click="shiftPeriod(-1)"
/>
<el-date-picker
v-if="!isCustomUnit"
class="time-period-search__picker"
:model-value="baseDate"
:type="getTimePeriodPickerType(props.unit)"
:format="getTimePeriodPickerFormat(props.unit)"
:clearable="false"
:editable="false"
:placeholder="`选择${unitLabel}`"
@update:model-value="handleDateChange"
/>
<el-date-picker
v-else
class="time-period-search__range-picker"
:model-value="rangeValue"
type="datetimerange"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss.SSS"
range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间"
:clearable="false"
:editable="false"
@update:model-value="handleRangeChange"
/>
<el-button
v-if="!isCustomUnit"
class="time-period-search__button"
:icon="ArrowRight"
:title="`下一个${unitLabel}`"
@click="shiftPeriod(1)"
/>
<el-button
v-if="!isCustomUnit"
class="time-period-search__button"
:icon="Clock"
:title="`当前${unitLabel}`"
@click="setCurrentPeriod"
/>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { ArrowLeft, ArrowRight, Clock } from '@element-plus/icons-vue'
import {
getTimePeriodPickerFormat,
getTimePeriodPickerType,
resolveTimePeriodUnitLabel,
shiftTimePeriod,
timePeriodUnitOptions,
type TimePeriodUnit
} from './timePeriod'
defineOptions({
name: 'TimePeriodSearch'
})
const props = defineProps<{
unit: TimePeriodUnit
modelValue: Date | string | number
rangeValue?: string[]
visibleUnits?: TimePeriodUnit[]
}>()
const emit = defineEmits<{
'update:unit': [value: TimePeriodUnit]
'update:modelValue': [value: Date]
'update:rangeValue': [value: string[]]
}>()
const baseDate = computed(() => new Date(props.modelValue))
const unitLabel = computed(() => resolveTimePeriodUnitLabel(props.unit))
const isCustomUnit = computed(() => props.unit === 'custom')
const visibleTimePeriodUnitOptions = computed(() => {
if (!props.visibleUnits?.length) return timePeriodUnitOptions
return timePeriodUnitOptions.filter(item => props.visibleUnits?.includes(item.value))
})
const rangeValue = computed(() => props.rangeValue || [])
const handleUnitChange = (value: TimePeriodUnit) => {
emit('update:unit', value)
}
const handleDateChange = (value: Date | string | number | null) => {
if (!value) return
emit('update:modelValue', new Date(value))
}
const handleRangeChange = (value: string[] | null) => {
if (!value?.length) return
emit('update:rangeValue', value)
}
const shiftPeriod = (offset: number) => {
emit('update:modelValue', shiftTimePeriod(props.unit, baseDate.value, offset))
}
const setCurrentPeriod = () => {
emit('update:modelValue', new Date())
}
</script>
<style scoped lang="scss">
.time-period-search {
display: flex;
width: 100%;
align-items: center;
gap: 4px;
}
.time-period-search__unit {
width: 56px;
flex: 0 0 56px;
}
.time-period-search__picker {
width: 112px;
flex: 0 0 112px;
}
.time-period-search__range-picker {
width: 360px;
flex: 1 1 360px;
min-width: 280px;
}
.time-period-search__button {
width: 28px;
flex: 0 0 28px;
padding: 8px 6px;
}
</style>