Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
何 广一
chatroom
Commits
ce20f0d3
Commit
ce20f0d3
authored
Aug 26, 2025
by
何 广一
Browse files
fix local backend interaction
parent
fe1da4d0
Changes
18
Show whitespace changes
Inline
Side-by-side
chat-room/prisma/dev.db
View file @
ce20f0d3
No preview for this file type
chat-room/src/app/(loginpage)/auto-login.tsx
0 → 100644
View file @
ce20f0d3
'
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
chat-room/src/app/page.tsx
→
chat-room/src/app/
(loginpage)/
page.tsx
View file @
ce20f0d3
'
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
chat-room/src/app/api/login-interface.tsx
View file @
ce20f0d3
...
@@ -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
;
chat-room/src/app/api/message/add/route.tsx
View file @
ce20f0d3
...
@@ -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
);
...
...
chat-room/src/app/api/room-api.tsx
View file @
ce20f0d3
...
@@ -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
.
RoomListRes
Ex
|
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
.
RoomPreviewInfo
Ex
[]
=
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
chat-room/src/app/api/room/add/route.tsx
View file @
ce20f0d3
...
@@ -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
);
...
...
chat-room/src/app/api/room/delete/route.tsx
View file @
ce20f0d3
...
@@ -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
);
...
...
chat-room/src/app/api/room/list/route.tsx
View file @
ce20f0d3
...
@@ -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
.
RoomListRes
Ex
|
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
chat-room/src/app/chat/confirm-modal.tsx
View file @
ce20f0d3
'
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
=
{
()
=>
setShow
ErrorModal
(
false
)
}
onClick
=
{
()
=>
clear
ErrorModal
()
}
>
>
<
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
=
{
()
=>
setShow
ErrorModal
(
false
)
}
onClick
=
{
()
=>
clear
ErrorModal
()
}
>
>
关闭
关闭
</
button
>
</
button
>
...
...
chat-room/src/app/chat/current-room.tsx
View file @
ce20f0d3
'
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
()
{
...
...
chat-room/src/app/chat/header.tsx
View file @
ce20f0d3
...
@@ -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"
>
...
...
chat-room/src/app/chat/room-context.tsx
View file @
ce20f0d3
...
@@ -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
,
...
...
chat-room/src/app/chat/room-list.tsx
View file @
ce20f0d3
...
@@ -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
.
RoomPreviewInfo
Ex
[]
>
([])
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
>
...
...
chat-room/src/app/chat/room-message.tsx
View file @
ce20f0d3
...
@@ -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
);
}
}
...
...
chat-room/src/app/chat/send-message.tsx
View file @
ce20f0d3
...
@@ -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
)
{
...
...
chat-room/src/app/chat/username-check.tsx
View file @
ce20f0d3
...
@@ -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
chat-room/src/app/interface.tsx
View file @
ce20f0d3
...
@@ -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
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment