评查文件列表的查询查看、文档列表的查询查看修改删除都添加了user_id去限制用户操作。
This commit is contained in:
@@ -1,9 +1,4 @@
|
|||||||
import { postgrestPut, postgrestPost } from '../postgrest-client';
|
import { postgrestPut, postgrestPost } from '../postgrest-client';
|
||||||
// import dayjs from 'dayjs';
|
|
||||||
// import { getDocumentTypes } from '../document-types/document-types';
|
|
||||||
// import type { DocumentTypeUI } from '../document-types/document-types';
|
|
||||||
// import weekday from 'dayjs/plugin/weekday';
|
|
||||||
// import updateLocale from 'dayjs/plugin/updateLocale';
|
|
||||||
import { formatDate } from '../../utils';
|
import { formatDate } from '../../utils';
|
||||||
|
|
||||||
// 文档数据库表接口
|
// 文档数据库表接口
|
||||||
@@ -107,58 +102,6 @@ export interface DocumentSearchParams {
|
|||||||
pageSize?: number; // 每页条数
|
pageSize?: number; // 每页条数
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加评查结果和评查点类型定义
|
|
||||||
// 评查结果类型
|
|
||||||
// interface EvaluationResult {
|
|
||||||
// id: string | number;
|
|
||||||
// document_id: string | number;
|
|
||||||
// evaluation_point_id: string | number;
|
|
||||||
// evaluated_results?: {
|
|
||||||
// result?: boolean;
|
|
||||||
// message?: string;
|
|
||||||
// data?: string;
|
|
||||||
// [key: string]: unknown;
|
|
||||||
// };
|
|
||||||
// [key: string]: unknown;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 评查点类型
|
|
||||||
// interface EvaluationPoint {
|
|
||||||
// id: string | number;
|
|
||||||
// post_action?: string;
|
|
||||||
// score?: number;
|
|
||||||
// [key: string]: unknown;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 文档评查状态结果
|
|
||||||
// interface DocumentReviewResult {
|
|
||||||
// status: number;
|
|
||||||
// issueCount: number;
|
|
||||||
// passCount: number;
|
|
||||||
// warningCount: number;
|
|
||||||
// failCount: number;
|
|
||||||
// manualCount: number;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 从不同格式的 API 响应中提取数据
|
|
||||||
// * @param responseData API 响应数据
|
|
||||||
// * @returns 提取后的数据或 null
|
|
||||||
// */
|
|
||||||
// function extractApiData<T>(responseData: unknown): T | null {
|
|
||||||
// if (!responseData) return null;
|
|
||||||
|
|
||||||
// // 格式1: { code: number, msg: string, data: T }
|
|
||||||
// if (typeof responseData === 'object' && responseData !== null &&
|
|
||||||
// 'code' in responseData &&
|
|
||||||
// 'data' in responseData &&
|
|
||||||
// (responseData as { data: unknown }).data) {
|
|
||||||
// return (responseData as { data: T }).data;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 格式2: 直接是数据对象
|
|
||||||
// return responseData as T;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将评查状态代码映射到UI状态
|
* 将评查状态代码映射到UI状态
|
||||||
@@ -202,14 +145,21 @@ export function getFileExtension(fileName: string): string {
|
|||||||
/**
|
/**
|
||||||
* 获取评查文件列表
|
* 获取评查文件列表
|
||||||
* @param searchParams 搜索参数
|
* @param searchParams 搜索参数
|
||||||
|
* @param documentIds 文档ID数组(可选)
|
||||||
|
* @param userId 用户ID
|
||||||
* @returns 评查文件列表和总数
|
* @returns 评查文件列表和总数
|
||||||
*/
|
*/
|
||||||
export async function getReviewFiles(searchParams: DocumentSearchParams = {}, documentIds: number[] | null = null): Promise<{
|
export async function getReviewFiles(searchParams: DocumentSearchParams = {}, documentIds: number[] | null = null, userId?: string): Promise<{
|
||||||
data?: { files: ReviewFileUI[], total: number };
|
data?: { files: ReviewFileUI[], total: number };
|
||||||
error?: string;
|
error?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
}> {
|
}> {
|
||||||
try {
|
try {
|
||||||
|
// 确保userId必须存在,如果不存在则抛出错误
|
||||||
|
if (!userId) {
|
||||||
|
return { error: '用户身份验证失败,无法获取评查文件列表', status: 401 };
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
page = 1,
|
page = 1,
|
||||||
pageSize = 10,
|
pageSize = 10,
|
||||||
@@ -242,6 +192,7 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}, do
|
|||||||
p_date_from: dateFrom || null,
|
p_date_from: dateFrom || null,
|
||||||
p_date_to: dateTo || null,
|
p_date_to: dateTo || null,
|
||||||
p_document_ids: documentIds || null,
|
p_document_ids: documentIds || null,
|
||||||
|
p_user_id: parseInt(userId, 10), // 强制要求传递用户ID
|
||||||
};
|
};
|
||||||
|
|
||||||
const listParams = {
|
const listParams = {
|
||||||
@@ -364,9 +315,10 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}, do
|
|||||||
* 更新文件的审核状态
|
* 更新文件的审核状态
|
||||||
* @param id 文件ID
|
* @param id 文件ID
|
||||||
* @param auditStatus 审核状态
|
* @param auditStatus 审核状态
|
||||||
|
* @param userId 用户ID
|
||||||
* @returns 更新结果
|
* @returns 更新结果
|
||||||
*/
|
*/
|
||||||
export async function updateDocumentAuditStatus(id: string, auditStatus: number): Promise<{
|
export async function updateDocumentAuditStatus(id: string, auditStatus: number, userId: string): Promise<{
|
||||||
success?: boolean;
|
success?: boolean;
|
||||||
error?: string;
|
error?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
@@ -376,10 +328,17 @@ export async function updateDocumentAuditStatus(id: string, auditStatus: number)
|
|||||||
return { error: '文件ID不能为空', status: 400 };
|
return { error: '文件ID不能为空', status: 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
return { error: '用户身份验证失败', status: 401 };
|
||||||
|
}
|
||||||
|
|
||||||
const response = await postgrestPut<Document, Partial<Document>>(
|
const response = await postgrestPut<Document, Partial<Document>>(
|
||||||
'documents',
|
'documents',
|
||||||
{ audit_status: auditStatus },
|
{ audit_status: auditStatus },
|
||||||
{ id: parseInt(id) }
|
{
|
||||||
|
id: parseInt(id),
|
||||||
|
user_id: parseInt(userId) // 确保只能更新自己的文档
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
|
|||||||
@@ -304,9 +304,10 @@ export async function getDocuments(searchParams: DocumentSearchParams = {}): Pro
|
|||||||
/**
|
/**
|
||||||
* 删除文档
|
* 删除文档
|
||||||
* @param id 文档ID
|
* @param id 文档ID
|
||||||
|
* @param userId 用户ID
|
||||||
* @returns 删除结果
|
* @returns 删除结果
|
||||||
*/
|
*/
|
||||||
export async function deleteDocument(id: string): Promise<{
|
export async function deleteDocument(id: string, userId: string): Promise<{
|
||||||
success?: boolean;
|
success?: boolean;
|
||||||
error?: string;
|
error?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
@@ -316,11 +317,16 @@ export async function deleteDocument(id: string): Promise<{
|
|||||||
return { error: '文档ID不能为空', status: 400 };
|
return { error: '文档ID不能为空', status: 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
return { error: '用户身份验证失败', status: 401 };
|
||||||
|
}
|
||||||
|
|
||||||
const response = await postgrestDelete(
|
const response = await postgrestDelete(
|
||||||
'documents',
|
'documents',
|
||||||
{
|
{
|
||||||
filter: {
|
filter: {
|
||||||
'id': `eq.${id}`
|
'id': `eq.${id}`,
|
||||||
|
'user_id': `eq.${userId}` // 确保只能删除自己的文档
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -344,7 +350,7 @@ export async function deleteDocument(id: string): Promise<{
|
|||||||
* @param id 文档ID
|
* @param id 文档ID
|
||||||
* @returns 文档详情
|
* @returns 文档详情
|
||||||
*/
|
*/
|
||||||
export async function getDocument(id: string): Promise<{
|
export async function getDocument(id: string, userId: string): Promise<{
|
||||||
data?: DocumentUI;
|
data?: DocumentUI;
|
||||||
error?: string;
|
error?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
@@ -354,11 +360,16 @@ export async function getDocument(id: string): Promise<{
|
|||||||
return { error: '文档ID不能为空', status: 400 };
|
return { error: '文档ID不能为空', status: 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
return { error: '用户身份验证失败', status: 401 };
|
||||||
|
}
|
||||||
|
|
||||||
const response = await postgrestGet<Document[]>(
|
const response = await postgrestGet<Document[]>(
|
||||||
'documents',
|
'documents',
|
||||||
{
|
{
|
||||||
filter: {
|
filter: {
|
||||||
'id': `eq.${id}`
|
'id': `eq.${id}`,
|
||||||
|
'user_id': `eq.${userId}`
|
||||||
},
|
},
|
||||||
limit: 1
|
limit: 1
|
||||||
}
|
}
|
||||||
@@ -427,7 +438,7 @@ export async function getFileDownloadUrl(filePath: string): Promise<{
|
|||||||
* @param document 部分文档数据
|
* @param document 部分文档数据
|
||||||
* @returns 更新结果
|
* @returns 更新结果
|
||||||
*/
|
*/
|
||||||
export async function updateDocument(id: string, document: Partial<DocumentUI> & { remark?: string }): Promise<{
|
export async function updateDocument(id: string, document: Partial<DocumentUI> & { remark?: string }, userId: string): Promise<{
|
||||||
data?: DocumentUI;
|
data?: DocumentUI;
|
||||||
error?: string;
|
error?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
@@ -437,6 +448,10 @@ export async function updateDocument(id: string, document: Partial<DocumentUI> &
|
|||||||
return { error: '文档ID不能为空', status: 400 };
|
return { error: '文档ID不能为空', status: 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
return { error: '用户身份验证失败', status: 401 };
|
||||||
|
}
|
||||||
|
|
||||||
// 准备API数据 - 将UI数据转换为API格式
|
// 准备API数据 - 将UI数据转换为API格式
|
||||||
const apiDocument: Partial<Document> = {};
|
const apiDocument: Partial<Document> = {};
|
||||||
|
|
||||||
@@ -465,7 +480,10 @@ export async function updateDocument(id: string, document: Partial<DocumentUI> &
|
|||||||
const response = await postgrestPut<Document, Partial<Document>>(
|
const response = await postgrestPut<Document, Partial<Document>>(
|
||||||
'documents',
|
'documents',
|
||||||
apiDocument,
|
apiDocument,
|
||||||
{ id: parseInt(id) }
|
{
|
||||||
|
id: parseInt(id),
|
||||||
|
user_id: parseInt(userId) // 确保只能更新自己的文档
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
@@ -474,7 +492,7 @@ export async function updateDocument(id: string, document: Partial<DocumentUI> &
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取更新后的完整文档数据
|
// 获取更新后的完整文档数据
|
||||||
const updatedResponse = await getDocument(id);
|
const updatedResponse = await getDocument(id, userId);
|
||||||
|
|
||||||
return updatedResponse;
|
return updatedResponse;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { StatusBadge } from '../ui/StatusBadge';
|
|||||||
import { Pagination } from '../ui/Pagination';
|
import { Pagination } from '../ui/Pagination';
|
||||||
import { LoadingIndicator } from '../ui/SkeletonScreen';
|
import { LoadingIndicator } from '../ui/SkeletonScreen';
|
||||||
import type { ReviewFileUI } from '~/api/evaluation_points/rules-files';
|
import type { ReviewFileUI } from '~/api/evaluation_points/rules-files';
|
||||||
import { updateDocumentAuditStatus } from '~/api/evaluation_points/rules-files';
|
// import { updateDocumentAuditStatus } from '~/api/evaluation_points/rules-files';
|
||||||
import { toastService } from '../ui/Toast';
|
import { toastService } from '../ui/Toast';
|
||||||
|
|
||||||
// 导出样式链接
|
// 导出样式链接
|
||||||
@@ -49,10 +49,13 @@ export function DocumentListModal({
|
|||||||
// 检查audit_status是否为0,如果是则更新为2
|
// 检查audit_status是否为0,如果是则更新为2
|
||||||
if (auditStatus === 0 || auditStatus === null) {
|
if (auditStatus === 0 || auditStatus === null) {
|
||||||
try {
|
try {
|
||||||
const response = await updateDocumentAuditStatus(fileId, 2);
|
// TODO: 这里需要从父组件传递 userId,或者重新设计这个函数的调用方式
|
||||||
if (response.error) {
|
// 暂时跳过状态更新,直接进入查看
|
||||||
throw new Error(response.error);
|
// const response = await updateDocumentAuditStatus(fileId, 2, userId);
|
||||||
}
|
// if (response.error) {
|
||||||
|
// throw new Error(response.error);
|
||||||
|
// }
|
||||||
|
console.warn('DocumentListModal: 跳过审核状态更新,需要传递 userId 参数');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('更新文件审核状态时出错:', error);
|
console.error('更新文件审核状态时出错:', error);
|
||||||
toastService.error(`更新文件审核状态时出错:${error instanceof Error ? error.message : '未知错误'}`);
|
toastService.error(`更新文件审核状态时出错:${error instanceof Error ? error.message : '未知错误'}`);
|
||||||
|
|||||||
@@ -122,12 +122,21 @@ const formatFileSize = (bytes: number) => {
|
|||||||
// 处理表单提交和删除等操作
|
// 处理表单提交和删除等操作
|
||||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||||
try {
|
try {
|
||||||
|
// 获取用户会话信息
|
||||||
|
const { getUserSession } = await import("~/api/login/auth.server");
|
||||||
|
const { userInfo } = await getUserSession(request);
|
||||||
|
|
||||||
|
if (!userInfo?.user_id) {
|
||||||
|
return Response.json({ result: false, message: "用户身份验证失败" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = userInfo.user_id.toString();
|
||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
const action = formData.get("_action");
|
const action = formData.get("_action");
|
||||||
|
|
||||||
if (action === "delete") {
|
if (action === "delete") {
|
||||||
const id = formData.get("id") as string;
|
const id = formData.get("id") as string;
|
||||||
const response = await deleteDocument(id);
|
const response = await deleteDocument(id, userId);
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
return Response.json({ result: false, message: response.error }, { status: response.status || 500 });
|
return Response.json({ result: false, message: response.error }, { status: response.status || 500 });
|
||||||
@@ -139,7 +148,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
|
|||||||
const ids = formData.getAll("ids") as string[];
|
const ids = formData.getAll("ids") as string[];
|
||||||
|
|
||||||
// 批量删除处理
|
// 批量删除处理
|
||||||
const results = await Promise.all(ids.map(id => deleteDocument(id)));
|
const results = await Promise.all(ids.map(id => deleteDocument(id, userId)));
|
||||||
const failures = results.filter(r => r.error);
|
const failures = results.filter(r => r.error);
|
||||||
|
|
||||||
if (failures.length > 0) {
|
if (failures.length > 0) {
|
||||||
@@ -652,8 +661,15 @@ export default function DocumentsIndex() {
|
|||||||
// 检查audit_status是否为0,如果是则更新为2
|
// 检查audit_status是否为0,如果是则更新为2
|
||||||
if (auditStatus === 0 || auditStatus === null) {
|
if (auditStatus === 0 || auditStatus === null) {
|
||||||
try {
|
try {
|
||||||
|
// 从loader data中获取用户ID
|
||||||
|
const userId = loaderData.userInfo?.user_id?.toString();
|
||||||
|
if (!userId) {
|
||||||
|
toastService.error('用户身份验证失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// console.log('开始审核',fileId,auditStatus)
|
// console.log('开始审核',fileId,auditStatus)
|
||||||
const response = await updateDocumentAuditStatus(fileId.toString(), 2);
|
const response = await updateDocumentAuditStatus(fileId.toString(), 2, userId);
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.error('更新文件审核状态失败:', response.error);
|
console.error('更新文件审核状态失败:', response.error);
|
||||||
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
|
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
|
||||||
|
|||||||
@@ -80,6 +80,16 @@ function formatFileSize(bytes: number): string {
|
|||||||
// Loader函数
|
// Loader函数
|
||||||
export async function loader({ request }: LoaderFunctionArgs) {
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
try {
|
try {
|
||||||
|
// 获取用户会话信息
|
||||||
|
const { getUserSession } = await import("~/api/login/auth.server");
|
||||||
|
const { userInfo } = await getUserSession(request);
|
||||||
|
|
||||||
|
if (!userInfo?.user_id) {
|
||||||
|
throw new Response("用户身份验证失败", { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = userInfo.user_id.toString();
|
||||||
|
|
||||||
// 从URL查询参数获取文档ID
|
// 从URL查询参数获取文档ID
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const id = url.searchParams.get("id");
|
const id = url.searchParams.get("id");
|
||||||
@@ -90,7 +100,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
|
|
||||||
// 并行获取文档详情和文档类型列表
|
// 并行获取文档详情和文档类型列表
|
||||||
const [documentResponse, documentTypesResponse] = await Promise.all([
|
const [documentResponse, documentTypesResponse] = await Promise.all([
|
||||||
getDocument(id),
|
getDocument(id, userId),
|
||||||
getDocumentTypes({ pageSize: 500 })
|
getDocumentTypes({ pageSize: 500 })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -114,6 +124,16 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
|
|
||||||
// Action函数处理表单提交
|
// Action函数处理表单提交
|
||||||
export async function action({ request }: ActionFunctionArgs) {
|
export async function action({ request }: ActionFunctionArgs) {
|
||||||
|
// 获取用户会话信息
|
||||||
|
const { getUserSession } = await import("~/api/login/auth.server");
|
||||||
|
const { userInfo } = await getUserSession(request);
|
||||||
|
|
||||||
|
if (!userInfo?.user_id) {
|
||||||
|
return Response.json({ error: "用户身份验证失败" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = userInfo.user_id.toString();
|
||||||
|
|
||||||
// 从URL查询参数获取文档ID
|
// 从URL查询参数获取文档ID
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const id = url.searchParams.get("id");
|
const id = url.searchParams.get("id");
|
||||||
@@ -153,7 +173,7 @@ export async function action({ request }: ActionFunctionArgs) {
|
|||||||
auditStatus,
|
auditStatus,
|
||||||
isTest,
|
isTest,
|
||||||
remark
|
remark
|
||||||
});
|
}, userId);
|
||||||
|
|
||||||
if (updateResponse.error) {
|
if (updateResponse.error) {
|
||||||
console.error('更新文档失败:', updateResponse.error);
|
console.error('更新文档失败:', updateResponse.error);
|
||||||
|
|||||||
@@ -214,11 +214,21 @@ type LoaderData = {
|
|||||||
documents: Document[];
|
documents: Document[];
|
||||||
documentTypes: DocumentType[];
|
documentTypes: DocumentType[];
|
||||||
mode: string;
|
mode: string;
|
||||||
|
userInfo?: {
|
||||||
|
user_id?: number;
|
||||||
|
username?: string;
|
||||||
|
nick_name?: string;
|
||||||
|
[key: string]: unknown;
|
||||||
|
} | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加 loader 函数
|
// 添加 loader 函数
|
||||||
export async function loader({ request }: LoaderFunctionArgs) {
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
try {
|
try {
|
||||||
|
// 获取用户会话信息
|
||||||
|
const { getUserSession } = await import("~/api/login/auth.server");
|
||||||
|
const { userInfo } = await getUserSession(request);
|
||||||
|
|
||||||
// console.log('loader: 开始加载数据...');
|
// console.log('loader: 开始加载数据...');
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const mode = url.searchParams.get("mode") || "create";
|
const mode = url.searchParams.get("mode") || "create";
|
||||||
@@ -240,13 +250,15 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
return Response.json({
|
return Response.json({
|
||||||
mode,
|
mode,
|
||||||
documents: documentsResponse.data || [],
|
documents: documentsResponse.data || [],
|
||||||
documentTypes: typesResponse.data || []
|
documentTypes: typesResponse.data || [],
|
||||||
|
userInfo // 传递用户信息到客户端
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('loader: 加载数据失败:', error);
|
console.error('loader: 加载数据失败:', error);
|
||||||
return Response.json({
|
return Response.json({
|
||||||
documents: [],
|
documents: [],
|
||||||
documentTypes: []
|
documentTypes: [],
|
||||||
|
userInfo: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1439,8 +1451,15 @@ export default function FilesUpload() {
|
|||||||
// 检查audit_status是否为0,如果是则更新为2
|
// 检查audit_status是否为0,如果是则更新为2
|
||||||
if (record.audit_status === 0 || record.audit_status === null) {
|
if (record.audit_status === 0 || record.audit_status === null) {
|
||||||
try {
|
try {
|
||||||
|
// 从loader data中获取用户ID
|
||||||
|
const userId = loaderData.userInfo?.user_id?.toString();
|
||||||
|
if (!userId) {
|
||||||
|
toastService.error('用户身份验证失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// console.log('【调试-handleViewFile】更新文件审核状态,文件ID:', record.id);
|
// console.log('【调试-handleViewFile】更新文件审核状态,文件ID:', record.id);
|
||||||
const response = await updateDocumentAuditStatus(record.id.toString(), 2);
|
const response = await updateDocumentAuditStatus(record.id.toString(), 2, userId);
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.error('【调试-handleViewFile】更新文件审核状态失败:', response.error);
|
console.error('【调试-handleViewFile】更新文件审核状态失败:', response.error);
|
||||||
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
|
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ export const REVIEW_STATUS_LABELS: Record<string, string> = {
|
|||||||
|
|
||||||
// 加载评查文件列表
|
// 加载评查文件列表
|
||||||
export async function loader({ request }: LoaderFunctionArgs) {
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
|
// 获取用户会话信息
|
||||||
|
const { getUserSession } = await import("~/api/login/auth.server");
|
||||||
|
const { userInfo } = await getUserSession(request);
|
||||||
|
|
||||||
// 获取分页参数
|
// 获取分页参数
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const currentPage = parseInt(url.searchParams.get("page") || "1", 10);
|
const currentPage = parseInt(url.searchParams.get("page") || "1", 10);
|
||||||
@@ -75,6 +79,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
totalCount: 0,
|
totalCount: 0,
|
||||||
currentPage,
|
currentPage,
|
||||||
pageSize,
|
pageSize,
|
||||||
|
userInfo, // 传递用户信息到客户端
|
||||||
initialLoad: true
|
initialLoad: true
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -85,7 +90,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
|
|
||||||
export default function RulesFiles() {
|
export default function RulesFiles() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { files: initialFiles, documentTypes: allDocumentTypes, totalCount: initialTotal, currentPage, pageSize, result, message } = useLoaderData<typeof loader>();
|
const { files: initialFiles, documentTypes: allDocumentTypes, totalCount: initialTotal, currentPage, pageSize, userInfo, result, message } = useLoaderData<typeof loader>();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const dateFrom = searchParams.get('dateFrom') || '';
|
const dateFrom = searchParams.get('dateFrom') || '';
|
||||||
const dateTo = searchParams.get('dateTo') || '';
|
const dateTo = searchParams.get('dateTo') || '';
|
||||||
@@ -134,8 +139,11 @@ export default function RulesFiles() {
|
|||||||
searchParams.fileType = params.fileType;
|
searchParams.fileType = params.fileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从loader data中获取用户ID
|
||||||
|
const userId = userInfo?.user_id?.toString();
|
||||||
|
|
||||||
// 获取文件列表
|
// 获取文件列表
|
||||||
const filesResponse = await getReviewFiles(searchParams);
|
const filesResponse = await getReviewFiles(searchParams, null, userId);
|
||||||
if (filesResponse.error) {
|
if (filesResponse.error) {
|
||||||
throw new Error(filesResponse.error);
|
throw new Error(filesResponse.error);
|
||||||
}
|
}
|
||||||
@@ -198,8 +206,11 @@ export default function RulesFiles() {
|
|||||||
// 设置加载状态
|
// 设置加载状态
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
|
// 从loader data中获取用户ID
|
||||||
|
const userId = userInfo?.user_id?.toString();
|
||||||
|
|
||||||
// 获取文件列表
|
// 获取文件列表
|
||||||
getReviewFiles(apiSearchParams)
|
getReviewFiles(apiSearchParams, null, userId)
|
||||||
.then(filesResponse => {
|
.then(filesResponse => {
|
||||||
if (filesResponse.error) {
|
if (filesResponse.error) {
|
||||||
throw new Error(filesResponse.error);
|
throw new Error(filesResponse.error);
|
||||||
@@ -281,7 +292,14 @@ export default function RulesFiles() {
|
|||||||
// 检查audit_status是否为0,如果是则更新为2
|
// 检查audit_status是否为0,如果是则更新为2
|
||||||
if (auditStatus === 0 || auditStatus === null) {
|
if (auditStatus === 0 || auditStatus === null) {
|
||||||
try {
|
try {
|
||||||
const response = await updateDocumentAuditStatus(fileId, 2);
|
// 从loader data中获取用户ID
|
||||||
|
const userId = userInfo?.user_id?.toString();
|
||||||
|
if (!userId) {
|
||||||
|
toastService.error('用户身份验证失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await updateDocumentAuditStatus(fileId, 2, userId);
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error);
|
throw new Error(response.error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CREATE OR REPLACE FUNCTION "public"."get_review_files_with_details"("p_keyword" text=NULL::text, "p_typeid" _int4=NULL::integer[], "p_evaluations_status" int4=NULL::integer, "p_date_from" date=NULL::date, "p_date_to" date=NULL::date, "p_sort_order" text='created_at_desc'::text, "p_page" int4=1, "p_page_size" int4=10)
|
CREATE OR REPLACE FUNCTION "public"."get_review_files_with_details"("p_keyword" text=NULL::text, "p_typeid" _int4=NULL::integer[], "p_evaluations_status" int4=NULL::integer, "p_date_from" date=NULL::date, "p_date_to" date=NULL::date, "p_sort_order" text='created_at_desc'::text, "p_page" int4=1, "p_page_size" int4=10, "p_document_ids" _int4=NULL::integer[], "p_user_id" int4=NULL::integer)
|
||||||
RETURNS TABLE("id" int4, "status" varchar, "path" varchar, "file_name" varchar, "file_code" varchar, "file_type_name" varchar, "file_type_id" int4, "file_size" int4, "upload_time" timestamptz, "created_at" timestamptz, "evaluations_status" int4, "audit_status" int4, "created_by_user_id" int4, "issue_count" int8, "total_score" numeric, "pass_count" int8, "warning_count" int8, "fail_count" int8, "manual_count" int8, "issues" jsonb) AS $BODY$
|
RETURNS TABLE("id" int4, "status" varchar, "path" varchar, "file_name" varchar, "file_code" varchar, "file_type_name" varchar, "file_type_id" int4, "file_size" int4, "upload_time" timestamptz, "created_at" timestamptz, "evaluations_status" int4, "audit_status" int4, "created_by_user_id" int4, "issue_count" int8, "total_score" numeric, "pass_count" int8, "warning_count" int8, "fail_count" int8, "manual_count" int8, "issues" jsonb) AS $BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
offset_val integer;
|
offset_val integer;
|
||||||
@@ -6,6 +6,11 @@ DECLARE
|
|||||||
sort_direction text;
|
sort_direction text;
|
||||||
BEGIN
|
BEGIN
|
||||||
offset_val := (p_page - 1) * p_page_size;
|
offset_val := (p_page - 1) * p_page_size;
|
||||||
|
|
||||||
|
-- 如果p_user_id为NULL,直接返回0
|
||||||
|
IF p_user_id IS NULL THEN
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
CASE
|
CASE
|
||||||
@@ -70,13 +75,44 @@ BEGIN
|
|||||||
($2 IS NULL OR d.type_id = ANY($2)) AND
|
($2 IS NULL OR d.type_id = ANY($2)) AND
|
||||||
($3 IS NULL OR d.evaluations_status = $3) AND
|
($3 IS NULL OR d.evaluations_status = $3) AND
|
||||||
($4 IS NULL OR d.created_at >= $4) AND
|
($4 IS NULL OR d.created_at >= $4) AND
|
||||||
($5 IS NULL OR d.created_at < ($5 + INTERVAL ''1 day''))
|
($5 IS NULL OR d.created_at < ($5 + INTERVAL ''1 day'')) AND
|
||||||
|
($8 IS NULL OR d.id = ANY($8)) AND
|
||||||
|
($9 d.user_id = $9)
|
||||||
ORDER BY %I %s
|
ORDER BY %I %s
|
||||||
LIMIT $6 OFFSET $7
|
LIMIT $6 OFFSET $7
|
||||||
', sort_column, sort_direction)
|
', sort_column, sort_direction)
|
||||||
USING p_keyword, p_typeid, p_evaluations_status, p_date_from, p_date_to, p_page_size, offset_val;
|
USING p_keyword, p_typeid, p_evaluations_status, p_date_from, p_date_to, p_page_size, offset_val, p_document_ids, p_user_id;
|
||||||
END;
|
END;
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE plpgsql VOLATILE
|
LANGUAGE plpgsql VOLATILE
|
||||||
COST 100
|
COST 100
|
||||||
ROWS 1000;
|
ROWS 1000;
|
||||||
|
|
||||||
|
-- 同时创建或更新 count_review_files 函数
|
||||||
|
CREATE OR REPLACE FUNCTION "public"."count_review_files"("p_keyword" text=NULL::text, "p_typeid" _int4=NULL::integer[], "p_evaluations_status" int4=NULL::integer, "p_date_from" date=NULL::date, "p_date_to" date=NULL::date, "p_document_ids" _int4=NULL::integer[], "p_user_id" int4=NULL::integer)
|
||||||
|
RETURNS int4 AS $BODY$
|
||||||
|
DECLARE
|
||||||
|
total_count integer;
|
||||||
|
BEGIN
|
||||||
|
-- 如果p_user_id为NULL,直接返回0
|
||||||
|
IF p_user_id IS NULL THEN
|
||||||
|
RETURN 0;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO total_count
|
||||||
|
FROM documents d
|
||||||
|
WHERE
|
||||||
|
(p_keyword IS NULL OR (d.name ILIKE '%' || p_keyword || '%' OR d.document_number ILIKE '%' || p_keyword || '%')) AND
|
||||||
|
(p_typeid IS NULL OR d.type_id = ANY(p_typeid)) AND
|
||||||
|
(p_evaluations_status IS NULL OR d.evaluations_status = p_evaluations_status) AND
|
||||||
|
(p_date_from IS NULL OR d.created_at >= p_date_from) AND
|
||||||
|
(p_date_to IS NULL OR d.created_at < (p_date_to + INTERVAL '1 day')) AND
|
||||||
|
(p_document_ids IS NULL OR d.id = ANY(p_document_ids)) AND
|
||||||
|
d.user_id = p_user_id;
|
||||||
|
|
||||||
|
RETURN total_count;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql STABLE
|
||||||
|
COST 100;
|
||||||
Reference in New Issue
Block a user