107 lines
4.9 KiB
Go
107 lines
4.9 KiB
Go
package v1
|
||
|
||
import "github.com/gogf/gf/v2/frame/g"
|
||
|
||
// ============================================================================
|
||
// 小程序端「年会」公开接口(免登录:/event/info、/event/seat/query)
|
||
// 依据:架构 §5.1 E1/E2、§5.3 骨架、§4.4 图④;PRD-02 §4.2.3 隐私边界。
|
||
//
|
||
// 结果最小化红线:返回体**只含本人**的桌号/桌名/座位号,以及「本人所在桌」的示意
|
||
// (各座位是否有人,但**不含任何他人姓名/手机号/全厅名单/统计**)。SeatCell 刻意只有
|
||
// seat_no / is_self / filled 三个字段。
|
||
// ============================================================================
|
||
|
||
// SeatCell 仅用于「本人所在桌」示意 —— 只含座位号与是否本人,不含任何他人信息
|
||
type SeatCell struct {
|
||
SeatNo int `json:"seat_no"`
|
||
IsSelf bool `json:"is_self"`
|
||
Filled bool `json:"filled"` // 是否有人(不返回是谁)
|
||
}
|
||
|
||
type StageOut struct {
|
||
X int `json:"x"`
|
||
Y int `json:"y"`
|
||
W int `json:"w"`
|
||
H int `json:"h"`
|
||
Shape string `json:"shape"`
|
||
Rotation int `json:"rotation"`
|
||
Color string `json:"color"`
|
||
}
|
||
|
||
type EventInfoReq struct {
|
||
g.Meta `path:"/event/info" method:"get" tags:"event" summary:"活动公开信息(查座页顶部)"`
|
||
EventId int64 `v:"required#活动不存在" json:"event_id"`
|
||
}
|
||
type EventInfoRes struct {
|
||
Title string `json:"title"`
|
||
Venue string `json:"venue"`
|
||
EventTime string `json:"event_time"`
|
||
Status string `json:"status"`
|
||
CanQuery bool `json:"can_query"` // status==published
|
||
Stage *StageOut `json:"stage"` // 用于定位,不含个人信息
|
||
}
|
||
|
||
// EventSeatQueryReq 查座入参:**姓名 / 手机号二选一即可发起查询**(C 端体验)。
|
||
//
|
||
// 匹配策略(后端 event_query.go 权威实现):
|
||
// - 只给 name → 按姓名匹配。若命中多张票(重名)→ 返回 4010 ambiguous,**不返回任何座位信息**,
|
||
// 前端引导用户补手机号做二次查询;
|
||
// - 只给 phone → 手机号在本企业内唯一,直接精确匹配;
|
||
// - 两个都给 → 双因子精确匹配(最安全)。
|
||
//
|
||
// 🔴 无论哪种组合,**重名时一律不返回座位信息**(4010),避免「输个名字就看到别人的桌号」。
|
||
type EventSeatQueryReq struct {
|
||
g.Meta `path:"/event/seat/query" method:"post" tags:"event" summary:"扫码查座(免登录)"`
|
||
EventId int64 `v:"required#活动不存在" json:"event_id"`
|
||
Name string `json:"name"`
|
||
Phone string `json:"phone"`
|
||
}
|
||
|
||
// EventSeatQueryRes 结果最小化:只有本人桌座 + 本人所在桌示意。
|
||
//
|
||
// Found=false 表示未查询到(不匹配/未录入/未分配座位),message 为统一模糊文案,
|
||
// 前端据 Found 判定;找不到时所有桌座字段为空,不透出任何他人信息。
|
||
type EventSeatQueryRes struct {
|
||
Found bool `json:"found"`
|
||
// 🔴 true = 命中重名,需补手机号二次确认。此时 Found=false 且所有座位字段为空(后端不下发)。
|
||
Ambiguous bool `json:"ambiguous"`
|
||
Message string `json:"message"`
|
||
TableNo string `json:"table_no"`
|
||
TableName string `json:"table_name"`
|
||
SeatNo int `json:"seat_no"`
|
||
Capacity int `json:"capacity"`
|
||
Seats []SeatCell `json:"seats"` // 本人所在桌,按座位号;Filled 不含身份
|
||
Stage *StageOut `json:"stage"`
|
||
// 本人桌圆心 x(大厅逻辑坐标系)。**仅 Found=true 时有意义,未命中为 0**。
|
||
TableX int `json:"table_x"`
|
||
// 本人桌圆心 y(大厅逻辑坐标系)。**仅 Found=true 时有意义,未命中为 0**。
|
||
TableY int `json:"table_y"`
|
||
// 大厅逻辑宽(取自 hall_layout.canvas.w,缺省 1600)。**仅 Found=true 时有意义,未命中为 0**。
|
||
HallW int `json:"hall_w"`
|
||
// 大厅逻辑高(取自 hall_layout.canvas.h,缺省 1200)。**仅 Found=true 时有意义,未命中为 0**。
|
||
HallH int `json:"hall_h"`
|
||
}
|
||
|
||
// ============================================================================
|
||
// 公开「可查询活动列表」(N4-A / E-list,免登录)
|
||
//
|
||
// 只返回已发布(can_query=true)的活动,仅暴露最小字段(event_id / title / venue / event_time);
|
||
// 无已发布活动 → {list:[]}(**非报错**,前端据此渲染空态);草稿 / 已结束**不出现**。
|
||
// ============================================================================
|
||
|
||
// EventPublicItem 公开活动条目(最小字段,不含任何组织/名单信息)
|
||
type EventPublicItem struct {
|
||
EventId int64 `json:"event_id"`
|
||
Title string `json:"title"`
|
||
Venue string `json:"venue"`
|
||
EventTime string `json:"event_time"`
|
||
}
|
||
|
||
// EventPublicListReq 公开可查询活动列表
|
||
type EventPublicListReq struct {
|
||
g.Meta `path:"/event/list" method:"get" tags:"event" summary:"公开可查询活动列表"`
|
||
}
|
||
type EventPublicListRes struct {
|
||
List []EventPublicItem `json:"list"`
|
||
}
|