- 迁移 0012:projects.owner_userid / tasks.task_chat_id / claims.owner_partner_id - lib/task-group-service.ts:懒建 appchat 任务群(首个内部群主领取时创建,成员 diff 补员),播报/卡片文案 - wecom-client 新增 appchat create/update/get/send 封装 - OAuth ticket 增可选 uid(v:1 兼容),内部成员领取按 wecom_userid 解析群主身份 - 外部 OAuth 领取人 upsert 打 partner_type='group_owner' - portal 链接带 ?owner= 穿透 OAuth 往返,claims 记录归属群主 - 后台任务卡「群主链接」面板:复制链接/推送内部群主/任务群状态 - 催办与超期升级同步播报进任务群
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { getRuntimeEnv } from "../../../lib/runtime-env";
|
||
import {
|
||
exchangeWecomOAuthCode,
|
||
fetchWecomExternalContactName,
|
||
resolveWecomConfig,
|
||
WecomClientError,
|
||
type WecomBindings,
|
||
} from "../../../lib/wecom-client";
|
||
import { signWecomIdentityTicket } from "../../../lib/wecom-oauth-service";
|
||
import { partnerOptions, withPartnerCors } from "../../../lib/partner-cors";
|
||
|
||
const env = getRuntimeEnv();
|
||
|
||
export function OPTIONS(request: Request) {
|
||
return partnerOptions(request);
|
||
}
|
||
|
||
async function handlePost(request: Request) {
|
||
try {
|
||
const body = (await request.json().catch(() => ({}))) as { code?: string };
|
||
const code = String(body.code ?? "").trim();
|
||
const config = resolveWecomConfig(env as unknown as WecomBindings);
|
||
if (!config.corpId || !config.agentId || !config.secret) {
|
||
return Response.json(
|
||
{ error: "未配置企业微信授权(WECOM_CORP_ID / WECOM_AGENT_ID / WECOM_SECRET)" },
|
||
{ status: 501 },
|
||
);
|
||
}
|
||
if (!code) {
|
||
return Response.json({ error: "缺少授权 code" }, { status: 400 });
|
||
}
|
||
const identity = await exchangeWecomOAuthCode(config, code);
|
||
if (identity.externalUserId) {
|
||
const displayName =
|
||
(await fetchWecomExternalContactName(config, identity.externalUserId)) ??
|
||
"企微客户";
|
||
const { ticket, expiresIn } = await signWecomIdentityTicket(
|
||
identity.externalUserId,
|
||
displayName,
|
||
);
|
||
return Response.json({
|
||
userType: "external",
|
||
identityTicket: ticket,
|
||
displayName,
|
||
expiresIn,
|
||
});
|
||
}
|
||
const userId = identity.userId ?? "";
|
||
if (!userId) {
|
||
return Response.json({ error: "企业微信未返回有效身份" }, { status: 400 });
|
||
}
|
||
const { ticket, expiresIn } = await signWecomIdentityTicket("", "", {
|
||
userId,
|
||
});
|
||
return Response.json({
|
||
userType: "internal",
|
||
userId,
|
||
identityTicket: ticket,
|
||
displayName: userId,
|
||
expiresIn,
|
||
});
|
||
} catch (error) {
|
||
const status = error instanceof WecomClientError ? error.status : 500;
|
||
return Response.json(
|
||
{ error: error instanceof Error ? error.message : "授权失败" },
|
||
{ status },
|
||
);
|
||
}
|
||
}
|
||
|
||
export async function POST(request: Request) {
|
||
const response = await handlePost(request);
|
||
response.headers.set("Cache-Control", "private, no-store");
|
||
return withPartnerCors(request, response);
|
||
}
|