feat: R27-2 R27-5 优化企微入口与 Portal 体验

这个提交包含在:
2026-03-22 19:52:54 +08:00
父节点 eaef213d22
当前提交 312200ec1b
共修改 16 个文件,包含 1213 行新增和 315 行删除
+22
查看文件
@@ -0,0 +1,22 @@
const WECOM_WEBVIEW_PATTERN = /(wxwork|wecom|wechatwork)/i;
const ENTERPRISE_IM_PATTERN = /(wxwork|wecom|wechatwork|dingtalk|aliapp\(dingtalk\))/i;
export function canUseWindow() {
return typeof window !== "undefined";
}
export function matchesMedia(query: string) {
return canUseWindow() && typeof window.matchMedia === "function" && window.matchMedia(query).matches;
}
export function readUserAgent() {
return canUseWindow() ? window.navigator.userAgent : "";
}
export function isWecomWebView(userAgent = readUserAgent()) {
return WECOM_WEBVIEW_PATTERN.test(userAgent);
}
export function isEnterpriseMessengerContainer(userAgent = readUserAgent()) {
return ENTERPRISE_IM_PATTERN.test(userAgent);
}
+148
查看文件
@@ -0,0 +1,148 @@
import type { WecomEntryConfig } from "../api/auth";
export type WecomNoticeTone = "info" | "warning" | "success";
export type WecomNotice = {
tone: WecomNoticeTone;
title: string;
description: string;
};
const STATUS_REASON_LABELS: Record<string, string> = {
wecom_disabled: "管理员尚未启用企业微信接入",
entry_disabled: "企业微信工作台入口尚未正式开放",
oauth_disabled: "企业微信 OAuth 尚未启用",
corp_id_missing: "未配置 CorpID",
agent_id_missing: "未配置 AgentID",
redirect_uri_missing: "未配置 OAuth 回调地址",
};
export function resolveWecomStatusReasonLabels(statusReasons: string[]) {
return statusReasons.map((reason) => STATUS_REASON_LABELS[reason] ?? reason);
}
export function resolveWecomEntryStatus(config?: WecomEntryConfig | null) {
if (!config) {
return {
label: "检测中",
tone: "info" as const,
description: "正在读取企业微信接入状态。",
reasonLabels: [],
};
}
if (config.status === "ready") {
return {
label: "已启用",
tone: "success" as const,
description: "员工可从企业微信工作台直接进入 OA,也可在个人设置里维护绑定。",
reasonLabels: [],
};
}
const reasonLabels = resolveWecomStatusReasonLabels(config.statusReasons);
if (config.bindEnabled && !config.entryEnabled) {
return {
label: "入口未开放",
tone: "warning" as const,
description: "当前可先完成绑定,企业微信工作台直达入口尚未正式开放。",
reasonLabels,
};
}
if (config.status === "misconfigured") {
return {
label: "配置不完整",
tone: "warning" as const,
description: "请管理员补齐 CorpID、AgentID 与回调地址后再开放企业微信入口。",
reasonLabels,
};
}
return {
label: "未启用",
tone: "info" as const,
description: "当前未启用企业微信入口,仍可使用账号密码登录。",
reasonLabels,
};
}
export function resolveWecomLoginNotice(value: string | null): WecomNotice | null {
if (value === "unbound") {
return {
tone: "warning",
title: "当前企业微信账号尚未绑定",
description: "请先用账号密码登录,再到个人设置完成绑定。",
};
}
if (value === "invalid") {
return {
tone: "warning",
title: "企业微信登录状态已失效",
description: "请重新从企业微信工作台进入,或改用账号密码登录。",
};
}
if (value === "expired") {
return {
tone: "warning",
title: "企业微信登录已超时",
description: "请重新从企业微信工作台进入 OA。",
};
}
return null;
}
export function resolveWecomBindNotice(value: string | null): WecomNotice | null {
if (value === "success") {
return {
tone: "success",
title: "企业微信绑定成功",
description: "下次可直接从企业微信工作台进入 OA。",
};
}
if (value === "conflict") {
return {
tone: "warning",
title: "该企业微信账号已绑定其他员工",
description: "请联系管理员核对后再处理。",
};
}
if (value === "employee_inactive") {
return {
tone: "warning",
title: "当前账号已停用",
description: "停用账号无法绑定企业微信,请联系管理员。",
};
}
if (value === "invalid") {
return {
tone: "warning",
title: "本次绑定状态无效",
description: "请回到个人设置后重新发起绑定。",
};
}
if (value === "expired") {
return {
tone: "warning",
title: "本次绑定已超时",
description: "请回到个人设置后重新发起绑定。",
};
}
return null;
}
export function buildWecomLoginUrl(loginUrl: string, returnTo: string) {
const baseOrigin = typeof window !== "undefined" ? window.location.origin : "http://127.0.0.1";
const url = new URL(loginUrl, baseOrigin);
url.searchParams.set("returnTo", returnTo);
return url.origin === baseOrigin ? `${url.pathname}${url.search}` : url.toString();
}