fix: 功能优化完善。

This commit is contained in:
tianyongbao
2025-12-13 19:05:13 +08:00
parent bdf4035816
commit 4965e96556
5 changed files with 299 additions and 9 deletions

View File

@@ -219,6 +219,7 @@
<script>
import Page from '../components/Page'
import ToolService from '../services/ToolService'
import Sortable from 'sortablejs'
export default {
name: 'ManagePage',
@@ -293,7 +294,10 @@ export default {
color: 'linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)',
sortOrder: 0
},
currentCategory: null
currentCategory: null,
categorySortable: null, // 分组拖拽实例
toolSortables: [], // 网址拖拽实例数组
superCategorySortable: null // 大分类拖拽实例
}
},
@@ -320,6 +324,18 @@ export default {
this.loadData()
},
mounted() {
// 初始化拖拽功能
this.initSortable()
},
updated() {
// 数据更新后重新初始化拖拽
this.$nextTick(() => {
this.initSortable()
})
},
methods: {
// 消息提示
showMessage(text, type = 'success') {
@@ -825,6 +841,179 @@ export default {
console.error('删除工具失败:', error)
this.showMessage('删除失败,请检查网络连接', 'error')
}
},
// 初始化拖拽排序
initSortable() {
// 销毁旧的 Sortable 实例
if (this.superCategorySortable) {
this.superCategorySortable.destroy()
}
if (this.categorySortable) {
this.categorySortable.destroy()
}
if (this.toolSortables) {
this.toolSortables.forEach(s => s.destroy())
}
this.toolSortables = []
// 大分类 Tab 拖拽
const tabListEl = document.querySelector('.tab-list')
if (tabListEl) {
this.superCategorySortable = Sortable.create(tabListEl, {
animation: 150,
handle: '.tab-item',
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: (evt) => {
this.handleSuperCategorySort(evt)
}
})
}
// 书签分组拖拽
const categoryListEl = document.querySelector('.category-list')
if (categoryListEl) {
this.categorySortable = Sortable.create(categoryListEl, {
animation: 150,
handle: '.category-item',
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: (evt) => {
this.handleCategorySort(evt)
}
})
}
// 网址列表拖拽(每个分组都需要初始化)
const toolLists = document.querySelectorAll('.tool-list')
toolLists.forEach((toolListEl, index) => {
const sortable = Sortable.create(toolListEl, {
animation: 150,
handle: '.tool-item',
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onEnd: (evt) => {
this.handleToolSort(evt, index)
}
})
this.toolSortables.push(sortable)
})
},
// 处理大分类排序
async handleSuperCategorySort(evt) {
const { oldIndex, newIndex } = evt
if (oldIndex === newIndex) return
const superCategories = [...this.superCategories]
const movedItem = superCategories[oldIndex]
superCategories.splice(oldIndex, 1)
superCategories.splice(newIndex, 0, movedItem)
// 更新排序号
const updates = superCategories.map((cat, index) => ({
id: cat.id,
sortOrder: index
}))
try {
// 批量更新排序
for (const update of updates) {
await ToolService.updateSuperCategory({
id: update.id,
superCategoryKey: superCategories.find(c => c.id === update.id).key,
superCategoryTitle: superCategories.find(c => c.id === update.id).title,
sortOrder: update.sortOrder
})
}
this.showMessage('排序保存成功')
await this.loadData()
} catch (error) {
console.error('排序失败:', error)
this.showMessage('排序保存失败', 'error')
await this.loadData()
}
},
// 处理书签分组排序
async handleCategorySort(evt) {
const { oldIndex, newIndex } = evt
if (oldIndex === newIndex) return
const categories = [...this.currentCategories]
const movedItem = categories[oldIndex]
categories.splice(oldIndex, 1)
categories.splice(newIndex, 0, movedItem)
// 更新排序号
const updates = categories.map((cat, index) => ({
id: cat.id,
sortOrder: index
}))
try {
// 批量更新排序
for (const update of updates) {
await ToolService.updateCategory({
id: update.id,
categoryKey: categories.find(c => c.id === update.id).key,
categoryTitle: categories.find(c => c.id === update.id).title,
superCategoryId: categories.find(c => c.id === update.id).superCategoryId,
sortOrder: update.sortOrder
})
}
this.showMessage('排序保存成功')
await this.loadData()
} catch (error) {
console.error('排序失败:', error)
this.showMessage('排序保存失败', 'error')
await this.loadData()
}
},
// 处理网址排序
async handleToolSort(evt, categoryIndex) {
const { oldIndex, newIndex } = evt
if (oldIndex === newIndex) return
const category = this.currentCategories[categoryIndex]
const tools = [...category.tools]
const movedItem = tools[oldIndex]
tools.splice(oldIndex, 1)
tools.splice(newIndex, 0, movedItem)
// 更新排序号
const updates = tools.map((tool, index) => ({
...tool,
sortOrder: index
}))
try {
// 批量更新排序
for (const tool of updates) {
await ToolService.updateTool({
id: tool.id,
categoryId: category.id,
name: tool.name,
description: tool.desc,
url: tool.url,
displayUrl: tool.displayUrl,
icon: tool.icon,
color: tool.color,
sortOrder: tool.sortOrder
})
}
this.showMessage('排序保存成功')
await this.loadData()
} catch (error) {
console.error('排序失败:', error)
this.showMessage('排序保存失败', 'error')
await this.loadData()
}
}
}
}
@@ -976,7 +1165,7 @@ export default {
background: #f5f7fa;
border: 2px solid transparent;
border-radius: 8px;
cursor: pointer;
cursor: move; // 显示可拖拽
transition: all 0.3s ease;
user-select: none;
@@ -1137,6 +1326,7 @@ export default {
border-radius: 6px;
border: 1px solid #e5e7eb;
transition: all 0.2s ease;
cursor: move; // 显示可拖拽
&:hover {
background: #f3f4f6;
@@ -1245,6 +1435,7 @@ export default {
border-radius: 6px;
border: 1px solid #e5e7eb;
transition: all 0.2s ease;
cursor: move; // 显示可拖拽
&:hover {
background: #f3f4f6;
@@ -1647,6 +1838,24 @@ button {
transform: translate(-50%, -20px);
}
// 拖拽样式
.sortable-ghost {
opacity: 0.4;
background: #e0e7ff !important;
border: 2px dashed @primary-color !important;
}
.sortable-chosen {
opacity: 0.8;
transform: scale(1.02);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.sortable-drag {
opacity: 0.8;
transform: rotate(2deg);
}
// 响应式布局 - 手机端
@media (max-width: 600px) {
.manage-header {