330 lines
10 KiB
Vue
330 lines
10 KiB
Vue
<template>
|
||
<div>
|
||
<div class="gva-table-box">
|
||
<div class="gva-btn-list">
|
||
<el-button type="primary" icon="plus" @click="handleAdd('0')">新增根栏目</el-button>
|
||
</div>
|
||
|
||
<!-- 由于此处菜单跟左侧列表一一对应所以不需要分页 pageSize默认999 -->
|
||
<el-table :data="tableData" row-key="ID">
|
||
<el-table-column align="left" label="ID" min-width="80" prop="ID" />
|
||
<el-table-column align="left" label="名称" min-width="200" prop="name" />
|
||
<el-table-column align="left" label="标题" min-width="200" prop="title" />
|
||
<el-table-column align="left" label="预览" min-width="120" prop="preview">
|
||
<template #default="scope">
|
||
<el-link type="primary" :href="'http://w1.zkzk.org.cn/channel/' + scope.row.ID + '.html'"
|
||
rel="noopener noreferrer" target="_blank">预览</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="left" label="摘要" min-width="260" prop="description" />
|
||
<el-table-column align="left" label="关键词" min-width="260" prop="keyword" />
|
||
<el-table-column align="left" label="介绍" min-width="260" prop="introduce" />
|
||
<el-table-column align="left" label="栏目模板" min-width="80" prop="channelTplId" />
|
||
<el-table-column align="left" label="文章页模板" min-width="140" prop="articleTplId" />
|
||
<el-table-column align="left" label="默认显示文章数" min-width="140" prop="pageNum" />
|
||
<el-table-column align="left" label="父节点" min-width="90" prop="parentId" />
|
||
<el-table-column align="left" fixed="right" label="操作" width="300">
|
||
<template #default="scope">
|
||
<el-button type="primary" link icon="plus" @click="handleAdd(scope.row.ID)">添加子栏目</el-button>
|
||
<el-button type="primary" link icon="edit" @click="handleEdit(scope.row.ID)">编辑</el-button>
|
||
<el-button type="danger" link icon="delete" @click="handleDelete(scope.row.ID)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
|
||
<el-drawer v-model="dialogFormVisible" size="550" :show-close="false" :before-close="handleCloseDialog"
|
||
:close-on-click-modal="false" :close-on-press-escape="false">
|
||
<template #header>
|
||
<div class="flex justify-between items-center">
|
||
<span class="text-lg">{{ !isEdit ? '添加' : '修改' }}栏目</span>
|
||
<div>
|
||
<el-button type="primary" @click="handleFormSubmit">确 定</el-button>
|
||
<el-button @click="handleCloseDialog">取 消</el-button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<el-form v-if="dialogFormVisible" ref="channelForm" label-position="right" label-width="auto" :inline="true"
|
||
:model="form" :rules="rules">
|
||
<div class="section-title">
|
||
<span>基本设置</span>
|
||
</div>
|
||
<el-form-item label="名称" prop="name" style="width: 88%">
|
||
<template #label>
|
||
<span>名称</span>
|
||
<span>
|
||
<el-tooltip content="导航用" placement="top">
|
||
<el-icon style="margin-left: 3px; margin-top: 9px;">
|
||
<QuestionFilled />
|
||
</el-icon>
|
||
</el-tooltip>
|
||
</span>
|
||
</template>
|
||
<el-input v-model="form.name" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="标题" prop="title" style="width: 88%">
|
||
<template #label>
|
||
<span>标题</span>
|
||
<span>
|
||
<el-tooltip content="栏目页使用" placement="top">
|
||
<el-icon style="margin-left: 3px; margin-top: 9px;">
|
||
<QuestionFilled />
|
||
</el-icon>
|
||
</el-tooltip>
|
||
</span>
|
||
</template>
|
||
<el-input v-model="form.title" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="每页数量" prop="pageNum" style="width: 88%">
|
||
<el-input-number v-model="form.pageNum" autocomplete="off" style="width:100%" />
|
||
</el-form-item>
|
||
<el-form-item label="父节点ID" style="width: 88%">
|
||
<el-cascader v-model="form.parentId" style="width:100%" :disabled="!isEdit" :options="channelOption"
|
||
:props="{ checkStrictly: true, label: 'title', value: 'ID', disabled: 'disabled', emitPath: false }"
|
||
:show-all-levels="false" filterable />
|
||
</el-form-item>
|
||
<el-divider />
|
||
<div class="section-title">
|
||
<span>Meta设置</span>
|
||
</div>
|
||
<el-form-item label="摘要" prop="description" style="width: 88%">
|
||
<el-input v-model="form.description" type="textarea" rows="2" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="关键词" prop="keyword" style="width: 88%">
|
||
<el-input v-model="form.keyword" type="textarea" rows="2" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="介绍" prop="introduce" style="width: 88%">
|
||
<el-input v-model="form.introduce" type="textarea" rows="2" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-divider />
|
||
<div class="section-title">
|
||
<span>模板设置</span>
|
||
</div>
|
||
<el-form-item label="栏目模板" prop="channelTplId" style="width: 88%">
|
||
<el-select v-model="form.channelTplId" placeholder="请选择" style="width: 240px">
|
||
<el-option v-for="item in channelTplOptions" :key="item.ID" :label="item.name" :value="item.ID" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="文章页模板" prop="articleTplId" style="width: 88%">
|
||
<el-select v-model="form.articleTplId" placeholder="请选择" style="width: 240px">
|
||
<el-option v-for="item in articleTplOptions" :key="item.ID" :label="item.name" :value="item.ID" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-drawer>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref } from 'vue'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
|
||
import {
|
||
getChannelTree,
|
||
addChannel,
|
||
updateChannel,
|
||
deleteChannel,
|
||
getChannelById
|
||
} from '@/api/channel'
|
||
|
||
const rules = reactive({
|
||
name: [
|
||
{ required: true, message: '请输入栏目名称', trigger: 'blur' }
|
||
],
|
||
title: [
|
||
{ required: true, message: '请输入栏目标题', trigger: 'blur' }
|
||
],
|
||
pageNum: [
|
||
{ required: true, type: 'number', message: '默认显示文章条数必须为大于0的整数', trigger: 'blur' }
|
||
],
|
||
})
|
||
|
||
// 查询
|
||
const tableData = ref([])
|
||
const getTableData = async () => {
|
||
const res = await getChannelTree()
|
||
if (res.code === 0) {
|
||
tableData.value = res.data.channelTree
|
||
}
|
||
}
|
||
|
||
getTableData()
|
||
|
||
const channelOption = ref([
|
||
{
|
||
ID: '0',
|
||
title: '根栏目'
|
||
}
|
||
])
|
||
const setOptions = () => {
|
||
channelOption.value = [
|
||
{
|
||
ID: '0',
|
||
title: '根栏目'
|
||
}
|
||
]
|
||
setChannelOptions(tableData.value, channelOption.value, false)
|
||
}
|
||
const setChannelOptions = (channelData, optionsData, disabled) => {
|
||
channelData &&
|
||
channelData.forEach(item => {
|
||
if (item.children && item.children.length) {
|
||
const option = {
|
||
title: item.name,
|
||
ID: String(item.ID),
|
||
disabled: disabled || item.ID === form.value.ID,
|
||
children: []
|
||
}
|
||
setChannelOptions(
|
||
item.children,
|
||
option.children,
|
||
disabled || item.ID === form.value.ID
|
||
)
|
||
optionsData.push(option)
|
||
} else {
|
||
const option = {
|
||
title: item.name,
|
||
ID: String(item.ID),
|
||
disabled: disabled || item.ID === form.value.ID
|
||
}
|
||
optionsData.push(option)
|
||
}
|
||
})
|
||
}
|
||
|
||
// ------ 获取模板 options ------
|
||
import { getTplOptions } from '@/api/channel'
|
||
const articleTplOptions = ref([])
|
||
const channelTplOptions = ref([])
|
||
const setTplOptions = async () => {
|
||
channelTplOptions.value = []
|
||
const res = await getTplOptions()
|
||
if (res.code === 0) {
|
||
articleTplOptions.value = res.data.articleTplOptions
|
||
channelTplOptions.value = res.data.channelTplOptions
|
||
}
|
||
}
|
||
// 初始化数据
|
||
setTplOptions()
|
||
|
||
// ----- 以下为 form 操作 -----
|
||
const form = ref({
|
||
ID: 0,
|
||
parentId: 0,
|
||
name: '',
|
||
title: '',
|
||
description: '',
|
||
keyword: '',
|
||
introduce: '',
|
||
channelTplId: 0,
|
||
articleTplId: 0,
|
||
pageNum: 10,
|
||
})
|
||
|
||
// 提交表单
|
||
const handleFormSubmit = async () => {
|
||
channelForm.value.validate(async valid => {
|
||
if (valid) {
|
||
let res
|
||
if (isEdit.value) {
|
||
res = await updateChannel(form.value)
|
||
} else {
|
||
res = await addChannel(form.value)
|
||
}
|
||
if (res.code === 0) {
|
||
ElMessage({
|
||
type: 'success',
|
||
message: isEdit.value ? '编辑成功' : '添加成功!'
|
||
})
|
||
getTableData()
|
||
}
|
||
initForm()
|
||
dialogFormVisible.value = false
|
||
}
|
||
})
|
||
}
|
||
|
||
// 初始化弹窗内表格方法
|
||
const channelForm = ref(null)
|
||
const checkFlag = ref(false)
|
||
const initForm = () => {
|
||
checkFlag.value = false
|
||
channelForm.value.resetFields()
|
||
form.value = {
|
||
ID: 0,
|
||
parentId: 0,
|
||
name: '',
|
||
title: '',
|
||
description: '',
|
||
keyword: '',
|
||
introduce: '',
|
||
channelTplId: 0,
|
||
articleTplId: 0,
|
||
pageNum: 10,
|
||
}
|
||
}
|
||
|
||
// 关闭弹窗
|
||
const dialogFormVisible = ref(false)
|
||
const handleCloseDialog = () => {
|
||
initForm()
|
||
dialogFormVisible.value = false
|
||
}
|
||
|
||
// 删除
|
||
const handleDelete = (ID) => {
|
||
ElMessageBox.confirm('此操作将永久删除栏目, 是否继续?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
const res = await deleteChannel({ id: ID })
|
||
if (res.code === 0) {
|
||
ElMessage({
|
||
type: 'success',
|
||
message: '删除成功!'
|
||
})
|
||
if (tableData.value.length === 1 && page.value > 1) {
|
||
page.value--
|
||
}
|
||
getTableData()
|
||
}
|
||
})
|
||
.catch(() => {
|
||
ElMessage({
|
||
type: 'info',
|
||
message: '已取消删除'
|
||
})
|
||
})
|
||
}
|
||
|
||
// 添加栏目方法,id为 0则为添加根栏目
|
||
const isEdit = ref(false)
|
||
const dialogTitle = ref('新增栏目')
|
||
const handleAdd = (id) => {
|
||
dialogTitle.value = '新增栏目'
|
||
form.value.parentId = String(id)
|
||
isEdit.value = false
|
||
setOptions()
|
||
dialogFormVisible.value = true
|
||
}
|
||
// 修改菜单方法
|
||
const handleEdit = async (ID) => {
|
||
dialogTitle.value = '编辑栏目'
|
||
const res = await getChannelById({ id: ID })
|
||
form.value = res.data.channel
|
||
isEdit.value = true
|
||
setOptions()
|
||
dialogFormVisible.value = true
|
||
}
|
||
|
||
</script>
|
||
|
||
<style type="scss">
|
||
.section-title {
|
||
font-size: 16px;
|
||
line-height: 1.2;
|
||
margin-bottom: 15px;
|
||
}
|
||
</style> |