This repository has been archived on 2026-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MetaLab/internal/model/shortcode.go
Victor_Jay 55c408d86c fix: 审计问题全量修复 + RateLimiter 原子化重构 + CDN 本地化收紧
- 安全:移除 CSP 中 esm.sh/cdnjs.cloudflare.com,highlight.js 主题已本地化 73 个文件
- 安全:StatusBanned 分支补 dummy hash 防时序攻击
- 安全:手写 constantTimeEq 替换为 crypto/subtle.ConstantTimeCompare
- Bug:锁定操作消息已删除→已锁定
- YAGNI:删除 12 个空预留模板目录
- KISS:删除 common.CheckPassword 薄封装,统一用 bcrypt 调用
- KISS:删除 tokenCtrl 别名字段,api.go 统一用 authCtrl
- RateLimiter:check()+recordFail 闭包模式重构为 try() 原子操作,消除竞态
- RateLimiter:新增 ClearIP() 方法,注册成功时清除 IP 计数
- 文档:修正 audit_service.go 注释编号跳跃(3→5→4)
- 文档:修正 deps_core.go 过清理→过期清理
2026-05-31 11:13:32 +08:00

93 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
// =============================================================================
// Shortcode — Markdown 扩展语法
//
// 用法:在 MD 正文中插入 [zone:类型:参数],渲染时替换为对应 UI 卡片。
//
// 支持的 shortcode
// [zone:event:活动ID] → 官方活动卡片(标题、时间、封面、链接)
// [zone:game:游戏slug] → 游戏信息卡片(名称、封面、类型)
// [zone:poll:投票ID] → 投票卡片(※后端 API 开发中)
// [zone:resource:资源ID] → 资源卡片(※后端 API 开发中)
//
// 扩展现有类型:在 ShortcodeRegistry 中注册新类型 + 实现 Renderer 即可。
// =============================================================================
import "regexp"
// =============================================================================
// 语法常量
// =============================================================================
// ShortcodePattern 匹配所有 [zone:type:params] 模式的 shortcode
// 捕获组:$1=类型, $2=参数
var ShortcodePattern = regexp.MustCompile(`\[zone:(\w+):([^\]]+)\]`)
// =============================================================================
// 已注册的 Shortcode 类型
// =============================================================================
// ShortcodeType 定义一种 shortcode 的类型标识
type ShortcodeType string
const (
ShortcodeEvent ShortcodeType = "event" // [zone:event:活动ID]
ShortcodeGame ShortcodeType = "game" // [zone:game:游戏slug]
ShortcodePoll ShortcodeType = "poll" // [zone:poll:投票ID] ※后端 API 开发中
ShortcodeResource ShortcodeType = "resource" // [zone:resource:资源ID] ※后端 API 开发中
)
// allTypes 所有已定义的 shortcode 类型,添加新类型时在这里追加
var allTypes = []ShortcodeType{
ShortcodeEvent,
ShortcodeGame,
ShortcodePoll,
ShortcodeResource,
}
// IsValidType 检查给定类型是否已注册
func IsValidType(t string) bool {
for _, st := range allTypes {
if string(st) == t {
return true
}
}
return false
}
// =============================================================================
// 解析结果
// =============================================================================
// Shortcode 一次解析的结果
type Shortcode struct {
Raw string // 原始文本,如 "[zone:event:abc123]"
Type ShortcodeType // 类型
Params string // 参数ID/slug 等)
}
// ShortcodeResult 整个 body 的解析结果
type ShortcodeResult struct {
// ProcessedBody 替换后的 bodyshortcode → HTML 占位符),可直接传给模板渲染
ProcessedBody string
// Shortcodes 本次解析到的所有 shortcode 列表
Shortcodes []Shortcode
}
// =============================================================================
// 卡片渲染数据 DTO
// =============================================================================
// ShortcodeCard 渲染一张卡片的通用数据
// 前端根据 Type 决定具体 UI 组件,字段按需填充
type ShortcodeCard struct {
Type ShortcodeType `json:"type"`
ID string `json:"id"` // 业务 ID活动ID / 游戏slug
Title string `json:"title,omitempty"`
Cover string `json:"cover,omitempty"`
Desc string `json:"desc,omitempty"`
URL string `json:"url,omitempty"`
Extra string `json:"extra,omitempty"` // 扩展字段时间、标签等JSON string
}