feat: 优化
This commit is contained in:
@@ -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 } }
|
||||
]
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user