From 3990811ed515737888e17cb352be1a2ceee6fd94 Mon Sep 17 00:00:00 2001 From: chenxing Date: Mon, 7 Sep 2026 19:21:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(B1):=20=E6=A0=A1=E7=BA=A7=E5=BB=BA?= =?UTF-8?q?=E7=AB=99=E5=85=A5=E5=8F=A3-=E6=96=B0=E5=BB=BA=E9=99=A2?= =?UTF-8?q?=E7=B3=BB=E5=AD=90=E7=AB=99(=E5=90=91=E5=AF=BC=E9=94=81?= =?UTF-8?q?=E5=AE=9A=E6=9C=AC=E6=A0=A1=E4=B8=BB=E7=AB=99)+=E5=AD=A6?= =?UTF-8?q?=E6=A0=A1=E4=BF=A1=E6=81=AF=E6=9C=8D=E5=8A=A1=E7=AB=AF=E7=BB=A7?= =?UTF-8?q?=E6=89=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SiteManage: 新建按钮校级显示"新建院系子站";编辑弹窗校级隐藏schId/schName(payload留空服务端继承) - SiteWizard: lockParentId 锁定上级为本校主站禁改 - SchoolWorkbench: 副文案改自助创建口径 - vitest 24/24 绿 + build 成功 --- src/views/cms/SchoolWorkbench.vue | 2 +- src/views/cms/SiteManage.vue | 25 +++++++++++++++---------- src/views/cms/SiteWizard.vue | 25 +++++++++++++++++-------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/views/cms/SchoolWorkbench.vue b/src/views/cms/SchoolWorkbench.vue index 3a2e098..d783d8d 100644 --- a/src/views/cms/SchoolWorkbench.vue +++ b/src/views/cms/SchoolWorkbench.vue @@ -198,7 +198,7 @@ onMounted(run);

我的学校

-

选择学校进入内容管理;学校与站点由平台管理员在「添加学校」中绑定创建。

+

选择学校进入内容管理;学校由平台管理员接入,院系子站可在「站点管理」自助创建。

diff --git a/src/views/cms/SiteManage.vue b/src/views/cms/SiteManage.vue index 6faefaa..c289777 100644 --- a/src/views/cms/SiteManage.vue +++ b/src/views/cms/SiteManage.vue @@ -32,6 +32,10 @@ const router = useRouter(); /** 超管全局视图(工作台入口带入 scope=all) */ const scopeAll = computed(() => route.query.scope === "all" && store.isSuperAdmin); +/** B1 建站权限拆分:校级(学校上下文内)可自助创建院系子站;超管向导行为不变 */ +const isSchoolAdmin = computed(() => !store.isSuperAdmin && !!store.currentSchool); +const canCreateSite = computed(() => store.isSuperAdmin || isSchoolAdmin.value); + const rows = ref([]); const loading = ref(false); const tableHeight = Utils.useTableHeight({ isOperat: true }); @@ -214,8 +218,9 @@ async function save() { id: form.id, code: form.code, parentSiteId: form.parentSiteId || 0, - schId: form.schId, - schName: form.schName || undefined, + // B1:校级角色隐藏学校信息字段,留空由服务端继承主站(防伪造通道) + schId: isSchoolAdmin.value ? undefined : form.schId, + schName: isSchoolAdmin.value ? undefined : form.schName || undefined, name: form.name, theme: form.theme || undefined, configJson: t ? mergeThemeParamsIntoConfigJson(form.configJson || "", t, themeParams) : form.configJson || undefined, @@ -285,10 +290,10 @@ watch(() => store.currentSchool?.schId, () => run()); 返回学校工作台
-
+
@@ -303,15 +308,15 @@ watch(() => store.currentSchool?.schId, () => run()); - -

院系子站挂在主站下,门户 header 右上出现"专业院系"下拉;层级固定两层。

+

院系子站挂在主站下,门户 header 右上出现"专业院系"下拉;层级固定两层。{{ isSchoolAdmin ? "校级角色仅可在本校主站之间改挂。" : "" }}

- + - + @@ -340,8 +345,8 @@ watch(() => store.currentSchool?.schId, () => run()); - - + + diff --git a/src/views/cms/SiteWizard.vue b/src/views/cms/SiteWizard.vue index a13087a..5d247b0 100644 --- a/src/views/cms/SiteWizard.vue +++ b/src/views/cms/SiteWizard.vue @@ -17,6 +17,8 @@ import SiteConfigForm from "@/views/cms/components/SiteConfigForm.vue"; const props = defineProps<{ visible: boolean; sites: SiteVo[]; + /** B1 建站权限拆分:校级锁定在本校主站下建院系子站(上级禁改、学校信息由服务端继承) */ + lockParentId?: number; }>(); const emit = defineEmits<{ @@ -51,7 +53,12 @@ const canPreview = computed(() => !!sourceSiteCode.value && !!themeName.value); const previewTick = ref(0); const previewParams = ref({}); -const parentOptions = computed(() => props.sites.filter(s => !s.parentSiteId)); +/** 锁定模式:上级仅本校主站;否则全部顶层站可选 */ +const parentOptions = computed(() => + props.lockParentId + ? props.sites.filter(s => s.id === props.lockParentId && !s.parentSiteId) + : props.sites.filter(s => !s.parentSiteId) +); function debouncePreview() { previewParams.value = { ...themeParams.value }; @@ -71,7 +78,7 @@ watch( async v => { if (!v) return; step.value = 1; - Object.assign(form, { code: "", parentSiteId: undefined, schId: undefined, schName: "", name: "", status: 1, configJson: "" }); + Object.assign(form, { code: "", parentSiteId: props.lockParentId, schId: undefined, schName: "", name: "", status: 1, configJson: "" }); sourceSiteCode.value = sourceSites.value[0]?.code || ""; if (!themes.value.length) await loadThemes(); themeName.value = "default"; @@ -128,8 +135,9 @@ async function createSite() { .save({ code: form.code, parentSiteId: form.parentSiteId || 0, - schId: form.schId, - schName: form.schName || undefined, + // B1:校级锁定模式学校信息留空,服务端校验后继承主站(防伪造) + schId: props.lockParentId ? undefined : form.schId, + schName: props.lockParentId ? undefined : form.schName || undefined, name: form.name, theme: themeName.value, configJson, @@ -148,7 +156,7 @@ async function createSite() {