feat: Hair Keeper v1.1.0 版本更新
本次更新包含以下主要改进: ## 新功能 - 添加quickstart.sh脚本帮助用户快速使用模板项目 - 添加simple_deploy.sh便于部署 - 新增院系管理功能(DeptAdmin),支持增删改查院系管理员信息 - 用户可以在header中切换管理的院系 - 添加zustand全局状态管理 - 添加DEFAULT_USER_PASSWORD环境变量,作为创建用户时的默认密码 - 添加p-limit库和DB_PARALLEL_LIMIT环境变量控制数据库批次操作并发数 ## 安全修复 - 修复Next.js CVE-2025-66478漏洞 - 限制只有超级管理员才能创建超级管理员用户 ## 开发环境优化 - 开发终端兼容云端环境 - MinIO客户端直传兼容云端环境 - 开发容器增加vim和Claude Code插件 - 编程代理改用Claude - docker-compose.yml添加全局name属性 ## Bug修复与代码优化 - 删除用户时级联删除SelectionLog - 手机端关闭侧边栏后刷新页面延迟调整(300ms=>350ms) - instrumentation.ts移至src内部以适配生产环境 - 删除部分引发类型错误的无用代码 - 优化quickstart.sh远程仓库推送相关配置 ## 文件变更 - 新增49个文件,修改多个配置和源代码文件 - 重构用户管理模块目录结构 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,33 @@ export const minioClient = new Client({
|
||||
|
||||
export const BUCKET_NAME = process.env.MINIO_BUCKET || 'app-files';
|
||||
|
||||
/**
|
||||
* 获取客户端访问的基础 URL
|
||||
* 优先使用 MINIO_SERVER_URL(公网地址),否则使用内部地址
|
||||
*/
|
||||
function getClientBaseUrl(): string {
|
||||
if (process.env.MINIO_SERVER_URL) {
|
||||
return process.env.MINIO_SERVER_URL;
|
||||
}
|
||||
const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http';
|
||||
const endpoint = process.env.MINIO_ENDPOINT || 'localhost';
|
||||
const port = process.env.MINIO_API_PORT || '9000';
|
||||
return `${protocol}://${endpoint}:${port}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换预签名 URL 中的内部地址为客户端可访问的地址
|
||||
*/
|
||||
function replaceUrlBase(originalUrl: string): string {
|
||||
const clientBase = getClientBaseUrl();
|
||||
const url = new URL(originalUrl);
|
||||
const clientUrl = new URL(clientBase);
|
||||
url.protocol = clientUrl.protocol;
|
||||
url.hostname = clientUrl.hostname;
|
||||
url.port = clientUrl.port; // 空字符串表示使用协议默认端口
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
// 桶初始化标志
|
||||
let bucketInitialized = false;
|
||||
|
||||
@@ -150,7 +177,7 @@ export async function generatePresignedPostPolicy(
|
||||
const presignedData = await minioClient.presignedPostPolicy(policy);
|
||||
|
||||
return {
|
||||
postURL: presignedData.postURL,
|
||||
postURL: replaceUrlBase(presignedData.postURL),
|
||||
formData: presignedData.formData,
|
||||
objectName,
|
||||
};
|
||||
@@ -237,7 +264,7 @@ export async function generatePresignedGetObject(
|
||||
);
|
||||
|
||||
return {
|
||||
url,
|
||||
url: replaceUrlBase(url),
|
||||
expiresIn: expirySeconds,
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -343,9 +370,5 @@ export async function getObjectMetadata(objectName: string) {
|
||||
* @returns 公开访问 URL
|
||||
*/
|
||||
export function getPublicUrl(objectName: string): string {
|
||||
const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http';
|
||||
const endpoint = process.env.MINIO_ENDPOINT || 'localhost';
|
||||
const port = process.env.MINIO_API_PORT || '9000';
|
||||
|
||||
return `${protocol}://${endpoint}:${port}/${BUCKET_NAME}/${objectName}`;
|
||||
return `${getClientBaseUrl()}/${BUCKET_NAME}/${objectName}`;
|
||||
}
|
||||
Reference in New Issue
Block a user