style:设备运行参数分析-时间控件优化

main
黄伟杰 1 week ago
parent 3a795c9632
commit 0e8771c22e

@ -33,15 +33,19 @@
<ContentWrap v-for="group in selectedGroups" :key="group.id"> <ContentWrap v-for="group in selectedGroups" :key="group.id">
<el-form class="-mb-15px device-param-analysis-form" :inline="true" label-width="auto"> <el-form class="-mb-15px device-param-analysis-form" :inline="true" label-width="auto">
<el-form-item :label="t('DataCollection.DeviceParamAnalysis.formTimeLabel')"> <el-form-item :label="t('DataCollection.DeviceParamAnalysis.formTimeLabel')">
<el-date-picker <div>
v-model="group.dateRange" <el-date-picker
type="datetimerange" v-model="group.dateRange"
:start-placeholder="t('DataCollection.DeviceParamAnalysis.formTimeStartPlaceholder')" type="datetimerange"
:end-placeholder="t('DataCollection.DeviceParamAnalysis.formTimeEndPlaceholder')" :start-placeholder="t('DataCollection.DeviceParamAnalysis.formTimeStartPlaceholder')"
value-format="YYYY-MM-DD HH:mm:ss" :end-placeholder="t('DataCollection.DeviceParamAnalysis.formTimeEndPlaceholder')"
:shortcuts="dateShortcuts" value-format="YYYY-MM-DD HH:mm:ss"
class="!w-360px" :shortcuts="dateShortcuts"
/> class="!w-360px"
:disabled-date="disableFutureDate"
@change="(value) => handleDateRangeChange(group, value)"
/>
</div>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button :disabled="group.chartLoading" @click="handleQuery(group)"> <el-button :disabled="group.chartLoading" @click="handleQuery(group)">
@ -131,45 +135,37 @@ const keyword = ref('')
const treeProps = { children: 'children', label: 'label', disabled: 'disabled' } const treeProps = { children: 'children', label: 'label', disabled: 'disabled' }
const treeData = ref<DeviceTreeNode[]>([]) const treeData = ref<DeviceTreeNode[]>([])
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'
const MAX_DATE_RANGE_HOURS = 8
const MAX_DATE_RANGE_MS = MAX_DATE_RANGE_HOURS * 60 * 60 * 1000
const lastValidDateRange = new Map<string, [string, string]>()
const disableFutureDate = (date: Date) => {
return dayjs(date).isAfter(dayjs(), 'day')
}
const buildDefaultDateRange = (): [string, string] => { const buildDefaultDateRange = (): [string, string] => {
const end = dayjs() const end = dayjs()
const start = end.subtract(2, 'hour') const start = end.subtract(2, 'hour')
return [start.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss')] return [start.format(DATE_TIME_FORMAT), end.format(DATE_TIME_FORMAT)]
} }
const dateShortcuts = [ const createLastHoursShortcut = (hours: number) => {
{ return {
text: t('DataCollection.DeviceParamAnalysis.shortcutLast7Days'), text: `最近${hours}小时`,
value: () => {
const end = dayjs().endOf('day').toDate()
const start = dayjs().subtract(6, 'day').startOf('day').toDate()
return [start, end]
}
},
{
text: t('DataCollection.DeviceParamAnalysis.shortcutLastWeek'),
value: () => {
const start = dayjs().subtract(1, 'week').startOf('week').toDate()
const end = dayjs().subtract(1, 'week').endOf('week').toDate()
return [start, end]
}
},
{
text: t('DataCollection.DeviceParamAnalysis.shortcutLastMonth'),
value: () => {
const start = dayjs().subtract(1, 'month').startOf('month').toDate()
const end = dayjs().subtract(1, 'month').endOf('month').toDate()
return [start, end]
}
},
{
text: t('DataCollection.DeviceParamAnalysis.shortcutLast3Months'),
value: () => { value: () => {
const end = dayjs().endOf('day').toDate() const end = dayjs().toDate()
const start = dayjs().subtract(3, 'month').startOf('day').toDate() const start = dayjs().subtract(hours, 'hour').toDate()
return [start, end] return [start, end]
} }
} }
}
const dateShortcuts = [
createLastHoursShortcut(1),
createLastHoursShortcut(2),
createLastHoursShortcut(4),
createLastHoursShortcut(8)
] ]
type ChartState = 'idle' | 'loading' | 'empty' | 'ready' type ChartState = 'idle' | 'loading' | 'empty' | 'ready'
@ -346,10 +342,78 @@ const loadTree = async () => {
} }
} }
const normalizeDateRangeValue = (value: any): [string, string] | undefined => {
if (!Array.isArray(value) || value.length !== 2) return undefined
const start = value[0]
const end = value[1]
if (!start || !end) return undefined
return [String(start), String(end)]
}
const ensureDateRangeWithin8Hours = (group: SelectedGroup, dateRange: [string, string]) => {
const now = dayjs()
let start = dayjs(dateRange[0])
let end = dayjs(dateRange[1])
if (!start.isValid() || !end.isValid()) return dateRange
if (start.isAfter(now) && end.isAfter(now)) {
end = now
start = now.subtract(2, 'hour')
} else {
if (end.isAfter(now)) end = now
if (start.isAfter(now)) start = end.subtract(2, 'hour')
}
const diffMs = end.valueOf() - start.valueOf()
if (diffMs < 0) {
end = now
start = now.subtract(2, 'hour')
const nextRange: [string, string] = [start.format(DATE_TIME_FORMAT), end.format(DATE_TIME_FORMAT)]
return nextRange
}
if (diffMs <= MAX_DATE_RANGE_MS) {
return [start.format(DATE_TIME_FORMAT), end.format(DATE_TIME_FORMAT)]
}
const clampedEnd = start.add(MAX_DATE_RANGE_HOURS, 'hour')
const finalEnd = clampedEnd.isAfter(now) ? now : clampedEnd
return [start.format(DATE_TIME_FORMAT), finalEnd.format(DATE_TIME_FORMAT)]
}
const ensureDateRange = (group: SelectedGroup) => { const ensureDateRange = (group: SelectedGroup) => {
if (!group.dateRange || group.dateRange.length !== 2) { if (!group.dateRange || group.dateRange.length !== 2) {
group.dateRange = buildDefaultDateRange() group.dateRange = buildDefaultDateRange()
lastValidDateRange.set(group.id, group.dateRange)
return
}
const normalized = normalizeDateRangeValue(group.dateRange)
if (!normalized) {
group.dateRange = buildDefaultDateRange()
lastValidDateRange.set(group.id, group.dateRange)
return
}
const nextRange = ensureDateRangeWithin8Hours(group, normalized)
group.dateRange = nextRange
lastValidDateRange.set(group.id, nextRange)
}
const handleDateRangeChange = (group: SelectedGroup, value: any) => {
const normalized = normalizeDateRangeValue(value) || normalizeDateRangeValue(group.dateRange)
if (!normalized) return
const now = dayjs()
const selectedStart = dayjs(normalized[0])
const selectedEnd = dayjs(normalized[1])
const hasFuture = (selectedStart.isValid() && selectedStart.isAfter(now)) || (selectedEnd.isValid() && selectedEnd.isAfter(now))
const nextRange = ensureDateRangeWithin8Hours(group, normalized)
const isClamped = nextRange[0] !== normalized[0] || nextRange[1] !== normalized[1]
if (hasFuture) {
message.warning('不能选择未来日期')
} else if (isClamped) {
message.warning('时间范围最多只能选择 8 小时')
} }
group.dateRange = nextRange
lastValidDateRange.set(group.id, nextRange)
} }
const resetChartData = (group: SelectedGroup) => { const resetChartData = (group: SelectedGroup) => {
@ -536,6 +600,7 @@ const syncGroupsByCheckedNodes = (checkedNodes: DeviceTreeNode[]) => {
chartRenderKey: 0 chartRenderKey: 0
} }
selectedGroups.value.push(group) selectedGroups.value.push(group)
lastValidDateRange.set(group.id, group.dateRange)
addedGroups.push(group) addedGroups.push(group)
} }
return addedGroups return addedGroups

Loading…
Cancel
Save