Files
SuperJump/src/lib/oss.ts
T
jacobxu666andClaude Opus 4.8 af7a144d58 第一期:家庭自学打卡系统
- 家长手机号登录 + 孩子设备一次性激活(长期会话)
- 周模板自动生成每日任务快照,支持拍照凭证直传对象存储
- 连击计算(空白日自动达成)、家长补卡带标记
- 家长端三标签:今日概览 / 任务模板 / 设备管理
- Docker 独立输出,经 Traefik 接入 jump.hn12301.net

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 23:19:13 +08:00

39 lines
1.5 KiB
TypeScript

// 对象存储签名工具:浏览器直传用查询串签名(浏览器无法设置 Date 请求头)
import crypto from "node:crypto";
const REGION = process.env.OSS_REGION ?? "oss-cn-hangzhou";
const BUCKET = process.env.OSS_BUCKET ?? "";
const ID = process.env.OSS_ACCESS_KEY_ID ?? "";
const SECRET = process.env.OSS_ACCESS_KEY_SECRET ?? "";
const HOST = `${BUCKET}.${REGION}.aliyuncs.com`;
// 生成带签名的临时访问地址
function signUrl(method: string, key: string, seconds: number, contentType = "") {
const expires = Math.floor(Date.now() / 1000) + seconds;
const resource = `/${BUCKET}/${key}`;
const str = `${method}\n\n${contentType}\n${expires}\n${resource}`;
const signature = crypto.createHmac("sha1", SECRET).update(str).digest("base64");
const qs = new URLSearchParams({
OSSAccessKeyId: ID,
Expires: String(expires),
Signature: signature,
});
return `https://${HOST}/${encodeURIComponent(key)}?${qs}`;
}
// 直传地址:浏览器收到后直接 fetch PUT,有效期 10 分钟
export function uploadUrl(key: string, contentType: string) {
return signUrl("PUT", key, 600, contentType);
}
// 展示地址:签名 GET,有效期 5 分钟,用完由页面刷新重新签发
export function viewUrl(key: string) {
return signUrl("GET", key, 300);
}
// 照片键名:photos/孩子ID/日期/随机16进制.jpg
export function photoKey(childId: number, date: string) {
return `photos/${childId}/${date}/${crypto.randomBytes(8).toString("hex")}.jpg`;
}