feat: 更新CC码监管方案业务版文档,新增摘要、UGC专项、直播专项、存量处置、误判申诉、水印嵌入、CC码生命周期、组织保障等章节;同步macode到cccode重命名及其他代码变更
This commit is contained in:
@@ -14,16 +14,16 @@ import (
|
||||
// 将 MA+哈希机制从 IPTV 扩展至 OTT、手机 APP,实现大小屏内容身份互通。
|
||||
// 对应任务:C.1 跨域解析网关、C.2 身份互通、B.2 扫码验真、D.1 跨屏权益子链。
|
||||
|
||||
// maCodePattern 匹配六段式 MA 码(含可选集级子标识 #Exx)。
|
||||
// ccCodePattern 匹配六段式 MA 码(含可选集级子标识 #Exx)。
|
||||
// 形如 MA.156.8531.6101/WD/20260000004 或 MA.156.8531.6101/WD/20260000004#E07
|
||||
var maCodePattern = regexp.MustCompile(
|
||||
var ccCodePattern = regexp.MustCompile(
|
||||
`^(MA)\.(\d{3})\.([0-9A-Za-z]+)\.([0-9A-Za-z]+)/([0-9A-Za-z]+)/(\d{4})(\d+)(?:#E(\d+))?$`)
|
||||
|
||||
// ParseMACode 解析六段式 MA 码(纯结构解析,不查链)。
|
||||
// ParseCCCode 解析六段式 MA 码(纯结构解析,不查链)。
|
||||
// 返回 Valid=false 表示结构不合法(可能是伪造/损坏的码)。
|
||||
func ParseMACode(maCode string) model.ParsedMA {
|
||||
p := model.ParsedMA{Raw: maCode}
|
||||
m := maCodePattern.FindStringSubmatch(strings.TrimSpace(maCode))
|
||||
func ParseCCCode(ccCode string) model.ParsedMA {
|
||||
p := model.ParsedMA{Raw: ccCode}
|
||||
m := ccCodePattern.FindStringSubmatch(strings.TrimSpace(ccCode))
|
||||
if m == nil {
|
||||
p.Valid = false
|
||||
return p
|
||||
@@ -44,19 +44,19 @@ func ParseMACode(maCode string) model.ParsedMA {
|
||||
return p
|
||||
}
|
||||
|
||||
// baseMACode 去除集级子标识 #Exx,返回整剧 MA 码(用于查链/查权益)。
|
||||
func baseMACode(maCode string) string {
|
||||
if i := strings.Index(maCode, "#"); i >= 0 {
|
||||
return maCode[:i]
|
||||
// baseCCCode 去除集级子标识 #Exx,返回整剧 MA 码(用于查链/查权益)。
|
||||
func baseCCCode(ccCode string) string {
|
||||
if i := strings.Index(ccCode, "#"); i >= 0 {
|
||||
return ccCode[:i]
|
||||
}
|
||||
return maCode
|
||||
return ccCode
|
||||
}
|
||||
|
||||
// Resolve 跨域解析网关(C.1/C.2):同一 MA 码在 IPTV/OTT/APP 统一解析。
|
||||
// 返回解析结构 + 流通状态 + 跨屏可用性,保证大小屏解析结果一致。
|
||||
func (s *Service) Resolve(maCode string) model.ResolveResult {
|
||||
res := model.ResolveResult{MACode: maCode}
|
||||
parsed := ParseMACode(maCode)
|
||||
func (s *Service) Resolve(ccCode string) model.ResolveResult {
|
||||
res := model.ResolveResult{CCCode: ccCode}
|
||||
parsed := ParseCCCode(ccCode)
|
||||
res.Parsed = parsed
|
||||
if !parsed.Valid {
|
||||
res.Resolved = false
|
||||
@@ -64,7 +64,7 @@ func (s *Service) Resolve(maCode string) model.ResolveResult {
|
||||
return res
|
||||
}
|
||||
|
||||
c, err := s.chain.QueryContent(baseMACode(maCode))
|
||||
c, err := s.chain.QueryContent(baseCCCode(ccCode))
|
||||
if err != nil {
|
||||
res.Resolved = false
|
||||
res.Message = "MA 码未在可信数据空间登记"
|
||||
@@ -89,9 +89,9 @@ func (s *Service) Resolve(maCode string) model.ResolveResult {
|
||||
}
|
||||
|
||||
// ScanVerify 用户扫码验真(B.2):验证内容 MA 码真伪、合规与流通状态,防盗版。
|
||||
func (s *Service) ScanVerify(maCode string) model.ScanVerifyResult {
|
||||
res := model.ScanVerifyResult{MACode: maCode}
|
||||
parsed := ParseMACode(maCode)
|
||||
func (s *Service) ScanVerify(ccCode string) model.ScanVerifyResult {
|
||||
res := model.ScanVerifyResult{CCCode: ccCode}
|
||||
parsed := ParseCCCode(ccCode)
|
||||
res.Parsed = parsed
|
||||
if !parsed.Valid {
|
||||
res.Authentic = false
|
||||
@@ -100,7 +100,7 @@ func (s *Service) ScanVerify(maCode string) model.ScanVerifyResult {
|
||||
return res
|
||||
}
|
||||
|
||||
c, err := s.chain.QueryContent(baseMACode(maCode))
|
||||
c, err := s.chain.QueryContent(baseCCCode(ccCode))
|
||||
if err != nil {
|
||||
res.Authentic = false
|
||||
res.Compliant = false
|
||||
@@ -127,14 +127,14 @@ func (s *Service) ScanVerify(maCode string) model.ScanVerifyResult {
|
||||
|
||||
// RecordPurchase 记录用户购买(D.1):用户在某一屏购买内容,记录跨屏权益。
|
||||
// 校验 MA 码有效、屏类型合法;同一用户对同一 MA 码重复购买不覆盖首次记录。
|
||||
func (s *Service) RecordPurchase(maCode, userHash string, screen model.ScreenType) (model.PurchaseRecord, error) {
|
||||
func (s *Service) RecordPurchase(ccCode, userHash string, screen model.ScreenType) (model.PurchaseRecord, error) {
|
||||
if userHash == "" {
|
||||
return model.PurchaseRecord{}, fmt.Errorf("service: 缺少用户标识")
|
||||
}
|
||||
if !model.ValidScreen(screen) {
|
||||
return model.PurchaseRecord{}, fmt.Errorf("service: 非法屏类型 %q(仅 iptv/ott/app)", screen)
|
||||
}
|
||||
base := baseMACode(maCode)
|
||||
base := baseCCCode(ccCode)
|
||||
if _, err := s.chain.QueryContent(base); err != nil {
|
||||
return model.PurchaseRecord{}, fmt.Errorf("service: MA 码无效或未登记: %w", err)
|
||||
}
|
||||
@@ -151,17 +151,17 @@ func (s *Service) RecordPurchase(maCode, userHash string, screen model.ScreenTyp
|
||||
return rec, nil
|
||||
}
|
||||
rec := model.PurchaseRecord{
|
||||
MACode: base, UserHash: userHash, Screen: screen, PurchasedAt: time.Now(),
|
||||
CCCode: base, UserHash: userHash, Screen: screen, PurchasedAt: time.Now(),
|
||||
}
|
||||
acct.Purchases[base] = rec
|
||||
return rec, nil
|
||||
}
|
||||
|
||||
// VerifyCrossScreenRights 跨屏权益核验(D.1):任一屏购买即全屏通看,不重复付费。
|
||||
func (s *Service) VerifyCrossScreenRights(maCode, userHash string, requestScreen model.ScreenType) model.CrossScreenRightsResult {
|
||||
base := baseMACode(maCode)
|
||||
func (s *Service) VerifyCrossScreenRights(ccCode, userHash string, requestScreen model.ScreenType) model.CrossScreenRightsResult {
|
||||
base := baseCCCode(ccCode)
|
||||
res := model.CrossScreenRightsResult{
|
||||
MACode: base, UserHash: userHash, RequestScreen: requestScreen,
|
||||
CCCode: base, UserHash: userHash, RequestScreen: requestScreen,
|
||||
}
|
||||
if !model.ValidScreen(requestScreen) {
|
||||
res.Entitled = false
|
||||
|
||||
Reference in New Issue
Block a user