|
@@ -266,6 +266,7 @@
|
|
|
v-model="timelineDuration"
|
|
v-model="timelineDuration"
|
|
|
size="small"
|
|
size="small"
|
|
|
style="width: 100px"
|
|
style="width: 100px"
|
|
|
|
|
+ :disabled="isTimelinePlaying"
|
|
|
@change="handleDurationChange"
|
|
@change="handleDurationChange"
|
|
|
>
|
|
>
|
|
|
<el-option :value="60" :label="t('1分钟')" />
|
|
<el-option :value="60" :label="t('1分钟')" />
|
|
@@ -273,7 +274,16 @@
|
|
|
<el-option :value="300" :label="t('5分钟')" />
|
|
<el-option :value="300" :label="t('5分钟')" />
|
|
|
<el-option :value="600" :label="t('10分钟')" />
|
|
<el-option :value="600" :label="t('10分钟')" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
- <el-button size="small" @click="addTimelinePoint()">+ {{ t('添加点') }}</el-button>
|
|
|
|
|
|
|
+ <el-button size="small" :disabled="isTimelinePlaying" @click="addTimelinePoint()">
|
|
|
|
|
+ + {{ t('添加点') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="isLoopEnabled"
|
|
|
|
|
+ :disabled="isTimelinePlaying"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ :active-text="t('循环')"
|
|
|
|
|
+ style="margin-left: 8px"
|
|
|
|
|
+ />
|
|
|
<el-button
|
|
<el-button
|
|
|
size="small"
|
|
size="small"
|
|
|
type="primary"
|
|
type="primary"
|
|
@@ -292,7 +302,7 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 时间轴轨道 -->
|
|
<!-- 时间轴轨道 -->
|
|
|
- <div class="timeline-track" ref="timelineTrackRef" @click="handleTimelineClick">
|
|
|
|
|
|
|
+ <div :class="['timeline-track', { 'is-playing': isTimelinePlaying }]" ref="timelineTrackRef">
|
|
|
<!-- 时间轴进度指示器 -->
|
|
<!-- 时间轴进度指示器 -->
|
|
|
<div class="timeline-progress" :style="{ width: `${timelineProgress}%` }"></div>
|
|
<div class="timeline-progress" :style="{ width: `${timelineProgress}%` }"></div>
|
|
|
<!-- 关键点 -->
|
|
<!-- 关键点 -->
|
|
@@ -303,14 +313,14 @@
|
|
|
'timeline-point',
|
|
'timeline-point',
|
|
|
{
|
|
{
|
|
|
active: point.active,
|
|
active: point.active,
|
|
|
- selected: selectedPoint?.id === point.id,
|
|
|
|
|
|
|
+ selected: !isTimelinePlaying && selectedPoint?.id === point.id,
|
|
|
dragging: draggingPoint?.id === point.id
|
|
dragging: draggingPoint?.id === point.id
|
|
|
}
|
|
}
|
|
|
]"
|
|
]"
|
|
|
:style="{ left: `${(point.time / timelineDuration) * 100}%` }"
|
|
:style="{ left: `${(point.time / timelineDuration) * 100}%` }"
|
|
|
- @click.stop="selectPoint(point)"
|
|
|
|
|
- @mousedown.stop="startDragPoint($event, point)"
|
|
|
|
|
- @contextmenu.prevent="handlePointContextMenu($event, point)"
|
|
|
|
|
|
|
+ @click.stop="!isTimelinePlaying && selectPoint(point)"
|
|
|
|
|
+ @mousedown.stop="!isTimelinePlaying && startDragPoint($event, point)"
|
|
|
|
|
+ @contextmenu.prevent="!isTimelinePlaying && handlePointContextMenu($event, point)"
|
|
|
>
|
|
>
|
|
|
<span class="point-label">{{ point.id }}</span>
|
|
<span class="point-label">{{ point.id }}</span>
|
|
|
<div class="point-tooltip">
|
|
<div class="point-tooltip">
|
|
@@ -327,16 +337,47 @@
|
|
|
</span>
|
|
</span>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <!-- 选中点的操作面板 -->
|
|
|
|
|
- <div v-if="selectedPoint" class="timeline-point-panel">
|
|
|
|
|
|
|
+ <!-- 选中点的操作面板(巡航中隐藏) -->
|
|
|
|
|
+ <div v-if="selectedPoint && !isTimelinePlaying" class="timeline-point-panel">
|
|
|
<span class="panel-label">
|
|
<span class="panel-label">
|
|
|
{{ t('当前选中') }}: {{ selectedPoint.presetName || `Point ${selectedPoint.id}` }}
|
|
{{ t('当前选中') }}: {{ selectedPoint.presetName || `Point ${selectedPoint.id}` }}
|
|
|
</span>
|
|
</span>
|
|
|
|
|
+ <!-- 关联已有预置位 -->
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="linkPresetId"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ :placeholder="t('关联预置位')"
|
|
|
|
|
+ style="width: 140px"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="handleLinkPreset"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="preset in ptzPresetList"
|
|
|
|
|
+ :key="preset.id"
|
|
|
|
|
+ :value="preset.id"
|
|
|
|
|
+ :label="preset.name || `Preset ${preset.id}`"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
<el-button size="small" type="primary" :loading="savingPreset" @click="saveCurrentPoint">
|
|
<el-button size="small" type="primary" :loading="savingPreset" @click="saveCurrentPoint">
|
|
|
{{ selectedPoint.active ? t('更新位置') : t('保存位置') }}
|
|
{{ selectedPoint.active ? t('更新位置') : t('保存位置') }}
|
|
|
</el-button>
|
|
</el-button>
|
|
|
<el-button size="small" type="danger" @click="deleteSelectedPoint">{{ t('删除') }}</el-button>
|
|
<el-button size="small" type="danger" @click="deleteSelectedPoint">{{ t('删除') }}</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <!-- 自动映射按钮(巡航中隐藏) -->
|
|
|
|
|
+ <div v-if="timelinePoints.length > 0 && !isTimelinePlaying" class="timeline-auto-link">
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ @click="autoLinkPresets"
|
|
|
|
|
+ :disabled="ptzPresetList.length === 0"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-icon>
|
|
|
|
|
+ <Link />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ {{ t('自动映射') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <span class="auto-link-hint">{{ t('将点1-N映射到Preset 1-N') }}</span>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 底部播放控制 -->
|
|
<!-- 底部播放控制 -->
|
|
@@ -627,7 +668,8 @@ import {
|
|
|
ZoomIn,
|
|
ZoomIn,
|
|
|
ZoomOut,
|
|
ZoomOut,
|
|
|
Close,
|
|
Close,
|
|
|
- Position
|
|
|
|
|
|
|
+ Position,
|
|
|
|
|
+ Link
|
|
|
} from '@element-plus/icons-vue'
|
|
} from '@element-plus/icons-vue'
|
|
|
import { Icon } from '@iconify/vue'
|
|
import { Icon } from '@iconify/vue'
|
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useI18n } from 'vue-i18n'
|
|
@@ -732,6 +774,8 @@ const selectedPoint = ref<TimelinePoint | null>(null)
|
|
|
const isTimelinePlaying = ref(false)
|
|
const isTimelinePlaying = ref(false)
|
|
|
const timelineProgress = ref(0)
|
|
const timelineProgress = ref(0)
|
|
|
const savingPreset = ref(false)
|
|
const savingPreset = ref(false)
|
|
|
|
|
+const linkPresetId = ref<string | null>(null) // 关联预置位选择
|
|
|
|
|
+const isLoopEnabled = ref(false) // 是否循环巡航
|
|
|
let timelinePlayAbort: AbortController | null = null
|
|
let timelinePlayAbort: AbortController | null = null
|
|
|
|
|
|
|
|
// 拖拽状态
|
|
// 拖拽状态
|
|
@@ -1547,22 +1591,6 @@ function formatTimelineTime(seconds: number): string {
|
|
|
return `${mins}:${secs.toString().padStart(2, '0')}`
|
|
return `${mins}:${secs.toString().padStart(2, '0')}`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 点击时间轴添加点
|
|
|
|
|
-function handleTimelineClick(e: MouseEvent) {
|
|
|
|
|
- // 如果正在拖拽,不添加点
|
|
|
|
|
- if (draggingPoint.value) return
|
|
|
|
|
-
|
|
|
|
|
- const track = timelineTrackRef.value
|
|
|
|
|
- if (!track) return
|
|
|
|
|
-
|
|
|
|
|
- const rect = track.getBoundingClientRect()
|
|
|
|
|
- const x = e.clientX - rect.left
|
|
|
|
|
- const percent = x / rect.width
|
|
|
|
|
- const time = Math.round(percent * timelineDuration.value)
|
|
|
|
|
-
|
|
|
|
|
- addTimelinePoint(time)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
// 开始拖拽点
|
|
// 开始拖拽点
|
|
|
function startDragPoint(e: MouseEvent, point: TimelinePoint) {
|
|
function startDragPoint(e: MouseEvent, point: TimelinePoint) {
|
|
|
// 只响应鼠标左键
|
|
// 只响应鼠标左键
|
|
@@ -1701,6 +1729,55 @@ function deleteSelectedPoint() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 关联已有预置位
|
|
|
|
|
+function handleLinkPreset(presetId: string | null) {
|
|
|
|
|
+ if (!selectedPoint.value || !presetId) {
|
|
|
|
|
+ linkPresetId.value = null
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const preset = ptzPresetList.value.find((p) => p.id === presetId)
|
|
|
|
|
+ if (preset) {
|
|
|
|
|
+ selectedPoint.value.presetId = parseInt(preset.id)
|
|
|
|
|
+ selectedPoint.value.presetName = preset.name || `Preset ${preset.id}`
|
|
|
|
|
+ selectedPoint.value.active = true
|
|
|
|
|
+ saveTimelineConfig()
|
|
|
|
|
+ ElMessage.success(`${t('已关联')}: ${selectedPoint.value.presetName}`)
|
|
|
|
|
+ linkPresetId.value = null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 自动映射:点1-N 对应 Preset 1-N
|
|
|
|
|
+function autoLinkPresets() {
|
|
|
|
|
+ if (ptzPresetList.value.length === 0) {
|
|
|
|
|
+ ElMessage.warning(t('暂无可用预置位'))
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 按ID排序预置位列表(取前几个数字小的)
|
|
|
|
|
+ const sortedPresets = [...ptzPresetList.value]
|
|
|
|
|
+ .filter((p) => !isNaN(parseInt(p.id)))
|
|
|
|
|
+ .sort((a, b) => parseInt(a.id) - parseInt(b.id))
|
|
|
|
|
+
|
|
|
|
|
+ let linkedCount = 0
|
|
|
|
|
+ timelinePoints.value.forEach((point, index) => {
|
|
|
|
|
+ if (index < sortedPresets.length) {
|
|
|
|
|
+ const preset = sortedPresets[index]
|
|
|
|
|
+ point.presetId = parseInt(preset.id)
|
|
|
|
|
+ point.presetName = preset.name || `Preset ${preset.id}`
|
|
|
|
|
+ point.active = true
|
|
|
|
|
+ linkedCount++
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (linkedCount > 0) {
|
|
|
|
|
+ saveTimelineConfig()
|
|
|
|
|
+ ElMessage.success(`${t('已映射')} ${linkedCount} ${t('个点位')}`)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.warning(t('没有可映射的点位'))
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 右键菜单删除点
|
|
// 右键菜单删除点
|
|
|
function handlePointContextMenu(e: MouseEvent, point: TimelinePoint) {
|
|
function handlePointContextMenu(e: MouseEvent, point: TimelinePoint) {
|
|
|
ElMessageBox.confirm(`${t('确定删除')} "${point.presetName || `Point ${point.id}`}"?`, t('删除确认'), {
|
|
ElMessageBox.confirm(`${t('确定删除')} "${point.presetName || `Point ${point.id}`}"?`, t('删除确认'), {
|
|
@@ -1732,6 +1809,10 @@ function handleDurationChange() {
|
|
|
saveTimelineConfig()
|
|
saveTimelineConfig()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 进度条动画帧ID
|
|
|
|
|
+let progressAnimationId: number | null = null
|
|
|
|
|
+let loopStartTime = 0
|
|
|
|
|
+
|
|
|
// 播放巡航
|
|
// 播放巡航
|
|
|
async function playTimeline() {
|
|
async function playTimeline() {
|
|
|
const activePoints = timelinePoints.value.filter((p) => p.active).sort((a, b) => a.time - b.time)
|
|
const activePoints = timelinePoints.value.filter((p) => p.active).sort((a, b) => a.time - b.time)
|
|
@@ -1748,46 +1829,61 @@ async function playTimeline() {
|
|
|
|
|
|
|
|
isTimelinePlaying.value = true
|
|
isTimelinePlaying.value = true
|
|
|
timelineProgress.value = 0
|
|
timelineProgress.value = 0
|
|
|
|
|
+ selectedPoint.value = null // 清除选中状态
|
|
|
timelinePlayAbort = new AbortController()
|
|
timelinePlayAbort = new AbortController()
|
|
|
|
|
|
|
|
- const startTime = Date.now()
|
|
|
|
|
const totalDuration = timelineDuration.value * 1000 // 转为毫秒
|
|
const totalDuration = timelineDuration.value * 1000 // 转为毫秒
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- // 循环播放各个点
|
|
|
|
|
- for (let i = 0; i < activePoints.length; i++) {
|
|
|
|
|
- if (timelinePlayAbort?.signal.aborted) break
|
|
|
|
|
-
|
|
|
|
|
- const point = activePoints[i]
|
|
|
|
|
- const nextPoint = activePoints[i + 1]
|
|
|
|
|
- const waitTime = (point.time / timelineDuration.value) * totalDuration - (Date.now() - startTime)
|
|
|
|
|
|
|
+ // 启动进度条动画(持续更新)
|
|
|
|
|
+ function updateProgress() {
|
|
|
|
|
+ if (!isTimelinePlaying.value) return
|
|
|
|
|
+ const elapsed = Date.now() - loopStartTime
|
|
|
|
|
+ const progress = Math.min((elapsed / totalDuration) * 100, 100)
|
|
|
|
|
+ timelineProgress.value = progress
|
|
|
|
|
+ progressAnimationId = requestAnimationFrame(updateProgress)
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 等待到达该点的时间
|
|
|
|
|
- if (waitTime > 0) {
|
|
|
|
|
- await sleep(waitTime, timelinePlayAbort.signal)
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 循环播放(do-while 支持循环模式)
|
|
|
|
|
+ do {
|
|
|
|
|
+ loopStartTime = Date.now()
|
|
|
|
|
+ timelineProgress.value = 0
|
|
|
|
|
+
|
|
|
|
|
+ // 启动/重启进度条动画
|
|
|
|
|
+ if (progressAnimationId) {
|
|
|
|
|
+ cancelAnimationFrame(progressAnimationId)
|
|
|
}
|
|
}
|
|
|
|
|
+ progressAnimationId = requestAnimationFrame(updateProgress)
|
|
|
|
|
|
|
|
- if (timelinePlayAbort?.signal.aborted) break
|
|
|
|
|
|
|
+ // 播放各个点
|
|
|
|
|
+ for (let i = 0; i < activePoints.length; i++) {
|
|
|
|
|
+ if (timelinePlayAbort?.signal.aborted) break
|
|
|
|
|
|
|
|
- // 跳转到该预置位
|
|
|
|
|
- if (point.presetId) {
|
|
|
|
|
- await presetGoto({ cameraId, presetId: point.presetId })
|
|
|
|
|
- selectedPoint.value = point
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const point = activePoints[i]
|
|
|
|
|
+ const targetTime = (point.time / timelineDuration.value) * totalDuration
|
|
|
|
|
+ const waitTime = targetTime - (Date.now() - loopStartTime)
|
|
|
|
|
|
|
|
- // 更新进度
|
|
|
|
|
- timelineProgress.value = (point.time / timelineDuration.value) * 100
|
|
|
|
|
|
|
+ // 等待到达该点的时间
|
|
|
|
|
+ if (waitTime > 0) {
|
|
|
|
|
+ await sleep(waitTime, timelinePlayAbort.signal)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (timelinePlayAbort?.signal.aborted) break
|
|
|
|
|
|
|
|
- // 计算在这个点停留的时间
|
|
|
|
|
- if (nextPoint) {
|
|
|
|
|
- const stayTime = ((nextPoint.time - point.time) / timelineDuration.value) * totalDuration
|
|
|
|
|
- if (stayTime > 0) {
|
|
|
|
|
- await sleep(stayTime, timelinePlayAbort.signal)
|
|
|
|
|
|
|
+ // 跳转到该预置位
|
|
|
|
|
+ if (point.presetId) {
|
|
|
|
|
+ await presetGoto({ cameraId, presetId: point.presetId })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // 播放完成
|
|
|
|
|
|
|
+ // 等待剩余时间
|
|
|
|
|
+ const remainingTime = totalDuration - (Date.now() - loopStartTime)
|
|
|
|
|
+ if (remainingTime > 0 && !timelinePlayAbort?.signal.aborted) {
|
|
|
|
|
+ await sleep(remainingTime, timelinePlayAbort.signal)
|
|
|
|
|
+ }
|
|
|
|
|
+ } while (isLoopEnabled.value && !timelinePlayAbort?.signal.aborted)
|
|
|
|
|
+
|
|
|
|
|
+ // 播放完成(非循环模式或被停止)
|
|
|
if (!timelinePlayAbort?.signal.aborted) {
|
|
if (!timelinePlayAbort?.signal.aborted) {
|
|
|
timelineProgress.value = 100
|
|
timelineProgress.value = 100
|
|
|
await sleep(500)
|
|
await sleep(500)
|
|
@@ -1799,6 +1895,11 @@ async function playTimeline() {
|
|
|
ElMessage.error(t('巡航播放失败'))
|
|
ElMessage.error(t('巡航播放失败'))
|
|
|
}
|
|
}
|
|
|
} finally {
|
|
} finally {
|
|
|
|
|
+ // 停止进度条动画
|
|
|
|
|
+ if (progressAnimationId) {
|
|
|
|
|
+ cancelAnimationFrame(progressAnimationId)
|
|
|
|
|
+ progressAnimationId = null
|
|
|
|
|
+ }
|
|
|
isTimelinePlaying.value = false
|
|
isTimelinePlaying.value = false
|
|
|
timelineProgress.value = 0
|
|
timelineProgress.value = 0
|
|
|
timelinePlayAbort = null
|
|
timelinePlayAbort = null
|
|
@@ -1807,6 +1908,11 @@ async function playTimeline() {
|
|
|
|
|
|
|
|
// 停止巡航
|
|
// 停止巡航
|
|
|
function stopTimeline() {
|
|
function stopTimeline() {
|
|
|
|
|
+ // 停止进度条动画
|
|
|
|
|
+ if (progressAnimationId) {
|
|
|
|
|
+ cancelAnimationFrame(progressAnimationId)
|
|
|
|
|
+ progressAnimationId = null
|
|
|
|
|
+ }
|
|
|
if (timelinePlayAbort) {
|
|
if (timelinePlayAbort) {
|
|
|
timelinePlayAbort.abort()
|
|
timelinePlayAbort.abort()
|
|
|
timelinePlayAbort = null
|
|
timelinePlayAbort = null
|
|
@@ -2216,9 +2322,17 @@ onMounted(async () => {
|
|
|
height: 32px;
|
|
height: 32px;
|
|
|
background: linear-gradient(to right, #374151, #374151);
|
|
background: linear-gradient(to right, #374151, #374151);
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
- cursor: crosshair;
|
|
|
|
|
margin-bottom: 8px;
|
|
margin-bottom: 8px;
|
|
|
|
|
|
|
|
|
|
+ &.is-playing {
|
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
|
+
|
|
|
|
|
+ .timeline-point {
|
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.timeline-progress {
|
|
.timeline-progress {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
top: 0;
|
|
top: 0;
|
|
@@ -2344,11 +2458,28 @@ onMounted(async () => {
|
|
|
padding: 10px 12px;
|
|
padding: 10px 12px;
|
|
|
background: #2a2a2a;
|
|
background: #2a2a2a;
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
|
|
|
.panel-label {
|
|
.panel-label {
|
|
|
color: #d1d5db;
|
|
color: #d1d5db;
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
|
|
+ min-width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .timeline-auto-link {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+ padding: 8px 12px;
|
|
|
|
|
+ background: #1f1f1f;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+
|
|
|
|
|
+ .auto-link-hint {
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+ font-size: 11px;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -2387,8 +2518,8 @@ onMounted(async () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.el-collapse-item__content {
|
|
.el-collapse-item__content {
|
|
|
- padding: 16px;
|
|
|
|
|
- padding-bottom: 12px;
|
|
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ // padding-bottom: 12px;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|