Merge remote-tracking branch 'origin/shiy-login' into Wren
This commit is contained in:
+13
-3
@@ -1,7 +1,7 @@
|
||||
import { type LoaderFunctionArgs, redirect } from "@remix-run/node";
|
||||
import { OAuthClient } from "~/api/login/oauth-client";
|
||||
import { OAUTH_CONFIG } from "~/config/api-config";
|
||||
import { sessionStorage } from "~/api/login/auth.server";
|
||||
import { sessionStorage, saveUserInfo } from "~/api/login/auth.server";
|
||||
import { toastService } from "~/components/ui";
|
||||
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
@@ -58,14 +58,24 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
session.set("tokenExpiresIn", tokenResponse.expires_in);
|
||||
session.set("userInfo", userInfo.data);
|
||||
|
||||
// 根据用户信息判断用户角色,这里可以根据实际业务逻辑调整
|
||||
const userRole = userInfo.data.username === "admin" ? "developer" : "common";
|
||||
// TODO 根据用户信息判断用户角色,这里可以根据实际业务逻辑调整 暂定都是common
|
||||
// const userRole = userInfo.data.username === "admin" ? "developer" : "common";
|
||||
const userRole = "common";
|
||||
session.set("userRole", userRole);
|
||||
|
||||
// 获取重定向URL
|
||||
const redirectTo = url.searchParams.get("redirect") || "/";
|
||||
|
||||
const cookie = await sessionStorage.commitSession(session);
|
||||
|
||||
// 成功获取用户信息之后通过auth.server.ts中的saveUserInfo方法去写入自己的数据库中,通过sub作为唯一值去添加数据
|
||||
const saveResult = await saveUserInfo(userInfo.data);
|
||||
if (!saveResult.success) {
|
||||
console.error("保存用户信息到数据库失败:", saveResult.error);
|
||||
// 注意:即使保存到数据库失败,我们仍然继续登录流程,因为用户已经通过了身份验证
|
||||
} else {
|
||||
console.log("用户信息已成功保存到数据库");
|
||||
}
|
||||
|
||||
return redirect(redirectTo, {
|
||||
headers: {
|
||||
|
||||
@@ -33,8 +33,12 @@ export const meta: MetaFunction = () => {
|
||||
];
|
||||
};
|
||||
|
||||
// 数据加载器
|
||||
// 数据加载器
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
// 获取用户会话信息
|
||||
const { getUserSession } = await import("~/api/login/auth.server");
|
||||
const { userInfo } = await getUserSession(request);
|
||||
|
||||
// 获取URL查询参数,只保留必要的分页参数
|
||||
const url = new URL(request.url);
|
||||
const page = parseInt(url.searchParams.get("page") || "1", 10);
|
||||
@@ -55,6 +59,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
page,
|
||||
pageSize,
|
||||
documentTypeOptions,
|
||||
userInfo, // 传递用户信息到客户端
|
||||
initialLoad: true // 标记这是初始加载
|
||||
});
|
||||
};
|
||||
@@ -117,12 +122,21 @@ const formatFileSize = (bytes: number) => {
|
||||
// 处理表单提交和删除等操作
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
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 action = formData.get("_action");
|
||||
|
||||
if (action === "delete") {
|
||||
const id = formData.get("id") as string;
|
||||
const response = await deleteDocument(id);
|
||||
const response = await deleteDocument(id, userId);
|
||||
|
||||
if (response.error) {
|
||||
return Response.json({ result: false, message: response.error }, { status: response.status || 500 });
|
||||
@@ -134,7 +148,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
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);
|
||||
|
||||
if (failures.length > 0) {
|
||||
@@ -195,6 +209,9 @@ export default function DocumentsIndex() {
|
||||
loadingBarService.show();
|
||||
|
||||
try {
|
||||
// 从loader data中获取用户ID
|
||||
const userId = loaderData.userInfo?.user_id?.toString();
|
||||
|
||||
// 构建搜索参数
|
||||
const searchParams = {
|
||||
name: search || undefined,
|
||||
@@ -205,6 +222,7 @@ export default function DocumentsIndex() {
|
||||
dateFrom: dateFrom || undefined,
|
||||
dateTo: dateTo || undefined,
|
||||
reviewType: storedReviewType || undefined,
|
||||
userId: userId, // 添加用户ID筛选
|
||||
page: currentPage,
|
||||
pageSize
|
||||
};
|
||||
@@ -238,7 +256,7 @@ export default function DocumentsIndex() {
|
||||
setIsLoadingData(false);
|
||||
loadingBarService.hide();
|
||||
}
|
||||
}, [search, documentNumber, documentType, auditStatus, fileStatus, dateFrom, dateTo, currentPage, pageSize]);
|
||||
}, [search, documentNumber, documentType, auditStatus, fileStatus, dateFrom, dateTo, currentPage, pageSize, loaderData.userInfo]);
|
||||
|
||||
// 在组件挂载时从 sessionStorage 获取 reviewType 并加载数据
|
||||
useEffect(() => {
|
||||
@@ -643,8 +661,15 @@ export default function DocumentsIndex() {
|
||||
// 检查audit_status是否为0,如果是则更新为2
|
||||
if (auditStatus === 0 || auditStatus === null) {
|
||||
try {
|
||||
// 从loader data中获取用户ID
|
||||
const userId = loaderData.userInfo?.user_id?.toString();
|
||||
if (!userId) {
|
||||
toastService.error('用户身份验证失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// console.log('开始审核',fileId,auditStatus)
|
||||
const response = await updateDocumentAuditStatus(fileId.toString(), 2);
|
||||
const response = await updateDocumentAuditStatus(fileId.toString(), 2, userId);
|
||||
if (response.error) {
|
||||
console.error('更新文件审核状态失败:', response.error);
|
||||
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
|
||||
|
||||
@@ -80,6 +80,16 @@ function formatFileSize(bytes: number): string {
|
||||
// Loader函数
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
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
|
||||
const url = new URL(request.url);
|
||||
const id = url.searchParams.get("id");
|
||||
@@ -90,7 +100,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
|
||||
// 并行获取文档详情和文档类型列表
|
||||
const [documentResponse, documentTypesResponse] = await Promise.all([
|
||||
getDocument(id),
|
||||
getDocument(id, userId),
|
||||
getDocumentTypes({ pageSize: 500 })
|
||||
]);
|
||||
|
||||
@@ -114,6 +124,16 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
|
||||
// Action函数处理表单提交
|
||||
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
|
||||
const url = new URL(request.url);
|
||||
const id = url.searchParams.get("id");
|
||||
@@ -153,7 +173,7 @@ export async function action({ request }: ActionFunctionArgs) {
|
||||
auditStatus,
|
||||
isTest,
|
||||
remark
|
||||
});
|
||||
}, userId);
|
||||
|
||||
if (updateResponse.error) {
|
||||
console.error('更新文档失败:', updateResponse.error);
|
||||
|
||||
@@ -214,11 +214,21 @@ type LoaderData = {
|
||||
documents: Document[];
|
||||
documentTypes: DocumentType[];
|
||||
mode: string;
|
||||
userInfo?: {
|
||||
user_id?: number;
|
||||
username?: string;
|
||||
nick_name?: string;
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
};
|
||||
|
||||
// 添加 loader 函数
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
try {
|
||||
// 获取用户会话信息
|
||||
const { getUserSession } = await import("~/api/login/auth.server");
|
||||
const { userInfo } = await getUserSession(request);
|
||||
|
||||
// console.log('loader: 开始加载数据...');
|
||||
const url = new URL(request.url);
|
||||
const mode = url.searchParams.get("mode") || "create";
|
||||
@@ -240,13 +250,15 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
return Response.json({
|
||||
mode,
|
||||
documents: documentsResponse.data || [],
|
||||
documentTypes: typesResponse.data || []
|
||||
documentTypes: typesResponse.data || [],
|
||||
userInfo // 传递用户信息到客户端
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('loader: 加载数据失败:', error);
|
||||
return Response.json({
|
||||
documents: [],
|
||||
documentTypes: []
|
||||
documentTypes: [],
|
||||
userInfo: null
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1439,8 +1451,15 @@ export default function FilesUpload() {
|
||||
// 检查audit_status是否为0,如果是则更新为2
|
||||
if (record.audit_status === 0 || record.audit_status === null) {
|
||||
try {
|
||||
// 从loader data中获取用户ID
|
||||
const userId = loaderData.userInfo?.user_id?.toString();
|
||||
if (!userId) {
|
||||
toastService.error('用户身份验证失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
console.error('【调试-handleViewFile】更新文件审核状态失败:', response.error);
|
||||
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));
|
||||
|
||||
+26
-10
@@ -3,7 +3,7 @@ import { useSearchParams, Form } from "@remix-run/react";
|
||||
import { type MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs, redirect } from "@remix-run/node";
|
||||
import { OAuthClient } from "~/api/login/oauth-client";
|
||||
import { OAUTH_CONFIG } from "~/config/api-config";
|
||||
import { getUserSession, getSession, createUserSession } from "~/api/login/auth.server";
|
||||
import { getUserSession, getSession, createUserSessionWithInfo, getUserBySub, addDefaultRole } from "~/api/login/auth.server";
|
||||
import styles from "~/styles/pages/login.css?url";
|
||||
|
||||
export const links = () => [
|
||||
@@ -44,13 +44,29 @@ export async function action({ request }: ActionFunctionArgs) {
|
||||
const formData = await request.formData();
|
||||
const intent = formData.get("intent");
|
||||
|
||||
if (intent === "temp_admin_login") {
|
||||
if (intent === "test_user_login") {
|
||||
// 获取重定向目标
|
||||
const session = await getSession(request);
|
||||
const redirectTo = session.get("redirectTo") || "/";
|
||||
|
||||
// 创建管理员会话
|
||||
return createUserSession(true, 'developer', redirectTo);
|
||||
// 使用测试用户登录
|
||||
const testUserSub = "001"; // 测试用户的sub
|
||||
const userResult = await getUserBySub(testUserSub);
|
||||
|
||||
if (userResult.success && userResult.data) {
|
||||
const user = userResult.data;
|
||||
|
||||
// 确保用户有默认角色
|
||||
if (user.id) {
|
||||
await addDefaultRole(user.id, 2); // 添加common角色
|
||||
}
|
||||
|
||||
// 创建用户会话,默认角色为common,并保存用户信息
|
||||
return createUserSessionWithInfo(true, 'common', redirectTo, user);
|
||||
} else {
|
||||
// 如果用户不存在,重定向到登录页面并显示错误
|
||||
return redirect(`/login?error=${encodeURIComponent("测试用户不存在")}`);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -149,25 +165,25 @@ export default function Login() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 临时管理员登录区域 */}
|
||||
{/* 测试用户登录区域 */}
|
||||
<div className="temp-login-section">
|
||||
<div className="section-divider">
|
||||
<span>或</span>
|
||||
</div>
|
||||
|
||||
<Form method="post" className="temp-login-form">
|
||||
<input type="hidden" name="intent" value="temp_admin_login" />
|
||||
<input type="hidden" name="intent" value="test_user_login" />
|
||||
<button
|
||||
type="submit"
|
||||
className="temp-admin-login-button"
|
||||
>
|
||||
<i className="ri-admin-line"></i>
|
||||
临时管理员登录
|
||||
<i className="ri-user-line"></i>
|
||||
测试用户登录
|
||||
</button>
|
||||
<div className="temp-login-tips">
|
||||
<p>
|
||||
<i className="ri-alert-line"></i>
|
||||
仅供开发测试使用,将以管理员身份登录
|
||||
<i className="ri-information-line"></i>
|
||||
使用测试用户(testuser1)登录,默认普通权限
|
||||
</p>
|
||||
</div>
|
||||
</Form>
|
||||
|
||||
@@ -58,6 +58,10 @@ export const REVIEW_STATUS_LABELS: Record<string, string> = {
|
||||
|
||||
// 加载评查文件列表
|
||||
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 currentPage = parseInt(url.searchParams.get("page") || "1", 10);
|
||||
@@ -75,6 +79,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
totalCount: 0,
|
||||
currentPage,
|
||||
pageSize,
|
||||
userInfo, // 传递用户信息到客户端
|
||||
initialLoad: true
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -85,7 +90,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
|
||||
export default function RulesFiles() {
|
||||
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 dateFrom = searchParams.get('dateFrom') || '';
|
||||
const dateTo = searchParams.get('dateTo') || '';
|
||||
@@ -134,8 +139,11 @@ export default function RulesFiles() {
|
||||
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) {
|
||||
throw new Error(filesResponse.error);
|
||||
}
|
||||
@@ -198,8 +206,11 @@ export default function RulesFiles() {
|
||||
// 设置加载状态
|
||||
setIsLoading(true);
|
||||
|
||||
// 从loader data中获取用户ID
|
||||
const userId = userInfo?.user_id?.toString();
|
||||
|
||||
// 获取文件列表
|
||||
getReviewFiles(apiSearchParams)
|
||||
getReviewFiles(apiSearchParams, null, userId)
|
||||
.then(filesResponse => {
|
||||
if (filesResponse.error) {
|
||||
throw new Error(filesResponse.error);
|
||||
@@ -281,7 +292,14 @@ export default function RulesFiles() {
|
||||
// 检查audit_status是否为0,如果是则更新为2
|
||||
if (auditStatus === 0 || auditStatus === null) {
|
||||
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) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user