四期(大小屏融合)后端可代码部分:跨域解析网关/扫码验真/跨屏权益通兑

- model/rights.go: ScreenType/ParsedMA/ResolveResult/ScanVerifyResult/UserRights/PurchaseRecord/CrossScreenRightsResult
- service/phase4.go: ParseMACode + Resolve(C.1/C.2) + ScanVerify(B.2) + RecordPurchase/VerifyCrossScreenRights(D.1)
- api/handlers.go: GET /content/resolve, POST /content/scan-verify, /rights/purchase, /rights/verify
- service/phase4_test.go: 18 单测全绿
- 同一MA码跨iptv/ott/app统一解析; 任一屏购买全屏通看不重复扣费
- OTT/移动端SDK/C2PA凭证标注需外部环境
- 更新 5-task-IPTV-四期.md 进度
This commit is contained in:
selfrelease
2026-06-14 19:01:26 +08:00
parent 959e5ac18e
commit 2cd5fbec6d
6 changed files with 590 additions and 13 deletions
+64
View File
@@ -60,6 +60,11 @@ func (h *Handler) Register(rg *gin.RouterGroup) {
rg.GET("/regulatory/national-stats", h.nationalStats) // 全国监管统计(三期F.2
rg.GET("/regulatory/daily-report", h.dailyReport) // 监管数据上报日报(三期A.2
rg.GET("/admin/segments", h.listSegments) // 号段管理(三期B.1
// ---- 四期:大小屏融合(跨域解析/扫码验真/跨屏权益)----
rg.GET("/content/resolve", h.resolve) // MA 跨域解析网关(C.1/C.2
rg.POST("/content/scan-verify", h.scanVerify) // 用户扫码验真(B.2
rg.POST("/rights/purchase", h.recordPurchase) // 记录跨屏购买(D.1
rg.POST("/rights/verify", h.verifyRights) // 跨屏权益核验(D.1
}
func roleOf(c *gin.Context) chain.Role {
@@ -680,3 +685,62 @@ func (h *Handler) dailyReport(c *gin.Context) {
func (h *Handler) listSegments(c *gin.Context) {
httpx.OK(c, gin.H{"segments": h.svc.ListSegments()})
}
// ---- 四期:大小屏融合(跨域解析/扫码验真/跨屏权益)----
func (h *Handler) resolve(c *gin.Context) {
maCode := c.Query("ma_code")
if maCode == "" {
httpx.Error(c, http.StatusBadRequest, "INVALID_REQUEST", "缺少 ma_code")
return
}
httpx.OK(c, h.svc.Resolve(maCode))
}
type scanVerifyReq struct {
MACode string `json:"ma_code"`
}
func (h *Handler) scanVerify(c *gin.Context) {
var req scanVerifyReq
if err := c.ShouldBindJSON(&req); err != nil {
httpx.Error(c, http.StatusBadRequest, "INVALID_REQUEST", err.Error())
return
}
httpx.OK(c, h.svc.ScanVerify(req.MACode))
}
type purchaseReq struct {
MACode string `json:"ma_code"`
UserHash string `json:"user_hash"`
Screen string `json:"screen"` // iptv/ott/app
}
func (h *Handler) recordPurchase(c *gin.Context) {
var req purchaseReq
if err := c.ShouldBindJSON(&req); err != nil {
httpx.Error(c, http.StatusBadRequest, "INVALID_REQUEST", err.Error())
return
}
rec, err := h.svc.RecordPurchase(req.MACode, req.UserHash, model.ScreenType(req.Screen))
if err != nil {
httpx.Error(c, http.StatusBadRequest, "PURCHASE_FAILED", err.Error())
return
}
httpx.OK(c, rec)
}
type verifyRightsReq struct {
MACode string `json:"ma_code"`
UserHash string `json:"user_hash"`
Screen string `json:"screen"` // 当前请求屏
}
func (h *Handler) verifyRights(c *gin.Context) {
var req verifyRightsReq
if err := c.ShouldBindJSON(&req); err != nil {
httpx.Error(c, http.StatusBadRequest, "INVALID_REQUEST", err.Error())
return
}
httpx.OK(c, h.svc.VerifyCrossScreenRights(req.MACode, req.UserHash, model.ScreenType(req.Screen)))
}