<template>
|
<el-dialog
|
v-model="visible"
|
title="设置播放顺序"
|
width="900px"
|
:before-close="handleClose"
|
>
|
<!-- 搜索栏 -->
|
<div class="search-bar">
|
<el-input
|
v-model="searchTitle"
|
placeholder="请输入新闻标题搜索"
|
style="width: 300px"
|
clearable
|
@input="handleSearch"
|
>
|
<template #prefix>
|
<el-icon><Search /></el-icon>
|
</template>
|
</el-input>
|
<el-button type="primary" @click="handleSearch">
|
<el-icon><Search /></el-icon>
|
搜索
|
</el-button>
|
</div>
|
|
<!-- 操作提示 -->
|
<el-alert
|
title="操作说明"
|
type="info"
|
:closable="false"
|
style="margin: 16px 0"
|
>
|
<template #default>
|
<div>
|
<p>• 在"排序"列中输入数字设置播放顺序,数字越小越靠前显示</p>
|
<p>• 输入0表示最优先播放,空白表示不参与排序</p>
|
<p>• 修改完成后点击"保存排序"按钮生效</p>
|
</div>
|
</template>
|
</el-alert>
|
|
<!-- 新闻列表 -->
|
<el-table
|
:data="filteredTableData"
|
style="width: 100%"
|
v-loading="loading"
|
max-height="400"
|
>
|
<el-table-column prop="title" label="新闻标题" min-width="200" />
|
<el-table-column prop="mediaCount" label="媒体数量" width="100" align="center">
|
<template #default="{ row }">
|
<el-tag type="info">{{ row.mediaCount || 0 }}</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column prop="createTime" label="创建时间" width="160" />
|
<el-table-column label="当前排序" width="100" align="center">
|
<template #default="{ row }">
|
<el-tag v-if="row.sortOrder !== null && row.sortOrder !== undefined" type="success">
|
{{ row.sortOrder }}
|
</el-tag>
|
<span v-else class="text-muted">未设置</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="新排序" width="120" align="center">
|
<template #default="{ row }">
|
<el-input-number
|
v-model="row.newSortOrder"
|
:min="0"
|
:max="9999"
|
size="small"
|
placeholder="排序"
|
style="width: 100px"
|
@change="handleSortOrderChange(row)"
|
/>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 底部操作栏 -->
|
<template #footer>
|
<div class="dialog-footer">
|
<div class="footer-info">
|
<span class="changed-count">已修改: {{ changedCount }} 项</span>
|
</div>
|
<div class="footer-actions">
|
<el-button @click="handleClose">取消</el-button>
|
<el-button
|
type="primary"
|
:loading="saving"
|
:disabled="changedCount === 0"
|
@click="handleSave"
|
>
|
保存排序
|
</el-button>
|
</div>
|
</div>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
import { ElMessage } from 'element-plus'
|
import { Search } from '@element-plus/icons-vue'
|
import { CarouselApi } from '@/api/carousel'
|
|
const props = defineProps({
|
modelValue: Boolean
|
})
|
|
const emit = defineEmits(['update:modelValue', 'success'])
|
|
const loading = ref(false)
|
const saving = ref(false)
|
const searchTitle = ref('')
|
const tableData = ref([])
|
const originalData = ref([])
|
|
// 控制弹窗显示
|
const visible = computed({
|
get: () => props.modelValue,
|
set: (value) => emit('update:modelValue', value)
|
})
|
|
// 过滤后的表格数据
|
const filteredTableData = computed(() => {
|
if (!searchTitle.value.trim()) {
|
return tableData.value
|
}
|
return tableData.value.filter(item =>
|
item.title.toLowerCase().includes(searchTitle.value.toLowerCase())
|
)
|
})
|
|
// 已修改的数量
|
const changedCount = computed(() => {
|
return tableData.value.filter(item => {
|
const original = originalData.value.find(orig => orig.id === item.id)
|
if (!original) return false
|
|
const originalSort = original.sortOrder
|
const newSort = item.newSortOrder
|
|
// 比较原始值和新值
|
if (originalSort === null || originalSort === undefined) {
|
return newSort !== null && newSort !== undefined
|
}
|
return originalSort !== newSort
|
}).length
|
})
|
|
// 监听弹窗显示状态
|
watch(visible, (newVal) => {
|
if (newVal) {
|
loadData()
|
}
|
})
|
|
// 加载数据
|
const loadData = async () => {
|
try {
|
loading.value = true
|
|
// 获取所有轮播图数据
|
const pageRequest = { page: 0, size: 1000 } // 获取所有数据
|
const response = await CarouselApi.getCarousels(pageRequest)
|
|
const carousels = response.carousels?.content || []
|
|
// 初始化数据
|
tableData.value = carousels.map(item => ({
|
...item,
|
newSortOrder: item.sortOrder // 初始化新排序值为当前排序值
|
}))
|
|
// 保存原始数据用于比较
|
originalData.value = JSON.parse(JSON.stringify(carousels))
|
|
console.log('加载轮播图数据:', tableData.value)
|
} catch (error) {
|
console.error('加载数据失败:', error)
|
ElMessage.error('加载数据失败: ' + error.message)
|
} finally {
|
loading.value = false
|
}
|
}
|
|
// 搜索处理
|
const handleSearch = () => {
|
// 搜索逻辑已在computed中处理
|
console.log('搜索关键词:', searchTitle.value)
|
}
|
|
// 排序值变化处理
|
const handleSortOrderChange = (row) => {
|
console.log('排序值变化:', row.id, row.newSortOrder)
|
}
|
|
// 保存排序
|
const handleSave = async () => {
|
try {
|
saving.value = true
|
|
// 收集所有有变化的排序数据
|
const sortOrders = {}
|
|
tableData.value.forEach(item => {
|
const original = originalData.value.find(orig => orig.id === item.id)
|
if (!original) return
|
|
const originalSort = original.sortOrder
|
const newSort = item.newSortOrder
|
|
// 检查是否有变化
|
if (originalSort !== newSort) {
|
sortOrders[item.id] = newSort === null || newSort === undefined ? null : newSort
|
}
|
})
|
|
console.log('准备保存的排序数据:', sortOrders)
|
|
if (Object.keys(sortOrders).length === 0) {
|
ElMessage.warning('没有需要保存的修改')
|
return
|
}
|
|
// 调用API保存
|
const result = await CarouselApi.updateSortOrders(sortOrders)
|
|
if (result.updateCarouselSortOrders) {
|
ElMessage.success(`成功更新 ${Object.keys(sortOrders).length} 项排序`)
|
emit('success')
|
handleClose()
|
} else {
|
throw new Error('保存失败')
|
}
|
|
} catch (error) {
|
console.error('保存排序失败:', error)
|
ElMessage.error('保存排序失败: ' + error.message)
|
} finally {
|
saving.value = false
|
}
|
}
|
|
// 关闭弹窗
|
const handleClose = () => {
|
visible.value = false
|
searchTitle.value = ''
|
tableData.value = []
|
originalData.value = []
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.search-bar {
|
display: flex;
|
gap: 12px;
|
margin-bottom: 16px;
|
align-items: center;
|
}
|
|
.text-muted {
|
color: #909399;
|
font-style: italic;
|
}
|
|
.dialog-footer {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.footer-info {
|
.changed-count {
|
color: #409eff;
|
font-weight: 500;
|
}
|
}
|
|
.footer-actions {
|
display: flex;
|
gap: 12px;
|
}
|
|
:deep(.el-alert__content) {
|
p {
|
margin: 4px 0;
|
font-size: 13px;
|
}
|
}
|
</style>
|