feat: 1. 完善交叉评查上传创建任务,改成动态加载文档类型。
2. 重新对齐交叉评查的接口。
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 验证用户是否有权访问指定文档
|
||||
*
|
||||
* 权限验证逻辑:
|
||||
* 1. 检查文档是否属于指定的任务
|
||||
* 2. 检查用户是否是该任务的参与者(评审员或发起人)
|
||||
* 3. 防止用户通过修改 URL 参数访问未授权的文档
|
||||
*/
|
||||
|
||||
import { postgrestGet } from "../postgrest-client";
|
||||
|
||||
interface DocumentAccessCheckParams {
|
||||
documentId: string | number;
|
||||
taskId: string | number;
|
||||
userId: number;
|
||||
jwtToken?: string;
|
||||
}
|
||||
|
||||
interface DocumentAccessCheckResult {
|
||||
hasAccess: boolean;
|
||||
reason?: string;
|
||||
userRole?: 'assigner' | 'assignee' | 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证文档访问权限
|
||||
* @param params 验证参数
|
||||
* @returns 验证结果
|
||||
*/
|
||||
export async function verifyDocumentAccess(
|
||||
params: DocumentAccessCheckParams
|
||||
): Promise<DocumentAccessCheckResult> {
|
||||
const { documentId, taskId, userId, jwtToken } = params;
|
||||
|
||||
try {
|
||||
// 1. 检查文档是否属于该任务(通过 cross_task_document_mapping 表)
|
||||
const documentMappingResponse = await postgrestGet('cross_task_document_mapping', {
|
||||
select: 'task_id,document_id',
|
||||
filter: {
|
||||
task_id: `eq.${taskId}`,
|
||||
document_id: `eq.${documentId}`
|
||||
},
|
||||
token: jwtToken
|
||||
});
|
||||
|
||||
if (documentMappingResponse.error) {
|
||||
console.error('❌ [verifyDocumentAccess] 查询文档-任务映射失败:', documentMappingResponse.error);
|
||||
return {
|
||||
hasAccess: false,
|
||||
reason: '查询文档-任务映射失败'
|
||||
};
|
||||
}
|
||||
|
||||
// 提取数据
|
||||
const mappingData = Array.isArray(documentMappingResponse.data)
|
||||
? documentMappingResponse.data
|
||||
: [];
|
||||
|
||||
// 文档不属于该任务
|
||||
if (mappingData.length === 0) {
|
||||
console.warn(`⚠️ [verifyDocumentAccess] 文档 ${documentId} 不属于任务 ${taskId}`);
|
||||
return {
|
||||
hasAccess: false,
|
||||
reason: '文档不属于该任务'
|
||||
};
|
||||
}
|
||||
|
||||
// 2. 检查用户是否是该任务的参与者
|
||||
const taskResponse = await postgrestGet('cross_examination_tasks', {
|
||||
select: 'assigner_id,assignee_ids',
|
||||
filter: {
|
||||
id: `eq.${taskId}`
|
||||
},
|
||||
token: jwtToken
|
||||
});
|
||||
|
||||
if (taskResponse.error) {
|
||||
console.error('❌ [verifyDocumentAccess] 查询任务信息失败:', taskResponse.error);
|
||||
return {
|
||||
hasAccess: false,
|
||||
reason: '查询任务信息失败'
|
||||
};
|
||||
}
|
||||
|
||||
const taskData = Array.isArray(taskResponse.data) ? taskResponse.data[0] : null;
|
||||
|
||||
if (!taskData) {
|
||||
console.warn(`⚠️ [verifyDocumentAccess] 任务 ${taskId} 不存在`);
|
||||
return {
|
||||
hasAccess: false,
|
||||
reason: '任务不存在'
|
||||
};
|
||||
}
|
||||
|
||||
// 3. 验证用户身份
|
||||
const isAssigner = taskData.assigner_id === userId;
|
||||
const assigneeIds = Array.isArray(taskData.assignee_ids) ? taskData.assignee_ids : [];
|
||||
const isAssignee = assigneeIds.includes(userId);
|
||||
|
||||
if (isAssigner) {
|
||||
console.log(`✅ [verifyDocumentAccess] 用户 ${userId} 是任务 ${taskId} 的发起人,允许访问文档 ${documentId}`);
|
||||
return {
|
||||
hasAccess: true,
|
||||
userRole: 'assigner'
|
||||
};
|
||||
}
|
||||
|
||||
if (isAssignee) {
|
||||
console.log(`✅ [verifyDocumentAccess] 用户 ${userId} 是任务 ${taskId} 的评审员,允许访问文档 ${documentId}`);
|
||||
return {
|
||||
hasAccess: true,
|
||||
userRole: 'assignee'
|
||||
};
|
||||
}
|
||||
|
||||
// 用户既不是发起人也不是评审员
|
||||
console.warn(`⚠️ [verifyDocumentAccess] 用户 ${userId} 无权访问任务 ${taskId} 的文档 ${documentId}`);
|
||||
return {
|
||||
hasAccess: false,
|
||||
reason: '您没有权限访问该文档',
|
||||
userRole: 'none'
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ [verifyDocumentAccess] 验证失败:', error);
|
||||
return {
|
||||
hasAccess: false,
|
||||
reason: error instanceof Error ? error.message : '权限验证失败'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速验证文档访问权限(仅返回布尔值)
|
||||
* @param params 验证参数
|
||||
* @returns 是否有权限访问
|
||||
*/
|
||||
export async function canAccessDocument(
|
||||
params: DocumentAccessCheckParams
|
||||
): Promise<boolean> {
|
||||
const result = await verifyDocumentAccess(params);
|
||||
return result.hasAccess;
|
||||
}
|
||||
Reference in New Issue
Block a user