6
0

Compare commits

..

3 Commits

Author SHA1 Message Date
8b692dd9af test(game): 补充 GetKfUrl 请求参数直接断言,验证 uid 空值不下发 2026-08-05 11:41:40 +08:00
a6cc33fcc4 feat(game): 新增 GetKfUrl 获取客服页面链接 2026-08-05 11:31:54 +08:00
cb6b85f727 refactor(chat): 违规封禁三接口业务字段 gkey/sid 改规范名 game_sign/server_id
统一根游戏标识=game_sign、区服id=server_id(对齐DMS命名):
- BanAccountItem/ViolationChatItem: Gkey/Sid → GameSign/ServerId(json game_sign/server_id)
- RoleBanQuery: Gkey → GameSign
- 签名调用方字段 Request.Gkey(field:gkey,值=center-api)不动;chat_records(独立接口)不动
2026-07-22 17:02:25 +08:00
6 changed files with 156 additions and 8 deletions

View File

@ -12,7 +12,7 @@ type BatchBanAccountRequest struct {
Gkey string `position:"Body" field:"gkey"`
Time string `position:"Body" field:"time"`
Sign string `position:"Body" field:"sign"`
Items string `position:"Body" field:"items"` // JSON 数组字符串,每项 {gkey,sid,uid,user_name,role_id,role_name,game_id},单次最多 200 条
Items string `position:"Body" field:"items"` // JSON 数组字符串,每项 {game_sign,server_id,uid,user_name,role_id,role_name,game_id},单次最多 200 条
Banduration int64 `position:"Body" field:"banduration"` // 封禁时长(分钟),必须 >0
Banremark string `position:"Body" field:"banremark"` // 封禁备注(写入 gr_block 留痕)
OpAdmin string `position:"Body" field:"op_admin"` // 操作人(拼进备注留痕)
@ -20,8 +20,8 @@ type BatchBanAccountRequest struct {
// BanAccountItem 待封角色Items 的 JSON 元素)
type BanAccountItem struct {
Gkey string `json:"gkey"` // 游戏标识
Sid string `json:"sid"` // 区服 ID
GameSign string `json:"game_sign"` // 根游戏标识
ServerId string `json:"server_id"` // 区服 ID
Uid int64 `json:"uid"` // 高热用户 ID
UserName string `json:"user_name"` // 高热账号
RoleId string `json:"role_id"` // 角色 ID

View File

@ -12,13 +12,13 @@ type RoleBanStatusRequest struct {
Gkey string `position:"Body" field:"gkey"`
Time string `position:"Body" field:"time"`
Sign string `position:"Body" field:"sign"`
Roles string `position:"Body" field:"roles"` // JSON 数组字符串,每项 {gkey,role_id},单次最多 500 条
Roles string `position:"Body" field:"roles"` // JSON 数组字符串,每项 {game_sign,role_id},单次最多 500 条
}
// RoleBanQuery 待查角色Roles 的 JSON 元素)
type RoleBanQuery struct {
Gkey string `json:"gkey"` // 游戏标识
RoleId string `json:"role_id"` // 角色 ID
GameSign string `json:"game_sign"` // 根游戏标识
RoleId string `json:"role_id"` // 角色 ID
}
// RoleBanStatusItem 单角色状态1=正常 2=封禁/禁言)

View File

@ -26,8 +26,8 @@ type ViolationChatItem struct {
Roleid string `json:"roleid"` // 角色 ID
Uname string `json:"uname"` // 角色名
Content string `json:"content"` // 聊天内容
Gkey string `json:"gkey"` // 游戏标识
Sid string `json:"sid"` // 区服
GameSign string `json:"game_sign"` // 根游戏标识
ServerId string `json:"server_id"` // 区服
Type int64 `json:"type"` // 消息类型
ChatTime string `json:"chat_time"` // 聊天时间 Y-m-d H:i:s
Imei string `json:"imei"` // 设备号

View File

@ -212,3 +212,10 @@ func (c *Client) GetPaySwitchUser(req *GetPaySwitchUserReq) (resp *GetPaySwitchU
err = c.DoAction(req, resp)
return
}
// GetKfUrl 获取客服页面链接(纯透传接口,业务参数由调用方准备)
func (c *Client) GetKfUrl(req *GetKfUrlReq) (resp *GetKfUrlResp, err error) {
resp = CreateGetKfUrlResp()
err = c.DoAction(req, resp)
return
}

57
services/game/kf.go Normal file
View File

@ -0,0 +1,57 @@
package game
import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)
// GetKfUrlReq 获取客服页面链接请求
//
// 该接口为纯透传game.gaore.com 只负责补 timestamp、算 sign、拼 URL
// 业务参数(根游戏 ID、uid 等)由调用方自行准备。
//
// 字段类型说明:除必填且恒非零的 GameId 外,其余字段一律用 string。
// 原因是 addParam 仅在 len(value) > 0 时下发参数string 空值会被自动跳过;
// 若用 int64零值会被格式化成 "0" 照样下发,既产生 role_id=0 之类噪声,
// 也会让游客场景错误地带上 uid=0。
type GetKfUrlReq struct {
*requests.JsonRequest
GameId int64 `position:"Json" field:"game_id"` // 根游戏 ID必填
Uid string `position:"Json" field:"uid"` // 贪玩账号 uid游客留空不下传
UserName string `position:"Json" field:"username"` // 贪玩账号名
MainGameId string `position:"Json" field:"main_game_id"` // 主包游戏 ID
SubGameId string `position:"Json" field:"sub_game_id"` // 子包游戏 ID
ServerId string `position:"Json" field:"server_id"` // 区服 ID
ServerName string `position:"Json" field:"server_name"` // 区服名称
RoleId string `position:"Json" field:"role_id"` // 角色 ID
RoleName string `position:"Json" field:"role_name"` // 角色名称
From string `position:"Json" field:"from"` // 来源pc / h5 / ios / android / mini_program
Navbar string `position:"Json" field:"navbar"` // 传 "1" 显示返回按钮,默认不显示
}
// GetKfUrlRespData 客服链接,有效期 12 小时,调用方不得缓存
type GetKfUrlRespData struct {
KfUrl string `json:"kf_url"`
}
type GetKfUrlResp struct {
*responses.BaseResponse
Code int `json:"code"`
Msg string `json:"msg"`
Data GetKfUrlRespData `json:"data"`
}
func CreateGetKfUrlReq() *GetKfUrlReq {
req := &GetKfUrlReq{
JsonRequest: &requests.JsonRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/game/getKfUrl")
req.Method = requests.POST
return req
}
func CreateGetKfUrlResp() *GetKfUrlResp {
return &GetKfUrlResp{
BaseResponse: &responses.BaseResponse{},
}
}

84
services/game/kf_test.go Normal file
View File

@ -0,0 +1,84 @@
package game
import (
"fmt"
"strings"
"testing"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
)
func TestGetKfUrl(t *testing.T) {
client, err := NewClient()
if err != nil {
t.Fatalf("NewClient err: %v", err)
}
req := CreateGetKfUrlReq()
req.GameId = 10001
req.Uid = "166146"
resp, err := client.GetKfUrl(req)
if err != nil {
t.Fatalf("GetKfUrl err: %v", err)
}
if resp.Code != 1 {
t.Fatalf("expect code 1, got %d, msg: %s", resp.Code, resp.Msg)
}
if !strings.Contains(resp.Data.KfUrl, "game_id=10001") {
t.Fatalf("kf_url 缺少 game_id: %s", resp.Data.KfUrl)
}
if !strings.Contains(resp.Data.KfUrl, "uid=166146") {
t.Fatalf("kf_url 缺少 uid: %s", resp.Data.KfUrl)
}
if !strings.Contains(resp.Data.KfUrl, "sign=") {
t.Fatalf("kf_url 缺少 sign: %s", resp.Data.KfUrl)
}
fmt.Println(resp.Code, resp.Msg, resp.Data.KfUrl)
}
// TestGetKfUrlGuest 游客场景:不设 Uid链接中不应出现 uid
func TestGetKfUrlGuest(t *testing.T) {
client, err := NewClient()
if err != nil {
t.Fatalf("NewClient err: %v", err)
}
req := CreateGetKfUrlReq()
req.GameId = 10003
resp, err := client.GetKfUrl(req)
if err != nil {
t.Fatalf("GetKfUrl err: %v", err)
}
if resp.Code != 1 {
t.Fatalf("expect code 1, got %d, msg: %s", resp.Code, resp.Msg)
}
if strings.Contains(resp.Data.KfUrl, "uid=") {
t.Fatalf("游客链接不应带 uid: %s", resp.Data.KfUrl)
}
fmt.Println(resp.Code, resp.Msg, resp.Data.KfUrl)
}
// TestGetKfUrlReqParams 直接断言请求参数:不设 Uid 时 JsonParams 里不应出现 "uid" key
// 设了 Uid 时应正确出现,避免只靠服务端返回的 kf_url 做间接验证。
func TestGetKfUrlReqParams(t *testing.T) {
guestReq := CreateGetKfUrlReq()
guestReq.GameId = 10003
if err := requests.InitParam(guestReq); err != nil {
t.Fatalf("InitParam err: %v", err)
}
if _, ok := guestReq.JsonParams["uid"]; ok {
t.Fatalf("游客请求不应包含 uid 参数: %v", guestReq.JsonParams["uid"])
}
userReq := CreateGetKfUrlReq()
userReq.GameId = 10001
userReq.Uid = "166146"
if err := requests.InitParam(userReq); err != nil {
t.Fatalf("InitParam err: %v", err)
}
if userReq.JsonParams["uid"] != "166146" {
t.Fatalf("expect uid=166146, got %v", userReq.JsonParams["uid"])
}
}