diff --git a/docs/openapi.json b/docs/openapi.json new file mode 100644 index 0000000..7ccb466 --- /dev/null +++ b/docs/openapi.json @@ -0,0 +1,480 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "WebGame 后端接口文档", + "version": "1.0.0", + "description": "WebGame 游戏后端 REST API 接口文档" + }, + "servers": [ + { + "url": "http://localhost:8080", + "description": "本地开发环境" + } + ], + "tags": [ + { "name": "账号", "description": "账号相关接口(登录、注册,无需认证)" }, + { "name": "用户", "description": "用户相关接口(需登录认证)" } + ], + "paths": { + "/account/login": { + "post": { + "tags": ["账号"], + "summary": "用户登录", + "description": "使用用户名和密码进行登录认证,成功返回 Sa-Token 令牌。该接口无需登录即可调用。", + "operationId": "login", + "security": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/LoginRequest" }, + "example": { + "username": "testuser", + "password": "123456" + } + } + } + }, + "responses": { + "200": { + "description": "登录成功,返回 token", + "content": { + "application/json": { + "schema": { + "allOf": [ + { "$ref": "#/components/schemas/ApiResponse" }, + { + "type": "object", + "properties": { + "data": { "$ref": "#/components/schemas/LoginResponse" } + } + } + ] + }, + "example": { + "code": 0, + "message": "success", + "data": { + "token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } + } + } + } + }, + "400": { "$ref": "#/components/responses/BadRequest" }, + "500": { "$ref": "#/components/responses/InternalError" } + } + } + }, + "/account/register": { + "post": { + "tags": ["账号"], + "summary": "用户注册", + "description": "注册新账号。用户名长度 3-32 位,密码长度 6-64 位。注册成功后自动登录并返回 token。该接口无需登录即可调用。", + "operationId": "register", + "security": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/RegisterRequest" }, + "example": { + "username": "newuser", + "password": "abc123" + } + } + } + }, + "responses": { + "200": { + "description": "注册成功,自动登录返回 token", + "content": { + "application/json": { + "schema": { + "allOf": [ + { "$ref": "#/components/schemas/ApiResponse" }, + { + "type": "object", + "properties": { + "data": { "$ref": "#/components/schemas/LoginResponse" } + } + } + ] + }, + "example": { + "code": 0, + "message": "success", + "data": { + "token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } + } + } + } + }, + "400": { "$ref": "#/components/responses/BadRequest" }, + "500": { "$ref": "#/components/responses/InternalError" } + } + } + }, + "/user/info": { + "get": { + "tags": ["用户"], + "summary": "获取当前登录用户信息", + "description": "根据请求头中的 saToken 获取当前登录用户的详细信息,包括昵称、头像、个性签名、年龄、性别、生日。需登录认证。", + "operationId": "getUserInfo", + "security": [{ "saToken": [] }], + "responses": { + "200": { + "description": "查询成功,返回用户信息", + "content": { + "application/json": { + "schema": { + "allOf": [ + { "$ref": "#/components/schemas/ApiResponse" }, + { + "type": "object", + "properties": { + "data": { "$ref": "#/components/schemas/UserInfoResponse" } + } + } + ] + }, + "example": { + "code": 0, + "message": "success", + "data": { + "nickName": "玩家001", + "avatar": "https://cdn.example.com/avatars/default.png", + "signature": "这个人很懒,什么都没写", + "age": 25, + "sex": 1, + "birthday": "2001-01-01" + } + } + } + } + }, + "401": { "$ref": "#/components/responses/Unauthorized" }, + "500": { "$ref": "#/components/responses/InternalError" } + } + } + } + }, + "components": { + "securitySchemes": { + "saToken": { + "type": "apiKey", + "in": "header", + "name": "saToken", + "description": "Sa-Token 认证令牌。登录/注册成功后返回的 token 值,在后续请求的 Header 中携带。" + } + }, + "schemas": { + "ApiResponse": { + "type": "object", + "description": "统一 API 响应信封。所有接口均使用此格式返回。", + "required": ["code", "message", "data"], + "properties": { + "code": { + "type": "integer", + "format": "int32", + "description": "业务状态码。0 表示成功,非 0 表示失败。详细错误码见 ErrorCode 枚举。" + }, + "message": { + "type": "string", + "description": "响应消息。成功时固定为 \"success\",失败时为具体错误描述。" + }, + "data": { + "nullable": true, + "description": "响应数据负载。成功时携带对应的业务数据对象,失败时为 null。" + } + } + }, + "LoginRequest": { + "type": "object", + "description": "登录请求体", + "required": ["username", "password"], + "properties": { + "username": { + "type": "string", + "description": "用户名,不能为空", + "minLength": 1, + "example": "testuser" + }, + "password": { + "type": "string", + "format": "password", + "description": "密码,不能为空", + "minLength": 1, + "example": "123456" + } + } + }, + "RegisterRequest": { + "type": "object", + "description": "注册请求体", + "required": ["username", "password"], + "properties": { + "username": { + "type": "string", + "description": "用户名,长度限制 3-32 位,不能为空", + "minLength": 3, + "maxLength": 32, + "example": "newuser" + }, + "password": { + "type": "string", + "format": "password", + "description": "密码,长度限制 6-64 位,不能为空", + "minLength": 6, + "maxLength": 64, + "example": "abc123" + } + } + }, + "LoginResponse": { + "type": "object", + "description": "登录或注册成功时返回的认证令牌", + "required": ["token"], + "properties": { + "token": { + "type": "string", + "description": "Sa-Token 认证令牌(UUID 格式)。后续请求需在 Header 中通过 saToken 字段携带此值。", + "example": "12345678-1234-1234-1234-123456789abc" + } + } + }, + "UserInfoResponse": { + "type": "object", + "description": "当前登录用户的详细信息", + "properties": { + "nickName": { + "type": "string", + "description": "用户昵称", + "maxLength": 16, + "example": "玩家001" + }, + "avatar": { + "type": "string", + "description": "头像图片 URL 地址,可能为 null", + "maxLength": 512, + "nullable": true, + "example": "https://cdn.example.com/avatars/default.png" + }, + "signature": { + "type": "string", + "description": "个性签名,可能为 null", + "maxLength": 64, + "nullable": true, + "example": "这个人很懒,什么都没写" + }, + "age": { + "type": "integer", + "format": "int32", + "description": "年龄,可能为 null", + "nullable": true, + "example": 25 + }, + "sex": { + "type": "integer", + "format": "int32", + "description": "性别。1=男,2=女,可能为 null", + "nullable": true, + "enum": [1, 2], + "x-enum-descriptions": { + "1": "男", + "2": "女" + }, + "example": 1 + }, + "birthday": { + "type": "string", + "format": "date", + "description": "生日(ISO 8601 日期格式),可能为 null", + "nullable": true, + "example": "2001-01-01" + } + } + }, + "ErrorResponse": { + "type": "object", + "description": "错误响应体模板。code 为具体错误码,message 为错误描述,data 恒为 null。", + "required": ["code", "message", "data"], + "properties": { + "code": { + "type": "integer", + "format": "int32", + "description": "错误码,详见 ErrorCode 枚举表" + }, + "message": { + "type": "string", + "description": "人类可读的错误描述信息" + }, + "data": { + "type": "null", + "description": "错误时恒为 null" + } + } + } + }, + "responses": { + "BadRequest": { + "description": "请求参数校验失败或业务逻辑错误(HTTP 200 但 code ≠ 0)", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" }, + "examples": { + "validation": { + "summary": "参数校验失败", + "value": { + "code": 400, + "message": "username 用户名不能为空; password 密码长度6-64位", + "data": null + } + }, + "usernameExists": { + "summary": "用户名已存在", + "value": { + "code": 1001, + "message": "用户名已存在", + "data": null + } + }, + "badCredentials": { + "summary": "用户名或密码错误", + "value": { + "code": 1002, + "message": "用户名或密码错误", + "data": null + } + }, + "userNotFound": { + "summary": "用户不存在", + "value": { + "code": 2001, + "message": "用户不存在", + "data": null + } + } + } + } + } + }, + "Unauthorized": { + "description": "未登录或 token 无效(HTTP 200 但 code=401)", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" }, + "example": { + "code": 401, + "message": "请先登录", + "data": null + } + } + } + }, + "Forbidden": { + "description": "无权限或无角色访问(HTTP 200 但 code=403)", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" }, + "example": { + "code": 403, + "message": "无权限", + "data": null + } + } + } + }, + "NotFound": { + "description": "请求的资源不存在", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" }, + "example": { + "code": 404, + "message": "资源不存在", + "data": null + } + } + } + }, + "MethodNotAllowed": { + "description": "请求方法不支持(如 GET 访问 POST 接口)", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" }, + "example": { + "code": 405, + "message": "请求方法不支持", + "data": null + } + } + } + }, + "InternalError": { + "description": "服务器内部错误(HTTP 200 但 code=5000)", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" }, + "example": { + "code": 5000, + "message": "服务器内部错误", + "data": null + } + } + } + } + }, + "x-enums": { + "ErrorCode": { + "description": "业务错误码枚举(com.webgame.webgamebackend.common.exception.ErrorCode)", + "values": { + "SUCCESS": { + "code": 0, + "message": "success", + "description": "操作成功" + }, + "BAD_REQUEST": { + "code": 400, + "message": "参数校验失败", + "description": "请求参数不符合校验规则" + }, + "USERNAME_EXISTS": { + "code": 1001, + "message": "用户名已存在", + "description": "注册时用户名已被占用" + }, + "BAD_CREDENTIALS": { + "code": 1002, + "message": "用户名或密码错误", + "description": "登录时用户名或密码不匹配" + }, + "USER_NOT_FOUND": { + "code": 2001, + "message": "用户不存在", + "description": "查询的用户记录不存在" + }, + "INTERNAL_ERROR": { + "code": 5000, + "message": "服务器内部错误", + "description": "未预期的服务器异常" + } + } + }, + "Sex": { + "description": "性别枚举(UserEntity.sex 字段)", + "values": { + "MALE": { + "code": 1, + "label": "男" + }, + "FEMALE": { + "code": 2, + "label": "女" + } + } + } + } + } +} \ No newline at end of file diff --git a/docs/prompt.txt b/docs/prompt.txt new file mode 100644 index 0000000..7f520df --- /dev/null +++ b/docs/prompt.txt @@ -0,0 +1,9 @@ +--- api接口文档提示词 --- +下面是后端提供的标准OpenAPI接口文档,你需要完成: +1. 生成统一axios请求封装; +2. 自动生成全部接口的TS类型定义; +3. 按模块拆分接口请求函数; +4. 严格遵循文档字段,不新增、不删减参数,区分必填/可选; +5. 按现有src/api/modules中的格式书写 +文档内容: +【粘贴后端OpenAPI文本】 \ No newline at end of file diff --git a/src/api/modules/account/index.ts b/src/api/modules/account/index.ts index fbe8e4b..870f4a4 100644 --- a/src/api/modules/account/index.ts +++ b/src/api/modules/account/index.ts @@ -1,12 +1,2 @@ -import { requestClient } from '@/api/request' - -/** 账户信息 */ -interface IAccountInfo { - id: number - username: string -} - -/** 获取账户信息 */ -function getAccountInfo() { - return requestClient.get('/account') -} +export * from './login.ts' +export * from './user.ts' diff --git a/src/api/modules/account/login.ts b/src/api/modules/account/login.ts new file mode 100644 index 0000000..6a84cb6 --- /dev/null +++ b/src/api/modules/account/login.ts @@ -0,0 +1,17 @@ +import { requestClient } from '@/api/request' + +/** 登录响应数据类型 */ +export interface ILoginResponse { + token: string +} + +/** 登录请求数据类型 */ +export interface ILoginRequest { + username: string + password: string +} + +/** 登录 */ +function login(req: ILoginRequest) { + return requestClient.post('/account', req) +} diff --git a/src/api/modules/account/user.ts b/src/api/modules/account/user.ts new file mode 100644 index 0000000..67f4987 --- /dev/null +++ b/src/api/modules/account/user.ts @@ -0,0 +1,12 @@ +import { requestClient } from '@/api/request' + +/** 账户信息 */ +export interface IUserInfo { + id: number + username: string +} + +/** 获取账户信息 */ +function getAccountInfo() { + return requestClient.get('/user/info') +}