初步优化成全部go+wails
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AppendCacheBuster 给 URL 追加时间戳,避免时间接口被缓存。
|
||||
func AppendCacheBuster(rawURL string) string {
|
||||
sep := "?"
|
||||
if strings.Contains(rawURL, "?") {
|
||||
sep = "&"
|
||||
}
|
||||
return rawURL + sep + "_=" + strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||
}
|
||||
|
||||
// CloneStringMap 复制 map,避免异步任务读到调用方后续修改。
|
||||
func CloneStringMap(in map[string]string) map[string]string {
|
||||
out := make(map[string]string, len(in))
|
||||
for k, v := range in {
|
||||
out[k] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// MergeCookie 把指定 Cookie 写入原 Cookie 字符串,已有同名 Cookie 会被覆盖。
|
||||
func MergeCookie(cookie, name, value string) string {
|
||||
parts := strings.Split(cookie, ";")
|
||||
pairs := make([]string, 0, len(parts)+1)
|
||||
replaced := false
|
||||
for _, part := range parts {
|
||||
part = strings.TrimSpace(part)
|
||||
if part == "" {
|
||||
continue
|
||||
}
|
||||
key, _, ok := strings.Cut(part, "=")
|
||||
if ok && strings.TrimSpace(key) == name {
|
||||
pairs = append(pairs, name+"="+value)
|
||||
replaced = true
|
||||
continue
|
||||
}
|
||||
pairs = append(pairs, part)
|
||||
}
|
||||
if !replaced && value != "" {
|
||||
pairs = append(pairs, name+"="+value)
|
||||
}
|
||||
return strings.Join(pairs, "; ")
|
||||
}
|
||||
|
||||
// TrimForLog 截断接口响应,避免日志刷屏。
|
||||
func TrimForLog(s string, max int) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) <= max {
|
||||
return s
|
||||
}
|
||||
return s[:max] + "..."
|
||||
}
|
||||
|
||||
// EmptyDefault 在字符串为空时返回默认值。
|
||||
func EmptyDefault(value, fallback string) string {
|
||||
if strings.TrimSpace(value) == "" {
|
||||
return fallback
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// SafeFilename 替换文件名中的危险字符。
|
||||
func SafeFilename(name string) string {
|
||||
replacer := strings.NewReplacer("/", "_", "\\", "_", ":", "_", "*", "_", "?", "_", "\"", "_", "<", "_", ">", "_", "|", "_")
|
||||
return replacer.Replace(name)
|
||||
}
|
||||
|
||||
// MaskCookie 返回 Cookie 摘要,避免把完整凭据暴露给前端。
|
||||
func MaskCookie(cookie string) string {
|
||||
pairs := strings.Split(cookie, ";")
|
||||
masked := make([]string, 0, 3)
|
||||
total := 0
|
||||
for _, pair := range pairs {
|
||||
key, value, ok := strings.Cut(strings.TrimSpace(pair), "=")
|
||||
if !ok || key == "" {
|
||||
continue
|
||||
}
|
||||
total++
|
||||
if len(masked) >= 3 {
|
||||
continue
|
||||
}
|
||||
masked = append(masked, key+"="+MaskValue(value))
|
||||
}
|
||||
if total == 0 {
|
||||
return ""
|
||||
}
|
||||
if total > len(masked) {
|
||||
masked = append(masked, fmt.Sprintf("...共%d项", total))
|
||||
}
|
||||
return strings.Join(masked, "; ")
|
||||
}
|
||||
|
||||
// MaskValue 保留少量首尾字符用于识别,其余替换为星号。
|
||||
func MaskValue(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
return "****"
|
||||
}
|
||||
runes := []rune(value)
|
||||
if len(runes) <= 8 {
|
||||
return "****"
|
||||
}
|
||||
return string(runes[:4]) + "****" + string(runes[len(runes)-4:])
|
||||
}
|
||||
|
||||
// RoundDuration 将时间四舍五入到毫秒。
|
||||
func RoundDuration(d time.Duration) time.Duration {
|
||||
return d.Round(time.Millisecond)
|
||||
}
|
||||
|
||||
// ReadJSON 读取请求 JSON。
|
||||
func ReadJSON(r *http.Request, out any) error {
|
||||
defer r.Body.Close()
|
||||
return json.NewDecoder(r.Body).Decode(out)
|
||||
}
|
||||
|
||||
// WriteJSON 写出 JSON 响应。
|
||||
func WriteJSON(w http.ResponseWriter, value any) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
_ = json.NewEncoder(w).Encode(value)
|
||||
}
|
||||
|
||||
// WriteError 写出统一错误 JSON,同时设置 HTTP 状态码。
|
||||
func WriteError(w http.ResponseWriter, status int, err error) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"success": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user