blog/src/views/console/menu/index.vue
2024-10-24 15:42:02 +08:00

358 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<n-scrollbar class="h-full">
<div class="mb-8 mt-8 relative">
<h1 class="text-center text-lg">导航管理</h1>
<div class="absolute top-0 right-[5%]">
<!-- <n-button class="mr-4" type="primary" @click="addClass">增加分类</n-button> -->
<n-button type="primary" @click="addMenu">增加导航</n-button>
</div>
</div>
<div class="table w-[95%] mx-auto mb-8">
<n-data-table :columns="columns" striped :single-line="false" :paginate-single-page="false"
:pagination="pagination" :data="menuList">
<template #empty>
<div>
<span>尚无导航</span><span class="text-pp-200 hover:underline" @click="add">去增加导航 ></span>
</div>
</template>
</n-data-table>
</div>
<n-drawer v-model:show="mshow" :width="702" :mask-closable="false">
<n-drawer-content title="新增导航" closable>
<n-form class="mb-20 px-4" ref="menuForm" :model="menuValue" :rules="menuRules" label-placement="left"
label-width="100">
<n-form-item-row label="导航名称" path="menuName">
<n-input v-model:value="menuValue.menuName" placeholder="请输入导航名称" />
</n-form-item-row>
<n-form-item-row label="导航类别" path="">
<n-select v-model:value="menuValue.menuClassId" placeholder="请选择导航类别" :options="classList"
@update:value="changeClass" />
</n-form-item-row>
<n-form-item-row label="导航链接" path="menuLink">
<n-input v-model:value="menuValue.menuLink" placeholder="请输入导航链接" />
</n-form-item-row>
<n-form-item-row label="导航图标" path="menuIcon">
<n-input v-model:value="menuValue.menuIcon" placeholder="请输入导航图标" />
</n-form-item-row>
<n-form-item-row label="导航描述" path="menuDesc">
<n-input type="textarea" v-model:value="menuValue.menuDesc" placeholder="请输入导航描述" />
</n-form-item-row>
<div class="px-[10%] ">
<n-button type="primary" block secondary strong @click="submitAddMenu">
增加导航
</n-button>
</div>
</n-form>
<n-divider class="mt-4" title-placement="left">
<n-icon size="20" color="#8A2BE2">
<icon-sciss></icon-sciss>
</n-icon>
<span class="ml-2 text-[20px]">增加类别</span>
</n-divider>
<n-form class="px-4" :model="classValue" ref="classForm" :rules="classRules" label-placement="left"
label-width="100">
<n-form-item label="分类名称" path="menuClass">
<n-input v-model:value="classValue.menuClass" placeholder="请输入分类名称" />
</n-form-item>
<n-form-item label="分类id" path="">
<n-input-number v-model:value="classValue.menuClassId" placeholder="请输入分类id" />
</n-form-item>
<div class="px-[10%]">
<n-button type="primary" block secondary strong @click="submitAddClass">创建分类</n-button>
</div>
</n-form>
</n-drawer-content>
</n-drawer>
<n-modal v-model:show="showModal" preset="dialog" title="删除" content="是否永久删除该文章?" positive-text="确认"
negative-text="取消" @positive-click="submitCallback" @negative-click="cancelCallback" />
</n-scrollbar>
</template>
<script setup>
import { resetObject } from '@/util/index.js';
import { onMounted, reactive, ref } from 'vue';
const menuValue = reactive({
menuName: null,
menuClassId: null,
menuLink: null,
menuIcon: null,
menuClass: null,
menuDesc: null,
})
const classValue = reactive({
menuClass: null,
menuClassId: null,
})
const mshow = ref(false)
const showModal = ref(false)
const menuList = ref([])
const classList = ref([])
const pagination = ref({
pageSize: 12,
})
const menuForm = ref(null)
const classForm = ref(null)
const dtitle = ref('');
const opId = ref(-1);
const curId = ref(-1);
const delId = ref(-1);
const show = ref('')
const columns = createColumns({
view: (row) => {
dshow.value = true
dtitle.value = '文章预览'
opId.value = row.id
show.value = 'view'
},
edit: (row) => {
dshow.value = true
dtitle.value = '编辑文章'
curId.value = row.id
show.value = 'edit'
},
remove: (row) => {
// showModal.value = true
// delId.value = row.id
}
})
const menuRules = {
menuName: {
required: true,
message: '请输入导航名称',
trigger: 'blur',
},
menuClassId: {
required: true,
message: '请选择导航类别',
trigger: 'change',
},
menuLink: {
required: true,
message: '请输入导航链接',
trigger: 'blur',
},
menuIcon: {
required: true,
message: '请输入导航图标',
trigger: 'blur',
},
}
const classRules = {
menuClass: {
required: true,
message: '请输入分类名称',
trigger: 'blur',
},
menuClassId: {
required: true,
message: '请输入分类id',
trigger: 'blur',
},
}
function createColumns({ edit, remove, view }) {
return [
{
title: '序号',
key: 'key',
align: 'center',
width: "80",
render: (_, index) => {
return `${index + 1}`
}
},
{
title: "导航名称",
align: 'center',
width: "300",
key: "menuName"
},
{
title: "导航分类",
align: 'center',
width: "200",
key: "menuClass"
},
{
title: "导航简介",
align: 'center',
key: "menuDesc",
ellipsis: {
tooltip: {
scorllable: true,
contentStyle: {
maxWidth: '45vw',
maxHeight: '70vh',
},
},
}
},
{
title: "操作",
align: 'center',
key: "actions",
width: "200",
render(row) {
return h(
'div',
[
h(NButton,
{
type: "primary",
text: true,
size: "small",
onClick: () => view(row)
},
{ default: () => "预览" }
),
h(NButton,
{
type: "primary",
text: true,
size: "small",
style: "margin-left: 10px",
onClick: () => edit(row)
},
{ default: () => "编辑" }
),
h(NButton,
{
type: "primary",
text: true,
style: "margin-left: 10px",
size: "small",
onClick: () => remove(row)
},
{ default: () => "删除" }
),
]
);
}
}
];
};
function addMenu() {
mshow.value = true
}
onMounted(async () => {
getClass()
getList()
})
async function getList() {
// 获取文章列表
const res = await $http.nav.listNav()
menuList.value = res.data
}
async function getClass() {
const res = await $http.nav.listClass()
if (res.code == 1) {
res.data.forEach(i => {
i.value = i.menuClassId
i.label = i.menuClass
});
classList.value = res.data
}
}
async function submitCallback() {
const res = await $http.art.deleteArti(delId.value)
if (res.code == 1) $msg.success(res.msg)
else $msg.error(res.msg)
showModal.value = false
delId.value = -1
getList()
}
function cancelCallback() {
showModal.value = false
delId.value = -1
}
async function submitAddMenu() {
if (menuValue.menuClassId == null || !menuValue.menuClassId) {
$msg.error('请选择导航类别')
return
}
menuForm.value?.validate(async errors => {
if (!errors) {
const res = await $http.nav.addMenu(menuValue)
if (res.code == 1) {
$msg.success(res.msg);
resetObject(menuValue)
getList()
} else {
$msg.error(res.msg);
}
} else {
$msg.error(errors[0][0].message)
}
});
}
function submitAddClass() {
console.log(classValue);
if (!classValue.menuClassId) {
$msg.error('请输入分类id')
return
}
classForm.value.validate(async errors => {
if (!errors) {
const res = await $http.nav.addClass(classValue)
if (res.code == 1) {
$msg.success(res.msg);
resetObject(classValue)
getClass()
} else {
$msg.error(res.msg);
}
} else {
$msg.error(errors[0][0].message)
}
});
}
function changeClass() {
menuValue.menuClass = classList.value.find(item => item.menuClassId == menuValue.menuClassId).menuClass
console.log(menuValue);
}
</script>
<style scoped lang="less">
:deep(.n-divider__line) {
background-color: @purple !important;
height: 2px !important;
}
:deep(.n-input-number) {
width: 100%;
}
:deep(.n-data-table__pagination) {
justify-content: center !important;
}
</style>