Files
web_hgtv_server/pub/common/utils/strings.go
T
rootandClaude Opus 5.5 ad016ee1ac 专题和短剧 slug 改为 8 位随机小写字母
后台新建/修改(未填 slug)和媒资入库时生成随机 slug,不再按标题拼音生成;标签、分类不变。

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:10:53 +08:00

143 lines
3.0 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 utils
import (
"encoding/json"
"math/rand/v2"
"strings"
"videoweb/pub/common/netutil"
"github.com/gosimple/slug"
)
// BinarySearch BinarySearch
func BinarySearch(s []string, t string, n int) (idx int) {
idx = -1
if n == 0 {
return
}
start, end := 0, n-1
for start <= end {
mid := (start + end) >> 1
if s[mid] < t {
start = mid + 1
} else if s[mid] > t {
end = mid - 1
} else {
idx = mid
break
}
}
return
}
var YesOrNo = map[bool]string{
true: "是",
false: "否",
}
// ApplyImgCdn 尝试解析节点 Content JSON,若含 "img" 字段则对其拼接 CDN 后重新序列化。
// 不符合 {"img": "..."} 结构的 Content 原样返回。
func ApplyImgCdn(cdn, content string) string {
if content == "" || cdn == "" {
return content
}
var m map[string]interface{}
if err := json.Unmarshal([]byte(content), &m); err != nil {
return content // 非 JSON 对象,原样返回
}
imgVal, ok := m["img"]
if !ok {
return content // 无 img 字段,原样返回
}
imgStr, ok := imgVal.(string)
if !ok || imgStr == "" {
return content
}
m["img"] = netutil.MergeURL(cdn, imgStr)
b, err := json.Marshal(m)
if err != nil {
return content
}
return string(b)
}
// 截取指定长度的字符串
func GetPrefix(s string, n int) string {
runes := []rune(s)
if len(runes) <= n {
return s
}
return string(runes[:n])
}
func GetRandomLetters(n int) string {
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
b := make([]byte, n)
for i := range b {
b[i] = letters[rand.IntN(len(letters))]
}
return string(b)
}
func GetSlugInfo(text string) string {
return SanitizeSlug(slug.Make(text))
}
// SanitizeSlug 去掉 slug 中的横杠等特殊符号,只保留字母和数字
func SanitizeSlug(s string) string {
s = strings.TrimSpace(s)
if s == "" {
return ""
}
var b strings.Builder
b.Grow(len(s))
for _, r := range s {
if r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' {
b.WriteRune(r)
}
}
return b.String()
}
// IsSlugAllDigits 判断 slug 是否全为数字
func IsSlugAllDigits(s string) bool {
s = strings.TrimSpace(s)
if s == "" {
return false
}
for _, r := range s {
if r < '0' || r > '9' {
return false
}
}
return true
}
// RandomSlugLength 随机 slug 长度
const RandomSlugLength = 8
// MakeRandomSlug 生成唯一的随机 slug(8 位小写字母);exists 返回 true 表示已被占用。
func MakeRandomSlug(exists func(string) bool) string {
for {
s := strings.ToLower(GetRandomLetters(RandomSlugLength))
if !exists(s) {
return s
}
}
}
// MakeUniqueSlug 生成唯一 slug;exists 返回 true 表示已被占用。生成结果不能全是数字。
func MakeUniqueSlug(source string, exists func(string) bool) string {
pinyin := GetSlugInfo(source)
if pinyin == "" {
pinyin = GetRandomLetters(5)
} else if IsSlugAllDigits(pinyin) {
pinyin = pinyin + GetRandomLetters(3)
}
finalSlug := pinyin
for exists(finalSlug) {
finalSlug = pinyin + GetRandomLetters(3)
}
return finalSlug
}