|
|
<template> <div class="content"> <div class="search"> <a-space> <a-input v-model:value="searchlist.blogtitle" placeholder="博客标题" /> <a-input v-model:value="searchlist.typename" placeholder="分类名称" /> <a-range-picker :locale="locale" show-time @change="onChange" /> </a-space> <a-space style="margin-left: 16px;"> <a-button @click="search">查询</a-button> <a-button type="primary" ghost @click="addModal">新增</a-button> </a-space> </div> <div class="modal"> <a-modal v-model:open="formControl.open" title="Basic Modal" width="100%" wrap-class-name="full-modal" @ok="onSubmit" ok-text="确认" cancel-text="取消"> <a-form ref="formRef" :model="formState" :rules="rules"> <a-flex gap="large" justify="space-between"> <a-form-item label="博客标题" name="blogtitle"> <a-input v-model:value="formState.blogtitle" placeholder="请输入博客标题" class="items" /> </a-form-item> <a-form-item label="博客类型" name="typeid"> <a-select v-model:value="formState.typeid" placeholder="请选择博客类型" class="items"> <a-select-option v-for="typeItem in typelist" :key="typeItem.key" :value="typeItem.id">{{ typeItem.typename }}</a-select-option> </a-select> </a-form-item> <a-form-item name="labelname" label="标签名称" class="items"> <a-select v-model:value="formState['labelname']" mode="multiple" placeholder="请选择标签"> <a-select-option :value="label.id" v-for="label in labellist">{{ label.labelname }}</a-select-option> </a-select> </a-form-item> <a-form-item label="文图地址" name="imglink" class="items"> <a-input v-model:value="formState.imglink" placeholder="请输入文图地址" /> </a-form-item> </a-flex> <v-md-editor v-model="formState.blogcontent" height="800px"></v-md-editor> <a-form-item label="博客备注" name="descr" class="desrpad"> <a-textarea v-model:value="formState.descr" /> </a-form-item> </a-form> </a-modal> </div> <div class="table"> <a-table bordered :data-source="bloglist" :columns="columns"> <template #bodyCell="{ column, record }"> <template v-if="column.key === 'labels'"> <span> <a-tag v-for="label in labelfilter(record.labelnames)" :key="label" color="cyan"> {{ label }} </a-tag> </span> </template> <template v-if="column.dataIndex === 'operation'"> <a-space> <div> <a-button size="small" danger @click="delModal(record.id)">删除</a-button> <a-modal v-model:open="open" title="提示" @ok="ackDelete(record)" ok-text="确认" cancel-text="取消" @cancel="unDelete"> <p>确认删除吗?</p> </a-modal> </div> <a-button size="small" type="primary" ghost @click="editModal(record.id)">{{ record.id }}编辑</a-button> <a-button size="small" type="primary" ghost @click="ackWatch(record)">预览</a-button> </a-space> </template> </template> </a-table> </div> </div> </template>
<script setup lang='ts'> import { ref, reactive, onMounted, toRefs } from 'vue'; import 'dayjs/locale/zh-cn'; import locale from 'ant-design-vue/es/date-picker/locale/zh_CN'; import dayjs from 'dayjs'; import type { Rule } from 'ant-design-vue/es/form'; import { useRouter } from "vue-router" import { message } from 'ant-design-vue'; import type { blogInterface } from "@/api/admin/index" import { get, post, put } from "@/tools/request" import { blogStore } from '@/stores'; import type { labelInterface, typeInterface } from "@/api/admin/index" dayjs.locale('zh-cn'); const router = useRouter() const { delControl } = blogStore() // 查询
const searchlist = reactive({ blogtitle: "", typename: "", start_date: '', end_date: '' }) const onChange = (date: string, dateString: string[]) => { if (date && dateString.length === 2) { searchlist.start_date = dateString[0]; searchlist.end_date = dateString[1]; } else { searchlist.start_date = ''; searchlist.end_date = ''; } console.log(dateString[0]); };
const search = async () => { try { const response = await get("/blogs/list/search", { blogtitle: searchlist.blogtitle, typename: searchlist.typename, start_date: searchlist.start_date, end_date: searchlist.end_date }); if (response && response.data) { bloglist.value = response.data.data.map((items: any, index: any) => ({ key: (index + 1).toString(), blogtitle: items.blogtitle, typename: items.typename, blogcontent: items.blogcontent, wordcount: items.wordcount, labelnames: items.labelnames, create_at: dayjs(items.create_at).format('YYYY-MM-DD HH:mm:ss'), update_at: dayjs(items.update_at).format('YYYY-MM-DD HH:mm:ss'), descr: items.descr })); console.log(response) } else { console.log("request has no data"); } } catch (error) { console.error("request is exception", error); } };
// 新增
const formState = ref({ id: '', blogtitle: '', typeid: null, blogcontent: "", labelname: [], descr: '', imglink: "" });
const labellist = ref<labelInterface[]>([]) const labelList = async () => { try { await get( "labels/list" ).then(response => { if (response) { labellist.value = response.data.data.map((items: any) => ({ id: items.id, labelname: items.labelname, descr: items.descr
})) } else { console.log("the interface request data does not exist!") }
}) } catch (error) { console.error("Failed to fetch data", error); } } const typelist = ref<typeInterface[]>([]) const typeList = async () => { try { await get("/types/list").then(response => { if (response) { typelist.value = response.data.data.map((items: any) => ({ ...items })) } else { console.log("the interface request data does not exist!") }
}) } catch (error) { console.error("Failed to fetch data", error); } }
const rules: Record<string, Rule[]> = { blogtitle: [ { required: true, message: '请输入博客标题', trigger: 'change' }, { min: 4, max: 20, message: '博客标题允许4-20个字符', trigger: 'blur' }, ], descr: [ { required: false }, { max: 255, message: '博客备注不得超过255个字符', trigger: 'change' }, ], };
const formControl=ref({ open:false, ids:null })
const formRef = ref(); const addModal = () => { formControl.value.open = true console.log(formControl.value.ids) } const editModal = (id: any) => { formControl.value.ids = id formControl.value.open = true get( `/blogs/list/search/${id}` ).then(response=>{ formState.value=response.data.data }) console.log(formControl.value.ids) } const onSubmit = () => { formRef.value .validate() .then(async () => { const labels = formState.value.labelname.map(labelId => { const label = labellist.value.find((label: any) => label.id === labelId); return label ? { "id": label.id, "labelname": label.labelname, "descr": label.descr } : null; }); const formdata = { blog: { blogtitle: formState.value.blogtitle, typeid: formState.value.typeid, imglink: formState.value.imglink, blogcontent: formState.value.blogcontent, descr: formState.value.descr }, labels: labels } if (formControl.value.ids) { await put(`/blogs/update/${formControl.value.ids}`, formdata) formControl.value.open=false, blogList() } else { await post('/blogs/add', formdata); formControl.value.open=false, blogList() } }) };
const open = ref<boolean>(false);
const delModal = (id: any) => { delControl.open = true; delControl.ids = id; };
const bloglist = ref<blogInterface[]>([]) const blogList = async () => { try { const response = await get("/blogs/list"); if (response) { bloglist.value = response.data.data.map((items: any, index: any) => ({ key: (index + 1).toString(), id: items.id, blogtitle: items.blogtitle, create_at: dayjs(items.create_at).format('YYYY-MM-DD HH:mm:ss'), update_at: dayjs(items.update_at).format('YYYY-MM-DD HH:mm:ss'), readnum: items.readnum, readminite: items.readminite, wordcount: items.wordcount, img: items.img, blogcontent: items.blogcontent, typename: items.typename, labelnames: items.labelnames })) } else { console.log("bloglist is not exits") } } catch (error) { console.log("bloglist is error") }
} const labelfilter = (labelnames: any) => { let labels = [] if (labelnames) { try { labels = JSON.parse(labelnames) } catch (error) { console.error('Invalid JSON string:', labelnames); } } return Array.isArray(labels) ? labels.filter(label => label && label.trim() !== '') : []; } // 博客删除
// const ackDelete = async (record:{key:string,id:number}) => {
// remove(`/blogs/delete/${toDelete.id}`).then((response) => {
// if (response.status === 200) {
// dataSource.value = dataSource.value.filter(item => item.key !== record.key);
// open.value = false;
// }
// message.info("删除成功")
// }).catch(error => {
// console.error('There was an error deleting the blog!', error);
// })
// };
// 博客修改
const ackUpdate = async (id: any) => { router.push(`/admin/blogmanage/update/${id}`); }; const ackWatch = async (record: { key: string, id: number }) => { router.push(`/admin/blogmanage/watch`); } const unDelete = async () => { message.warn("取消删除") } const columns = [ { title: '序号', dataIndex: 'key', width: '5%', }, { title: '博客标题', dataIndex: 'blogtitle', width: '20%', }, { title: '博客分类', dataIndex: 'typename', }, { title: '博客标签', dataIndex: 'labelnames', key: "labels" }, { title: '总字数', dataIndex: 'wordcount', key: "wordcount" }, { title: '发布时间', dataIndex: 'create_at', }, { title: '修改时间', dataIndex: 'update_at', }, { title: '操作', dataIndex: 'operation', }, ];
onMounted(async () => { blogList() typeList() labelList() }); </script>
<style scoped> .content { padding: 24px 24px 0 24px; }
.search { margin: 0 0 24px 0; }
.vditor { width: 100%; border: 1px solid #ccc; }
.items { width: calc(75vw/4); }
.desrpad { padding: 24px 0 0 0; } </style>
|