diff --git a/.gitignore b/.gitignore index 0ee026a..7bfbab0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ gateway/static/* gateway/main gateway/.env gateway/config/urls.json +doc/src/.vuepress/public/pdfjs/ \ No newline at end of file diff --git a/doc/src/.vuepress/client.ts b/doc/src/.vuepress/client.ts index beb924d..d58e73b 100644 --- a/doc/src/.vuepress/client.ts +++ b/doc/src/.vuepress/client.ts @@ -1,9 +1,11 @@ import { defineClientConfig } from "@vuepress/client"; import UserInfo from "./components/UserInfo.vue"; +import SecureMedia from "./components/SecureMedia.vue"; export default defineClientConfig({ enhance({ app, router }) { app.component("UserInfo", UserInfo); + app.component("SecureMedia", SecureMedia); // 仅在客户端执行 if (typeof window !== 'undefined') { diff --git a/doc/src/.vuepress/components/SecureMedia.vue b/doc/src/.vuepress/components/SecureMedia.vue new file mode 100644 index 0000000..176b782 --- /dev/null +++ b/doc/src/.vuepress/components/SecureMedia.vue @@ -0,0 +1,139 @@ + + + + + \ No newline at end of file diff --git a/doc/src/.vuepress/navbar.ts b/doc/src/.vuepress/navbar.ts index 4701304..e9cbdff 100644 --- a/doc/src/.vuepress/navbar.ts +++ b/doc/src/.vuepress/navbar.ts @@ -2,5 +2,5 @@ import { navbar } from "vuepress-theme-hope"; export default navbar([ "/", - "/processed/", + "/enhance/", ]); diff --git a/doc/src/.vuepress/sidebar.ts b/doc/src/.vuepress/sidebar.ts index 540c7da..0518222 100644 --- a/doc/src/.vuepress/sidebar.ts +++ b/doc/src/.vuepress/sidebar.ts @@ -4,10 +4,10 @@ export default sidebar({ "/": [ "", { - text: "译文", + text: "拓展", icon: "laptop-code", - prefix: "processed/", - link: "processed/", + prefix: "enhance/", + link: "enhance/", children: "structure", }, { diff --git a/doc/src/.vuepress/theme.ts b/doc/src/.vuepress/theme.ts index 34a41f6..f950ac9 100644 --- a/doc/src/.vuepress/theme.ts +++ b/doc/src/.vuepress/theme.ts @@ -1,5 +1,4 @@ import { hopeTheme } from "vuepress-theme-hope"; -import UserInfo from "./components/UserInfo.vue"; import navbar from "./navbar.js"; import sidebar from "./sidebar.js"; @@ -24,7 +23,7 @@ export default hopeTheme({ navbarLayout: { start: ["Brand"], center: ["Links"], - end: [ "Outlook", "UserInfo"], + end: ["Outlook", "UserInfo"], }, // 侧边栏 @@ -135,6 +134,11 @@ export default hopeTheme({ components: { components: ["Badge", "VPCard", "PDF"], + componentOptions: { + pdf: { + pdfjs: '/pdfjs/', // 假设 PDF.js 放在 public/pdfjs/web/ + }, + }, }, icon: { diff --git a/doc/src/processed/10.md b/doc/src/enhance/10.md similarity index 100% rename from doc/src/processed/10.md rename to doc/src/enhance/10.md diff --git a/doc/src/processed/README.md b/doc/src/enhance/README.md similarity index 78% rename from doc/src/processed/README.md rename to doc/src/enhance/README.md index c319e82..641d786 100644 --- a/doc/src/processed/README.md +++ b/doc/src/enhance/README.md @@ -1,5 +1,5 @@ --- -title: 译文 +title: 拓展 index: false icon: laptop-code --- diff --git a/doc/src/processed/intro.md b/doc/src/enhance/intro.md similarity index 100% rename from doc/src/processed/intro.md rename to doc/src/enhance/intro.md diff --git a/doc/src/processed/relation.md b/doc/src/enhance/relation.md similarity index 99% rename from doc/src/processed/relation.md rename to doc/src/enhance/relation.md index b6a0000..23d5698 100644 --- a/doc/src/processed/relation.md +++ b/doc/src/enhance/relation.md @@ -2,6 +2,8 @@ title: 人物关系 --- + + ## 十一世 - **可观**:有一子,光友。生卒不详。 diff --git a/doc/src/enhance/show.md b/doc/src/enhance/show.md new file mode 100644 index 0000000..1d2d5fa --- /dev/null +++ b/doc/src/enhance/show.md @@ -0,0 +1,13 @@ +--- +title: 媒体展示 +--- + +善琪公之墓碑 + + + +善琪公与德艳公墓地环绕 + + + + diff --git a/doc/src/processed/simple.md b/doc/src/enhance/simple.md similarity index 100% rename from doc/src/processed/simple.md rename to doc/src/enhance/simple.md diff --git a/doc/src/processed/tomb.md b/doc/src/enhance/tomb.md similarity index 100% rename from doc/src/processed/tomb.md rename to doc/src/enhance/tomb.md diff --git a/gateway/handlers/media.go b/gateway/handlers/media.go new file mode 100644 index 0000000..f20de3f --- /dev/null +++ b/gateway/handlers/media.go @@ -0,0 +1,79 @@ +package handlers + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "net/http" + "net/url" + "os" + "strings" + "time" + + "github.com/gin-gonic/gin" +) + +type SecureUrlRequest struct { + URL string `json:"url"` +} + +// urlEncode 对URL路径进行编码,保持斜杠不变 +func urlEncode(s string) string { + return strings.ReplaceAll(url.QueryEscape(s), "%2F", "/") +} + +// toHex16 将时间戳转换为16进制小写形式 +func toHex16(t int64) string { + return fmt.Sprintf("%x", t) +} + +func GenerateSecureURL(c *gin.Context) { + var req SecureUrlRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求"}) + return + } + + // 从环境变量获取防盗链密钥 + secretKey := os.Getenv("QINIU_ANTILEECH_KEY") + if secretKey == "" { + c.JSON(http.StatusInternalServerError, gin.H{"error": "未配置防盗链密钥"}) + return + } + + // 设置链接有效期为5分钟 + deadline := time.Now().Add(5 * time.Minute).Unix() + deadlineHex := toHex16(deadline) + + // 解析URL + parsedURL, err := url.Parse(req.URL) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "无效的URL"}) + return + } + + // 获取并编码路径部分 + urlPath := parsedURL.Path + encodedPath := urlEncode(urlPath) + + // 构建签名字符串 + signStr := secretKey + encodedPath + deadlineHex + + // 计算MD5签名 + hash := md5.New() + hash.Write([]byte(signStr)) + sign := hex.EncodeToString(hash.Sum(nil)) + + // 构建查询参数 + query := parsedURL.Query() + query.Set("sign", sign) + query.Set("t", deadlineHex) + + // 重建URL + parsedURL.RawQuery = query.Encode() + secureUrl := parsedURL.String() + + c.JSON(http.StatusOK, gin.H{ + "secureUrl": secureUrl, + }) +} diff --git a/gateway/main.go b/gateway/main.go index 069d823..e8f1816 100644 --- a/gateway/main.go +++ b/gateway/main.go @@ -75,6 +75,7 @@ func main() { // 添加路由认证中间件 r.Use(middleware.RouteAuthMiddleware()) + r.POST("/api/secure-url", handlers.GenerateSecureURL) // 在权限校验中间件后添加退出路由 r.GET("/logout", handlers.Logout)