- Service 层:energy_service → energize/operations/admin/query 四文件 - Service 层:post_service → helpers/audit + 核心 CRUD 保留 - Service 层:favorite_service → items + 核心文件夹操作保留 - Service 层:auth_service → password + 核心注册/登录保留 - Service 层:notification_service → notify + 核心列表/已读保留 - Service 层:audit_service → review + 核心列表/详情保留 - Controller 层:studio_controller → page/write/api/post_api/action 五文件 - Controller 层:post_controller → page/api/upload 三文件 - Controller 层:comment_controller → list/write/action/upload 四文件 - 清理未使用导入(notification_service.go 移除 fmt)
67 lines
1.7 KiB
Go
67 lines
1.7 KiB
Go
package service
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// mdPatterns Markdown 语法正则(用于生成纯文本摘要)
|
|
var mdPatterns = []*regexp.Regexp{
|
|
// 代码块 ```...```
|
|
regexp.MustCompile("(?s)```[^`]*```"),
|
|
// 行内代码 `...`
|
|
regexp.MustCompile("`[^`]+`"),
|
|
// 图片 
|
|
regexp.MustCompile(`!\[.*?\]\(.*?\)`),
|
|
// 链接 [text](url)
|
|
regexp.MustCompile(`\[([^\]]*)\]\(.*?\)`),
|
|
// 标题标记 #
|
|
regexp.MustCompile(`^#{1,6}\s+`),
|
|
// 粗体/斜体/删除线标记
|
|
regexp.MustCompile(`\*{1,3}|_{1,3}|~~`),
|
|
// 引用 >
|
|
regexp.MustCompile(`^>\s?`),
|
|
// 列表标记
|
|
regexp.MustCompile(`^[\s]*[-*+]\s+`),
|
|
regexp.MustCompile(`^[\s]*\d+\.\s+`),
|
|
// 分割线
|
|
regexp.MustCompile(`^[-*_]{3,}\s*$`),
|
|
}
|
|
|
|
// generateExcerpt 从 Markdown 生成纯文本摘要(最多 300 字符)
|
|
// MD 作为纯文本存储无 XSS 风险,前端由 Vditor 渲染
|
|
func generateExcerpt(md string) string {
|
|
text := md
|
|
|
|
// 按行处理,保留行结构
|
|
lines := strings.Split(text, "\n")
|
|
var cleaned []string
|
|
for _, line := range lines {
|
|
cleanedLine := line
|
|
for _, re := range mdPatterns {
|
|
if re == mdPatterns[2] {
|
|
// 链接保留文字: [text](url) → text
|
|
cleanedLine = re.ReplaceAllString(cleanedLine, "$1")
|
|
} else {
|
|
cleanedLine = re.ReplaceAllString(cleanedLine, "")
|
|
}
|
|
}
|
|
cleanedLine = strings.TrimSpace(cleanedLine)
|
|
if cleanedLine != "" {
|
|
cleaned = append(cleaned, cleanedLine)
|
|
}
|
|
}
|
|
|
|
result := strings.Join(cleaned, " ")
|
|
|
|
// 按 rune 截断,不切中文字符
|
|
const maxChars = 300
|
|
if utf8.RuneCountInString(result) > maxChars {
|
|
runes := []rune(result)
|
|
result = string(runes[:maxChars]) + "..."
|
|
}
|
|
|
|
return result
|
|
}
|