Commit ce20f0d3 authored by 何 广一's avatar 何 广一
Browse files

fix local backend interaction

parent fe1da4d0
No preview for this file type
'use client';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useLocalBackend } from '../interface';
import * as Auth from '../api/login-interface';
import * as Ty from '../interface';
export default function AutoLoginProvider() {
const router = useRouter();
const autoLogin = async () => {
try {
/*
- url: /api/auth/autoLogin
- method: POST
*/
const res = await fetch(`${Ty.urlPrefix}/api/auth/autoLogin`, {
method: 'POST',
});
if (!res.ok) throw new Error('自动登录失败:' + res.status);
const data: Ty.BackendResponse<Auth.LoginResult> = await res.json();
if (data.code !== 0) return;
router.push(`/chat?username=${encodeURIComponent(data.data.user)}`);
} catch (error) {
console.error(error);
alert(error.message);
}
};
useEffect(() => {
autoLogin();
}, [router]);
return <></>;
}
\ No newline at end of file
'use client'; 'use client';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useLocalBackend } from './interface'; import * as Auth from '../api/login-interface';
import * as Auth from './api/login-interface'; import * as Ty from '../interface';
import * as Ty from './interface'; import AutoLoginProvider from './auto-login';
function Home_Local(){ function Home_Local(){
const [isLogin, setIsLogin] = useState(true); const [isLogin, setIsLogin] = useState(true);
...@@ -150,8 +150,10 @@ function Home_Local(){ ...@@ -150,8 +150,10 @@ function Home_Local(){
}; };
return ( return (
<>
<AutoLoginProvider />
<div className="bg-gray-100 h-screen flex flex-col items-center justify-center relative"> <div className="bg-gray-100 h-screen flex flex-col items-center justify-center relative">
<h1 className="text-2xl mb-4">请输入用户名</h1> <h1 className="text-2xl mb-4">{isLogin?'登录账户':'注册账户'}</h1>
<input <input
className="border border-gray-300 rounded px-3 py-2 mb-4" className="border border-gray-300 rounded px-3 py-2 mb-4"
type="text" type="text"
...@@ -196,10 +198,11 @@ function Home_Local(){ ...@@ -196,10 +198,11 @@ function Home_Local(){
hover:bg-blue-600 active:bg-blue-700" hover:bg-blue-600 active:bg-blue-700"
onClick={() => setIsLogin(v => !v)} onClick={() => setIsLogin(v => !v)}
> >
{isLogin ? '切换到注册' : '切换到登录'} {isLogin ? '新用户注册' : '老用户登录'}
</button> </button>
</div> </div>
</div> </div>
</>
); );
} }
...@@ -239,7 +242,7 @@ function Home_External() { ...@@ -239,7 +242,7 @@ function Home_External() {
); );
} }
const HomeFn = useLocalBackend ? Home_Local : Home_External; const HomeFn = Ty.useLocalBackend ? Home_Local : Home_External;
export default function Home() { export default function Home() {
return HomeFn(); return HomeFn();
} }
\ No newline at end of file
...@@ -48,5 +48,7 @@ export const authArgsSchema = z.object({ ...@@ -48,5 +48,7 @@ export const authArgsSchema = z.object({
export const reloginErrorCode = 1919810; export const reloginErrorCode = 1919810;
export const invalidUserErrorCode = 8848; export const invalidUserErrorCode = 8848;
export const abnormalLoginState = 108;
export const incorrectUserName = 105;
export const notAuthorizedToDeleteRoomErrorCode = 2; export const notAuthorizedToDeleteRoomErrorCode = 2;
...@@ -13,14 +13,14 @@ interface MessageAddArgs { ...@@ -13,14 +13,14 @@ interface MessageAddArgs {
} }
- response: null (只要code为0即为成功) - response: null (只要code为0即为成功)
*/ */
export async function POST(req: NextRequest): Promise<NextResponse<Ty.BackendResponse<null>>> { export async function POST(req: NextRequest): Promise<NextResponse<Ty.BackendResponse<null | Ty.UserNameRedirectArgs>>> {
const cookieData = await Db.VerifyCookie(req.cookies); const cookieData = await Db.VerifyCookie(req.cookies);
if('code' in cookieData)return NextResponse.json(cookieData); if('code' in cookieData)return NextResponse.json(cookieData);
const { roomId, content, sender } = await req.json() as Ty.MessageAddArgs; const { roomId, content, sender } = await req.json() as Ty.MessageAddArgs;
const checkResult = await Db.CheckUser(sender, cookieData.userToken); const checkResult = await Db.CheckUser(sender, cookieData.userToken);
if (!checkResult) return Db.IncorrectUserResponse; if (!checkResult) return Db.IncorrectUserResponse(cookieData.userToken);
const response = await Db.AddMessage({ roomId, content, sender }); const response = await Db.AddMessage({ roomId, content, sender });
return NextResponse.json(response); return NextResponse.json(response);
......
...@@ -33,6 +33,14 @@ const toFrontMsg = async (m: any) : Promise<Ty.Message | null> => { ...@@ -33,6 +33,14 @@ const toFrontMsg = async (m: any) : Promise<Ty.Message | null> => {
}; };
}; };
const isRoomSelfCreated = async (roomId: number, userToken: string): Promise<boolean> => {
const room = await prisma.room.findUnique({
where: { id: roomId },
select: { creator: { select: { userToken: true } } }
});
return room ? room.creator.userToken === userToken : false;
};
const getUserToken = async (name: string) => { const getUserToken = async (name: string) => {
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { name }, where: { name },
...@@ -41,6 +49,14 @@ const getUserToken = async (name: string) => { ...@@ -41,6 +49,14 @@ const getUserToken = async (name: string) => {
return user ? user.userToken : null; return user ? user.userToken : null;
}; };
const getUserNameByToken = async (token: string) => {
const user = await prisma.user.findUnique({
where: { userToken: token },
select: { name: true }
});
return user ? user.name : null;
};
const getRandomToken = (): string => { const getRandomToken = (): string => {
return [...crypto.getRandomValues(new Uint8Array(16))] return [...crypto.getRandomValues(new Uint8Array(16))]
.map(b => b.toString(36)) .map(b => b.toString(36))
...@@ -49,7 +65,7 @@ const getRandomToken = (): string => { ...@@ -49,7 +65,7 @@ const getRandomToken = (): string => {
const getRandomStr = () => (randomBytes(32).toString('hex')); const getRandomStr = () => (randomBytes(32).toString('hex'));
export async function GetRoomList(): Promise<Ty.BackendResponse<Ty.RoomListRes | null>> { export async function GetRoomList(userToken : string): Promise<Ty.BackendResponse<Ty.RoomListResEx | null>> {
const rooms = await prisma.room.findMany({ const rooms = await prisma.room.findMany({
select: { select: {
id: true, id: true,
...@@ -62,12 +78,13 @@ export async function GetRoomList(): Promise<Ty.BackendResponse<Ty.RoomListRes | ...@@ -62,12 +78,13 @@ export async function GetRoomList(): Promise<Ty.BackendResponse<Ty.RoomListRes |
}); });
const preview: Ty.RoomPreviewInfo[] = await Promise.all(rooms.map(async (r) => { const preview: Ty.RoomPreviewInfoEx[] = await Promise.all(rooms.map(async (r) => {
const lastMessage = r.messages[0] ? await toFrontMsg(r.messages[0]) : null; const lastMessage = r.messages[0] ? await toFrontMsg(r.messages[0]) : null;
return { return {
roomId: r.id, roomId: r.id,
roomName: r.roomName, roomName: r.roomName,
lastMessage lastMessage,
selfCreated: await isRoomSelfCreated(r.id, userToken)
}; };
})); }));
...@@ -257,6 +274,7 @@ export async function Login(args: Auth.AuthArgs) : Promise<Ty.BackendResponse<Au ...@@ -257,6 +274,7 @@ export async function Login(args: Auth.AuthArgs) : Promise<Ty.BackendResponse<Au
data: { data: {
token: authToken, token: authToken,
userName: username, userName: username,
/* 登录过期模拟 : 改成 + 60000 即可模拟1分钟过期 */
expiresAt: new Date(Date.now() + 60 * 60 * 1000 * 24 * 7), // 7 days expiresAt: new Date(Date.now() + 60 * 60 * 1000 * 24 * 7), // 7 days
ua: userAgent, ua: userAgent,
ip: userIP ip: userIP
...@@ -381,8 +399,8 @@ export async function VerifyCookie(cookie : RequestCookies) : Promise<Ty.Backend ...@@ -381,8 +399,8 @@ export async function VerifyCookie(cookie : RequestCookies) : Promise<Ty.Backend
}); });
if(!result.success || !result.data.authToken || !result.data.userToken) { if(!result.success || !result.data.authToken || !result.data.userToken) {
return { return {
code: 1, code: Auth.abnormalLoginState,
message: '无效的Cookie', message: '登录异常,请重新登录。',
data: null data: null
}; };
} }
...@@ -426,8 +444,10 @@ export async function CheckUser(name: string, token: string) : Promise<boolean> ...@@ -426,8 +444,10 @@ export async function CheckUser(name: string, token: string) : Promise<boolean>
if (!user) return false; if (!user) return false;
return user.userToken === token; return user.userToken === token;
} }
export const IncorrectUserResponse: NextResponse<Ty.BackendResponse<null>> = NextResponse.json({ export const IncorrectUserResponse = async (token: string) : Promise<NextResponse<Ty.BackendResponse<Ty.UserNameRedirectArgs>>> => {
code: 105, return NextResponse.json({
message: '用户名与登录令牌不匹配', code: Auth.incorrectUserName,
data: null message: '用户名与登录令牌不匹配,将重定向到正确用户名。',
}); data: { user: await getUserNameByToken(token) }
\ No newline at end of file });
};
\ No newline at end of file
...@@ -15,14 +15,14 @@ interface RoomAddRes { ...@@ -15,14 +15,14 @@ interface RoomAddRes {
roomId: number; roomId: number;
} }
*/ */
export async function POST(req: NextRequest) { export async function POST(req: NextRequest) : Promise<NextResponse<Ty.BackendResponse<null | Ty.UserNameRedirectArgs | Ty.RoomAddResult>>> {
const cookieData = await Db.VerifyCookie(req.cookies); const cookieData = await Db.VerifyCookie(req.cookies);
if('code' in cookieData)return NextResponse.json(cookieData); if('code' in cookieData)return NextResponse.json(cookieData);
const { user, roomName }: Ty.RoomAddArgs = await req.json(); const { user, roomName }: Ty.RoomAddArgs = await req.json();
const checkResult = await Db.CheckUser(user, cookieData.userToken); const checkResult = await Db.CheckUser(user, cookieData.userToken);
if (!checkResult) return Db.IncorrectUserResponse; if (!checkResult) return Db.IncorrectUserResponse(cookieData.userToken);
const response = await Db.AddRoom({ user, roomName }); const response = await Db.AddRoom({ user, roomName });
return NextResponse.json(response); return NextResponse.json(response);
......
...@@ -13,14 +13,14 @@ interface RoomDeleteArgs { ...@@ -13,14 +13,14 @@ interface RoomDeleteArgs {
- response: null (只要code为0即为成功) - response: null (只要code为0即为成功)
*/ */
export async function POST(req: NextRequest): Promise<NextResponse<Ty.BackendResponse<null>>> { export async function POST(req: NextRequest): Promise<NextResponse<Ty.BackendResponse<null | Ty.UserNameRedirectArgs>>> {
const cookieData = await Db.VerifyCookie(req.cookies); const cookieData = await Db.VerifyCookie(req.cookies);
if('code' in cookieData) return NextResponse.json(cookieData); if('code' in cookieData) return NextResponse.json(cookieData);
const { user, roomId } = await req.json() as Ty.RoomDeleteArgs; const { user, roomId } = await req.json() as Ty.RoomDeleteArgs;
const checkResult = await Db.CheckUser(user, cookieData.userToken); const checkResult = await Db.CheckUser(user, cookieData.userToken);
if (!checkResult) return Db.IncorrectUserResponse; if (!checkResult) return Db.IncorrectUserResponse(cookieData.userToken);
const response = await Db.DeleteRoom({ user, roomId }, cookieData.userToken); const response = await Db.DeleteRoom({ user, roomId }, cookieData.userToken);
return NextResponse.json(response); return NextResponse.json(response);
......
...@@ -11,10 +11,10 @@ interface RoomListRes { ...@@ -11,10 +11,10 @@ interface RoomListRes {
rooms: RoomPreviewInfo[]; rooms: RoomPreviewInfo[];
} }
*/ */
export async function GET(req: NextRequest) : Promise<NextResponse<Ty.BackendResponse<Ty.RoomListRes | null>>> { export async function GET(req: NextRequest) : Promise<NextResponse<Ty.BackendResponse<Ty.RoomListResEx | null>>> {
const cookieData = await Db.VerifyCookie(req.cookies); const cookieData = await Db.VerifyCookie(req.cookies);
if('code' in cookieData) return NextResponse.json(cookieData); if('code' in cookieData) return NextResponse.json(cookieData);
const response = await Db.GetRoomList(); const response = await Db.GetRoomList(cookieData.userToken);
return NextResponse.json(response); return NextResponse.json(response);
} }
\ No newline at end of file
'use client' 'use client'
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useRoom } from './room-context' import { useRoom } from './room-context'
import { after } from 'node:test';
import { set } from 'zod';
export default function ConfirmModalProvider() { export default function ConfirmModalProvider() {
...@@ -11,6 +13,8 @@ export default function ConfirmModalProvider() { ...@@ -11,6 +13,8 @@ export default function ConfirmModalProvider() {
setNewRoomName, setNewRoomName,
showErrorModal, showErrorModal,
setShowErrorModal, setShowErrorModal,
afterErrorModalEvent,
setAfterErrorModalEvent,
errorModalMsg, errorModalMsg,
triggerCreateRoom } = useRoom(); triggerCreateRoom } = useRoom();
...@@ -20,6 +24,12 @@ export default function ConfirmModalProvider() { ...@@ -20,6 +24,12 @@ export default function ConfirmModalProvider() {
} }
}, [showCreateModal, setNewRoomName]); }, [showCreateModal, setNewRoomName]);
const clearErrorModal = () => {
setShowErrorModal(false);
afterErrorModalEvent?.();
setAfterErrorModalEvent(null);
}
return ( return (
<> <>
{showCreateModal && {showCreateModal &&
...@@ -58,7 +68,7 @@ export default function ConfirmModalProvider() { ...@@ -58,7 +68,7 @@ export default function ConfirmModalProvider() {
{showErrorModal && {showErrorModal &&
<div <div
className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 " className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 "
onClick={() => setShowErrorModal(false)} onClick={() => clearErrorModal()}
> >
<div <div
className="bg-white p-8 rounded shadow-lg min-w-[300px]" className="bg-white p-8 rounded shadow-lg min-w-[300px]"
...@@ -69,7 +79,7 @@ export default function ConfirmModalProvider() { ...@@ -69,7 +79,7 @@ export default function ConfirmModalProvider() {
<div className="flex justify-end space-x-2"> <div className="flex justify-end space-x-2">
<button <button
className="bg-gray-300 px-4 py-2 mt-2 rounded hover:bg-gray-400 active:bg-gray-500" className="bg-gray-300 px-4 py-2 mt-2 rounded hover:bg-gray-400 active:bg-gray-500"
onClick={() => setShowErrorModal(false)} onClick={() => clearErrorModal()}
> >
关闭 关闭
</button> </button>
......
'use client' 'use client'
import { createContext, useContext, useState, ReactNode, useEffect } from 'react' import { createContext, useContext, useState, ReactNode, useEffect } from 'react'
import * as Ty from './interface'
import { useRoom } from './room-context' import { useRoom } from './room-context'
export default function RoomHeaderProvider() { export default function RoomHeaderProvider() {
......
...@@ -2,16 +2,40 @@ ...@@ -2,16 +2,40 @@
import { useRoom } from './room-context' import { useRoom } from './room-context'
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import * as Ty from '../interface'
import * as Auth from '../api/login-interface'
export default function PageHeaderProvider() { export default function PageHeaderProvider() {
const { username } = useRoom(); const { username } = useRoom();
const router = useRouter(); const router = useRouter();
const logout = () => { const logout_Local = async () => {
/* 这段后面换成登录 */ try {
//URL : /api/auth/logout
//method: POST
const res = await fetch('/api/auth/logout', {
method: 'POST',
});
if (!res.ok) {
throw new Error('无法登出,错误码:' + res.status);
}
const data: Ty.BackendResponse<null> = await res.json();
if (data.code !== 0) {
throw new Error('无法登出,错误信息:' + data.message);
}
router.push('/'); router.push('/');
} catch (error) {
console.error('Logout failed:', error);
}
}; };
const logout_External = () => {
router.push('/');
};
const logout = Ty.useLocalBackend ? logout_Local : logout_External;
return ( return (
<header className="h-14 bg-white shadow flex items-center px-4 shrink-0"> <header className="h-14 bg-white shadow flex items-center px-4 shrink-0">
......
...@@ -14,6 +14,8 @@ interface RoomCtxValue { ...@@ -14,6 +14,8 @@ interface RoomCtxValue {
setShowCreateModal: (show: boolean) => void; setShowCreateModal: (show: boolean) => void;
showErrorModal: boolean; showErrorModal: boolean;
setShowErrorModal: (error: boolean) => void; setShowErrorModal: (error: boolean) => void;
afterErrorModalEvent: (() => void) | null;
setAfterErrorModalEvent: (event: (() => void) | null) => void;
errorModalMsg: string; errorModalMsg: string;
triggerErrorModal: (msg: string) => void; triggerErrorModal: (msg: string) => void;
newRoomName: string; newRoomName: string;
...@@ -26,7 +28,6 @@ const RoomContext = createContext<RoomCtxValue>({} as RoomCtxValue) ...@@ -26,7 +28,6 @@ const RoomContext = createContext<RoomCtxValue>({} as RoomCtxValue)
export function RoomProvider({ children }: { children: ReactNode }) { export function RoomProvider({ children }: { children: ReactNode }) {
/* 这段后面换成登录 */
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const userName = searchParams.get('username')?.trim() || ''; const userName = searchParams.get('username')?.trim() || '';
...@@ -38,6 +39,7 @@ export function RoomProvider({ children }: { children: ReactNode }) { ...@@ -38,6 +39,7 @@ export function RoomProvider({ children }: { children: ReactNode }) {
const [createRoomVersion, setCreateRoomVersion] = useState(0); const [createRoomVersion, setCreateRoomVersion] = useState(0);
const [showErrorModal, setShowErrorModal] = useState(false); const [showErrorModal, setShowErrorModal] = useState(false);
const [errorModalMsg, setErrorModalMsg] = useState(''); const [errorModalMsg, setErrorModalMsg] = useState('');
const [afterErrorModalEvent, setAfterErrorModalEvent] = useState<(() => void) | null>(null);
const triggerRefresh = useCallback(() => setMsgVersion(v => v + 1), []); const triggerRefresh = useCallback(() => setMsgVersion(v => v + 1), []);
const triggerCreateRoom = useCallback(() => setCreateRoomVersion(v => v + 1), []); const triggerCreateRoom = useCallback(() => setCreateRoomVersion(v => v + 1), []);
...@@ -58,6 +60,8 @@ export function RoomProvider({ children }: { children: ReactNode }) { ...@@ -58,6 +60,8 @@ export function RoomProvider({ children }: { children: ReactNode }) {
setShowCreateModal, setShowCreateModal,
showErrorModal, showErrorModal,
setShowErrorModal, setShowErrorModal,
afterErrorModalEvent,
setAfterErrorModalEvent,
errorModalMsg, errorModalMsg,
triggerErrorModal, triggerErrorModal,
newRoomName, newRoomName,
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import * as Ty from '../interface' import * as Ty from '../interface'
import { useRoom } from './room-context' import { useRoom } from './room-context'
import { notAuthorizedToDeleteRoomErrorCode } from '../api/login-interface' import { notAuthorizedToDeleteRoomErrorCode, incorrectUserName, reloginErrorCode } from '../api/login-interface'
export default function RoomListProvider() { export default function RoomListProvider() {
const [roomsLoading, setRoomsLoading] = useState<boolean>(false) const [roomsLoading, setRoomsLoading] = useState<boolean>(false)
const [roomsError, setRoomsError] = useState<string>('') const [roomsError, setRoomsError] = useState<string>('')
const [rooms, setRooms] = useState<Ty.RoomPreviewInfo[]>([]) const [rooms, setRooms] = useState<Ty.RoomPreviewInfoEx[]>([])
const { const {
username, username,
currentRoomInfo, currentRoomInfo,
...@@ -16,6 +16,7 @@ export default function RoomListProvider() { ...@@ -16,6 +16,7 @@ export default function RoomListProvider() {
msgVersion, msgVersion,
triggerRefresh, triggerRefresh,
setShowCreateModal, setShowCreateModal,
setAfterErrorModalEvent,
triggerErrorModal, triggerErrorModal,
createRoomVersion, createRoomVersion,
newRoomName, newRoomName,
...@@ -56,13 +57,33 @@ export default function RoomListProvider() { ...@@ -56,13 +57,33 @@ export default function RoomListProvider() {
throw new Error('创建房间失败,错误码:' + res.status); throw new Error('创建房间失败,错误码:' + res.status);
} }
const data: Ty.BackendResponse<Ty.RoomAddResult> = await res.json(); const data: Ty.BackendResponse<Ty.RoomAddResult | null | Ty.UserNameRedirectArgs> = await res.json();
if (data.code !== 0) { if (data.code !== 0) {
if(Ty.useLocalBackend)
{
if(data.code === incorrectUserName)
{
const redirectData = data.data as Ty.UserNameRedirectArgs;
if (redirectData.user) {
const userName = redirectData.user;
setAfterErrorModalEvent(() => () => {
window.location.href = `/chat?username=${encodeURIComponent(userName)}`;
});
}
} else if(data.code === reloginErrorCode)
{
setAfterErrorModalEvent(() => {
window.location.href = `/`;
});
}
}
throw new Error('创建房间失败,错误信息:' + data.message); throw new Error('创建房间失败,错误信息:' + data.message);
} }
return data.data.roomId; const roomData = data.data as Ty.RoomAddResult;
return roomData.roomId;
} catch (error) { } catch (error) {
console.error('创建房间失败:', error); console.error('创建房间失败:', error);
setRoomsError(error.message); setRoomsError(error.message);
...@@ -115,7 +136,7 @@ export default function RoomListProvider() { ...@@ -115,7 +136,7 @@ export default function RoomListProvider() {
throw new Error('删除房间失败,错误码:' + res.status); throw new Error('删除房间失败,错误码:' + res.status);
} }
const data: Ty.BackendResponse<null> = await res.json(); const data: Ty.BackendResponse<null | Ty.UserNameRedirectArgs> = await res.json();
/* /*
Error : You are not the creator. deletion failed. Error : You are not the creator. deletion failed.
...@@ -131,6 +152,24 @@ export default function RoomListProvider() { ...@@ -131,6 +152,24 @@ export default function RoomListProvider() {
return false; return false;
} }
else if (data.code !== 0) { else if (data.code !== 0) {
if(Ty.useLocalBackend)
{
if(data.code === incorrectUserName)
{
const redirectData = data.data as Ty.UserNameRedirectArgs;
if (redirectData.user) {
const userName = redirectData.user;
setAfterErrorModalEvent(() => () => {
window.location.href = `/chat?username=${encodeURIComponent(userName)}`;
});
}
} else if(data.code === reloginErrorCode)
{
setAfterErrorModalEvent(() => {
window.location.href = `/`;
});
}
}
throw new Error('删除房间失败,错误信息:' + data.message); throw new Error('删除房间失败,错误信息:' + data.message);
} }
...@@ -173,14 +212,26 @@ export default function RoomListProvider() { ...@@ -173,14 +212,26 @@ export default function RoomListProvider() {
throw new Error('无法获取房间列表,错误码:' + res.status); throw new Error('无法获取房间列表,错误码:' + res.status);
} }
const data: Ty.BackendResponse<Ty.RoomListRes> = await res.json(); if(Ty.useLocalBackend){
const data: Ty.BackendResponse<Ty.RoomListResEx> = await res.json();
if (data.code !== 0) { if (data.code !== 0) {
if(data.code === reloginErrorCode)
{
setAfterErrorModalEvent(() => {
window.location.href = `/`;
});
}
throw new Error('无法获取房间列表,错误信息:' + data.message); throw new Error('无法获取房间列表,错误信息:' + data.message);
} }
setRooms(data.data.rooms); setRooms(data.data.rooms);
} else {
const data: Ty.BackendResponse<Ty.RoomListRes> = await res.json();
if (data.code !== 0) {
throw new Error('无法获取房间列表,错误信息:' + data.message);
}
setRooms(data.data.rooms.map(r => ({...r, selfCreated: true})));
// 给的后端不支持 selfCreated 字段,全部设为 true
}
} catch (error) { } catch (error) {
console.error('房间列表获取失败:', error); console.error('房间列表获取失败:', error);
setRoomsError(error.message); setRoomsError(error.message);
...@@ -220,6 +271,7 @@ export default function RoomListProvider() { ...@@ -220,6 +271,7 @@ export default function RoomListProvider() {
{rooms && rooms.map((room) => ( {rooms && rooms.map((room) => (
<li key={room.roomId} className="relative"> <li key={room.roomId} className="relative">
<div className="bg-gray-200 p-4 mb-2 border-b border-gray-300 rounded w-full" onClick={() => handleRoomClick(room)}> <div className="bg-gray-200 p-4 mb-2 border-b border-gray-300 rounded w-full" onClick={() => handleRoomClick(room)}>
{room.selfCreated && (
<button <button
className=" className="
absolute top-1 right-1 absolute top-1 right-1
...@@ -236,7 +288,8 @@ export default function RoomListProvider() { ...@@ -236,7 +288,8 @@ export default function RoomListProvider() {
}} }}
> >
</button> </button>)
}
<h3>{room.roomName}</h3> <h3>{room.roomName}</h3>
{room.lastMessage ? ( {room.lastMessage ? (
<p>{room.lastMessage.sender}: {room.lastMessage.content}</p> <p>{room.lastMessage.sender}: {room.lastMessage.content}</p>
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
import { useState, useEffect, useRef, use } from 'react' import { useState, useEffect, useRef, use } from 'react'
import * as Ty from '../interface' import * as Ty from '../interface'
import { useRoom } from './room-context' import { useRoom } from './room-context'
import { reloginErrorCode } from '../api/login-interface'
export default function RoomMessageProvider() { export default function RoomMessageProvider() {
const { const {
currentRoomInfo, currentRoomInfo,
setAfterErrorModalEvent,
triggerErrorModal, triggerErrorModal,
msgVersion msgVersion
} = useRoom() } = useRoom()
...@@ -53,6 +55,12 @@ export default function RoomMessageProvider() { ...@@ -53,6 +55,12 @@ export default function RoomMessageProvider() {
const data: Ty.BackendResponse<Ty.RoomMessageListRes> = await res.json(); const data: Ty.BackendResponse<Ty.RoomMessageListRes> = await res.json();
if (data.code !== 0) { if (data.code !== 0) {
if(Ty.useLocalBackend && data.code === reloginErrorCode)
{
setAfterErrorModalEvent(() => {
window.location.href = `/`;
});
}
throw new Error('无法获取消息列表,错误信息:' + data.message); throw new Error('无法获取消息列表,错误信息:' + data.message);
} }
...@@ -104,6 +112,12 @@ export default function RoomMessageProvider() { ...@@ -104,6 +112,12 @@ export default function RoomMessageProvider() {
const data: Ty.BackendResponse<Ty.RoomMessageGetUpdateRes> = await res.json(); const data: Ty.BackendResponse<Ty.RoomMessageGetUpdateRes> = await res.json();
if (data.code !== 0) { if (data.code !== 0) {
if(Ty.useLocalBackend && data.code === reloginErrorCode)
{
setAfterErrorModalEvent(() => {
window.location.href = `/`;
});
}
throw new Error('无法更新消息列表,错误信息:' + data.message); throw new Error('无法更新消息列表,错误信息:' + data.message);
} }
......
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
import { useRoom } from './room-context' import { useRoom } from './room-context'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import * as Ty from '../interface' import * as Ty from '../interface'
import * as Auth from '../api/login-interface'
export default function SendMessageProvider() { export default function SendMessageProvider() {
const { const {
username, username,
currentRoomInfo, currentRoomInfo,
setAfterErrorModalEvent,
triggerErrorModal, triggerErrorModal,
triggerRefresh triggerRefresh
} = useRoom() } = useRoom()
...@@ -51,12 +53,30 @@ export default function SendMessageProvider() { ...@@ -51,12 +53,30 @@ export default function SendMessageProvider() {
body: JSON.stringify(Args) body: JSON.stringify(Args)
}); });
const data: Ty.BackendResponse<null> = await response.json(); const data: Ty.BackendResponse<null | Ty.UserNameRedirectArgs> = await response.json();
if (data.code === 0) { if (data.code === 0) {
setText(''); setText('');
triggerRefresh(); triggerRefresh();
} else { } else {
if(Ty.useLocalBackend)
{
if(data.code === Auth.incorrectUserName)
{
const redirectData = data.data as Ty.UserNameRedirectArgs;
if (redirectData.user) {
const userName = redirectData.user;
setAfterErrorModalEvent(() => {
window.location.href = `/chat?username=${encodeURIComponent(userName)}`;
});
}
} else if(data.code === Auth.reloginErrorCode)
{
setAfterErrorModalEvent(() => {
window.location.href = `/`;
});
}
}
throw new Error(`发送失败: ${data.message}`); throw new Error(`发送失败: ${data.message}`);
} }
} catch (error: any) { } catch (error: any) {
......
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { redirect } from 'next/navigation'; import { redirect } from 'next/navigation';
import { useRoom } from './room-context' import { useRoom } from './room-context'
import { useLocalBackend } from '../interface';
export default function UsernameCheck() { function UsernameCheck_External() {
const { username } = useRoom() const { username } = useRoom()
useEffect(() => { useEffect(() => {
if (!username) { if (!username) {
...@@ -16,3 +17,16 @@ export default function UsernameCheck() { ...@@ -16,3 +17,16 @@ export default function UsernameCheck() {
return null; return null;
} }
function UsernameCheck_Local() {
//URL /api/auth/logged
//TODO
return null;
}
const UsernameCheckFn = useLocalBackend ? UsernameCheck_Local : UsernameCheck_External;
export default function UsernameCheck() {
UsernameCheckFn();
return null;
}
\ No newline at end of file
...@@ -34,6 +34,10 @@ export interface RoomPreviewInfo { ...@@ -34,6 +34,10 @@ export interface RoomPreviewInfo {
lastMessage: Message | null; lastMessage: Message | null;
} }
export interface RoomPreviewInfoEx extends RoomPreviewInfo {
selfCreated: boolean;
}
export interface RoomAddArgs { export interface RoomAddArgs {
user: string; user: string;
roomName: string; roomName: string;
...@@ -47,6 +51,10 @@ export interface RoomListRes { ...@@ -47,6 +51,10 @@ export interface RoomListRes {
rooms: RoomPreviewInfo[]; rooms: RoomPreviewInfo[];
} }
export interface RoomListResEx {
rooms: RoomPreviewInfoEx[];
}
export interface RoomDeleteArgs { export interface RoomDeleteArgs {
user: string; user: string;
roomId: number; roomId: number;
...@@ -83,3 +91,7 @@ export interface RoomMessageGetUpdateArgs { ...@@ -83,3 +91,7 @@ export interface RoomMessageGetUpdateArgs {
export interface RoomMessageGetUpdateRes { export interface RoomMessageGetUpdateRes {
messages: Message[]; messages: Message[];
} }
export interface UserNameRedirectArgs {
user: string | null;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment