8db9d33694
- A.1 备案对接: BindFiling/QueryFiling 关联网标号+备案号 - A.2 监管上报: DailyRegulatoryReport 日报 - B.1 号段管理: ListSegments + /admin/segments - C.1/C.2 全国统计按省聚合 + 跨省协同(单一可信源天然联动) - F.2 全国监管大屏: NationalStats(按省/类目/状态) - B(遗留) 监管大屏BFF: internal/bff + cmd/console-bff, 密钥仅存后端浏览器只用会话令牌 - G 真实链合约源码: contracts/tcs_registry/registry.go (ChainMaker Go) - 新增9个API+BFF服务; 5项新测试; 端到端BFF验证 - D/E(压测/等保/HSM)/F.1(标准)/真实链部署 标注需外部环境
116 lines
3.2 KiB
Go
116 lines
3.2 KiB
Go
package service
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/tcs-iptv/tcs/internal/macode"
|
|
"github.com/tcs-iptv/tcs/internal/model"
|
|
)
|
|
|
|
// 三期:备案对接、全国统计、号段管理、监管上报。
|
|
|
|
// 机构节点 → 省份映射(与发码机构号段分配一致;示例覆盖部分省)。
|
|
var orgNodeProvince = map[string]string{
|
|
"6101": "陕西", "4401": "广东", "3301": "浙江", "3201": "江苏",
|
|
"1101": "北京", "3101": "上海", "5101": "四川", "4201": "湖北",
|
|
}
|
|
|
|
// BindFiling 关联备案号/网标号至 MA 码(三期 A.1,对接广电总局备案系统)。
|
|
func (s *Service) BindFiling(maCode, licenseNo, filingNo string) (model.FilingRecord, error) {
|
|
if _, err := s.chain.QueryContent(maCode); err != nil {
|
|
return model.FilingRecord{}, err
|
|
}
|
|
rec := model.FilingRecord{
|
|
MACode: maCode, LicenseNo: licenseNo, FilingNo: filingNo,
|
|
BoundAt: time.Now().Format(time.RFC3339),
|
|
}
|
|
s.mu.Lock()
|
|
s.filings[maCode] = rec
|
|
s.mu.Unlock()
|
|
s.prov.Record(model.ProvenanceEvent{
|
|
MACode: maCode, Node: model.NodeIssue, Operator: "广电总局备案系统",
|
|
Detail: "关联网标号 " + licenseNo + " / 备案号 " + filingNo,
|
|
})
|
|
return rec, nil
|
|
}
|
|
|
|
// QueryFiling 查询备案关联。
|
|
func (s *Service) QueryFiling(maCode string) (model.FilingRecord, bool) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
r, ok := s.filings[maCode]
|
|
return r, ok
|
|
}
|
|
|
|
// NationalStats 全国监管统计(三期 A.2/F.2)。
|
|
func (s *Service) NationalStats() (model.NationalStats, error) {
|
|
all, err := s.chain.ListContents("")
|
|
if err != nil {
|
|
return model.NationalStats{}, err
|
|
}
|
|
st := model.NationalStats{
|
|
ByStatus: map[string]int{},
|
|
ByCategory: map[string]int{},
|
|
ByProvince: map[string]model.ProvinceStat{},
|
|
}
|
|
st.TotalContents = len(all)
|
|
for _, c := range all {
|
|
st.ByStatus[c.Status]++
|
|
p, perr := macode.Parse(c.MACode)
|
|
if perr == nil {
|
|
st.ByCategory[p.Category]++
|
|
prov := orgNodeProvince[p.OrgNode]
|
|
if prov == "" {
|
|
prov = "其他(" + p.OrgNode + ")"
|
|
}
|
|
ps := st.ByProvince[prov]
|
|
ps.Province = prov
|
|
ps.OrgNode = p.OrgNode
|
|
ps.Total++
|
|
switch c.Status {
|
|
case model.StatusPublished:
|
|
ps.Published++
|
|
case model.StatusRevoked:
|
|
ps.Revoked++
|
|
}
|
|
st.ByProvince[prov] = ps
|
|
}
|
|
}
|
|
return st, nil
|
|
}
|
|
|
|
// ListSegments 列出已登记号段及使用情况(三期 B.1)。
|
|
func (s *Service) ListSegments() []macode.SegmentInfo {
|
|
return s.gen.Segments()
|
|
}
|
|
|
|
// RegisterSegment 登记新号段(三期 B.1,与发码机构对接后配置)。
|
|
func (s *Service) RegisterSegment(seg macode.Segment) error {
|
|
return s.gen.RegisterSegment(seg)
|
|
}
|
|
|
|
// DailyRegulatoryReport 生成监管数据上报日报(三期 A.2)。
|
|
func (s *Service) DailyRegulatoryReport(date string) (model.RegulatoryReport, error) {
|
|
all, err := s.chain.ListContents("")
|
|
if err != nil {
|
|
return model.RegulatoryReport{}, err
|
|
}
|
|
rep := model.RegulatoryReport{
|
|
ReportType: "daily_summary", Date: date,
|
|
LevelDist: map[string]int{},
|
|
}
|
|
for _, c := range all {
|
|
rep.TotalNew++
|
|
if p, perr := macode.Parse(c.MACode); perr == nil {
|
|
rep.LevelDist[p.Category]++
|
|
}
|
|
if c.Status == model.StatusRevoked {
|
|
rep.RevokedCnt++
|
|
}
|
|
}
|
|
s.mu.Lock()
|
|
rep.BlacklistCnt = len(s.black)
|
|
s.mu.Unlock()
|
|
return rep, nil
|
|
}
|