chore: 前置快照-assetUrl前缀与学校切换收敛会话遗留(执行方案B1~B5前既有未提交变更)
This commit is contained in:
@@ -88,7 +88,8 @@ const form = ref({
|
||||
});
|
||||
|
||||
const rules = {
|
||||
schId: [{ required: true, message: "请选择学校(来自用户中心)", trigger: "change" }],
|
||||
// 必须声明 type:"number":schId 是 UserBase 组 ID(数字),缺省按 string 校验会把已选中的数字 ID 判为不通过
|
||||
schId: [{ required: true, type: "number", message: "请选择学校(来自用户中心)", trigger: "change" }],
|
||||
code: [
|
||||
{ required: true, message: "主站编码不得为空", trigger: "blur" },
|
||||
{ pattern: /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/, message: "仅限小写字母/数字/短横线", trigger: "blur" },
|
||||
@@ -125,11 +126,10 @@ async function loadThemes() {
|
||||
|
||||
function onSchoolPick(id: number) {
|
||||
const opt = options.value.find(o => o.id === id);
|
||||
// 校名/编码/名称始终跟随当前选中学校带出,避免切换学校后残留上一所的默认值造成“已选好”的假象
|
||||
form.value.schName = opt?.name || "";
|
||||
if (!form.value.name && opt) {
|
||||
if (opt) {
|
||||
form.value.name = `${opt.name}门户网站`;
|
||||
}
|
||||
if (!form.value.code && opt) {
|
||||
form.value.code = `sch-${opt.id}`;
|
||||
}
|
||||
}
|
||||
@@ -171,27 +171,30 @@ onMounted(run);
|
||||
|
||||
<template>
|
||||
<div class="workbench">
|
||||
<header class="wb-header fix">
|
||||
<h4 class="fl align-middle">云海CMS · 学校工作台</h4>
|
||||
<div class="wb-header-aside fr">
|
||||
<Button v-if="isSuper" size="small" class="wb-btn" @click="goAllSites" :disabled="!cards.length">
|
||||
<Icon type="ios-globe" />
|
||||
全部站点总览
|
||||
</Button>
|
||||
<Button v-if="isSuper" size="small" type="primary" class="wb-btn" @click="openAdd">
|
||||
<Icon type="ios-add" />
|
||||
添加学校
|
||||
</Button>
|
||||
<span class="delimiter align-middle"></span>
|
||||
<img :src="userInfo.avatar" v-if="userInfo.avatar" class="fl align-middle wb-avatar" @click="linkUserInfo" />
|
||||
<a class="name fl align-middle" href="javascript:void(0);" @click="linkUserInfo">{{ userInfo.name }}</a>
|
||||
<span class="delimiter align-middle"></span>
|
||||
<a href="javascript:;" @click="logout" title="退出登陆">
|
||||
<header class="wb-header">
|
||||
<h4>云海CMS · 学校工作台</h4>
|
||||
<div class="wb-header-aside">
|
||||
<img :src="userInfo.avatar" v-if="userInfo.avatar" class="wb-avatar" @click="linkUserInfo" />
|
||||
<a class="name" href="javascript:void(0);" @click="linkUserInfo">{{ userInfo.name }}</a>
|
||||
<span class="delimiter"></span>
|
||||
<a href="javascript:;" class="logout" @click="logout" title="退出登陆">
|
||||
<i class="iconfont icon-logout"></i>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 操作工具行(Notice search-wrap 同款灰底条):按钮居左,账号区保持在深色 header 右侧 -->
|
||||
<div class="wb-toolbar" v-if="isSuper">
|
||||
<Button class="wb-btn" @click="goAllSites" :disabled="!cards.length">
|
||||
<Icon type="ios-globe" />
|
||||
全部站点总览
|
||||
</Button>
|
||||
<Button type="primary" class="wb-btn" @click="openAdd">
|
||||
<Icon type="ios-add" />
|
||||
添加学校
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="wb-body">
|
||||
<div class="wb-title">
|
||||
<h3>我的学校</h3>
|
||||
@@ -225,7 +228,7 @@ onMounted(run);
|
||||
</div>
|
||||
<div v-else class="empty-state">
|
||||
<Icon type="ios-school" :size="48" />
|
||||
<p v-if="isSuper">还没有学校 —— 点击右上角「添加学校」绑定用户中心学校并创建门户主站。</p>
|
||||
<p v-if="isSuper">还没有学校 —— 点击上方「添加学校」绑定用户中心学校并创建门户主站。</p>
|
||||
<p v-else>暂无可管理的学校站点,请联系平台管理员。</p>
|
||||
<Button v-if="isSuper" type="primary" @click="openAdd">
|
||||
<Icon type="ios-add" />
|
||||
@@ -279,6 +282,7 @@ onMounted(run);
|
||||
}
|
||||
.wb-header {
|
||||
height: 56px;
|
||||
flex-shrink: 0;
|
||||
background: #1f2a3a;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
@@ -288,9 +292,9 @@ onMounted(run);
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
line-height: 56px;
|
||||
}
|
||||
.wb-header-aside {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
@@ -307,12 +311,24 @@ onMounted(run);
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wb-btn {
|
||||
// 深色 header 上按钮保持默认浅色块
|
||||
.logout {
|
||||
color: #fff;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 工具行:Notice front .search-wrap 同款(#f7f7f7 底 + 10px 16px 内边距 ≈ 52px 高),按钮居左 */
|
||||
.wb-toolbar {
|
||||
flex-shrink: 0;
|
||||
background: #f7f7f7;
|
||||
padding: 10px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.wb-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { Message } from "view-ui-plus";
|
||||
import Utils from "@/utils/index";
|
||||
import { siteApi, themeApi, themePreviewUrl } from "@/api/module/cms";
|
||||
import { assetUrl, siteApi, themeApi, themePreviewUrl } from "@/api/module/cms";
|
||||
import { useCmsStore } from "@/store";
|
||||
import config from "@/assets/config/host.config";
|
||||
import { SiteVo, ThemeVo } from "@/types/cms";
|
||||
@@ -18,6 +18,8 @@ import SiteWizard from "@/views/cms/SiteWizard.vue";
|
||||
* 站点管理(方案 §9.1 + §6.2 主题选择增强)。
|
||||
* 学校化管理(docs/09 §3.3):默认只显示当前学校站点(主站+院系子站);
|
||||
* 超管可经工作台「全部站点总览」(?scope=all)查看全局列表。
|
||||
* 行「进入管理」= 院系子站切换入口(壳面包屑条切换器已按 UX 收敛移除):
|
||||
* 切 store.currentSite 落文章列表,跨校行先重建学校上下文;当前站点行带「当前」标记。
|
||||
* 新建 → 三步向导(选模板→微调预览→确认);已建站点 → 编辑弹窗内
|
||||
* 主题卡片单选 + 参数微调表单,保存带 themeParams(服务端合并进 config_json,方案 §5.3)。
|
||||
* config_json 结构化编辑见 SiteConfigForm(docs/09 §3.1):
|
||||
@@ -25,6 +27,7 @@ import SiteWizard from "@/views/cms/SiteWizard.vue";
|
||||
*/
|
||||
const store = useCmsStore();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
/** 超管全局视图(工作台入口带入 scope=all) */
|
||||
const scopeAll = computed(() => route.query.scope === "all" && store.isSuperAdmin);
|
||||
@@ -43,7 +46,18 @@ const themeMeta = computed(() => {
|
||||
|
||||
const columns = [
|
||||
{ title: "站点编码", key: "code", width: 140 },
|
||||
{ title: "站点名称", key: "name", minWidth: 200, tooltip: true },
|
||||
{
|
||||
title: "站点名称",
|
||||
key: "name",
|
||||
minWidth: 200,
|
||||
tooltip: true,
|
||||
render: (h: any, p: any) =>
|
||||
h("span", { style: "display:inline-flex;align-items:center;gap:6px" }, [
|
||||
h("span", p.row.name),
|
||||
// 当前操作站点标记:壳面包屑校名后缀同源(store.currentSite)
|
||||
p.row.id === store.siteId ? h(Tag, { color: "success" }, () => "当前") : null,
|
||||
]),
|
||||
},
|
||||
{ title: "学校", key: "schName", width: 150, tooltip: true },
|
||||
{
|
||||
title: "所属主站",
|
||||
@@ -60,7 +74,7 @@ const columns = [
|
||||
const t = themeMeta.value[p.row.theme || "default"];
|
||||
return h("span", { style: "display:inline-flex;align-items:center;gap:6px" }, [
|
||||
t
|
||||
? h("img", { src: t.screenshotUrl, style: "width:44px;height:28px;object-fit:cover;border-radius:3px;border:1px solid #eee", alt: "" })
|
||||
? h("img", { src: assetUrl(t.screenshotUrl), style: "width:44px;height:28px;object-fit:cover;border-radius:3px;border:1px solid #eee", alt: "" })
|
||||
: h("span", { style: "display:inline-block;width:44px;height:28px;background:#f0f2f5;border-radius:3px" }),
|
||||
h("span", t ? `${t.title}(${p.row.theme})` : p.row.theme || "default"),
|
||||
]);
|
||||
@@ -84,6 +98,7 @@ const columns = [
|
||||
fixed: "right",
|
||||
align: "center",
|
||||
render: (h: any, p: any) => [
|
||||
Utils.operatingHandle(h, "进入管理", "icon-apps", () => enterManage(p.row), p.row.id === store.siteId),
|
||||
Utils.operatingHandle(h, "编辑", "icon-edit", () => openEdit(p.row)),
|
||||
Utils.operatingHandle(h, "门户", "icon-browse", () => openPortal(p.row)),
|
||||
],
|
||||
@@ -219,6 +234,30 @@ function openPortal(row: SiteVo) {
|
||||
window.open(`${config.serviceHost}/portal/${row.code}/`, "_blank");
|
||||
}
|
||||
|
||||
/** 行级「进入管理」(docs/09 §3.3 子站管理入口):切当前操作站点后落文章列表;
|
||||
* 全局视图跨校行先重建学校上下文(面包屑/左侧菜单跟随),子站行向上找主站行定学校壳 */
|
||||
function enterManage(row: SiteVo) {
|
||||
const main = row.parentSiteId ? rows.value.find(s => s.id === row.parentSiteId) : row;
|
||||
if (!main) {
|
||||
Message.warning("未找到所属主站,无法进入管理");
|
||||
return;
|
||||
}
|
||||
if (main.code !== store.schoolCode) {
|
||||
store.enterSchool(
|
||||
{
|
||||
schId: row.schId,
|
||||
schName: row.schName,
|
||||
mainSiteId: main.id,
|
||||
mainSiteCode: main.code,
|
||||
mainSiteName: main.name,
|
||||
},
|
||||
rows.value.filter(s => s.id === main.id || s.parentSiteId === main.id)
|
||||
);
|
||||
}
|
||||
store.setCurrentSite({ id: row.id, code: row.code, name: row.name });
|
||||
router.push(`/sch/${main.code}/article`);
|
||||
}
|
||||
|
||||
function openEditPreview() {
|
||||
previewVisible.value = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user