Compare commits

..

9 Commits

Author SHA1 Message Date
dayjoy
eb39f41f0c fix(server): 处理错误消息 2025-09-26 17:28:06 +08:00
dayjoy
a4ccdada1c fix(script): 修改server启动命令 2025-09-26 17:25:58 +08:00
dayjoy
d8a921b50a fix(server): 处理错误消息 2025-09-26 17:25:43 +08:00
dayjoy
a5048bafb3 fix(client): 获取token逻辑修正 2025-09-26 17:10:17 +08:00
dayjoy
999a8e2520 fix(client): 接口结果修正 2025-09-26 16:57:09 +08:00
dayjoy
b78a07f192 fix(client): 替换接口path 2025-09-26 16:46:38 +08:00
dayjoy
5688bb4242 fix(server): 接口path修改 2025-09-26 16:45:12 +08:00
dayjoy
b1530ce06e fix(server): 用户信息接口不返回token 2025-09-26 16:29:26 +08:00
dayjoy
f53aed1b82 fix(script): 修改server启动命令 2025-09-26 16:29:09 +08:00
8 changed files with 43 additions and 35 deletions

View File

@@ -6,9 +6,9 @@
], ],
"scripts": { "scripts": {
"start": "yarn start:all", "start": "yarn start:all",
"start:all": "concurrently -n 'client,server' 'yarn workspace egret-app-client dev' 'yarn workspace egret-app-server start'", "start:all": "concurrently -n 'client,server' 'yarn workspace egret-app-client dev' 'yarn workspace egret-app-server serve'",
"start:client": "yarn workspace egret-app-client dev", "start:client": "yarn workspace egret-app-client dev",
"start:server": "yarn workspace egret-app-server start", "start:server": "yarn workspace egret-app-server serve",
"build": "lerna run build && node ./scripts/post-build.js" "build": "lerna run build && node ./scripts/post-build.js"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -54,32 +54,38 @@ export const apiRequest = async <T = any>(
// 便捷的HTTP方法封装 // 便捷的HTTP方法封装
export const api = { export const api = {
get: <T = any>(endpoint: string, options?: RequestOptions): Promise<T> => get: <T = any>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>> =>
apiRequest<T>(endpoint, { ...options, method: 'GET' }), apiRequest<ApiResponse<T>>(endpoint, { ...options, method: 'GET' }),
post: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> => post: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<ApiResponse<T>> =>
apiRequest<T>(endpoint, { apiRequest<ApiResponse<T>>(endpoint, {
...options, ...options,
method: 'POST', method: 'POST',
body: data ? JSON.stringify(data) : undefined, body: data ? JSON.stringify(data) : undefined,
}), }),
put: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> => put: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<ApiResponse<T>> =>
apiRequest<T>(endpoint, { apiRequest<ApiResponse<T>>(endpoint, {
...options, ...options,
method: 'PUT', method: 'PUT',
body: data ? JSON.stringify(data) : undefined, body: data ? JSON.stringify(data) : undefined,
}), }),
patch: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> => patch: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<ApiResponse<T>> =>
apiRequest<T>(endpoint, { apiRequest<ApiResponse<T>>(endpoint, {
...options, ...options,
method: 'PATCH', method: 'PATCH',
body: data ? JSON.stringify(data) : undefined, body: data ? JSON.stringify(data) : undefined,
}), }),
delete: <T = any>(endpoint: string, options?: RequestOptions): Promise<T> => delete: <T = any>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>> =>
apiRequest<T>(endpoint, { ...options, method: 'DELETE' }), apiRequest<ApiResponse<T>>(endpoint, { ...options, method: 'DELETE' }),
}; };
export type ApiResponse<T> = {
code: number;
message: string;
data: T;
}
export default api; export default api;

View File

@@ -1,5 +1,4 @@
import api from "@/api/index.ts"; import api from "@/api/index.ts";
import {getGroupId} from "@/utils/auth.ts";
export type UserInfo = { export type UserInfo = {
userId: number; userId: number;
@@ -15,15 +14,15 @@ export type UserInfo = {
/** /**
* 获取当前用户的信息 * 获取当前用户的信息
*/ */
export const getUserInfo = async (): Promise<UserInfo> => { export const getUserInfo = async (): Promise<UserInfo | null> => {
return await api.post<UserInfo>('https://egret.byteawake.com/api/user/info'); const res = await api.get<UserInfo>('/api/user/info');
return res.code === 200 ? res.data : null;
}; };
/** /**
* 获取群组内所有用户的信息 * 获取群组内所有用户的信息
*/ */
export const getGroupUsers = async (): Promise<UserInfo[]> => { export const getGroupUsers = async (): Promise<UserInfo[]> => {
return await api.post<UserInfo[]>('https://egret.byteawake.com/api/group/members', { const res = await api.get<UserInfo[]>('/api/group/members');
groupId: Number(getGroupId()), return res.code === 200 ? res.data || [] : [];
});
}; };

View File

@@ -36,14 +36,16 @@ export const saveGroupId = (groupId: string): void => {
* 从localStorage获取authToken * 从localStorage获取authToken
*/ */
export const getAuthToken = (): string | null => { export const getAuthToken = (): string | null => {
return localStorage.getItem(AUTH_TOKEN_KEY); const tokenFromUrl = getAuthTokenFromUrl();
return tokenFromUrl || localStorage.getItem(AUTH_TOKEN_KEY);
}; };
/** /**
* 从localStorage获取groupId * 从localStorage获取groupId
*/ */
export const getGroupId = (): string | null => { export const getGroupId = (): string | null => {
return localStorage.getItem(GROUP_ID_KEY); const groupIdFromUrl = getGroupIdFromUrl();
return groupIdFromUrl || localStorage.getItem(GROUP_ID_KEY);
}; };
/** /**

View File

@@ -5,7 +5,7 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "tsoa -c tsoaConfig.json spec-and-routes && tsc && tsc-alias", "build": "tsoa -c tsoaConfig.json spec-and-routes && tsc && tsc-alias",
"serve": "node ./build/index.js", "serve": "yarn build && node ./build/index.js",
"start": "nodemon" "start": "nodemon"
}, },
"keywords": [], "keywords": [],

View File

@@ -4,7 +4,7 @@ import type {Request as ExpressRequest} from 'express';
import axios from "axios"; import axios from "axios";
import type {UserInfo} from "../types/user"; import type {UserInfo} from "../types/user";
export const getGroupUsers = async (groupId: number, token: string): Promise<UserInfo[]> => { export const getGroupMembers = async (groupId: number, token: string): Promise<UserInfo[]> => {
try { try {
const response = await axios.post<ApiResponse<UserInfo[]>>( const response = await axios.post<ApiResponse<UserInfo[]>>(
"https://egret.byteawake.com/api/group/members", "https://egret.byteawake.com/api/group/members",
@@ -18,20 +18,20 @@ export const getGroupUsers = async (groupId: number, token: string): Promise<Use
); );
if (response.data.code !== 200) { if (response.data.code !== 200) {
throw new Error(`Failed to get group users: ${response.data.message}`); throw new Error(response.data.message);
} }
return response.data.data ?? []; return response.data.data ?? [];
} catch (error: any) { } catch (error: any) {
if (error.response) { if (error.response) {
// API returned error response // API returned error response
throw new Error(`Failed to get user information: ${error.response.status} ${error.response.statusText}`); throw new ApiError(400, `Failed to get group members information: ${error.response.status} ${error.response.statusText}`);
} else if (error.request) { } else if (error.request) {
// Request was sent but no response received // Request was sent but no response received
throw new Error("Failed to get user information: timeout or network error"); throw new ApiError(400, "Failed to get group members information: timeout or network error");
} else { } else {
// Other errors // Other errors
throw new Error(`Failed to get user information: ${error.message}`); throw new ApiError(400, `Failed to get group members information: ${error.message}`);
} }
} }
}; };
@@ -44,12 +44,12 @@ export class GroupController extends Controller {
* @summary 获取当前聊天群组的全部用户信息 * @summary 获取当前聊天群组的全部用户信息
* @description 获取当前聊天群组的全部用户信息 * @description 获取当前聊天群组的全部用户信息
*/ */
@Get('/users') @Get('/members')
@Security("jwt") @Security("jwt")
@Response<ApiResponse<UserInfo[]>>(200, 'Success') @Response<ApiResponse<UserInfo[]>>(200, 'Success')
@Response<ApiResponse<null>>(400, 'Bad Request') @Response<ApiResponse<null>>(400, 'Bad Request')
@Response<ApiResponse<null>>(401, 'Unauthorized') @Response<ApiResponse<null>>(401, 'Unauthorized')
public async getGroupUsers(@Request() req: ExpressRequest): Promise<ApiResponse<UserInfo[]>> { public async getGroupMembers(@Request() req: ExpressRequest): Promise<ApiResponse<UserInfo[]>> {
const user = req.user; const user = req.user;
const groupId = req.headers.groupid; const groupId = req.headers.groupid;
@@ -57,7 +57,7 @@ export class GroupController extends Controller {
throw new ApiError(400, 'groupId is required in headers'); throw new ApiError(400, 'groupId is required in headers');
} }
const users = await getGroupUsers(Number(groupId), user.token); const users = await getGroupMembers(Number(groupId), user.token);
return { return {
code: 200, code: 200,

View File

@@ -16,11 +16,12 @@ export class UserController extends Controller {
@Security('jwt') @Security('jwt')
@Response<ApiResponse<UserInfo>>(200, 'Success') @Response<ApiResponse<UserInfo>>(200, 'Success')
@Response(401, 'Unauthorized') @Response(401, 'Unauthorized')
public async getUserGroupInfo(@Request() req: ExpressRequest): Promise<ApiResponse<UserInfo>> { public async getUserGroupInfo(@Request() req: ExpressRequest): Promise<ApiResponse<Omit<UserInfo, 'token'>>> {
const { token, ...rest } = req.user;
return { return {
code: 200, code: 200,
message: 'success', message: 'success',
data: req.user data: rest
}; };
} }
} }

View File

@@ -55,20 +55,20 @@ export const getUserInfoByToken = async (token: string): Promise<UserInfo> => {
); );
if (response.data.code !== 200 || !response.data.data) { if (response.data.code !== 200 || !response.data.data) {
throw new Error(`Failed to get user information: ${response.data.message}`); throw new Error(response.data.message);
} }
return {...response.data.data, token}; return {...response.data.data, token};
} catch (error: any) { } catch (error: any) {
if (error.response) { if (error.response) {
// API returned error response // API returned error response
throw new Error(`Failed to get user information: ${error.response.status} ${error.response.statusText}`); throw new ApiError(401, `Failed to get user information: ${error.response.status} ${error.response.statusText}`);
} else if (error.request) { } else if (error.request) {
// Request was sent but no response received // Request was sent but no response received
throw new Error("Failed to get user information: timeout or network error"); throw new ApiError(401, "Failed to get user information: timeout or network error");
} else { } else {
// Other errors // Other errors
throw new Error(`Failed to get user information: ${error.message}`); throw new ApiError(401, `Failed to get user information: ${error.message}`);
} }
} }
}; };