This commit is contained in:
2025-04-25 11:47:08 +08:00
parent f9381e74ed
commit dfb552b7ed
15 changed files with 488 additions and 114 deletions

View File

@@ -412,6 +412,14 @@ const admin = {
data: data
});
},
getArticleCategoryList2: async (data) => {
const res = await request({
url: '/admin/articleCategory/getList',
method: Method.POST,
data: data
});
return {data: res.data.list};
},
addArticleCategory: async (data) => {
return request({
url: '/admin/articleCategory/add',
@@ -433,7 +441,7 @@ const admin = {
data: data
});
},
delArticle: async (id) => {
delArticleCategory: async (id) => {
return request({
url: '/admin/articleCategory/del',
method: Method.POST,
@@ -447,6 +455,96 @@ const admin = {
data: data
});
},
getArticleList: async (data) => {
return request({
url: '/admin/article/getList',
method: Method.POST,
data: data
});
},
addArticle: async (data) => {
return request({
url: '/admin/article/add',
method: Method.POST,
data: data
});
},
statusArticle: async (id) => {
return request({
url: '/admin/article/status',
method: Method.POST,
data: {id}
});
},
topArticle: async (id) => {
return request({
url: '/admin/article/top',
method: Method.POST,
data: {id}
});
},
weighArticle: async (data) => {
return request({
url: '/admin/article/weigh',
method: Method.POST,
data: data
});
},
delArticle: async (id) => {
return request({
url: '/admin/article/del',
method: Method.POST,
data: {id}
});
},
editArticle: async (data) => {
return request({
url: '/admin/article/edit',
method: Method.POST,
data: data
});
},
typeArticle: async () => {
return request({
url: '/admin/article/getType',
method: Method.POST,
});
},
getSingleList: async (data) => {
return request({
url: '/admin/single/getList',
method: Method.POST,
data: data,
});
},
addSingle: async (data) => {
return request({
url: '/admin/single/add',
method: Method.POST,
data: data,
});
},
editSingle: async (data) => {
return request({
url: '/admin/single/edit',
method: Method.POST,
data: data,
});
},
delSingle: async (id) => {
return request({
url: '/admin/single/del',
method: Method.POST,
data: {id},
});
},
detailSingle: async (id) => {
return request({
url: '/admin/single/detail',
method: Method.POST,
data: {id},
});
},
}
export default admin;

View File

@@ -1,7 +1,8 @@
<script setup>
import {ref, watch, computed, nextTick} from "vue";
import {computed, nextTick, ref, watch} from "vue";
import Editor from "@tinymce/tinymce-vue";
import {VITE_TINYMCE_KEY} from "../../utils/index.js";
import Api from "../../api/index.js";
const content = defineModel('content');
const EditorIF = ref(true);
@@ -28,7 +29,13 @@ const INIT = computed(() => ({
images_upload_url: 'http://your-api/upload',
images_upload_credentials: true,
images_upload_handler: (blobInfo, success, failure) => {
console.log(blobInfo, success, failure);
return new Promise((resolve, reject) => {
Api.system.uploadFile(blobInfo.blob()).then(({data}) => {
resolve(data);
}).catch(err => {
reject(err);
});
})
},
file_picker_types: 'image',
images_reuse_filename: true,

View File

@@ -1,17 +1,47 @@
<script setup>
import TinyMCE from "./index.vue";
import {ref} from "vue";
import {ref, watch} from "vue";
import TinyMCE from './index.vue';
const {title, preview} = defineProps({
title: {
type: String,
default: ''
},
preview: {
type: Boolean,
default: false,
}
});
const emits = defineEmits(['success', 'show']);
const content = defineModel('content');
const contentTitle = defineModel('contentTitle');
const inputRef = ref();
const visible = ref(false);
const fullscreen = ref(false);
watch(
() => visible.value,
(val) => {
if (val) emits('show');
}
)
const success = async () => {
emits('success');
}
const clickInput = () => {
inputRef.value.focus();
}
</script>
<template>
<a-link v-if="!$slots.default" :hoverable="false" @click="visible=true">编辑</a-link>
<div v-else><slot></slot></div>
<div v-else @click="visible=true">
<slot></slot>
</div>
<a-modal
@ok="success"
id="TinyMCEModal"
:mask-closable="false"
:unmount-on-close="true"
@@ -19,23 +49,30 @@ const fullscreen = ref(false);
width="800px"
:draggable="true"
title-align="start"
title="编辑"
v-bind="$attrs"
v-model:visible="visible">
<template #title>
<div class="flex justify-between w-full pr-[30px]">
<div>
编辑
{{ title }}
</div>
<div>
<a-input v-if="!preview" ref="inputRef" @click="clickInput"
v-model:model-value="contentTitle"></a-input>
<div v-else>{{ contentTitle }}</div>
</div>
<a-link @click="fullscreen = !fullscreen">
<icon-fullscreen v-if="!fullscreen" />
<icon-fullscreen-exit v-else />
<icon-fullscreen v-if="!fullscreen"/>
<icon-fullscreen-exit v-else/>
</a-link>
</div>
</template>
<TinyMCE
v-if="!preview"
v-model:content="content"
:skin="fullscreen ? 'fluent' : 'borderless'">
</TinyMCE>
<div v-else v-html="content" class="p-[24px]"></div>
</a-modal>
</template>

View File

@@ -1,12 +1,17 @@
<script setup>
import {onMounted, reactive} from "vue";
const {api, fieldName} = defineProps({
const {api, fieldName, apiPo} = defineProps({
api: {
type: Function,
default: async () => {},
default: async () => {
},
required: true,
},
apiPo: {
type: Object,
default: {}
},
fieldName: {
type: Object,
default: {value: 'id', label: 'name'},
@@ -15,7 +20,7 @@ const {api, fieldName} = defineProps({
const list = reactive([]);
onMounted(() => {
api && api().then(({data}) => {
api && api(apiPo).then(({data}) => {
list.length = 0;
list.push(...data);
});

View File

@@ -24,7 +24,7 @@ const beforeUpload = (file) => {
<a-upload draggable @before-upload="beforeUpload">
<template #upload-button v-if="files">
<div class="x-upload-one-image">
<a-image :preview="false" :src="files"></a-image>
<a-image fit="contain" width="100%" height="100%" :preview="false" :src="files"></a-image>
</div>
</template>
</a-upload>

View File

@@ -0,0 +1,58 @@
<script setup>
import {reactive} from "vue";
import TinyMCEModal from "../../../../../components/TinyMCE/modal.vue";
import Api from "../../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const emits = defineEmits(['success']);
const {detail, preview} = defineProps({
detail: {
type: Object,
default: {}
},
preview: {
type: Boolean,
default: false,
}
});
const form = reactive({
title: null,
content: null,
});
const showModal = async () => {
if (detail.id) {
const {data: {content}} = await Api.admin.detailSingle(detail.id);
detail.content = content;
}
Object.assign(form, detail);
}
const success = async () => {
if (detail.id) {
const {msg} = await Api.admin.editSingle(form);
Message.success(msg);
} else {
const {msg} = await Api.admin.addSingle(form);
Message.success(msg);
}
emits('success');
}
</script>
<template>
<TinyMCEModal
v-model:content-title="form.title"
:preview="preview"
:title="detail?.id ? '编辑' : '新增'"
v-model:content="form.content"
v-bind="$attrs"
@show="showModal"
@success="success">
<slot></slot>
</TinyMCEModal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -65,7 +65,9 @@ const success = async () => {
v-model:visible="visible">
<a-form layout="vertical">
<a-form-item label="封面">
<upload-one v-model:file="form.file"></upload-one>
<div class="w-full h-[140px]">
<upload-one v-model:file="form.file"></upload-one>
</div>
</a-form-item>
<JumpMethod v-model:form="form" :api="Api.admin.getADVType"></JumpMethod>
</a-form>

View File

@@ -5,16 +5,17 @@ import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
import EditBanner from "./EditBanner.vue";
import XSwitch from "../../../../../components/XSwitch/index.vue";
import {Message} from "@arco-design/web-vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'id',
width: 120,
},
{
title: '封面',
dataIndex: 'key',
dataIndex: 'file',
slotName: 'file',
},
{
@@ -58,6 +59,14 @@ const {loading, pagination, fetchData} = useTableQuery({
Object.assign(vo, data);
}
});
const del = async (id) => {
const {code, msg} = await Api.admin.barrageDel({
id: id
});
if (code === 1) Message.success(msg);
await fetchData();
}
</script>
<template>
@@ -93,7 +102,7 @@ const {loading, pagination, fetchData} = useTableQuery({
<EditBanner :position="2" :detail="record" @success="fetchData">
<a-link :hoverable="false">编辑</a-link>
</EditBanner>
<a-popconfirm content="确认删除吗?" @ok="delADV(record.id)">
<a-popconfirm content="确认删除吗?" @ok="del(record.id)">
<a-link :hoverable="false" status="danger">删除</a-link>
</a-popconfirm>
</div>

View File

@@ -1,18 +1,19 @@
<script setup>
import TinyMCEModal from "../../../../../components/TinyMCE/modal.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
import AddRichTextContent from "./AddRichTextContent.vue";
import {Message} from "@arco-design/web-vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'id',
width: 120,
},
{
title: '标题',
dataIndex: 'key',
dataIndex: 'title',
},
{
title: '预览',
@@ -35,22 +36,30 @@ const vo = reactive({
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
const {loading, pagination, fetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
api: Api.admin.getSingleList,
callback: (data) => {
Object.assign(vo, data);
}
});
const del = async (id) => {
const {msg} = await Api.admin.delSingle(id);
Message.success(msg);
await fetchData();
}
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<AddRichTextContent @success="fetchData">
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
</AddRichTextContent>
<a-table
:loading="loading"
@@ -59,13 +68,22 @@ const {loading, pagination, initFetchData} = useTableQuery({
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:preview>
<a-link :hoverable="false"><icon-eye />预览</a-link>
<template v-slot:preview="{record}">
<AddRichTextContent @success="fetchData" :detail="record" :preview="true">
<a-link :hoverable="false">
<icon-eye/>
预览
</a-link>
</AddRichTextContent>
</template>
<template v-slot:action="{record}">
<div class="flex gap-[20px]">
<TinyMCEModal v-model:content="record.content"></TinyMCEModal>
<a-link :hoverable="false" status="danger">删除</a-link>
<AddRichTextContent @success="fetchData" :detail="record">
<a-link :hoverable="false">编辑</a-link>
</AddRichTextContent>
<a-popconfirm content="确定删除吗?" @ok="del(record.id)">
<a-link :hoverable="false" status="danger">删除</a-link>
</a-popconfirm>
</div>
</template>
</a-table>

View File

@@ -1,28 +1,30 @@
<script setup>
import SequenceAdjustment from "../../../../../../components/SequenceAdjustment/index.vue";
import EditBanner from "../EditBanner.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../../hooks/useTableQuery.js";
import Api from "../../../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
import XSwitch from "../../../../../../components/XSwitch/index.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'id',
width: 120,
},
{
title: '封面',
dataIndex: 'key',
dataIndex: 'file',
slotName: 'file',
},
{
title: '跳转方式',
dataIndex: 'key',
dataIndex: 'type_text',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
dataIndex: 'isStatus',
slotName: 'isStatus',
width: 100,
align: 'center',
},
@@ -40,29 +42,34 @@ const columns = [
},
];
const po = reactive({});
const po = reactive({
position: 3,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
const {loading, pagination, fetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
api: Api.admin.getADVList,
callback: (data) => {
Object.assign(vo, data);
}
});
const del = async (id) => {
const {code, msg} = await Api.admin.barrageDel({
id: id
});
if (code === 1) Message.success(msg);
await fetchData();
}
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<EditBanner :position="3" @success="fetchData"></EditBanner>
<a-table
:loading="loading"
@@ -71,18 +78,25 @@ const {loading, pagination, initFetchData} = useTableQuery({
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
<template v-slot:file="{record}">
<a-image height="60" :src="record.file"></a-image>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
<template v-slot:isStatus="{record}">
<x-switch
v-model:model-value="record.status"
:id="record.id"
:api="Api.admin.setADVStatus"
@change="fetchData">
</x-switch>
</template>
<template v-slot:action>
<template v-slot:action="{record}">
<div class="flex gap-[10px]">
<EditBanner>
<EditBanner :position="3" :detail="record" @success="fetchData">
<a-link :hoverable="false">编辑</a-link>
</EditBanner>
<a-link :hoverable="false" status="danger">删除</a-link>
<a-popconfirm content="确认删除吗?" @ok="del(record.id)">
<a-link :hoverable="false" status="danger">删除</a-link>
</a-popconfirm>
</div>
</template>
</a-table>

View File

@@ -3,38 +3,32 @@ import SequenceAdjustment from "../../../../../../components/SequenceAdjustment/
import {reactive} from "vue";
import useTableQuery from "../../../../../../hooks/useTableQuery.js";
import Api from "../../../../../../api/index.js";
import XSwitch from "../../../../../../components/XSwitch/index.vue";
import {Message} from "@arco-design/web-vue";
import AddBasicTeaching from "./components/AddBasicTeaching.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'id',
width: 120,
},
{
title: '二级分类',
dataIndex: 'key',
},
{
title: '封面',
dataIndex: 'key',
dataIndex: 'name',
},
{
title: '标题',
dataIndex: 'key',
dataIndex: 'title',
},
{
title: '简介',
dataIndex: 'key',
},
{
title: '跳转方式',
dataIndex: 'key',
dataIndex: 'content',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
dataIndex: 'isStatus',
slotName: 'isStatus',
width: 100,
align: 'center',
},
@@ -58,24 +52,35 @@ const columns = [
width: 120,
},
];
const po = reactive({});
const po = reactive({
pid: 2
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
const {loading, pagination, fetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
api: Api.admin.getArticleList,
callback: (data) => {
Object.assign(vo, data);
}
});
const del = async (id) => {
const {msg} = await Api.admin.delArticle(id);
Message.success(msg);
await fetchData();
}
</script>
<template>
<AddBasicTeaching></AddBasicTeaching>
<AddBasicTeaching
:pid="2"
@success="fetchData">
</AddBasicTeaching>
<a-table
:loading="loading"
@@ -84,21 +89,40 @@ const {loading, pagination, initFetchData} = useTableQuery({
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
<template v-slot:isStatus="{record}">
<x-switch
v-model:model-value="record.status"
:id="record.id"
:api="Api.admin.statusArticle"
@change="fetchData">
</x-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
<template v-slot:isTop="{record}">
<x-switch
v-model:model-value="record.is_top"
:id="record.id"
:api="Api.admin.topArticle"
@change="fetchData">
</x-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
<template v-slot:sort="{record}">
<SequenceAdjustment
:id="record.id"
@success="fetchData"
:api="Api.admin.weighArticle">
</SequenceAdjustment>
</template>
<template v-slot:action>
<template v-slot:action="{record}">
<div class="flex gap-[20px]">
<AddBasicTeaching>
<AddBasicTeaching
@success="fetchData"
:detail="record"
:pid="2">
<a-link :hoverable="false">编辑</a-link>
</AddBasicTeaching>
<a-link :hoverable="false" status="danger">删除</a-link>
<a-popconfirm content="确认删除吗?" @ok="del(record.id)">
<a-link :hoverable="false" status="danger">删除</a-link>
</a-popconfirm>
</div>
</template>
</a-table>

View File

@@ -4,29 +4,31 @@ import {reactive} from "vue";
import useTableQuery from "../../../../../../hooks/useTableQuery.js";
import Api from "../../../../../../api/index.js";
import AddFrequentlyQuestions from "./components/AddFrequentlyQuestions.vue";
import XSwitch from "../../../../../../components/XSwitch/index.vue";
import {Message} from "@arco-design/web-vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'id',
width: 120,
},
{
title: '二级分类',
dataIndex: 'key',
dataIndex: 'name',
},
{
title: '标题',
dataIndex: 'key',
dataIndex: 'title',
},
{
title: '简介',
dataIndex: 'key',
dataIndex: 'content',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
dataIndex: 'isStatus',
slotName: 'isStatus',
width: 100,
align: 'center',
},
@@ -50,7 +52,9 @@ const columns = [
width: 120,
},
];
const po = reactive({});
const po = reactive({
pid: 1
});
const vo = reactive({
page: '',
rows: [],
@@ -59,15 +63,22 @@ const vo = reactive({
const {loading, pagination, fetchData} = useTableQuery({
parameter: po,
api: Api.admin.getArticlevategoryList,
api: Api.admin.getArticleList,
callback: (data) => {
Object.assign(vo, data);
}
});
const del = async (id) => {
const {msg} = await Api.admin.delArticle(id);
Message.success(msg);
await fetchData();
}
</script>
<template>
<AddFrequentlyQuestions
:pid="1"
@success="fetchData">
</AddFrequentlyQuestions>
@@ -78,21 +89,40 @@ const {loading, pagination, fetchData} = useTableQuery({
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
<template v-slot:isStatus="{record}">
<x-switch
v-model:model-value="record.status"
:id="record.id"
:api="Api.admin.statusArticle"
@change="fetchData">
</x-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
<template v-slot:isTop="{record}">
<x-switch
v-model:model-value="record.is_top"
:id="record.id"
:api="Api.admin.topArticle"
@change="fetchData">
</x-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
<template v-slot:sort="{record}">
<SequenceAdjustment
:id="record.id"
@success="fetchData"
:api="Api.admin.weighArticle">
</SequenceAdjustment>
</template>
<template v-slot:action>
<template v-slot:action="{record}">
<div class="flex gap-[20px]">
<AddFrequentlyQuestions>
<AddFrequentlyQuestions
@success="fetchData"
:detail="record"
:pid="1">
<a-link :hoverable="false">编辑</a-link>
</AddFrequentlyQuestions>
<a-link :hoverable="false" status="danger">删除</a-link>
<a-popconfirm content="确认删除吗?" @ok="del(record.id)">
<a-link :hoverable="false" status="danger">删除</a-link>
</a-popconfirm>
</div>
</template>
</a-table>

View File

@@ -59,7 +59,7 @@ const {loading: loading2, pagination: pagination2, fetchData: fetchData2} = useT
});
const del = async (id) => {
const {msg} = await Api.admin.delArticle(id);
const {msg} = await Api.admin.delArticleCategory(id);
Message.success(msg);
await fetchData1();
await fetchData2();

View File

@@ -1,14 +1,47 @@
<script setup>
import Api from "../../../../../../../api/index.js";
import JumpMethod from "../../../../../../../components/JumpMethod/index.vue";
import {reactive, ref, watch} from 'vue';
import XSelect from "../../../../../../../components/XSelect/index.vue";
import JumpMethod from '../../../../../../../components/JumpMethod/index.vue';
import {reactive, ref} from "vue";
import Api from "../../../../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const emits = defineEmits(['success']);
const {pid, detail} = defineProps({
pid: {
type: Number,
default: 2,
},
detail: {
type: Object,
default: {}
}
});
const visible = ref(false);
const form = reactive({
type: null,
title: null,
category_id: null,
content: null,
});
watch(
() => visible.value,
(val) => {
if (val) Object.assign(form, detail);
}
)
const success = async () => {
if (detail.id) {
const {msg} = await Api.admin.editArticle({...form, pid});
Message.success(msg);
} else {
const {msg} = await Api.admin.addArticle({...form, pid});
Message.success(msg);
}
emits('success');
}
</script>
<template>
@@ -24,6 +57,7 @@ const form = reactive({
<a-modal
@ok="success"
title="新增常见问题"
title-align="start"
v-model:visible="visible">
@@ -31,20 +65,20 @@ const form = reactive({
layout="vertical"
:model="form">
<a-form-item label="二级分类">
<XSelect :api="Api.system.getSelect" placeholder="请选择二级分类"></XSelect>
</a-form-item>
<a-form-item label="标题">
<a-upload></a-upload>
<XSelect
v-model:model-value="form.category_id"
:api="Api.admin.getArticleCategoryList2"
:api-po="{pid}"
placeholder="请选择二级分类">
</XSelect>
</a-form-item>
<a-form-item label="标题">
<a-input v-model:model-value="form.title" placeholder="请输入标题"></a-input>
</a-form-item>
<a-form-item label="简介">
<a-textarea placeholder="请输入简介"></a-textarea>
</a-form-item>
<a-form-item label="跳转方式">
<JumpMethod></JumpMethod>
<a-textarea v-model:model-value="form.content" placeholder="请输入简介"></a-textarea>
</a-form-item>
<JumpMethod v-model:form="form" :api="Api.admin.typeArticle"></JumpMethod>
</a-form>
</a-modal>
</template>

View File

@@ -1,13 +1,45 @@
<script setup>
import {ref, reactive} from 'vue';
import {reactive, ref, watch} from 'vue';
import XSelect from "../../../../../../../components/XSelect/index.vue";
import Api from "../../../../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const emits = defineEmits(['success']);
const {pid, detail} = defineProps({
pid: {
type: Number,
default: 1,
},
detail: {
type: Object,
default: {}
}
});
const visible = ref(false);
const form = reactive({
title: null,
category_id: null,
content: null,
});
watch(
() => visible.value,
(val) => {
if (val) Object.assign(form, detail);
}
)
const success = async () => {
if (detail.id) {
const {msg} = await Api.admin.editArticle({...form, pid});
Message.success(msg);
} else {
const {msg} = await Api.admin.addArticle({...form, pid});
Message.success(msg);
}
emits('success');
}
</script>
<template>
@@ -23,6 +55,7 @@ const form = reactive({
<a-modal
@ok="success"
title="新增常见问题"
title-align="start"
v-model:visible="visible">
@@ -30,13 +63,18 @@ const form = reactive({
layout="vertical"
:model="form">
<a-form-item label="二级分类">
<XSelect :api="Api.system.getSelect" placeholder="请选择二级分类"></XSelect>
<XSelect
v-model:model-value="form.category_id"
:api="Api.admin.getArticleCategoryList2"
:api-po="{pid}"
placeholder="请选择二级分类">
</XSelect>
</a-form-item>
<a-form-item label="标题">
<a-input v-model:model-value="form.title" placeholder="请输入标题"></a-input>
</a-form-item>
<a-form-item label="简介">
<a-textarea placeholder="请输入简介"></a-textarea>
<a-textarea v-model:model-value="form.content" placeholder="请输入简介"></a-textarea>
</a-form-item>
</a-form>
</a-modal>