From 7ec5cee7b05e5fdd2466c2c20e629b65752a31fd Mon Sep 17 00:00:00 2001 From: William Date: Tue, 30 Jun 2026 16:27:34 +0600 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=81=E9=9D=A2=E5=9B=BE=20HTTP=20?= =?UTF-8?q?=E2=86=92=20HTTPS=20=E7=BB=95=E8=BF=87=20ATS=20=E9=99=90?= =?UTF-8?q?=E5=88=B6=EF=BC=9B=E6=AF=8F=E9=A1=B5=E9=A1=B5=E9=9D=A2=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E7=8B=AC=E7=AB=8B=EF=BC=9B=E6=97=A0=E8=B4=A6=E5=8F=B7?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=9C=AC=E5=9C=B0=E5=8C=96=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 封面图加载失败:阿里云 VOD CoverURL 返回 HTTP,ATS 默认禁止,替换为 HTTPS - 签名编码优化:percentEncodeURL 不编码逗号,URL 中 Fields 参数保持原样 - 每个页面独立 navigationTitle(视频库/下载任务/账号配置/操作日志) - 无账号时 ContentUnavailableView 显示本地化提示 - 每页条数选择器宽度 80→120,避免文字截断 --- apps/macos/VODManager/PRIVACY.md | 67 ++++++++++++++++++ .../UserInterfaceState.xcuserstate | Bin 0 -> 36041 bytes .../xcschemes/xcschememanagement.plist | 14 ++++ .../VODManager/Localizable.xcstrings | 21 +++++- .../VODManager/Services/VODClient.swift | 2 +- .../VODManager/Services/VODSignature.swift | 13 ++++ .../VODManager/Views/AccountListView.swift | 1 + .../VODManager/Views/LogListView.swift | 1 + .../VODManager/Views/VideoListView.swift | 24 ++++--- 9 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 apps/macos/VODManager/PRIVACY.md create mode 100644 apps/macos/VODManager/VODManager.xcodeproj/project.xcworkspace/xcuserdata/william.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 apps/macos/VODManager/VODManager.xcodeproj/xcuserdata/william.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/apps/macos/VODManager/PRIVACY.md b/apps/macos/VODManager/PRIVACY.md new file mode 100644 index 0000000..4bd77a5 --- /dev/null +++ b/apps/macos/VODManager/PRIVACY.md @@ -0,0 +1,67 @@ +# 隐私政策 + +最后更新日期:2026 年 6 月 30 日 + +感谢您使用 VOD 视频管理器(以下简称"本应用")。本应用尊重并保护您的隐私。 + +## 数据收集 + +本应用 **不会收集、存储或上传任何个人数据**。 + +- 本应用不包含任何分析服务、广告 SDK 或第三方跟踪代码。 +- 本应用不向第三方服务器发送任何用户数据。 +- 本应用无需注册账户即可使用。 + +## 用户输入的数据 + +### 阿里云 AccessKey + +使用本应用时,您需要自行输入阿里云的 AccessKey ID 和 AccessKey Secret。这些信息: + +- **仅存储在您的本地设备上**(通过 SwiftData 本地数据库)。 +- **不会传输到任何第三方服务器**。 +- 仅用于直接访问阿里云视频点播(VOD)OpenAPI。 +- 您可以随时在应用中删除这些信息。 + +### 视频数据 + +本应用从阿里云 VOD 服务获取的视频列表、播放地址等信息: + +- **仅存储在您的本地设备上**。 +- 不会上传到任何第三方服务。 + +## 网络通信 + +本应用仅与 **阿里云 VOD API**(`vod.{region}.aliyuncs.com`)直接通信,用于执行您主动发起的操作,例如: + +- 拉取视频列表和详情 +- 获取播放地址 +- 删除视频 +- 下载视频文件 + +所有网络请求均通过 HTTPS 加密传输。 + +## 数据删除 + +您可以通过以下方式删除所有本地数据: + +- 在应用中删除账号配置。 +- 删除应用的本地数据库文件。 +- 卸载本应用。 + +## 第三方服务 + +本应用使用了以下系统框架和服务: + +- **SwiftData**:本地数据持久化(SQLite) +- **URLSession**:网络请求(仅连接阿里云 API) + +## 隐私政策更新 + +如果本隐私政策发生变更,我们会在本页面更新。继续使用本应用即表示您同意更新后的条款。 + +## 联系我们 + +如有任何关于隐私政策的问题,请通过以下方式联系: + +- GitHub:[https://github.com/anomalyco/Aliyun-VOD-Media-Library-Manager](https://github.com/anomalyco/Aliyun-VOD-Media-Library-Manager) diff --git a/apps/macos/VODManager/VODManager.xcodeproj/project.xcworkspace/xcuserdata/william.xcuserdatad/UserInterfaceState.xcuserstate b/apps/macos/VODManager/VODManager.xcodeproj/project.xcworkspace/xcuserdata/william.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..1000e96c5c88a2d1aaa8eec850d4fed42e1cab7d GIT binary patch literal 36041 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 B + + + + SchemeUserState + + VODManager.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/apps/macos/VODManager/VODManager/Localizable.xcstrings b/apps/macos/VODManager/VODManager/Localizable.xcstrings index aee0399..9f5abae 100644 --- a/apps/macos/VODManager/VODManager/Localizable.xcstrings +++ b/apps/macos/VODManager/VODManager/Localizable.xcstrings @@ -1267,7 +1267,26 @@ } }, "error.no_active_account" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Active Account" + } + }, + "ug" : { + "stringUnit" : { + "state" : "translated", + "value" : "ھەساب يوق" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "没有激活的账号" + } + } + } }, "error.no_play_url" : { "localizations" : { diff --git a/apps/macos/VODManager/VODManager/Services/VODClient.swift b/apps/macos/VODManager/VODManager/Services/VODClient.swift index 885b20a..55b93a8 100644 --- a/apps/macos/VODManager/VODManager/Services/VODClient.swift +++ b/apps/macos/VODManager/VODManager/Services/VODClient.swift @@ -67,7 +67,7 @@ actor VODClient { let host = endpoint() let query = params.sorted(by: { $0.key < $1.key }) - .map { "\(VODSignature.percentEncodePublic($0.key))=\(VODSignature.percentEncodePublic($0.value))" } + .map { "\(VODSignature.percentEncodeURL($0.key))=\(VODSignature.percentEncodeURL($0.value))" } .joined(separator: "&") let urlString = "https://\(host)/?\(query)" diff --git a/apps/macos/VODManager/VODManager/Services/VODSignature.swift b/apps/macos/VODManager/VODManager/Services/VODSignature.swift index 5a6c771..c61fea9 100644 --- a/apps/macos/VODManager/VODManager/Services/VODSignature.swift +++ b/apps/macos/VODManager/VODManager/Services/VODSignature.swift @@ -43,6 +43,19 @@ struct VODSignature { percentEncode(value) } + static func percentEncodeURL(_ value: String) -> String { + let allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~," + var result = "" + for char in value.utf8 { + if allowed.utf8.contains(char) { + result.append(Character(UnicodeScalar(char))) + } else { + result.append(String(format: "%%%02X", char)) + } + } + return result + } + private static func percentEncode(_ value: String) -> String { let allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~" var result = "" diff --git a/apps/macos/VODManager/VODManager/Views/AccountListView.swift b/apps/macos/VODManager/VODManager/Views/AccountListView.swift index a3d2282..cefb77c 100644 --- a/apps/macos/VODManager/VODManager/Views/AccountListView.swift +++ b/apps/macos/VODManager/VODManager/Views/AccountListView.swift @@ -79,6 +79,7 @@ struct AccountListView: View { .sheet(isPresented: $showAddForm) { AccountFormView(account: nil) } + .navigationTitle("nav.account_config") } } diff --git a/apps/macos/VODManager/VODManager/Views/LogListView.swift b/apps/macos/VODManager/VODManager/Views/LogListView.swift index 47f9010..3b6239c 100644 --- a/apps/macos/VODManager/VODManager/Views/LogListView.swift +++ b/apps/macos/VODManager/VODManager/Views/LogListView.swift @@ -26,5 +26,6 @@ struct LogListView: View { } .padding(.vertical, 4) } + .navigationTitle("nav.operation_logs") } } diff --git a/apps/macos/VODManager/VODManager/Views/VideoListView.swift b/apps/macos/VODManager/VODManager/Views/VideoListView.swift index 332ccf6..5e1d5c5 100644 --- a/apps/macos/VODManager/VODManager/Views/VideoListView.swift +++ b/apps/macos/VODManager/VODManager/Views/VideoListView.swift @@ -20,15 +20,18 @@ struct VideoListView: View { private var totalPages: Int { max(1, (filteredVideos.count + pageSize - 1) / pageSize) } var body: some View { - if accountStore.activeAccount == nil { - ContentUnavailableView( - "error.no_active_account", - systemImage: "person.slash", - description: Text("account.add") - ) - } else { - content + Group { + if accountStore.activeAccount == nil { + ContentUnavailableView { + Label("error.no_active_account", systemImage: "person.slash") + } description: { + Text("account.add") + } + } else { + content + } } + .navigationTitle("nav.video_library") } @ViewBuilder @@ -126,7 +129,8 @@ struct VideoListView: View { TableColumn("video.table.title") { video in HStack { - AsyncImage(url: video.coverURL.flatMap(URL.init)) { image in + let coverURL = video.coverURL?.replacingOccurrences(of: "http://", with: "https://") + AsyncImage(url: coverURL.flatMap(URL.init)) { image in image.resizable().scaledToFill() } placeholder: { Color.gray @@ -192,7 +196,7 @@ struct VideoListView: View { Text("\(pageSizes[i])").tag(i) } } - .frame(width: 80) + .frame(width: 120) .onChange(of: pageSizeIndex) { _, _ in pageNo = 1 updateDisplay()