fix(walkthrough): menuRoute 识别 /sch/{code} 壳路径免回退告警;栏目弹窗按钮 type=link 改 text;mock 补 cherry-bloom/violet-iris 主题
build / build (push) Successful in 2m20s

This commit is contained in:
chenxing
2026-09-19 17:47:51 +08:00
parent f29c193ea7
commit be19ed066a
5 changed files with 90 additions and 4 deletions
+2 -2
View File
@@ -231,7 +231,7 @@ export function seedDb(): MockDb {
schId: 1001, schId: 1001,
schName: "云海大学", schName: "云海大学",
name: "机电学院", name: "机电学院",
theme: "default", theme: "cherry-bloom",
configJson: JSON.stringify({ configJson: JSON.stringify({
public_base_url: "http://www.yunhai-demo.edu.cn/college/jdx", public_base_url: "http://www.yunhai-demo.edu.cn/college/jdx",
copyright: "机电学院 · Mock 数据", copyright: "机电学院 · Mock 数据",
@@ -247,7 +247,7 @@ export function seedDb(): MockDb {
schId: 1001, schId: 1001,
schName: "云海大学", schName: "云海大学",
name: "信息工程学院", name: "信息工程学院",
theme: "default", theme: "violet-iris",
configJson: JSON.stringify({ configJson: JSON.stringify({
public_base_url: "http://www.yunhai-demo.edu.cn/college/xxgc", public_base_url: "http://www.yunhai-demo.edu.cn/college/xxgc",
copyright: "信息工程学院 · Mock 数据", copyright: "信息工程学院 · Mock 数据",
+28
View File
@@ -103,6 +103,34 @@ const THEMES: MockTheme[] = [
{ key: "bg", cssVar: "--bg", label: "页面底色", type: "color", defaultValue: "#fff8f0" }, { key: "bg", cssVar: "--bg", label: "页面底色", type: "color", defaultValue: "#fff8f0" },
], ],
}, },
{
name: "cherry-bloom",
title: "樱语粉韵",
description: "温柔樱粉风门户:樱花粉品牌色 + 大圆角 16px 卡片网格列表,适合幼儿园与小学。",
version: "1.0.0",
author: "yunhai",
bannerSize: "1920x560",
screenshotUrl: "/api/theme/cherry-bloom/asset/screenshot.png",
params: [
{ key: "primary", cssVar: "--primary", label: "主色", type: "color", defaultValue: "#DB5A8B" },
{ key: "primaryDark", cssVar: "--primary-dark", label: "主色加深", type: "color", defaultValue: "#B23A68" },
{ key: "bg", cssVar: "--bg", label: "页面底色", type: "color", defaultValue: "#FFFAFB" },
],
},
{
name: "violet-iris",
title: "鸢尾紫韵",
description: "雅致鸢尾紫门户:沉静书卷气 + 圆角 12px 卡片网格列表,适合高校与教科研机构。",
version: "1.0.0",
author: "yunhai",
bannerSize: "1920x560",
screenshotUrl: "/api/theme/violet-iris/asset/screenshot.png",
params: [
{ key: "primary", cssVar: "--primary", label: "主色", type: "color", defaultValue: "#6552D9" },
{ key: "primaryDark", cssVar: "--primary-dark", label: "主色加深", type: "color", defaultValue: "#4A39B0" },
{ key: "bg", cssVar: "--bg", label: "页面底色", type: "color", defaultValue: "#F8F7FD" },
],
},
]; ];
function themeByName(name: string): MockTheme | undefined { function themeByName(name: string): MockTheme | undefined {
+54
View File
@@ -0,0 +1,54 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@/store", () => ({
useCmsStore: () => ({ schoolCode: "demo" }),
}));
import { resolveMenuPage } from "./menuRoute";
describe("resolveMenuPage 学校壳具体路径匹配", () => {
let warn: ReturnType<typeof vi.spyOn>;
beforeEach(() => {
warn = vi.spyOn(console, "warn").mockImplementation(() => {});
});
it("/sch/{code}/article 直接命中,不回退名称识别、不告警", () => {
expect(resolveMenuPage("/sch/demo/article", null, "文章列表")).toEqual({
path: "/sch/demo/article",
external: false,
});
expect(warn).not.toHaveBeenCalled();
});
it("他校编码的壳路径重映射到当前学校上下文", () => {
expect(resolveMenuPage("/sch/fsz/category", null, "栏目管理")).toEqual({
path: "/sch/demo/category",
external: false,
});
expect(warn).not.toHaveBeenCalled();
});
it("裸子路径 /article 仍命中学校壳路由", () => {
expect(resolveMenuPage("/article", null, "文章列表")).toEqual({
path: "/sch/demo/article",
external: false,
});
expect(warn).not.toHaveBeenCalled();
});
it("顶层绝对路由不受影响(/workbench)", () => {
expect(resolveMenuPage("/workbench", null, "工作台")).toEqual({
path: "/workbench",
external: false,
});
expect(warn).not.toHaveBeenCalled();
});
it("配错路径仍走名称回退(行为保持)", () => {
expect(resolveMenuPage("/no-such-page", null, "友情链接")).toEqual({
path: "/sch/demo/link",
external: false,
});
expect(warn).toHaveBeenCalledTimes(1);
});
});
+5 -1
View File
@@ -119,7 +119,11 @@ function matchRoute(candidate: string): string | null {
// 2. 学校壳内子路径匹配(/article → /sch/{code}/article),兼容新旧上下文前缀(历史 /cms、现网 /yschcms) // 2. 学校壳内子路径匹配(/article → /sch/{code}/article),兼容新旧上下文前缀(历史 /cms、现网 /yschcms)
const stripped = lower.startsWith("/cms/") ? lower.slice("/cms".length) const stripped = lower.startsWith("/cms/") ? lower.slice("/cms".length)
: lower.startsWith("/yschcms/") ? lower.slice("/yschcms".length) : lower; : lower.startsWith("/yschcms/") ? lower.slice("/yschcms".length) : lower;
const entry = ROUTE_ENTRIES.find(e => !e.absolute && e.sub.toLowerCase() === stripped); // 平台侧已配成具体壳路径(/sch/{任意编码}/article):剥壳后按子路径命中,
// 运行时经 toConcrete 重映射到当前学校上下文(他校编码不直接透传)
const deshelled = /^\/sch\/[^/]+(?=\/)/.test(stripped) ? stripped.replace(/^\/sch\/[^/]+/, "") : stripped;
const entry = ROUTE_ENTRIES.find(e => !e.absolute &&
(e.sub.toLowerCase() === stripped || e.sub.toLowerCase() === deshelled));
if (entry) { if (entry) {
return toConcrete(entry); return toConcrete(entry);
} }
+1 -1
View File
@@ -563,7 +563,7 @@ function openLink(url: string) {
</FormItem> </FormItem>
</Form> </Form>
<template #footer> <template #footer>
<Button v-if="!form.id" type="link" @click="switchToBatch">切换至批量添加</Button> <Button v-if="!form.id" type="text" @click="switchToBatch">切换至批量添加</Button>
<Button @click="modalVisible = false">取消</Button> <Button @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="saving" @click="save">保存</Button> <Button type="primary" :loading="saving" @click="save">保存</Button>
</template> </template>