feat: 优化

This commit is contained in:
2026-03-04 19:29:00 +08:00
parent fab8480f83
commit f6dc899bb9
2 changed files with 0 additions and 364 deletions

View File

@@ -104,7 +104,6 @@ function buildRoutesFromNav(config) {
const hiddenRoutes = [
{ path: 'trends/heat', name: '热度分析', component: () => import('../views/trends/Heat.vue'), meta: { hidden: true } },
{ path: 'material/group', name: '素材分组', component: () => import('../views/material/MaterialGroup.vue'), meta: { hidden: true } },
{ path: 'user/profile', name: '个人中心', component: () => import('../views/user/Profile.vue'), meta: { hidden: true } }
]

View File

@@ -1,363 +0,0 @@
<template>
<div class="material-group">
<div class="material-group__header">
<h1 class="material-group__title">素材分组</h1>
<a-button type="primary" @click="handleCreateGroup">
<template #icon>
<PlusOutlined />
</template>
新建分组
</a-button>
</div>
<!-- 分组列表 -->
<div class="material-group__content">
<a-spin :spinning="loading" tip="加载中..." style="width: 100%; min-height: 400px;">
<template v-if="groupList.length > 0">
<a-table
:data-source="groupList"
:columns="columns"
:pagination="false"
row-key="id"
:customRow="customRow"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'name'">
<div class="table-name-cell">
<span class="table-name">{{ record.name }}</span>
<a-tag color="blue">{{ record.fileCount || 0 }} 个文件</a-tag>
</div>
</template>
<template v-else-if="column.key === 'description'">
<span class="table-description">{{ record.description || '暂无描述' }}</span>
</template>
<template v-else-if="column.key === 'createTime'">
<span class="table-time">{{ formatDate(record.createTime) }}</span>
</template>
<template v-else-if="column.key === 'action'">
<div class="table-actions">
<a-button type="link" @click="handleEditGroup(record)">
<template #icon>
<EditOutlined />
</template>
编辑
</a-button>
<a-button type="link" danger @click="handleDeleteGroup(record)">
<template #icon>
<DeleteOutlined />
</template>
删除
</a-button>
</div>
</template>
</template>
</a-table>
</template>
<template v-else>
<a-empty description="暂无分组" />
</template>
</a-spin>
</div>
<!-- 创建/编辑分组对话框 -->
<a-modal
v-model:visible="groupModalVisible"
:title="groupModalTitle"
@ok="handleSaveGroup"
@cancel="handleCancelGroup"
@close="handleCancelGroup"
>
<a-form ref="groupFormRef" :model="groupForm" layout="vertical">
<a-form-item label="分组名称" name="name" :rules="[{ required: true, message: '请输入分组名称' }]">
<a-input v-model:value="groupForm.name" placeholder="请输入分组名称" />
</a-form-item>
<a-form-item label="分组描述" name="description">
<a-textarea
v-model:value="groupForm.description"
placeholder="请输入分组描述"
:auto-size="{ minRows: 3, maxRows: 5 }"
/>
</a-form-item>
<a-form-item label="排序" name="sort">
<a-input-number v-model:value="groupForm.sort" :min="0" placeholder="排序值" />
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import {
PlusOutlined,
EditOutlined,
DeleteOutlined
} from '@ant-design/icons-vue'
import { MaterialGroupService } from '@/api/material'
// 数据
const loading = ref(false)
const groupList = ref([])
const groupModalVisible = ref(false)
const groupModalTitle = ref('新建分组')
const isEdit = ref(false)
const groupFormRef = ref(null)
// 表格列配置
const columns = [
{
title: '分组名称',
dataIndex: 'name',
key: 'name',
width: 300
},
{
title: '描述',
dataIndex: 'description',
key: 'description'
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200
},
{
title: '操作',
key: 'action',
width: 200,
align: 'right'
}
]
// 自定义行样式
const customRow = (record) => {
return {
class: 'custom-table-row'
}
}
// 表单
const groupForm = reactive({
id: undefined,
name: '',
description: '',
sort: 0
})
// 加载分组列表
const loadGroupList = async () => {
if (loading.value) return // 防止重复请求
loading.value = true
try {
console.log('[MaterialGroup] 开始加载分组列表...')
const res = await MaterialGroupService.getGroupList()
console.log('[MaterialGroup] 分组列表响应:', res)
console.log('[MaterialGroup] 响应类型:', typeof res)
console.log('[MaterialGroup] 响应结构:', JSON.stringify(res, null, 2))
// 检查多种可能的数据结构
if (res.code === 0 || res.code === '0') {
groupList.value = res.data || []
console.log('[MaterialGroup] 分组列表加载成功code===0共', groupList.value.length, '个分组')
console.log('[MaterialGroup] 分组数据:', groupList.value)
} else if (Array.isArray(res)) {
// 如果直接返回数组
groupList.value = res
console.log('[MaterialGroup] 分组列表加载成功(直接数组),共', groupList.value.length, '个分组')
console.log('[MaterialGroup] 分组数据:', groupList.value)
} else if (res && typeof res === 'object') {
// 检查其他可能的字段
const possibleData = res.data || res.list || res.result || res.rows
if (Array.isArray(possibleData)) {
groupList.value = possibleData
console.log('[MaterialGroup] 分组列表加载成功(其他字段),共', groupList.value.length, '个分组')
console.log('[MaterialGroup] 分组数据:', groupList.value)
} else {
console.error('[MaterialGroup] 响应结构异常:', res)
message.error('响应数据结构异常')
groupList.value = []
}
} else {
console.error('[MaterialGroup] 分组列表加载失败,响应结构异常:', res)
message.error('响应数据结构异常')
groupList.value = []
}
// 强制触发视图更新
console.log('[MaterialGroup] 当前 groupList 值:', groupList.value)
console.log('[MaterialGroup] groupList 长度:', groupList.value?.length)
} catch (error) {
console.error('[MaterialGroup] 加载分组列表失败:', error)
message.error('加载失败,请重试: ' + (error.message || error))
groupList.value = []
} finally {
loading.value = false
}
}
// 创建分组
const handleCreateGroup = () => {
isEdit.value = false
groupModalTitle.value = '新建分组'
groupForm.id = undefined
groupForm.name = ''
groupForm.description = ''
groupForm.sort = 0
groupModalVisible.value = true
// 清除表单验证状态
setTimeout(() => {
groupFormRef.value?.clearValidate()
}, 0)
}
// 编辑分组
const handleEditGroup = (group) => {
isEdit.value = true
groupModalTitle.value = '编辑分组'
groupForm.id = group.id
groupForm.name = group.name
groupForm.description = group.description || ''
groupForm.sort = group.sort || 0
groupModalVisible.value = true
// 清除表单验证状态
setTimeout(() => {
groupFormRef.value?.clearValidate()
}, 0)
}
// 保存分组
const handleSaveGroup = async () => {
try {
// 验证表单
const values = await groupFormRef.value.validateFields()
if (isEdit.value) {
await MaterialGroupService.updateGroup(groupForm)
message.success('更新成功')
} else {
await MaterialGroupService.createGroup(groupForm)
message.success('创建成功')
}
groupModalVisible.value = false
loadGroupList()
} catch (error) {
if (error?.errorFields) {
// 表单验证失败不显示错误提示Ant Design会自动显示
return
}
console.error('保存分组失败:', error)
message.error(error.message || '保存失败,请重试')
}
}
// 取消
const handleCancelGroup = () => {
groupModalVisible.value = false
groupForm.id = undefined
groupForm.name = ''
groupForm.description = ''
groupForm.sort = 0
// 清除表单验证状态
groupFormRef.value?.resetFields()
}
// 删除分组
const handleDeleteGroup = (group) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除分组"${group.name}"吗?删除后分组内的文件不会被删除。`,
onOk: async () => {
try {
await MaterialGroupService.deleteGroup(group.id)
message.success('删除成功')
loadGroupList()
} catch (error) {
console.error('删除分组失败:', error)
message.error(error.message || '删除失败,请重试')
}
}
})
}
// 工具函数
const formatDate = (dateStr) => {
if (!dateStr) return ''
const date = new Date(dateStr)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
})
}
// 初始化
onMounted(() => {
loadGroupList()
})
</script>
<style scoped>
.material-group {
padding: 24px;
height: 100%;
display: flex;
flex-direction: column;
}
.material-group__header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
}
.material-group__title {
font-size: 24px;
font-weight: 600;
margin: 0;
}
.material-group__content {
flex: 1;
overflow-y: auto;
position: relative;
border-radius: 8px;
padding: 16px;
}
.table-name-cell {
display: flex;
align-items: center;
gap: 12px;
}
.table-name {
font-size: 15px;
font-weight: 500;
color: #fff;
}
.table-description {
color: #595959;
font-size: 14px;
}
.table-time {
color: #8c8c8c;
font-size: 14px;
}
.table-actions {
display: flex;
gap: 8px;
justify-content: flex-end;
}
</style>