feat(interceptor): 添加APP端token验证接口并实现用户私有数据鉴权
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 31s
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 31s
refactor(api/user): 重构用户相关接口使用token验证替代user_id路径参数 docs: 更新API文档规范,明确私有接口需携带token及返回字段要求 fix(service/user): 避免写入未使用字段的零值导致MySQL校验错误 style: 统一格式化部分代码缩进和导入顺序 chore: 更新DS_Store等IDE配置文件
This commit is contained in:
parent
1ab39d2f5a
commit
42e7cb5f12
BIN
bindboxgame_api
Executable file
BIN
bindboxgame_api
Executable file
Binary file not shown.
BIN
docs/.DS_Store
vendored
Normal file
BIN
docs/.DS_Store
vendored
Normal file
Binary file not shown.
214
docs/docs.go
214
docs/docs.go
@ -1978,6 +1978,30 @@ const docTemplate = `{
|
||||
"name": "page_size",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "用户昵称",
|
||||
"name": "nickname",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "邀请码",
|
||||
"name": "inviteCode",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "开始日期(YYYY-MM-DD)",
|
||||
"name": "startDate",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "结束日期(YYYY-MM-DD)",
|
||||
"name": "endDate",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -3170,46 +3194,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/app/users/phone/login": {
|
||||
"post": {
|
||||
"description": "使用手机号登录,沿用 code 字段承载手机号或手机号授权码",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"APP端.用户"
|
||||
],
|
||||
"summary": "手机号登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "请求参数",
|
||||
"name": "RequestBody",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/app.phoneLoginRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/app.phoneLoginResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/code.Failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/app/users/weixin/login": {
|
||||
"post": {
|
||||
"description": "微信静默登录(需传递 code;可选 invite_code)",
|
||||
@ -3252,6 +3236,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "修改用户昵称与头像",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3299,6 +3288,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/coupons": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户持有的优惠券列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3353,6 +3347,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/invites": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看被该用户邀请的用户列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3407,6 +3406,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/item_cards": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "获取指定用户的道具卡列表,支持分页",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3469,6 +3473,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/item_cards/uses": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "获取指定用户的道具卡使用记录,支持分页",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3531,6 +3540,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/orders": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户抽奖来源订单记录",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3585,6 +3599,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/phone/bind": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "使用微信手机号 code 换取手机号并绑定到指定用户",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3632,6 +3651,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/points": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户积分流水记录",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3686,6 +3710,11 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/app/users/{user_id}/points/balance": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户积分余额(过滤过期积分)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -5430,6 +5459,32 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.couponItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"rules": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "integer"
|
||||
},
|
||||
"valid_end": {
|
||||
"type": "string"
|
||||
},
|
||||
"valid_start": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.drawLogItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -5573,7 +5628,7 @@ const docTemplate = `{
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.UserCoupons"
|
||||
"$ref": "#/definitions/app.couponItem"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
@ -5814,35 +5869,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.phoneLoginRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"description": "兼容参数名:这里作为手机号或第三方手机号code",
|
||||
"type": "string"
|
||||
},
|
||||
"invite_code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.phoneLoginResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"invite_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.pointsBalanceResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -5931,6 +5957,9 @@ const docTemplate = `{
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer"
|
||||
}
|
||||
@ -6234,51 +6263,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.UserCoupons": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"coupon_id": {
|
||||
"description": "券模板ID(system_coupons.id)",
|
||||
"type": "integer"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "创建时间",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"description": "状态:1未使用 2已使用 3已过期",
|
||||
"type": "integer"
|
||||
},
|
||||
"updated_at": {
|
||||
"description": "更新时间",
|
||||
"type": "string"
|
||||
},
|
||||
"used_at": {
|
||||
"description": "核销时间",
|
||||
"type": "string"
|
||||
},
|
||||
"used_order_id": {
|
||||
"description": "核销的订单ID(orders.id)",
|
||||
"type": "integer"
|
||||
},
|
||||
"user_id": {
|
||||
"description": "用户ID(user_members.id)",
|
||||
"type": "integer"
|
||||
},
|
||||
"valid_end": {
|
||||
"description": "有效期结束",
|
||||
"type": "string"
|
||||
},
|
||||
"valid_start": {
|
||||
"description": "有效期开始",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.UserItemCards": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@ -1970,6 +1970,30 @@
|
||||
"name": "page_size",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "用户昵称",
|
||||
"name": "nickname",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "邀请码",
|
||||
"name": "inviteCode",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "开始日期(YYYY-MM-DD)",
|
||||
"name": "startDate",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "结束日期(YYYY-MM-DD)",
|
||||
"name": "endDate",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -3162,46 +3186,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/app/users/phone/login": {
|
||||
"post": {
|
||||
"description": "使用手机号登录,沿用 code 字段承载手机号或手机号授权码",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"APP端.用户"
|
||||
],
|
||||
"summary": "手机号登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "请求参数",
|
||||
"name": "RequestBody",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/app.phoneLoginRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/app.phoneLoginResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/code.Failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/app/users/weixin/login": {
|
||||
"post": {
|
||||
"description": "微信静默登录(需传递 code;可选 invite_code)",
|
||||
@ -3244,6 +3228,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "修改用户昵称与头像",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3291,6 +3280,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/coupons": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户持有的优惠券列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3345,6 +3339,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/invites": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看被该用户邀请的用户列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3399,6 +3398,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/item_cards": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "获取指定用户的道具卡列表,支持分页",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3461,6 +3465,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/item_cards/uses": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "获取指定用户的道具卡使用记录,支持分页",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3523,6 +3532,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/orders": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户抽奖来源订单记录",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3577,6 +3591,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/phone/bind": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "使用微信手机号 code 换取手机号并绑定到指定用户",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3624,6 +3643,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/points": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户积分流水记录",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -3678,6 +3702,11 @@
|
||||
},
|
||||
"/api/app/users/{user_id}/points/balance": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "查看用户积分余额(过滤过期积分)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
@ -5422,6 +5451,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.couponItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"rules": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "integer"
|
||||
},
|
||||
"valid_end": {
|
||||
"type": "string"
|
||||
},
|
||||
"valid_start": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.drawLogItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -5565,7 +5620,7 @@
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.UserCoupons"
|
||||
"$ref": "#/definitions/app.couponItem"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
@ -5806,35 +5861,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.phoneLoginRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"description": "兼容参数名:这里作为手机号或第三方手机号code",
|
||||
"type": "string"
|
||||
},
|
||||
"invite_code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.phoneLoginResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"invite_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.pointsBalanceResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -5923,6 +5949,9 @@
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer"
|
||||
}
|
||||
@ -6226,51 +6255,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.UserCoupons": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"coupon_id": {
|
||||
"description": "券模板ID(system_coupons.id)",
|
||||
"type": "integer"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "创建时间",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "主键ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"description": "状态:1未使用 2已使用 3已过期",
|
||||
"type": "integer"
|
||||
},
|
||||
"updated_at": {
|
||||
"description": "更新时间",
|
||||
"type": "string"
|
||||
},
|
||||
"used_at": {
|
||||
"description": "核销时间",
|
||||
"type": "string"
|
||||
},
|
||||
"used_order_id": {
|
||||
"description": "核销的订单ID(orders.id)",
|
||||
"type": "integer"
|
||||
},
|
||||
"user_id": {
|
||||
"description": "用户ID(user_members.id)",
|
||||
"type": "integer"
|
||||
},
|
||||
"valid_end": {
|
||||
"description": "有效期结束",
|
||||
"type": "string"
|
||||
},
|
||||
"valid_start": {
|
||||
"description": "有效期开始",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.UserItemCards": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@ -1044,6 +1044,23 @@ definitions:
|
||||
success:
|
||||
type: boolean
|
||||
type: object
|
||||
app.couponItem:
|
||||
properties:
|
||||
amount:
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
rules:
|
||||
type: string
|
||||
status:
|
||||
type: integer
|
||||
valid_end:
|
||||
type: string
|
||||
valid_start:
|
||||
type: string
|
||||
type: object
|
||||
app.drawLogItem:
|
||||
properties:
|
||||
current_level:
|
||||
@ -1137,7 +1154,7 @@ definitions:
|
||||
properties:
|
||||
list:
|
||||
items:
|
||||
$ref: '#/definitions/model.UserCoupons'
|
||||
$ref: '#/definitions/app.couponItem'
|
||||
type: array
|
||||
page:
|
||||
type: integer
|
||||
@ -1293,25 +1310,6 @@ definitions:
|
||||
user:
|
||||
$ref: '#/definitions/app.userItem'
|
||||
type: object
|
||||
app.phoneLoginRequest:
|
||||
properties:
|
||||
code:
|
||||
description: 兼容参数名:这里作为手机号或第三方手机号code
|
||||
type: string
|
||||
invite_code:
|
||||
type: string
|
||||
type: object
|
||||
app.phoneLoginResponse:
|
||||
properties:
|
||||
avatar:
|
||||
type: string
|
||||
invite_code:
|
||||
type: string
|
||||
nickname:
|
||||
type: string
|
||||
user_id:
|
||||
type: integer
|
||||
type: object
|
||||
app.pointsBalanceResponse:
|
||||
properties:
|
||||
balance:
|
||||
@ -1369,6 +1367,8 @@ definitions:
|
||||
type: string
|
||||
nickname:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
user_id:
|
||||
type: integer
|
||||
type: object
|
||||
@ -1591,39 +1591,6 @@ definitions:
|
||||
description: 下单用户ID(user_members.id)
|
||||
type: integer
|
||||
type: object
|
||||
model.UserCoupons:
|
||||
properties:
|
||||
coupon_id:
|
||||
description: 券模板ID(system_coupons.id)
|
||||
type: integer
|
||||
created_at:
|
||||
description: 创建时间
|
||||
type: string
|
||||
id:
|
||||
description: 主键ID
|
||||
type: integer
|
||||
status:
|
||||
description: 状态:1未使用 2已使用 3已过期
|
||||
type: integer
|
||||
updated_at:
|
||||
description: 更新时间
|
||||
type: string
|
||||
used_at:
|
||||
description: 核销时间
|
||||
type: string
|
||||
used_order_id:
|
||||
description: 核销的订单ID(orders.id)
|
||||
type: integer
|
||||
user_id:
|
||||
description: 用户ID(user_members.id)
|
||||
type: integer
|
||||
valid_end:
|
||||
description: 有效期结束
|
||||
type: string
|
||||
valid_start:
|
||||
description: 有效期开始
|
||||
type: string
|
||||
type: object
|
||||
model.UserItemCards:
|
||||
properties:
|
||||
card_id:
|
||||
@ -3083,6 +3050,22 @@ paths:
|
||||
name: page_size
|
||||
required: true
|
||||
type: integer
|
||||
- description: 用户昵称
|
||||
in: query
|
||||
name: nickname
|
||||
type: string
|
||||
- description: 邀请码
|
||||
in: query
|
||||
name: inviteCode
|
||||
type: string
|
||||
- description: 开始日期(YYYY-MM-DD)
|
||||
in: query
|
||||
name: startDate
|
||||
type: string
|
||||
- description: 结束日期(YYYY-MM-DD)
|
||||
in: query
|
||||
name: endDate
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
@ -3871,6 +3854,8 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 修改用户信息
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -3908,6 +3893,8 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 查看用户优惠券
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -3945,6 +3932,8 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 查看用户邀请记录
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -3986,6 +3975,8 @@ paths:
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 获取用户道具卡列表
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -4027,6 +4018,8 @@ paths:
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 获取用户道具卡使用记录
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -4064,6 +4057,8 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 查看用户订单记录
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -4095,6 +4090,8 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 绑定手机号
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -4132,6 +4129,8 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 查看用户积分记录
|
||||
tags:
|
||||
- APP端.用户
|
||||
@ -4157,35 +4156,11 @@ paths:
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 查看用户积分余额
|
||||
tags:
|
||||
- APP端.用户
|
||||
/api/app/users/phone/login:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用手机号登录,沿用 code 字段承载手机号或手机号授权码
|
||||
parameters:
|
||||
- description: 请求参数
|
||||
in: body
|
||||
name: RequestBody
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/app.phoneLoginRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/app.phoneLoginResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
summary: 手机号登录
|
||||
tags:
|
||||
- APP端.用户
|
||||
/api/app/users/weixin/login:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
@ -21,6 +21,20 @@
|
||||
- 所有接口必须定义 `Request` 与 `Response` 结构体
|
||||
- 成功统一:`ctx.Payload(res)`,`res.Message` 使用统一文案 `操作成功`
|
||||
|
||||
### 4.1 认证与鉴权(强制)
|
||||
- 所有“用户私有数据”接口必须携带请求头 `Authorization: <token>`(微信登录返回的令牌),后端基于令牌解析当前用户。
|
||||
- 路径中的 `user_id` 为 REST 占位参数,后端不使用该值进行身份识别;实际的用户身份以令牌为准,禁止越权访问他人数据。
|
||||
- 未携带或令牌无效时返回 `401` 与业务码 `JWTAuthVerifyError`。
|
||||
|
||||
### 4.2 统一返回字段(示例:优惠券)
|
||||
- 优惠券列表返回 `list` 中的元素为:
|
||||
- `id`:持券记录ID
|
||||
- `name`:优惠券名称
|
||||
- `amount`:优惠面值(分;折扣为千分比已转百分比文案)
|
||||
- `valid_start`/`valid_end`:有效期(`yyyy-MM-dd HH:mm:ss`)
|
||||
- `status`:状态(1未使用 2已使用 3已过期)
|
||||
- `rules`:使用规则说明(直减/满减/折扣)
|
||||
|
||||
## 5. 参数绑定与校验
|
||||
- JSON:`ctx.ShouldBindJSON(req)`
|
||||
- 表单/查询:`ctx.ShouldBindForm(req)`
|
||||
@ -44,6 +58,8 @@
|
||||
## 10. Swagger 注释规范
|
||||
- 标签:APP 端统一使用 `@Tags APP端.活动`(或模块名)
|
||||
- 必填注释:`@Summary/@Description/@Accept/@Produce/@Param/@Success/@Failure/@Router`
|
||||
- 安全注释:用户私有接口必须添加 `@Security LoginVerifyToken`
|
||||
- `user_id` 参数文档需注明“占位,不参与鉴权,按令牌解析用户”,示例:`@Param user_id path integer true "用户ID(占位,按令牌解析)"`
|
||||
|
||||
## 11. 统一 Handler 模板(示例)
|
||||
以下示例来自 `internal/api/activity/activity_issues_list.go:46-127`,作为 APP 端列表接口标准参考:
|
||||
@ -143,4 +159,5 @@ func (h *handler) ListActivityIssues() core.HandlerFunc {
|
||||
## 12. 文档生成与预览
|
||||
- 生成:`make gen-swagger`
|
||||
- 预览:`make serve-swagger`(默认端口 `36666`,访问 `http://localhost:36666/docs`)
|
||||
- 预览时在右上角 `Authorize` 设置 `Authorization` 值,接口将自动附带令牌进行校验
|
||||
|
||||
|
||||
19
docs/需求文档.md
19
docs/需求文档.md
@ -148,3 +148,22 @@
|
||||
1.8 查看商品列表: /api/admin/products
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@6A 现在有以下问题需要修改
|
||||
1. 用户查看自己的优惠券 接口有问题: 'http://127.0.0.1:9991/api/app/users/12/coupons?page=1&page_size=20' 这里不应该用 user_id 来查询; 应该用 token 来查询; 因为用户可以查看自己的优惠券, 但是其他用户不能查看; 所以这里应该用 token 来查询;
|
||||
2. 优惠券返回的信息中; 应该包含 优惠券的名称, 优惠券的金额, 优惠券的有效期, 优惠券的使用规则;
|
||||
3. 用户邀请记录也是 接口有问题: 'http://127.0.0.1:9991/api/app/users/12/invites?page=1&page_size=20' 这里不应该用 user_id 来查询; 应该用 token 来查询; 因为用户可以查看自己的邀请记录, 但是其他用户不能查看; 所以这里应该用 token 来查询;
|
||||
4. 其他的 接口都存在这个问题 修复一下
|
||||
|
||||
|
||||
仪表盘数据分析:
|
||||
1. 总访问次数 在线访客数 点击量 新用户 : 这一块我想改成:道具卡销量 / 活动抽奖次数 / 新用户注册数 用户总积分
|
||||
|
||||
|
||||
|
||||
2. 用户概述: 想统计出 用户增长趋势 访问量: 改成活动抽奖量统计
|
||||
3. 新用户:这里面可以放用户 积分 资产等数据
|
||||
4. 动态: 显示实时抽奖数据
|
||||
5. 代办事项: 显示用户需要完成的任务; 比如 绑定手机号 绑定邮箱 绑定工会
|
||||
|
||||
@ -76,11 +76,20 @@ func (h *handler) ListUsers() core.HandlerFunc {
|
||||
q = q.Where(h.readDB.Admin.Username.Like("%" + req.UserName + "%"))
|
||||
}
|
||||
if req.UserEmail != "" {
|
||||
// 注意:Admin模型没有邮箱字段,这里用昵称字段来支持搜索
|
||||
q = q.Where(h.readDB.Admin.Nickname.Like("%" + req.UserEmail + "%"))
|
||||
}
|
||||
if req.UserPhone != "" {
|
||||
q = q.Where(h.readDB.Admin.Mobile.Like("%" + req.UserPhone + "%"))
|
||||
}
|
||||
if req.Status != "" {
|
||||
// 状态筛选:1-正常 0-禁用
|
||||
if req.Status == "1" || req.Status == "正常" {
|
||||
q = q.Where(h.readDB.Admin.LoginStatus.Eq(1))
|
||||
} else if req.Status == "0" || req.Status == "禁用" {
|
||||
q = q.Where(h.readDB.Admin.LoginStatus.Eq(0))
|
||||
}
|
||||
}
|
||||
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
|
||||
@ -13,8 +13,12 @@ import (
|
||||
)
|
||||
|
||||
type listUsersRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
Nickname string `form:"nickname"`
|
||||
InviteCode string `form:"inviteCode"`
|
||||
StartDate string `form:"startDate"`
|
||||
EndDate string `form:"endDate"`
|
||||
}
|
||||
type listUsersResponse struct {
|
||||
Page int `json:"page"`
|
||||
@ -31,6 +35,10 @@ type listUsersResponse struct {
|
||||
// @Produce json
|
||||
// @Param page query int true "页码" default(1)
|
||||
// @Param page_size query int true "每页数量,最多100" default(20)
|
||||
// @Param nickname query string false "用户昵称"
|
||||
// @Param inviteCode query string false "邀请码"
|
||||
// @Param startDate query string false "开始日期(YYYY-MM-DD)"
|
||||
// @Param endDate query string false "结束日期(YYYY-MM-DD)"
|
||||
// @Success 200 {object} listUsersResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/users [get]
|
||||
@ -53,6 +61,27 @@ func (h *handler) ListAppUsers() core.HandlerFunc {
|
||||
req.PageSize = 100
|
||||
}
|
||||
q := h.readDB.Users.WithContext(ctx.RequestContext()).ReadDB()
|
||||
|
||||
// 应用搜索条件
|
||||
if req.Nickname != "" {
|
||||
q = q.Where(h.readDB.Users.Nickname.Like("%" + req.Nickname + "%"))
|
||||
}
|
||||
if req.InviteCode != "" {
|
||||
q = q.Where(h.readDB.Users.InviteCode.Eq(req.InviteCode))
|
||||
}
|
||||
if req.StartDate != "" {
|
||||
if startTime, err := time.Parse("2006-01-02", req.StartDate); err == nil {
|
||||
q = q.Where(h.readDB.Users.CreatedAt.Gte(startTime))
|
||||
}
|
||||
}
|
||||
if req.EndDate != "" {
|
||||
if endTime, err := time.Parse("2006-01-02", req.EndDate); err == nil {
|
||||
// 设置结束时间为当天的23:59:59
|
||||
endTime = endTime.Add(24 * time.Hour).Add(-time.Second)
|
||||
q = q.Where(h.readDB.Users.CreatedAt.Lte(endTime))
|
||||
}
|
||||
}
|
||||
|
||||
total, err := q.Count()
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 20101, err.Error()))
|
||||
@ -227,6 +256,57 @@ func (h *handler) ListUserInventory() core.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
type listUserItemCardsRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
}
|
||||
|
||||
type listUserItemCardsResponse struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
Total int64 `json:"total"`
|
||||
List []*user.ItemCardWithTemplate `json:"list"`
|
||||
}
|
||||
|
||||
// ListUserItemCards 查看用户道具卡列表
|
||||
// @Summary 查看用户道具卡列表
|
||||
// @Description 查看指定用户的道具卡持有记录
|
||||
// @Tags 管理端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param page query int true "页码" default(1)
|
||||
// @Param page_size query int true "每页数量,最多100" default(20)
|
||||
// @Success 200 {object} listUserItemCardsResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/users/{user_id}/item_cards [get]
|
||||
// @Security LoginVerifyToken
|
||||
func (h *handler) ListUserItemCards() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(listUserItemCardsRequest)
|
||||
rsp := new(listUserItemCardsResponse)
|
||||
if err := ctx.ShouldBindForm(req); err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
items, total, err := h.user.ListUserItemCardsWithTemplate(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 20106, err.Error()))
|
||||
return
|
||||
}
|
||||
rsp.Page = req.Page
|
||||
rsp.PageSize = req.PageSize
|
||||
rsp.Total = total
|
||||
rsp.List = items
|
||||
ctx.Payload(rsp)
|
||||
}
|
||||
}
|
||||
|
||||
type listCouponsRequest struct {
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
)
|
||||
|
||||
type listCouponsRequest struct {
|
||||
@ -15,10 +15,20 @@ type listCouponsRequest struct {
|
||||
PageSize int `form:"page_size"`
|
||||
}
|
||||
type listCouponsResponse struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
Total int64 `json:"total"`
|
||||
List []*model.UserCoupons `json:"list"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
Total int64 `json:"total"`
|
||||
List []couponItem `json:"list"`
|
||||
}
|
||||
|
||||
type couponItem struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Amount int64 `json:"amount"`
|
||||
ValidStart string `json:"valid_start"`
|
||||
ValidEnd string `json:"valid_end"`
|
||||
Status int32 `json:"status"`
|
||||
Rules string `json:"rules"`
|
||||
}
|
||||
|
||||
// ListUserCoupons 查看用户优惠券
|
||||
@ -27,7 +37,8 @@ type listCouponsResponse struct {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param page query int true "页码" default(1)
|
||||
// @Param page_size query int true "每页数量,最多100" default(20)
|
||||
// @Success 200 {object} listCouponsResponse
|
||||
@ -41,20 +52,70 @@ func (h *handler) ListUserCoupons() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
items, total, err := h.user.ListCoupons(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10003, err.Error()))
|
||||
return
|
||||
}
|
||||
rsp.Page = req.Page
|
||||
rsp.PageSize = req.PageSize
|
||||
rsp.Total = total
|
||||
rsp.List = items
|
||||
ctx.Payload(rsp)
|
||||
}
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
items, total, err := h.user.ListCoupons(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10003, err.Error()))
|
||||
return
|
||||
}
|
||||
rsp.Page = req.Page
|
||||
rsp.PageSize = req.PageSize
|
||||
rsp.Total = total
|
||||
if len(items) == 0 {
|
||||
rsp.List = []couponItem{}
|
||||
ctx.Payload(rsp)
|
||||
return
|
||||
}
|
||||
ids := make([]int64, 0, len(items))
|
||||
for _, it := range items {
|
||||
ids = append(ids, it.CouponID)
|
||||
}
|
||||
rows, err := h.readDB.SystemCoupons.WithContext(ctx.RequestContext()).Where(h.readDB.SystemCoupons.ID.In(ids...)).Find()
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10003, err.Error()))
|
||||
return
|
||||
}
|
||||
mp := make(map[int64]*model.SystemCoupons, len(rows))
|
||||
for i := range rows {
|
||||
c := rows[i]
|
||||
mp[c.ID] = c
|
||||
}
|
||||
rsp.List = make([]couponItem, 0, len(items))
|
||||
for _, it := range items {
|
||||
sc := mp[it.CouponID]
|
||||
name := ""
|
||||
amount := int64(0)
|
||||
rules := ""
|
||||
if sc != nil {
|
||||
name = sc.Name
|
||||
amount = sc.DiscountValue
|
||||
rules = buildCouponRules(sc)
|
||||
}
|
||||
vi := couponItem{
|
||||
ID: it.ID,
|
||||
Name: name,
|
||||
Amount: amount,
|
||||
ValidStart: it.ValidStart.Format("2006-01-02 15:04:05"),
|
||||
ValidEnd: it.ValidEnd.Format("2006-01-02 15:04:05"),
|
||||
Status: it.Status,
|
||||
Rules: rules,
|
||||
}
|
||||
rsp.List = append(rsp.List, vi)
|
||||
}
|
||||
ctx.Payload(rsp)
|
||||
}
|
||||
}
|
||||
|
||||
func buildCouponRules(c *model.SystemCoupons) string {
|
||||
switch c.DiscountType {
|
||||
case 1:
|
||||
return fmt.Sprintf("直减%v分,满%v分可用", c.DiscountValue, c.MinSpend)
|
||||
case 2:
|
||||
return fmt.Sprintf("满%v分减%v分", c.MinSpend, c.DiscountValue)
|
||||
case 3:
|
||||
p := float64(c.DiscountValue) / 10.0
|
||||
return fmt.Sprintf("折扣%0.1f%%,满%v分可用", p, c.MinSpend)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
)
|
||||
|
||||
type listInvitesRequest struct {
|
||||
@ -32,7 +31,8 @@ type listInvitesResponse struct {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param page query int true "页码" default(1)
|
||||
// @Param page_size query int true "每页数量,最多100" default(20)
|
||||
// @Success 200 {object} listInvitesResponse
|
||||
@ -46,12 +46,8 @@ func (h *handler) ListUserInvites() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
items, total, err := h.user.ListInvites(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
items, total, err := h.user.ListInvites(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10007, err.Error()))
|
||||
return
|
||||
|
||||
@ -2,7 +2,6 @@ package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
@ -29,6 +28,7 @@ type listUserItemCardsResponse struct {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param page query integer false "页码,默认1"
|
||||
// @Param page_size query integer false "每页条数,默认10"
|
||||
// @Success 200 {object} listUserItemCardsResponse
|
||||
@ -44,11 +44,7 @@ func (h *handler) ListUserItemCards() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
items, total, err := h.user.ListUserItemCards(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10008, err.Error()))
|
||||
@ -81,6 +77,7 @@ type listUserItemCardUsesResponse struct {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param page query integer false "页码,默认1"
|
||||
// @Param page_size query integer false "每页条数,默认10"
|
||||
// @Success 200 {object} listUserItemCardUsesResponse
|
||||
@ -96,11 +93,7 @@ func (h *handler) ListUserItemCardUses() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
items, total, err := h.user.ListUserItemCardUses(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10009, err.Error()))
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
)
|
||||
|
||||
type listOrdersRequest struct {
|
||||
@ -27,7 +26,8 @@ type listOrdersResponse struct {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param page query int true "页码" default(1)
|
||||
// @Param page_size query int true "每页数量,最多100" default(20)
|
||||
// @Success 200 {object} listOrdersResponse
|
||||
@ -41,12 +41,8 @@ func (h *handler) ListUserOrders() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
items, total, err := h.user.ListOrders(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
items, total, err := h.user.ListOrders(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10002, err.Error()))
|
||||
return
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/configs"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/miniprogram"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/pkg/wechat"
|
||||
"bindbox-game/configs"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/miniprogram"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/pkg/wechat"
|
||||
)
|
||||
|
||||
type bindPhoneRequest struct {
|
||||
@ -27,7 +26,8 @@ type bindPhoneResponse struct {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param RequestBody body bindPhoneRequest true "请求参数"
|
||||
// @Success 200 {object} bindPhoneResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
@ -40,12 +40,11 @@ func (h *handler) BindPhone() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
uidStr := ctx.Param("user_id")
|
||||
userID, _ := strconv.ParseInt(uidStr, 10, 64)
|
||||
if userID <= 0 || req.Code == "" {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "缺少必要参数"))
|
||||
return
|
||||
}
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
if userID <= 0 || req.Code == "" {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "缺少必要参数"))
|
||||
return
|
||||
}
|
||||
|
||||
cfg := configs.Get()
|
||||
var tokenRes struct {
|
||||
@ -66,10 +65,10 @@ func (h *handler) BindPhone() core.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := h.writeDB.Users.WithContext(ctx.RequestContext()).Where(h.writeDB.Users.ID.Eq(userID)).Updates(map[string]any{"mobile": mobile}); err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
||||
return
|
||||
}
|
||||
if _, err := h.writeDB.Users.WithContext(ctx.RequestContext()).Where(h.writeDB.Users.ID.Eq(userID)).Updates(map[string]any{"mobile": mobile}); err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
||||
return
|
||||
}
|
||||
rsp.Success = true
|
||||
rsp.Mobile = mobile
|
||||
ctx.Payload(rsp)
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
)
|
||||
|
||||
type listPointsRequest struct {
|
||||
@ -30,7 +29,8 @@ type pointsBalanceResponse struct {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param page query int true "页码" default(1)
|
||||
// @Param page_size query int true "每页数量,最多100" default(20)
|
||||
// @Success 200 {object} listPointsResponse
|
||||
@ -44,12 +44,8 @@ func (h *handler) ListUserPoints() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
items, total, err := h.user.ListPointsLedger(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
items, total, err := h.user.ListPointsLedger(ctx.RequestContext(), userID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10004, err.Error()))
|
||||
return
|
||||
@ -68,19 +64,16 @@ func (h *handler) ListUserPoints() core.HandlerFunc {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Success 200 {object} pointsBalanceResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/app/users/{user_id}/points/balance [get]
|
||||
func (h *handler) GetUserPointsBalance() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
rsp := new(pointsBalanceResponse)
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
total, err := h.user.GetPointsBalance(ctx.RequestContext(), userID)
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
total, err := h.user.GetPointsBalance(ctx.RequestContext(), userID)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10005, err.Error()))
|
||||
return
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/validation"
|
||||
)
|
||||
|
||||
type modifyUserRequest struct {
|
||||
@ -30,7 +29,8 @@ type modifyUserResponse struct {
|
||||
// @Tags APP端.用户
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Param user_id path integer true "用户ID"
|
||||
// @Security LoginVerifyToken
|
||||
// @Param RequestBody body modifyUserRequest true "请求参数"
|
||||
// @Success 200 {object} modifyUserResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
@ -43,12 +43,8 @@ func (h *handler) ModifyUser() core.HandlerFunc {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||||
return
|
||||
}
|
||||
userID, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
||||
return
|
||||
}
|
||||
item, err := h.user.UpdateProfile(ctx.RequestContext(), userID, req.Nickname, req.Avatar)
|
||||
userID := int64(ctx.SessionUserInfo().Id)
|
||||
item, err := h.user.UpdateProfile(ctx.RequestContext(), userID, req.Nickname, req.Avatar)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10001, err.Error()))
|
||||
return
|
||||
|
||||
36
internal/router/interceptor/app_auth.go
Normal file
36
internal/router/interceptor/app_auth.go
Normal file
@ -0,0 +1,36 @@
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"bindbox-game/configs"
|
||||
"bindbox-game/internal/code"
|
||||
"bindbox-game/internal/pkg/core"
|
||||
"bindbox-game/internal/pkg/jwtoken"
|
||||
"bindbox-game/internal/proposal"
|
||||
)
|
||||
|
||||
func (i *interceptor) AppTokenAuthVerify(ctx core.Context) (sessionUserInfo proposal.SessionUserInfo, err core.BusinessError) {
|
||||
headerAuthorizationString := ctx.GetHeader("Authorization")
|
||||
if headerAuthorizationString == "" {
|
||||
err = core.Error(
|
||||
http.StatusUnauthorized,
|
||||
code.JWTAuthVerifyError,
|
||||
"无法确认您的身份,请进行登录。",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
jwtClaims, jwtErr := jwtoken.New(configs.Get().JWT.PatientSecret).Parse(headerAuthorizationString)
|
||||
if jwtErr != nil {
|
||||
err = core.Error(
|
||||
http.StatusUnauthorized,
|
||||
code.JWTAuthVerifyError,
|
||||
"您的账号登录过期,请重新登录。",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
sessionUserInfo = jwtClaims.SessionUserInfo
|
||||
return
|
||||
}
|
||||
@ -10,8 +10,11 @@ import (
|
||||
var _ Interceptor = (*interceptor)(nil)
|
||||
|
||||
type Interceptor interface {
|
||||
// AdminTokenAuthVerify 管理端授权验证
|
||||
AdminTokenAuthVerify(ctx core.Context) (sessionUserInfo proposal.SessionUserInfo, err core.BusinessError)
|
||||
// AdminTokenAuthVerify 管理端授权验证
|
||||
AdminTokenAuthVerify(ctx core.Context) (sessionUserInfo proposal.SessionUserInfo, err core.BusinessError)
|
||||
|
||||
// AppTokenAuthVerify APP端授权验证
|
||||
AppTokenAuthVerify(ctx core.Context) (sessionUserInfo proposal.SessionUserInfo, err core.BusinessError)
|
||||
|
||||
// i 为了避免被其他包实现
|
||||
i()
|
||||
|
||||
@ -115,6 +115,7 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo) (core.Mux, error) {
|
||||
adminAuthApiRouter.POST("/users/:user_id/coupons/add", adminHandler.AddUserCoupon())
|
||||
adminAuthApiRouter.POST("/users/:user_id/rewards/grant", adminHandler.GrantReward())
|
||||
adminAuthApiRouter.GET("/users/:user_id/inventory", adminHandler.ListUserInventory())
|
||||
adminAuthApiRouter.GET("/users/:user_id/item_cards", adminHandler.ListUserItemCards())
|
||||
|
||||
// 道具卡管理
|
||||
adminAuthApiRouter.POST("/system_item_cards", adminHandler.CreateSystemItemCard())
|
||||
@ -152,35 +153,41 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo) (core.Mux, error) {
|
||||
systemApiRouter.POST("/role/:role_id/actions", adminHandler.AssignRoleActions())
|
||||
}
|
||||
|
||||
// APP 端接口路由组
|
||||
appApiRouter := mux.Group("/api/app")
|
||||
{
|
||||
appApiRouter.GET("/activities", activityHandler.ListActivities())
|
||||
appApiRouter.GET("/activities/:activity_id", activityHandler.GetActivityDetail())
|
||||
appApiRouter.GET("/activities/:activity_id/issues", activityHandler.ListActivityIssues())
|
||||
appApiRouter.GET("/activities/:activity_id/issues/:issue_id/rewards", activityHandler.ListIssueRewards())
|
||||
appApiRouter.GET("/activities/:activity_id/issues/:issue_id/draw_logs", activityHandler.ListDrawLogs())
|
||||
// APP 端公开接口路由组
|
||||
appPublicApiRouter := mux.Group("/api/app")
|
||||
{
|
||||
appPublicApiRouter.GET("/activities", activityHandler.ListActivities())
|
||||
appPublicApiRouter.GET("/activities/:activity_id", activityHandler.GetActivityDetail())
|
||||
appPublicApiRouter.GET("/activities/:activity_id/issues", activityHandler.ListActivityIssues())
|
||||
appPublicApiRouter.GET("/activities/:activity_id/issues/:issue_id/rewards", activityHandler.ListIssueRewards())
|
||||
appPublicApiRouter.GET("/activities/:activity_id/issues/:issue_id/draw_logs", activityHandler.ListDrawLogs())
|
||||
|
||||
appApiRouter.GET("/guilds", guildHandler.ListGuilds())
|
||||
appApiRouter.GET("/guilds/:guild_id", guildHandler.GetGuildDetail())
|
||||
appApiRouter.POST("/guilds/:guild_id/members", guildHandler.JoinGuild())
|
||||
appApiRouter.DELETE("/guilds/:guild_id/members/:user_id", guildHandler.LeaveGuild())
|
||||
appApiRouter.GET("/guilds/:guild_id/members", guildHandler.ListGuildMembers())
|
||||
appPublicApiRouter.GET("/guilds", guildHandler.ListGuilds())
|
||||
appPublicApiRouter.GET("/guilds/:guild_id", guildHandler.GetGuildDetail())
|
||||
appPublicApiRouter.POST("/guilds/:guild_id/members", guildHandler.JoinGuild())
|
||||
appPublicApiRouter.DELETE("/guilds/:guild_id/members/:user_id", guildHandler.LeaveGuild())
|
||||
appPublicApiRouter.GET("/guilds/:guild_id/members", guildHandler.ListGuildMembers())
|
||||
|
||||
// APP 端轮播图
|
||||
appApiRouter.GET("/banners", appapi.NewBanner(logger, db).ListBannersForApp())
|
||||
// APP 端轮播图
|
||||
appPublicApiRouter.GET("/banners", appapi.NewBanner(logger, db).ListBannersForApp())
|
||||
|
||||
appApiRouter.PUT("/users/:user_id", userHandler.ModifyUser())
|
||||
appApiRouter.GET("/users/:user_id/orders", userHandler.ListUserOrders())
|
||||
appApiRouter.GET("/users/:user_id/coupons", userHandler.ListUserCoupons())
|
||||
appApiRouter.GET("/users/:user_id/points", userHandler.ListUserPoints())
|
||||
appApiRouter.GET("/users/:user_id/points/balance", userHandler.GetUserPointsBalance())
|
||||
appApiRouter.POST("/users/weixin/login", userHandler.WeixinLogin())
|
||||
appApiRouter.POST("/users/:user_id/phone/bind", userHandler.BindPhone())
|
||||
appApiRouter.GET("/users/:user_id/invites", userHandler.ListUserInvites())
|
||||
appApiRouter.GET("/users/:user_id/item_cards", userHandler.ListUserItemCards())
|
||||
appApiRouter.GET("/users/:user_id/item_cards/uses", userHandler.ListUserItemCardUses())
|
||||
}
|
||||
// 登录保持公开
|
||||
appPublicApiRouter.POST("/users/weixin/login", userHandler.WeixinLogin())
|
||||
}
|
||||
|
||||
// APP 端认证接口路由组
|
||||
appAuthApiRouter := mux.Group("/api/app", core.WrapAuthHandler(intc.AppTokenAuthVerify))
|
||||
{
|
||||
appAuthApiRouter.PUT("/users/:user_id", userHandler.ModifyUser())
|
||||
appAuthApiRouter.GET("/users/:user_id/orders", userHandler.ListUserOrders())
|
||||
appAuthApiRouter.GET("/users/:user_id/coupons", userHandler.ListUserCoupons())
|
||||
appAuthApiRouter.GET("/users/:user_id/points", userHandler.ListUserPoints())
|
||||
appAuthApiRouter.GET("/users/:user_id/points/balance", userHandler.GetUserPointsBalance())
|
||||
appAuthApiRouter.POST("/users/:user_id/phone/bind", userHandler.BindPhone())
|
||||
appAuthApiRouter.GET("/users/:user_id/invites", userHandler.ListUserInvites())
|
||||
appAuthApiRouter.GET("/users/:user_id/item_cards", userHandler.ListUserItemCards())
|
||||
appAuthApiRouter.GET("/users/:user_id/item_cards/uses", userHandler.ListUserItemCardUses())
|
||||
}
|
||||
|
||||
return mux, nil
|
||||
}
|
||||
|
||||
@ -45,6 +45,13 @@ func (s *service) AddItemCard(ctx context.Context, userID int64, cardID int64, q
|
||||
item.ValidEnd = tpl.ValidEnd
|
||||
}
|
||||
do := s.writeDB.UserItemCards.WithContext(ctx)
|
||||
// 避免写入未使用相关字段的零值,触发 MySQL 时间字段校验错误
|
||||
do = do.Omit(
|
||||
s.writeDB.UserItemCards.UsedAt,
|
||||
s.writeDB.UserItemCards.UsedDrawLogID,
|
||||
s.writeDB.UserItemCards.UsedActivityID,
|
||||
s.writeDB.UserItemCards.UsedIssueID,
|
||||
)
|
||||
if tpl.ValidEnd.IsZero() {
|
||||
do = do.Omit(s.writeDB.UserItemCards.ValidEnd)
|
||||
}
|
||||
|
||||
@ -6,6 +6,16 @@ import (
|
||||
"bindbox-game/internal/repository/mysql/model"
|
||||
)
|
||||
|
||||
type ItemCardWithTemplate struct {
|
||||
*model.UserItemCards
|
||||
Name string `json:"name"`
|
||||
CardType int32 `json:"card_type"`
|
||||
ScopeType int32 `json:"scope_type"`
|
||||
EffectType int32 `json:"effect_type"`
|
||||
StackingStrategy int32 `json:"stacking_strategy"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// ListUserItemCards 获取用户道具卡列表
|
||||
// 功能描述:
|
||||
// - 查询指定用户的道具卡列表
|
||||
@ -44,3 +54,69 @@ func (s *service) ListUserItemCards(ctx context.Context, userID int64, page, pag
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
func (s *service) ListUserItemCardsWithTemplate(ctx context.Context, userID int64, page, pageSize int) (items []*ItemCardWithTemplate, total int64, err error) {
|
||||
q := s.readDB.UserItemCards.WithContext(ctx).ReadDB().Where(s.readDB.UserItemCards.UserID.Eq(userID))
|
||||
total, err = q.Count()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
if pageSize > 100 {
|
||||
pageSize = 100
|
||||
}
|
||||
rows, err := q.Order(s.readDB.UserItemCards.ID.Desc()).Offset((page-1)*pageSize).Limit(pageSize).Find()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
cidMap := make(map[int64]struct{})
|
||||
for _, r := range rows {
|
||||
if r.CardID > 0 {
|
||||
cidMap[r.CardID] = struct{}{}
|
||||
}
|
||||
}
|
||||
tpls := map[int64]*model.SystemItemCards{}
|
||||
if len(cidMap) > 0 {
|
||||
ids := make([]int64, 0, len(cidMap))
|
||||
for id := range cidMap {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
list, err := s.readDB.SystemItemCards.WithContext(ctx).ReadDB().Where(s.readDB.SystemItemCards.ID.In(ids...)).Find()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
for _, it := range list {
|
||||
tpls[it.ID] = it
|
||||
}
|
||||
}
|
||||
items = make([]*ItemCardWithTemplate, len(rows))
|
||||
for i, r := range rows {
|
||||
tpl := tpls[r.CardID]
|
||||
var name string
|
||||
var cardType, scopeType, effectType, stacking int32
|
||||
var remark string
|
||||
if tpl != nil {
|
||||
name = tpl.Name
|
||||
cardType = tpl.CardType
|
||||
scopeType = tpl.ScopeType
|
||||
effectType = tpl.EffectType
|
||||
stacking = tpl.StackingStrategy
|
||||
remark = tpl.Remark
|
||||
}
|
||||
items[i] = &ItemCardWithTemplate{
|
||||
UserItemCards: r,
|
||||
Name: name,
|
||||
CardType: cardType,
|
||||
ScopeType: scopeType,
|
||||
EffectType: effectType,
|
||||
StackingStrategy: stacking,
|
||||
Remark: remark,
|
||||
}
|
||||
}
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,9 @@ type Service interface {
|
||||
AddCoupon(ctx context.Context, userID int64, couponID int64) error
|
||||
GrantReward(ctx context.Context, userID int64, req GrantRewardRequest) (*GrantRewardResponse, error)
|
||||
AddItemCard(ctx context.Context, userID int64, cardID int64, quantity int) error
|
||||
ListUserItemCards(ctx context.Context, userID int64, page, pageSize int) (items []*model.UserItemCards, total int64, err error)
|
||||
ListUserItemCardUses(ctx context.Context, userID int64, page, pageSize int) (items []*model.ActivityDrawEffects, total int64, err error)
|
||||
ListUserItemCards(ctx context.Context, userID int64, page, pageSize int) (items []*model.UserItemCards, total int64, err error)
|
||||
ListUserItemCardsWithTemplate(ctx context.Context, userID int64, page, pageSize int) (items []*ItemCardWithTemplate, total int64, err error)
|
||||
ListUserItemCardUses(ctx context.Context, userID int64, page, pageSize int) (items []*model.ActivityDrawEffects, total int64, err error)
|
||||
}
|
||||
|
||||
type service struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user