Browse Source

add new

master
panda 8 months ago
parent
commit
116aebcc0f
  1. 1
      src/api/admin/index.ts
  2. 3
      src/stores/index.ts
  3. 75
      src/views/admin/ClassticManageView.vue
  4. 174
      src/views/admin/blogmange/BlogFormView.vue
  5. 188
      src/views/admin/blogmange/BlogManageView.vue

1
src/api/admin/index.ts

@ -1,5 +1,6 @@
export interface blogInterface {
key: string,
id:number,
blogtitle: string,
create_at: Date,
readnum: number,

3
src/stores/index.ts

@ -6,12 +6,11 @@ export const mainWrapperStore=defineStore("mainWrapper",()=>{
})
export const blogStore = defineStore("blog", () => {
const delControl = reactive({
open: false,
ids: ""
})
return { delControl }
})
export const classticStore = defineStore("classtic", () => {

75
src/views/admin/ClassticManageView.vue

@ -7,53 +7,48 @@
<a-space style="margin-left: 16px;">
<a-button @click="search">查询</a-button>
<a-button type="primary" ghost @click="addModal">新增</a-button>
<a-modal v-model:open="addControl.open" :title="addControl.title" cancelText="取消" okText="确定" @ok="add">
<a-form ref="formRef" :model="addList" name="basic" :label-col="{ span: 4, offset: 2 }"
:wrapper-col="{ span: 16 }">
<a-form-item label="语录标题" name="header" :rules="[{ required: true, message: '请输入语录标题!' }]">
<a-input v-model:value="addList.header" />
</a-form-item>
<a-form-item label="语录内容" name="text" :rules="[{ required: true, message: '请输入语录内容!' }]">
<a-input v-model:value="addList.text" />
</a-form-item>
<a-form-item label="备注" name="descr" :rules="[{ required: true, message: '请输入备注!' }]">
<a-input v-model:value="addList.descr" />
</a-form-item>
</a-form>
</a-modal>
</a-space>
</div>
<div class="modal">
<a-modal v-model:open="addControl.open" :title="addControl.title" cancelText="取消" okText="确定" @ok="add">
<a-form ref="formRef" :model="addList" name="basic" :label-col="{ span: 4, offset: 2 }"
:wrapper-col="{ span: 16 }">
<a-form-item label="语录标题" name="header" :rules="[{ required: true, message: '请输入语录标题!' }]">
<a-input v-model:value="addList.header" />
</a-form-item>
<a-form-item label="语录内容" name="text" :rules="[{ required: true, message: '请输入语录内容!' }]">
<a-input v-model:value="addList.text" />
</a-form-item>
<a-form-item label="备注" name="descr" :rules="[{ required: true, message: '请输入备注!' }]">
<a-input v-model:value="addList.descr" />
</a-form-item>
</a-form>
</a-modal>
<a-modal v-model:open="delControl.open" title="提示" ok-text="确认" cancel-text="取消" @ok="del">
<p>确认删除吗</p>
</a-modal>
<a-modal v-model:open="editControl.open" :title="editControl.title" cancelText="取消" okText="确定" @ok="edit">
<a-form ref="formRef" :model="editList" name="basic" :label-col="{ span: 4, offset: 2 }"
:wrapper-col="{ span: 16 }">
<a-form-item label="语录标题" name="header" :rules="[{ required: true, message: '请修改语录标题!' }]">
<a-input v-model:value="editList.header" />
</a-form-item>
<a-form-item label="语录内容" name="text" :rules="[{ required: true, message: '请修改语录内容!' }]">
<a-input v-model:value="editList.text" />
</a-form-item>
<a-form-item label="备注" name="descr" :rules="[{ required: true, message: '请修改备注!' }]">
<a-input v-model:value="editList.descr" />
</a-form-item>
</a-form>
</a-modal>
</div>
<div class="table">
<a-table bordered :data-source="classticlist" :columns="columns">
<template #bodyCell="{ column, record }">
<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="delControl.open" title="提示" ok-text="确认" cancel-text="取消"
@ok="del">
<p>确认删除吗</p>
</a-modal>
</div>
<a-button size="small" danger @click="delModal(record.id)">删除</a-button>
<a-button size="small" type="primary" ghost @click="editModal(record.id)">编辑</a-button>
<a-modal v-model:open="editControl.open" :title="editControl.title" cancelText="取消"
okText="确定" @ok="edit">
<a-form ref="formRef" :model="editList" name="basic" :label-col="{ span: 4, offset: 2 }"
:wrapper-col="{ span: 16 }">
<a-form-item label="语录标题" name="header"
:rules="[{ required: true, message: '请修改语录标题!' }]">
<a-input v-model:value="editList.header" />
</a-form-item>
<a-form-item label="语录内容" name="text"
:rules="[{ required: true, message: '请修改语录内容!' }]">
<a-input v-model:value="editList.text" />
</a-form-item>
<a-form-item label="备注" name="descr"
:rules="[{ required: true, message: '请修改备注!' }]">
<a-input v-model:value="editList.descr" />
</a-form-item>
</a-form>
</a-modal>
</a-space>
</template>
</template>
@ -137,8 +132,8 @@ const add = async () => {
"/classtics/add",
addList.value
)
classticList()
addControl.open = false
classticList()
formRef.value.resetFields();
} catch (error) {
console.log("interface request exception")

174
src/views/admin/blogmange/BlogFormView.vue

@ -1,174 +0,0 @@
<template>
<div id="content">
<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="400px"></v-md-editor>
<a-form-item label="博客备注" name="descr" class="desrpad">
<a-textarea v-model:value="formState.descr" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 2, offset: 22 }">
<a-button @click="resetForm">重置</a-button>
<a-button style="margin-left: 24px" type="primary" @click="onSubmit">提交</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive } from 'vue';
import type { UnwrapRef } from 'vue';
import type { Rule } from 'ant-design-vue/es/form';
import { post, get, put } from '@/tools/request';
import { useRouter } from 'vue-router'
import type { labelInterface, typeInterface } from '@/api/admin';
const router = useRouter()
interface FormState {
id?: number;
blogtitle: string;
typeid: null;
blogcontent: string;
labelname: string[];
descr: string;
imglink: string
}
const formRef = ref();
const formState: UnwrapRef<FormState> = reactive({
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 onSubmit = () => {
formRef.value
.validate()
.then(async () => {
const labels = formState.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.blogtitle,
typeid: formState.typeid,
imglink:formState.imglink,
blogcontent: formState.blogcontent,
descr: formState.descr
},
labels:labels
}
if (formState.id) {
await put(`/blogs/update/${formState.id}`, formdata);
} else {
await post('/blogs/add', formdata);
}
})
router.push("/admin/blogmanage")
.catch((error: any) => {
console.log('error', error);
});
};
onMounted(async () => {
labelList()
typeList()
});
const resetForm = () => {
formRef.value.resetFields();
};
</script>
<style scoped>
.editor-container {
width: 100%;
}
.vditor {
width: 100%;
border: 1px solid #ccc;
}
.items {
width: calc(75vw/4);
}
#content {
padding: 24px 24px 0 24px;
}
.desrpad {
padding: 24px 0 0 0;
}
</style>

188
src/views/admin/blogmange/BlogManageView.vue

@ -8,9 +8,41 @@
</a-space>
<a-space style="margin-left: 16px;">
<a-button @click="search">查询</a-button>
<a-button type="primary" ghost @click="blogAdd">新增</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 }">
@ -24,13 +56,14 @@
<template v-if="column.dataIndex === 'operation'">
<a-space>
<div>
<a-button size="small" danger @click="showModal(record.id)">删除</a-button>
<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="ackUpdate(record)">编辑</a-button>
<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>
@ -41,15 +74,17 @@
</template>
<script setup lang='ts'>
import { ref, reactive, onMounted } from 'vue';
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 } from "@/tools/request"
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()
@ -85,7 +120,7 @@ const search = async () => {
blogtitle: items.blogtitle,
typename: items.typename,
blogcontent: items.blogcontent,
wordcount:items.wordcount,
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'),
@ -99,17 +134,126 @@ const search = async () => {
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 showModal = (id: any) => {
const delModal = (id: any) => {
delControl.open = true;
delControl.ids = id;
};
//
const blogAdd = function () {
router.push('/admin/blogmanage/add')
}
const bloglist = ref<blogInterface[]>([])
const blogList = async () => {
try {
@ -117,6 +261,7 @@ const blogList = async () => {
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'),
@ -159,10 +304,10 @@ const labelfilter = (labelnames: any) => {
// console.error('There was an error deleting the blog!', error);
// })
// };
//
const ackUpdate = async (record: { key: string, id: number }) => {
router.push(`/admin/blogmanage/update/${record.id}`);
const ackUpdate = async (id: any) => {
router.push(`/admin/blogmanage/update/${id}`);
};
const ackWatch = async (record: { key: string, id: number }) => {
router.push(`/admin/blogmanage/watch`);
@ -211,6 +356,8 @@ const columns = [
onMounted(async () => {
blogList()
typeList()
labelList()
});
</script>
@ -222,4 +369,17 @@ onMounted(async () => {
.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>
Loading…
Cancel
Save