fix(upload): 上传与用户设置目录改为持久化目录并保留旧目录回退
- 上传目录默认 process.cwd()/public/uploads,支持 UPLOAD_DIR 覆盖,避免代码部署覆盖用户上传文件 - 用户设置目录默认 process.cwd()/data,支持 DATA_DIR 覆盖,旧 data/user_settings.json 自动回退读取
这个提交包含在:
@@ -161,12 +161,20 @@ app.use(
|
||||
})
|
||||
);
|
||||
|
||||
// 静态文件与对象存储目录配置
|
||||
const uploadDir = path.resolve(__dirname, '../public/uploads');
|
||||
// 静态文件与对象存储目录配置(优先持久化目录 process.cwd()/public/uploads,避免代码构建部署覆盖用户上传文件)
|
||||
const persistentUploadDir = process.env.UPLOAD_DIR
|
||||
? path.resolve(process.env.UPLOAD_DIR)
|
||||
: path.resolve(process.cwd(), 'public/uploads');
|
||||
const fallbackUploadDir = path.resolve(__dirname, '../public/uploads');
|
||||
|
||||
const uploadDir = persistentUploadDir;
|
||||
if (!fs.existsSync(uploadDir)) {
|
||||
fs.mkdirSync(uploadDir, { recursive: true });
|
||||
}
|
||||
app.use('/uploads', express.static(uploadDir));
|
||||
if (uploadDir !== fallbackUploadDir && fs.existsSync(fallbackUploadDir)) {
|
||||
app.use('/uploads', express.static(fallbackUploadDir));
|
||||
}
|
||||
|
||||
// Multer 文件上传引擎配置
|
||||
const storage = multer.diskStorage({
|
||||
@@ -4226,7 +4234,9 @@ app.post('/api/users/:id/profile', async (req: Request, res: Response) => {
|
||||
|
||||
// 7.2.1.b 用户隐私安全与通知订阅偏好持久化接口
|
||||
// 用户设置文件存放于对外不可见的私有目录,避免被 /uploads 静态服务公开读取
|
||||
const userSettingsDir = path.resolve(__dirname, '../data');
|
||||
const userSettingsDir = process.env.DATA_DIR
|
||||
? path.resolve(process.env.DATA_DIR)
|
||||
: path.resolve(process.cwd(), 'data');
|
||||
if (!fs.existsSync(userSettingsDir)) {
|
||||
try {
|
||||
fs.mkdirSync(userSettingsDir, { recursive: true });
|
||||
@@ -4235,12 +4245,17 @@ if (!fs.existsSync(userSettingsDir)) {
|
||||
}
|
||||
}
|
||||
const userSettingsFilePath = path.resolve(userSettingsDir, 'user_settings.json');
|
||||
const fallbackUserSettingsFilePath = path.resolve(__dirname, '../data/user_settings.json');
|
||||
function readAllUserSettings(): Record<string, { privacyHidePhone: boolean; noticeSubscribe: boolean; updatedAt: string }> {
|
||||
try {
|
||||
if (fs.existsSync(userSettingsFilePath)) {
|
||||
const raw = fs.readFileSync(userSettingsFilePath, 'utf-8');
|
||||
return JSON.parse(raw) || {};
|
||||
}
|
||||
if (userSettingsFilePath !== fallbackUserSettingsFilePath && fs.existsSync(fallbackUserSettingsFilePath)) {
|
||||
const raw = fs.readFileSync(fallbackUserSettingsFilePath, 'utf-8');
|
||||
return JSON.parse(raw) || {};
|
||||
}
|
||||
} catch (e) {
|
||||
logServerError('userSettings.read', e);
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户