This commit is contained in:
2025-03-24 14:17:48 +08:00
parent 46fc546d6f
commit 79fcae935b
15 changed files with 773 additions and 119 deletions

View File

@@ -0,0 +1,44 @@
<script setup>
import {ref} from 'vue';
const group = [
{
label: '站内URL',
value: 0,
},
{
label: '站内富文本页面',
value: 1,
},
{
label: '微信链接',
value: 2,
},
{
label: '外部链接',
value: 3,
},
{
label: '弹窗',
value: 4,
},
{
label: '空',
value: 5,
},
];
const type = ref(0);
</script>
<template>
<a-radio-group v-model:model-value="type">
<div class="grid grid-cols-3">
<a-radio v-for="item in group" :key="item.value" :value="item.value">
{{item.label}}
</a-radio>
</div>
</a-radio-group>
</template>
<style scoped lang="scss">
</style>

View File

@@ -23,7 +23,12 @@ onMounted(() => {
</script> </script>
<template> <template>
<a-select v-bind="$attrs" :options="list" :field-names="fieldName" placeholder="请选择"></a-select> <a-select
v-bind="$attrs"
:options="list"
:field-names="fieldName"
placeholder="请选择">
</a-select>
</template> </template>
<style scoped> <style scoped>

View File

@@ -0,0 +1,36 @@
<script setup>
import {ref} from "vue";
import JumpMethod from '../../../../../components/JumpMethod/index.vue';
const visible = ref(false);
</script>
<template>
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<div v-else @click="visible=true">
<slot></slot>
</div>
<a-modal
title="编辑平台消息"
title-align="start"
v-model:visible="visible">
<a-form layout="vertical">
<a-form-item label="封面">
<a-upload></a-upload>
</a-form-item>
<a-form-item label="跳转方式">
<JumpMethod></JumpMethod>
</a-form-item>
</a-form>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,35 @@
<script setup>
import {ref} from 'vue';
const {title} = defineProps({
title: {
type: String,
default: '二维码'
}
});
const visible = ref(false);
</script>
<template>
<a-link :hoverable="false" @click="visible=true">编辑</a-link>
<a-modal
ok-text="提交"
:title="title"
title-align="start"
v-model:visible="visible">
<a-form>
<a-form-item label="位置">
<a-input placeholder="首页/添加客服&我的/联系客服"></a-input>
</a-form-item>
<a-form-item label="二维码">
<a-upload></a-upload>
</a-form-item>
</a-form>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -3,6 +3,7 @@ import SequenceAdjustment from "../../../../../components/SequenceAdjustment/ind
import {reactive} from "vue"; import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js"; import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js"; import Api from "../../../../../api/index.js";
import EditBanner from "./EditBanner.vue";
const columns = [ const columns = [
{ {
@@ -35,7 +36,7 @@ const columns = [
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
slotName: 'action', slotName: 'action',
width: 60, width: 120,
}, },
]; ];
@@ -56,12 +57,7 @@ const {loading, pagination, initFetchData} = useTableQuery({
</script> </script>
<template> <template>
<a-button type="primary"> <EditBanner></EditBanner>
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table <a-table
:loading="loading" :loading="loading"
@@ -77,7 +73,12 @@ const {loading, pagination, initFetchData} = useTableQuery({
<SequenceAdjustment></SequenceAdjustment> <SequenceAdjustment></SequenceAdjustment>
</template> </template>
<template v-slot:action> <template v-slot:action>
<a-link :hoverable="false" status="danger">删除</a-link> <div class="flex gap-[10px]">
<EditBanner>
<a-link :hoverable="false">编辑</a-link>
</EditBanner>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template> </template>
</a-table> </a-table>
</template> </template>

View File

@@ -1,129 +1,55 @@
<script setup> <script setup>
import {reactive, ref} from "vue"; import {defineAsyncComponent} from "vue";
import SequenceAdjustment from "../../../../../components/SequenceAdjustment/index.vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js"; const FrequentlyQuestions = defineAsyncComponent(() => import('./tabs/FrequentlyQuestions.vue'));
import Api from "../../../../../api/index.js"; const BasicTeaching = defineAsyncComponent(() => import('./tabs/BasicTeaching.vue'));
const BannerManagement = defineAsyncComponent(() => import('./tabs/BannerManagement.vue'));
const SecondaryClassificationManagement = defineAsyncComponent(() => import('./tabs/SecondaryClassificationManagement.vue'));
const tabs = [ const tabs = [
{ {
title: '常见问题', title: '常见问题',
key: '1', key: '1',
component: FrequentlyQuestions
}, },
{ {
title: '基础教学', title: '基础教学',
key: '2', key: '2',
component: BasicTeaching
}, },
{ {
title: 'banner管理', title: 'banner管理',
key: '3', key: '3',
component: BannerManagement
}, },
{ {
title: '二级分类管理', title: '二级分类管理',
key: '4', key: '4',
component: SecondaryClassificationManagement
}, },
]; ];
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '二级分类',
dataIndex: 'key',
},
{
title: '标题',
dataIndex: 'key',
},
{
title: '简介',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '是否置顶',
dataIndex: 'isTop',
slotName: 'isTop',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const activeKey = ref('1');
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<a-tabs v-model:active-key="activeKey" type="text"> <a-tabs
<a-tab-pane class="w-full"
v-for="item in tabs" :justify="true"
:key="item.key" :destroy-on-hide="true"
:title="item.title"> type="rounded">
<a-tab-pane v-for="item in tabs" :key="item.key" :title="item.title">
<Suspense>
<template #default>
<div class="h-full flex flex-col items-start">
<component :is="item.component"></component>
</div>
</template>
<template #fallback>
加载中...
</template>
</Suspense>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">编辑</a-link>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -3,6 +3,7 @@ import SequenceAdjustment from "../../../../../components/SequenceAdjustment/ind
import {reactive} from "vue"; import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js"; import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js"; import Api from "../../../../../api/index.js";
import EditBanner from "./EditBanner.vue";
const columns = [ const columns = [
{ {
@@ -35,7 +36,7 @@ const columns = [
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
slotName: 'action', slotName: 'action',
width: 60, width: 120,
}, },
]; ];
@@ -56,12 +57,7 @@ const {loading, pagination, initFetchData} = useTableQuery({
</script> </script>
<template> <template>
<a-button type="primary"> <EditBanner></EditBanner>
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table <a-table
:loading="loading" :loading="loading"
@@ -77,7 +73,12 @@ const {loading, pagination, initFetchData} = useTableQuery({
<SequenceAdjustment></SequenceAdjustment> <SequenceAdjustment></SequenceAdjustment>
</template> </template>
<template v-slot:action> <template v-slot:action>
<a-link :hoverable="false" status="danger">删除</a-link> <div class="flex gap-[10px]">
<EditBanner>
<a-link :hoverable="false">编辑</a-link>
</EditBanner>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template> </template>
</a-table> </a-table>
</template> </template>

View File

@@ -2,6 +2,7 @@
import {reactive} from "vue"; import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js"; import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js"; import Api from "../../../../../api/index.js";
import EditQR from "./EditQR.vue";
const columns = [ const columns = [
{ {
@@ -59,7 +60,7 @@ const {loading, pagination, initFetchData} = useTableQuery({
</a-image> </a-image>
</template> </template>
<template v-slot:action> <template v-slot:action>
<a-link :hoverable="false">编辑</a-link> <EditQR></EditQR>
</template> </template>
</a-table> </a-table>
</template> </template>

View File

@@ -0,0 +1,93 @@
<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";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '封面',
dataIndex: 'key',
},
{
title: '跳转方式',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[10px]">
<EditBanner>
<a-link :hoverable="false">编辑</a-link>
</EditBanner>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,109 @@
<script setup>
import SequenceAdjustment from "../../../../../../components/SequenceAdjustment/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../../hooks/useTableQuery.js";
import Api from "../../../../../../api/index.js";
import AddBasicTeaching from "./components/AddBasicTeaching.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '二级分类',
dataIndex: 'key',
},
{
title: '封面',
dataIndex: 'key',
},
{
title: '标题',
dataIndex: 'key',
},
{
title: '简介',
dataIndex: 'key',
},
{
title: '跳转方式',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '是否置顶',
dataIndex: 'isTop',
slotName: 'isTop',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<AddBasicTeaching></AddBasicTeaching>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<AddBasicTeaching>
<a-link :hoverable="false">编辑</a-link>
</AddBasicTeaching>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,101 @@
<script setup>
import SequenceAdjustment from "../../../../../../components/SequenceAdjustment/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../../hooks/useTableQuery.js";
import Api from "../../../../../../api/index.js";
import AddFrequentlyQuestions from "./components/AddFrequentlyQuestions.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '二级分类',
dataIndex: 'key',
},
{
title: '标题',
dataIndex: 'key',
},
{
title: '简介',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '是否置顶',
dataIndex: 'isTop',
slotName: 'isTop',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<AddFrequentlyQuestions></AddFrequentlyQuestions>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<AddFrequentlyQuestions>
<a-link :hoverable="false">编辑</a-link>
</AddFrequentlyQuestions>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,129 @@
<script setup>
import SequenceAdjustment from "../../../../../../components/SequenceAdjustment/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../../hooks/useTableQuery.js";
import Api from "../../../../../../api/index.js";
import AddSecondaryClassificationManagement from "./components/AddSecondaryClassificationManagement.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
},
{
title: '二级分类名称',
dataIndex: 'key',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo1 = reactive({
page: '',
rows: [],
total: 0,
});
const vo2 = reactive({
page: '',
rows: [],
total: 0,
});
const {loading: loading1, pagination: pagination1, initFetchData: initFetchData1} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo1, data);
}
});
const {loading: loading2, pagination: pagination2, initFetchData: initFetchData2} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo2, data);
}
});
</script>
<template>
<div class="w-full h-full flex gap-[20px]">
<div class="flex-grow flex flex-col gap-[20px]">
<div class="flex justify-between">
<div class="title">常见问题</div>
<AddSecondaryClassificationManagement :max-class="1"></AddSecondaryClassificationManagement>
</div>
<a-table
@page-change="(e) => pagination1.current = e"
:pagination="pagination1"
:data="vo1.rows"
:loading="loading1"
:columns="columns"
class="w-full h-full">
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[10px]">
<AddSecondaryClassificationManagement :max-class="1">
<a-link :hoverable="false">编辑</a-link>
</AddSecondaryClassificationManagement>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</div>
<div class="flex-grow flex flex-col gap-[20px]">
<div class="flex justify-between">
<div class="title">基础教学</div>
<AddSecondaryClassificationManagement :max-class="2"></AddSecondaryClassificationManagement>
</div>
<a-table
@page-change="(e) => pagination2.current = e"
:pagination="pagination2"
:data="vo2.rows"
:loading="loading2"
:columns="columns"
class="w-full h-full">
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[10px]">
<AddSecondaryClassificationManagement :max-class="2">
<a-link :hoverable="false">编辑</a-link>
</AddSecondaryClassificationManagement>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</div>
</div>
</template>
<style scoped lang="scss">
.title {
color: rgb(29, 33, 41);
font-size: 16px;
font-weight: 500;
line-height: 24px;
letter-spacing: 0;
text-align: left;
}
</style>

View File

@@ -0,0 +1,54 @@
<script setup>
import Api from "../../../../../../../api/index.js";
import XSelect from "../../../../../../../components/XSelect/index.vue";
import JumpMethod from '../../../../../../../components/JumpMethod/index.vue';
import {reactive, ref} from "vue";
const visible = ref(false);
const form = reactive({
title: null,
});
</script>
<template>
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<div v-else @click="visible=true">
<slot></slot>
</div>
<a-modal
title="新增常见问题"
title-align="start"
v-model:visible="visible">
<a-form
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>
</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-form-item>
</a-form>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,47 @@
<script setup>
import {ref, reactive} from 'vue';
import XSelect from "../../../../../../../components/XSelect/index.vue";
import Api from "../../../../../../../api/index.js";
const visible = ref(false);
const form = reactive({
title: null,
});
</script>
<template>
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<div v-else @click="visible=true">
<slot></slot>
</div>
<a-modal
title="新增常见问题"
title-align="start"
v-model:visible="visible">
<a-form
layout="vertical"
:model="form">
<a-form-item label="二级分类">
<XSelect :api="Api.system.getSelect" 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>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,72 @@
<script setup>
import XSelect from "../../../../../../../components/XSelect/index.vue";
import {reactive, ref} from "vue";
const {maxClass} = defineProps({
maxClass: {
type: Number,
default: 1,
}
});
const visible = ref(false);
const form = reactive({
title: null,
});
const getData = async () => {
return new Promise((resolve) => {
resolve({
data: [
{
id: 1,
name: '常见问题',
},
{
id: 2,
name: '基础教学',
},
]
});
})
}
</script>
<template>
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<div v-else @click="visible=true">
<slot></slot>
</div>
<a-modal
title="新增二级分类"
title-align="start"
v-model:visible="visible">
<a-form
layout="vertical"
:model="form">
<a-form-item label="一级分类">
<XSelect
:default-value="maxClass"
:api="getData"
placeholder="请选择二级分类"
:disabled="true">
</XSelect>
</a-form-item>
<a-form-item label="二级分类名称">
<a-input v-model:model-value="form.title" placeholder="请输入二级分类名称"></a-input>
</a-form-item>
</a-form>
</a-modal>
</template>
<style scoped lang="scss">
</style>