<template>
|
<div class="page">
|
<h3 class="section-title">内容设置</h3>
|
|
<div class="toolbar-row">
|
<el-radio-group v-model="activeTab">
|
<el-radio-button label="ABOUT">关于我们</el-radio-button>
|
<el-radio-button label="NOTICE">入园须知</el-radio-button>
|
<el-radio-button label="FLOW">入园流程</el-radio-button>
|
</el-radio-group>
|
</div>
|
|
<div class="editor-wrap" v-loading="loading">
|
<Toolbar
|
:key="`toolbar-${activeTab}`"
|
class="w-toolbar"
|
:editor="editorRef"
|
:default-config="toolbarConfig"
|
mode="default"
|
/>
|
<Editor
|
:key="`editor-${activeTab}`"
|
v-model="currentHtml"
|
class="w-editor"
|
:default-config="editorConfig"
|
mode="default"
|
@onCreated="handleCreated"
|
/>
|
</div>
|
|
<div v-if="activeTab === 'ABOUT'" class="about-enable-row">
|
<span class="about-enable-label">是否启用</span>
|
<el-switch v-permission="'config:content-settings:update'" v-model="form.aboutUsEnabled" />
|
</div>
|
|
<div class="save-bar">
|
<el-button v-permission="'config:content-settings:update'" type="primary" :loading="saving" @click="save">保存</el-button>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import "@wangeditor/editor/dist/css/style.css";
|
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
import { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, ref, watch } from "vue";
|
import { ElMessage } from "element-plus";
|
import http from "../api/http";
|
import type { IEditorConfig } from "@wangeditor/editor";
|
|
type TabKey = "ABOUT" | "NOTICE" | "FLOW";
|
|
const loading = ref(false);
|
const saving = ref(false);
|
const activeTab = ref<TabKey>("ABOUT");
|
const editorRef = shallowRef();
|
|
const form = ref({
|
aboutUsHtml: "",
|
parkNoticeHtml: "",
|
parkFlowHtml: "",
|
aboutUsEnabled: false,
|
});
|
|
const currentHtml = computed({
|
get() {
|
if (activeTab.value === "ABOUT") return form.value.aboutUsHtml;
|
if (activeTab.value === "NOTICE") return form.value.parkNoticeHtml;
|
return form.value.parkFlowHtml;
|
},
|
set(v: string) {
|
if (activeTab.value === "ABOUT") form.value.aboutUsHtml = v || "";
|
else if (activeTab.value === "NOTICE") form.value.parkNoticeHtml = v || "";
|
else form.value.parkFlowHtml = v || "";
|
},
|
});
|
|
const toolbarConfig = {
|
excludeKeys: ["group-image", "uploadImage", "insertImage", "group-video", "uploadVideo", "insertVideo"],
|
};
|
const editorConfig: Partial<IEditorConfig> = {
|
placeholder: "请输入内容",
|
autoFocus: false,
|
MENU_CONF: {
|
uploadImage: {
|
customUpload() {
|
ElMessage.warning("暂未对接图片上传");
|
},
|
},
|
insertImage: {
|
checkImage() {
|
ElMessage.warning("暂未对接图片上传");
|
return false;
|
},
|
},
|
uploadVideo: {
|
customUpload() {
|
ElMessage.warning("暂未对接视频上传");
|
},
|
},
|
insertVideo: {
|
checkVideo() {
|
ElMessage.warning("暂未对接视频上传");
|
return false;
|
},
|
},
|
},
|
};
|
|
function handleCreated(editor: unknown) {
|
editorRef.value = editor as never;
|
}
|
|
watch(activeTab, async () => {
|
editorRef.value = undefined;
|
await nextTick();
|
});
|
|
async function load() {
|
loading.value = true;
|
try {
|
const { data } = await http.get("/config/content-settings");
|
const r = data.result || {};
|
form.value.aboutUsHtml = String(r.aboutUsHtml || "");
|
form.value.parkNoticeHtml = String(r.parkNoticeHtml || "");
|
form.value.parkFlowHtml = String(r.parkFlowHtml || "");
|
form.value.aboutUsEnabled = !!r.aboutUsEnabled;
|
await nextTick();
|
} catch (e: unknown) {
|
ElMessage.error(e instanceof Error ? e.message : "加载失败");
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
async function save() {
|
saving.value = true;
|
try {
|
await http.put("/config/content-settings", {
|
aboutUsHtml: form.value.aboutUsHtml,
|
parkNoticeHtml: form.value.parkNoticeHtml,
|
parkFlowHtml: form.value.parkFlowHtml,
|
aboutUsEnabled: form.value.aboutUsEnabled,
|
});
|
await load();
|
ElMessage.success("已保存");
|
} catch (e: unknown) {
|
ElMessage.error(e instanceof Error ? e.message : "保存失败");
|
} finally {
|
saving.value = false;
|
}
|
}
|
|
onBeforeUnmount(() => {
|
const editor = editorRef.value as { destroy?: () => void } | undefined;
|
editor?.destroy?.();
|
});
|
|
onMounted(load);
|
</script>
|
|
<style scoped>
|
.page {
|
padding: 0;
|
}
|
.section-title {
|
font-size: 16px;
|
font-weight: 600;
|
margin: 0 0 12px;
|
padding-left: 10px;
|
border-left: 3px solid #409eff;
|
color: #303133;
|
}
|
.toolbar-row {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
margin-bottom: 12px;
|
}
|
.editor-wrap {
|
border: 1px solid #dcdfe6;
|
border-radius: 6px;
|
overflow: hidden;
|
background: #fff;
|
}
|
.w-toolbar {
|
border-bottom: 1px solid #ebeef5;
|
}
|
.w-editor {
|
min-height: 360px;
|
}
|
:deep(.w-e-text-container) {
|
min-height: 360px !important;
|
}
|
.about-enable-row {
|
margin-top: 12px;
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
}
|
.about-enable-label {
|
color: #606266;
|
font-size: 14px;
|
}
|
.save-bar {
|
margin-top: 12px;
|
}
|
</style>
|