技能提交
This commit is contained in:
1 parent
210cb5117f
commit
6851c96a45
38 files changed
+8043
-1903
No files matched your search
@@ -211,6 +211,13 @@ export function AgentModuleSidebar({
|
||||
<Link
|
||||
key={`${keyPrefix}:${agent.id}`}
|
||||
href={href}
|
||||
onClick={() => {
|
||||
try {
|
||||
sessionStorage.setItem(`agent-module:${moduleKey}:last-agent`, agent.id);
|
||||
} catch {
|
||||
// Ignore storage failures; route navigation is the source of truth.
|
||||
}
|
||||
}}
|
||||
className={cn(
|
||||
"group relative flex w-full items-start gap-2.5 rounded-xl border px-2.5 py-2 transition-colors",
|
||||
isActive
|
||||
|
||||
@@ -84,6 +84,7 @@ function writeCachedYUserInfo(yUserId: string, info: Record<string, unknown>): v
|
||||
function buildExternalUserInfo(
|
||||
yUserId: string,
|
||||
result: Record<string, unknown>,
|
||||
access_token: string | null | undefined,
|
||||
previous: Record<string, unknown>,
|
||||
cached: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
@@ -101,6 +102,12 @@ function buildExternalUserInfo(
|
||||
return next;
|
||||
}
|
||||
|
||||
const queryAccessToken = normalizeExternalAccessToken(access_token);
|
||||
if (queryAccessToken) {
|
||||
next.accessToken = queryAccessToken;
|
||||
return next;
|
||||
}
|
||||
|
||||
const previousYUserId = readStoredYUserId(previous);
|
||||
const previousAccessToken =
|
||||
previousYUserId === yUserId ? normalizeExternalAccessToken(previous.accessToken) : "";
|
||||
@@ -121,6 +128,7 @@ function buildExternalUserInfo(
|
||||
export async function loginByYUserId(
|
||||
yUserId: string,
|
||||
token?: string | null,
|
||||
access_token?: string | null,
|
||||
): Promise<void> {
|
||||
if (token) {
|
||||
authStorageSet(TOOLS_TOKEN_STORAGE_KEY, token);
|
||||
@@ -134,12 +142,11 @@ export async function loginByYUserId(
|
||||
// consumer 返回 { accessToken, gateDepartName, typeName, userName }。
|
||||
// 一并存入路由参数 yUserId,使「应用管理」里 source=yUserId 的路由参数能取到(与
|
||||
// source=userName/gateDepartName/typeName 直接取接口值统一走 userInfo[source])。
|
||||
// 注意:接口也会返回 accessToken,但 XK/PG 及 source=accessToken 要用路由透传的
|
||||
// access_token,故登录流程随后会用 persistAccessToken 覆盖 userInfo.accessToken。
|
||||
// 注意:接口返回的 accessToken 优先;登录 URL 的 access_token 只在接口值为空时兜底。
|
||||
const result = res.data ?? {};
|
||||
const previous = readExternalUserInfo();
|
||||
const cached = readCachedYUserInfo(yUserId);
|
||||
const next = buildExternalUserInfo(yUserId, result, previous, cached);
|
||||
const next = buildExternalUserInfo(yUserId, result, access_token, previous, cached);
|
||||
authStorageSet(EXTERNAL_USER_INFO_STORAGE_KEY, JSON.stringify(next));
|
||||
writeCachedYUserInfo(yUserId, next);
|
||||
}
|
||||
@@ -149,7 +156,7 @@ export function persistToolsToken(token: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* 把内网登录路由参数 access_token 合并写入 userInfo.accessToken(覆盖接口返回的同名值)。
|
||||
* 把内网登录路由参数 access_token 合并写入 userInfo.accessToken。
|
||||
* 据此拼参的有:XK/PG 中任务 iframe(XK 用 accessToken、PG 用 access_token,二者均读
|
||||
* external-links.getAccessToken() = userInfo.accessToken);以及「应用管理」里
|
||||
* source=accessToken 的轻应用路由参数(resolveRouteParamValue 取 userInfo.accessToken)。
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function LoginPage() {
|
||||
const yUserId = searchParams.get('yUserId')?.trim() ?? '';
|
||||
const toolToken = searchParams.get('token')?.trim() ?? '';
|
||||
// 内网登录透传的访问令牌:存入 userInfo.accessToken,供 XK/PG 中任务 iframe 拼参
|
||||
const accessToken = searchParams.get('access_token')?.trim() ?? '';
|
||||
const access_token = searchParams.get('access_token')?.trim() ?? '';
|
||||
// 用户名直登口令门:开启后端开关时,口令从 ?password= 透传
|
||||
const gatePassword = searchParams.get('password') ?? '';
|
||||
// token 换登录:?authToken= 传上游 token(与 tools_token 的 ?token= 区分开)
|
||||
@@ -182,7 +182,7 @@ export default function LoginPage() {
|
||||
if (onlineTicket) {
|
||||
deerflowUsername = await resolveUsernameByOnlineTicket(onlineTicket);
|
||||
} else if (yUserId) {
|
||||
await loginByYUserId(yUserId, toolToken || null);
|
||||
await loginByYUserId(yUserId, toolToken || null, access_token || null);
|
||||
} else if (toolToken) {
|
||||
persistToolsToken(toolToken);
|
||||
}
|
||||
@@ -212,9 +212,11 @@ export default function LoginPage() {
|
||||
}
|
||||
// 标准登录把用户名写入 userInfo,供顶栏用户区显示(已有则不覆盖)
|
||||
setStoredUserName(loginUserName);
|
||||
// 内网透传的 access_token 合并进 userInfo(在 loginByYUserId 覆盖之后),
|
||||
// XK/PG 中任务 iframe 据此取 accessToken
|
||||
persistAccessToken(accessToken);
|
||||
// 非 yUserId 登录仍可直接持久化 access_token;yUserId 登录已在 loginByYUserId 内按
|
||||
// “接口 accessToken 优先,URL access_token 仅兜底”的规则处理。
|
||||
if (!yUserId) {
|
||||
persistAccessToken(access_token);
|
||||
}
|
||||
// 嵌入模式不写 sidebarEnabled(localStorage 的「简洁/全量」偏好会跨标签污染正常页);
|
||||
// 去 chrome 由按标签页的嵌入会话(isEmbedActive)驱动,见 PageLayout。
|
||||
if (!isEmbed) persistSidebarEnabled(sidebarEnabled);
|
||||
@@ -273,7 +275,7 @@ export default function LoginPage() {
|
||||
sidebarEnabled,
|
||||
yUserId,
|
||||
toolToken,
|
||||
accessToken,
|
||||
access_token,
|
||||
onlineTicket,
|
||||
authToken,
|
||||
gatePassword,
|
||||
|
||||
@@ -8,21 +8,21 @@ import {
|
||||
|
||||
import { RouteBaseContext } from "@/core/route-base";
|
||||
|
||||
export function useRouter() {
|
||||
const navigate = useNavigate();
|
||||
const base = useContext(RouteBaseContext);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
push: (href: string) =>
|
||||
navigate(href.replace("/page/workspace", base)),
|
||||
replace: (href: string) =>
|
||||
navigate(href.replace("/page/workspace", base), { replace: true }),
|
||||
back: () => navigate(-1),
|
||||
forward: () => navigate(1),
|
||||
refresh: () => window.location.reload(),
|
||||
prefetch: async () => {},
|
||||
}),
|
||||
export function useRouter() {
|
||||
const navigate = useNavigate();
|
||||
const base = useContext(RouteBaseContext);
|
||||
const resolveHref = (href: string) =>
|
||||
href.startsWith(base) ? href : href.replace("/page/workspace", base);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
push: (href: string) => navigate(resolveHref(href)),
|
||||
replace: (href: string) => navigate(resolveHref(href), { replace: true }),
|
||||
back: () => navigate(-1),
|
||||
forward: () => navigate(1),
|
||||
refresh: () => window.location.reload(),
|
||||
prefetch: async () => {},
|
||||
}),
|
||||
[navigate, base],
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user