Skip to content

Commit 6f8fdc3

Browse files
committed
0.2.1 feat: 重构项目架构,新增多媒体资源管理、下载引擎及跨平台构建脚本。
1 parent 6dd0cf5 commit 6f8fdc3

60 files changed

Lines changed: 926 additions & 1057 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components.d.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ declare module 'vue' {
1212
BookScrollerContent: typeof import('./src/components/book/BookScrollerContent.vue')['default']
1313
BookSwitchSource: typeof import('./src/components/dialog/BookSwitchSource.vue')['default']
1414
ComicSwitchSource: typeof import('./src/components/dialog/ComicSwitchSource.vue')['default']
15-
DialogAnimate: typeof import('./src/components/animate/DialogAnimate.vue')['default']
16-
DialogWindow: typeof import('./src/components/animate/DialogWindow.vue')['default']
1715
DraggableSongBar: typeof import('./src/components/songbar/DraggableSongBar.vue')['default']
1816
Guide: typeof import('./src/components/codeEditor/Guide.vue')['default']
1917
HorizonList: typeof import('./src/components/list/HorizonList.vue')['default']
@@ -41,7 +39,6 @@ declare module 'vue' {
4139
RouterView: typeof import('vue-router')['RouterView']
4240
SearchDialog: typeof import('./src/components/media/SearchDialog.vue')['default']
4341
SearchField: typeof import('./src/components/search/SearchField.vue')['default']
44-
SVipButton: typeof import('./src/components/button/SVipButton.vue')['default']
4542
VanActionSheet: typeof import('vant/es')['ActionSheet']
4643
VanBackTop: typeof import('vant/es')['BackTop']
4744
VanBadge: typeof import('vant/es')['Badge']
@@ -75,6 +72,9 @@ declare module 'vue' {
7572
VanSearch: typeof import('vant/es')['Search']
7673
VanSidebar: typeof import('vant/es')['Sidebar']
7774
VanSidebarItem: typeof import('vant/es')['SidebarItem']
75+
VanSkeleton: typeof import('vant/es')['Skeleton']
76+
VanSkeletonImage: typeof import('vant/es')['SkeletonImage']
77+
VanSkeletonParagraph: typeof import('vant/es')['SkeletonParagraph']
7878
VanSlider: typeof import('vant/es')['Slider']
7979
VanStepper: typeof import('vant/es')['Stepper']
8080
VanSwitch: typeof import('vant/es')['Switch']
@@ -95,7 +95,6 @@ declare module 'vue' {
9595
WPagination: typeof import('./src/components/pagination/WPagination.vue')['default']
9696
WSongBar: typeof import('./src/components/songbar/WSongBar.vue')['default']
9797
WSongBarReal: typeof import('./src/components/songbar/WSongBarReal.vue')['default']
98-
WTaichiAnimate: typeof import('./src/components/animate/WTaichiAnimate.vue')['default']
9998
WVideoTab: typeof import('./src/components/tab/WVideoTab.vue')['default']
10099
}
101100
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "wuji-app",
33
"type": "module",
4-
"version": "0.1.27",
4+
"version": "0.2.1",
55
"private": true,
66
"scripts": {
77
"dev": "vite",

packages/components/src/components/LoadImage.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ async function processSrc(
5353
if (src.startsWith('blob:')) {
5454
return src;
5555
}
56-
if (src.startsWith('data:image') && src.includes('base64')) {
56+
if (src.startsWith('data:') && src.includes('base64')) {
5757
// 转为blob
5858
const dataURLToBlobURL = async (dataURL: string) => {
5959
try {

packages/fetch/src/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,15 @@ export async function cachedFetch(
285285
init?: RequestInit & ClientOptions,
286286
imageAndCompress = false,
287287
): Promise<Response> {
288-
if (!input.toString().length) {
288+
const inputUrl = input instanceof Request ? input.url : input.toString();
289+
if (!inputUrl.length) {
289290
return Response.error();
290291
}
291-
if ('caches' in window) {
292-
const cacheKey = input.toString() + imageAndCompress.toString();
292+
const isSupportedScheme
293+
= inputUrl.startsWith('http://') || inputUrl.startsWith('https://');
294+
295+
if ('caches' in window && isSupportedScheme) {
296+
const cacheKey = inputUrl + imageAndCompress.toString();
293297
const cache = await caches.open('wuji-cache');
294298

295299
const cachedResponse = await cache.match(cacheKey);

scripts/build-all-android.ps1

Lines changed: 128 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
param(
55
[Parameter(Mandatory=$false)]
6-
[string]$OutputDir = "C:\Users\14438\Desktop\wuji_things"
6+
[string]$OutputDir = "C:\Users\14438\Desktop\wuji_things",
7+
[string]$Notes = "",
8+
[switch]$SkipBuild
79
)
810

911
# 定义Android目标平台
@@ -34,58 +36,62 @@ Write-Host "输出目录: $OutputDir" -ForegroundColor Cyan
3436
Write-Host "======================================" -ForegroundColor Cyan
3537

3638
# 首先打包通用版本(不加target参数)
37-
Write-Host "`n[1/5] 正在打包通用版本..." -ForegroundColor Yellow
38-
try {
39-
pnpm tauri android build
40-
if ($LASTEXITCODE -eq 0) {
41-
Write-Host "✓ 通用版本打包成功" -ForegroundColor Green
42-
43-
# 复制APK到输出目录
44-
$apkFiles = Get-ChildItem -Path $apkSourcePath -Filter "*.apk"
45-
foreach ($apk in $apkFiles) {
46-
$newName = "wuji-$version-universal.apk"
47-
$destPath = Join-Path $OutputDir $newName
48-
Copy-Item $apk.FullName $destPath -Force
49-
Write-Host " 已保存: $newName" -ForegroundColor Gray
39+
if (-not $SkipBuild) {
40+
Write-Host "`n[1/5] 正在打包通用版本..." -ForegroundColor Yellow
41+
try {
42+
pnpm tauri android build
43+
if ($LASTEXITCODE -eq 0) {
44+
Write-Host "✓ 通用版本打包成功" -ForegroundColor Green
45+
46+
# 复制APK到输出目录
47+
$apkFiles = Get-ChildItem -Path $apkSourcePath -Filter "*.apk"
48+
foreach ($apk in $apkFiles) {
49+
$newName = "wuji-$version-universal.apk"
50+
$destPath = Join-Path $OutputDir $newName
51+
Copy-Item $apk.FullName $destPath -Force
52+
Write-Host " 已保存: $newName" -ForegroundColor Gray
53+
}
54+
} else {
55+
Write-Host "✗ 通用版本打包失败" -ForegroundColor Red
5056
}
51-
} else {
52-
Write-Host "通用版本打包失败" -ForegroundColor Red
57+
} catch {
58+
Write-Host "通用版本打包出错: $_" -ForegroundColor Red
5359
}
54-
} catch {
55-
Write-Host "✗ 通用版本打包出错: $_" -ForegroundColor Red
56-
}
5760

58-
# 打包每个平台
59-
$index = 2
60-
foreach ($target in $targets) {
61-
Write-Host "`n[$index/5] 正在打包 $target 平台..." -ForegroundColor Yellow
62-
63-
try {
64-
pnpm tauri android build --target $target
61+
# 打包每个平台
62+
$index = 2
63+
foreach ($target in $targets) {
64+
Write-Host "`n[$index/5] 正在打包 $target 平台..." -ForegroundColor Yellow
6565

66-
if ($LASTEXITCODE -eq 0) {
67-
Write-Host "$target 平台打包成功" -ForegroundColor Green
66+
try {
67+
pnpm tauri android build --target $target
6868

69-
# 复制APK到输出目录
70-
if (Test-Path $apkSourcePath) {
71-
$apkFiles = Get-ChildItem -Path $apkSourcePath -Filter "*.apk"
72-
foreach ($apk in $apkFiles) {
73-
$newName = "wuji-$version-${target}.apk"
74-
$destPath = Join-Path $OutputDir $newName
75-
Copy-Item $apk.FullName $destPath -Force
76-
Write-Host " 已保存: $newName" -ForegroundColor Gray
69+
if ($LASTEXITCODE -eq 0) {
70+
Write-Host "$target 平台打包成功" -ForegroundColor Green
71+
72+
# 复制APK到输出目录
73+
if (Test-Path $apkSourcePath) {
74+
$apkFiles = Get-ChildItem -Path $apkSourcePath -Filter "*.apk"
75+
foreach ($apk in $apkFiles) {
76+
$newName = "wuji-$version-${target}.apk"
77+
$destPath = Join-Path $OutputDir $newName
78+
Copy-Item $apk.FullName $destPath -Force
79+
Write-Host " 已保存: $newName" -ForegroundColor Gray
80+
}
81+
} else {
82+
Write-Host " 警告: 找不到APK文件路径" -ForegroundColor Yellow
7783
}
7884
} else {
79-
Write-Host " 警告: 找不到APK文件路径" -ForegroundColor Yellow
85+
Write-Host "$target 平台打包失败" -ForegroundColor Red
8086
}
81-
} else {
82-
Write-Host "$target 平台打包失败" -ForegroundColor Red
87+
} catch {
88+
Write-Host "$target 平台打包出错: $_" -ForegroundColor Red
8389
}
84-
} catch {
85-
Write-Host "$target 平台打包出错: $_" -ForegroundColor Red
90+
91+
$index++
8692
}
87-
88-
$index++
93+
} else {
94+
Write-Host "`n跳过 Android 打包步骤,直接处理现有文件..." -ForegroundColor Yellow
8995
}
9096

9197
# 打包完成统计
@@ -95,9 +101,88 @@ Write-Host "======================================" -ForegroundColor Cyan
95101

96102
$allApks = Get-ChildItem -Path $OutputDir -Filter "wuji-$version-*.apk"
97103
Write-Host "共生成 $($allApks.Count) 个APK文件:" -ForegroundColor Green
104+
105+
# 准备更新 updater_android.json
106+
$updaterJsonPath = "C:\Users\14438\Documents\GitHub\wuji-tauri\scripts\update\updater_android.json"
107+
$androidPlatforms = @{}
108+
98109
foreach ($apk in $allApks) {
99110
$size = [math]::Round($apk.Length / 1MB, 2)
100111
Write-Host " - $($apk.Name) ($size MB)" -ForegroundColor Gray
112+
113+
# 构建下载 URL (缤纷云地址)
114+
$encodedName = [Uri]::EscapeDataString($apk.Name)
115+
$downloadUrl = "https://wuji.moshangwangluo.com/$encodedName"
116+
117+
# 提取平台名称
118+
if ($apk.Name -match "wuji-$version-(.*).apk") {
119+
$platformKey = "android-" + $Matches[1]
120+
$androidPlatforms[$platformKey] = @{ url = $downloadUrl }
121+
}
122+
}
123+
124+
# 更新 updater_android.json
125+
if (Test-Path $updaterJsonPath) {
126+
try {
127+
$jsonContent = Get-Content $updaterJsonPath -Raw -Encoding UTF8 | ConvertFrom-Json
128+
129+
# 更新基础信息
130+
$jsonContent.version = $version
131+
$jsonContent.pub_date = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00"
132+
133+
if ([string]::IsNullOrWhiteSpace($Notes)) {
134+
$jsonContent.notes = "更新版本 $version"
135+
} else {
136+
$jsonContent.notes = $Notes
137+
}
138+
139+
# 保留原有的 cloudpan,更新或添加 android 平台
140+
if (-not $jsonContent.platforms) {
141+
$jsonContent.platforms = @{}
142+
}
143+
144+
foreach ($key in $androidPlatforms.Keys) {
145+
$jsonContent.platforms.$key = $androidPlatforms[$key]
146+
}
147+
148+
# 保存 JSON (2 空格缩进)
149+
$jsonRaw = $jsonContent | ConvertTo-Json -Depth 10 -Compress
150+
151+
# 尝试用 Python 进行格式化 (最稳定)
152+
# 注意:这里需要项目根目录,但脚本中没定义 projectRoot,我们通过当前脚本位置反推
153+
$scriptDir = Split-Path $MyInvocation.MyCommand.Path -Parent
154+
$rootPath = Split-Path $scriptDir -Parent # scripts 目录的上级
155+
$pythonPath = Join-Path $rootPath ".venv\Scripts\python.exe"
156+
if (-not (Test-Path $pythonPath)) { $pythonPath = "python" }
157+
158+
try {
159+
$bytes = [System.Text.Encoding]::UTF8.GetBytes($jsonRaw)
160+
$base64 = [System.Convert]::ToBase64String($bytes)
161+
$pyCmd = "import json, base64, sys; data=json.loads(base64.b64decode('$base64').decode('utf-8')); print(json.dumps(data, indent=2, ensure_ascii=False))"
162+
# 使用 Out-String 确保保留从 Python 输出的换行符
163+
$newJson = & $pythonPath -c $pyCmd | Out-String
164+
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($newJson)) { throw "Python 格式化失败" }
165+
} catch {
166+
Write-Host " ⚠ 警告: Python 格式化失败,使用备用正则修复缩进" -ForegroundColor Yellow
167+
$newJson = $jsonContent | ConvertTo-Json -Depth 10
168+
$newJson = [regex]::Replace($newJson, "(?m)^( +)", {
169+
param($m)
170+
$len = $m.Value.Length
171+
$newLen = [int]($len / 4) * 2
172+
if ($newLen -lt 2) { $newLen = 2 }
173+
return " " * $newLen
174+
})
175+
$newJson = $newJson -replace '": +', '": '
176+
}
177+
178+
# 使用无 BOM 的 UTF-8 编码
179+
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
180+
[System.IO.File]::WriteAllText($updaterJsonPath, $newJson, $utf8NoBom)
181+
182+
Write-Host "`n✓ 已更新 updater_android.json" -ForegroundColor Green
183+
} catch {
184+
Write-Host "`n✗ 更新 updater_android.json 失败: $_" -ForegroundColor Red
185+
}
101186
}
102187

103188
Write-Host "所有APK已保存到: $OutputDir" -ForegroundColor Green

scripts/build-all-win.ps1

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
param(
55
[string]$OutputDir = "C:\Users\14438\Desktop\wuji_things",
6-
[Parameter(Mandatory=$true)]
7-
[string]$Password
6+
[Parameter(Mandatory=$false)] # 修改为非强制,因为 SkipBuild 时不需要
7+
[string]$Password,
8+
[string]$Notes = "",
9+
[switch]$SkipBuild
810
)
911

1012
# 基础路径
@@ -34,19 +36,30 @@ Write-Host "版本号: $version" -ForegroundColor Cyan
3436
Write-Host "输出目录: $OutputDir" -ForegroundColor Cyan
3537
Write-Host "======================================" -ForegroundColor Cyan
3638

37-
# 设置签名密码环境变量
38-
# Tauri 会自动读取此环境变量进行签名,无需交互式输入
39-
$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = $Password
40-
Write-Host "已设置签名密码环境变量 (TAURI_SIGNING_PRIVATE_KEY_PASSWORD)" -ForegroundColor Green
41-
4239
# 执行构建
43-
Write-Host "`n正在执行 pnpm run tauri:build ..." -ForegroundColor Yellow
44-
45-
# 运行构建命令
46-
pnpm run tauri:build
47-
48-
if ($LASTEXITCODE -eq 0) {
40+
if (-not $SkipBuild) {
41+
if ([string]::IsNullOrWhiteSpace($Password)) {
42+
Write-Host "✗ 错误: 打包模式必须提供签名密码 (-Password)" -ForegroundColor Red
43+
exit 1
44+
}
45+
46+
# 设置签名密码环境变量
47+
$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = $Password
48+
Write-Host "已设置签名密码环境变量 (TAURI_SIGNING_PRIVATE_KEY_PASSWORD)" -ForegroundColor Green
49+
50+
Write-Host "`n正在执行 pnpm run tauri:build ..." -ForegroundColor Yellow
51+
pnpm run tauri:build
52+
if ($LASTEXITCODE -ne 0) {
53+
Write-Host "✗ 构建失败" -ForegroundColor Red
54+
exit 1
55+
}
4956
Write-Host "✓ 构建命令执行完成" -ForegroundColor Green
57+
} else {
58+
Write-Host "跳过打包步骤,直接处理现有文件..." -ForegroundColor Yellow
59+
}
60+
61+
# 此时无论是刚构建完还是跳过构建,都检查输出目录是否有 artifact
62+
if ($true) { # 始终执行后续的同步和 JSON 更新逻辑
5063

5164
# 查找生成的exe文件
5265
# 过滤包含版本号的exe文件,如果找不到尝试找最新的
@@ -83,7 +96,11 @@ if ($LASTEXITCODE -eq 0) {
8396
# 更新基础信息
8497
$jsonContent.version = $version
8598
$jsonContent.pub_date = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00"
86-
$jsonContent.notes = "更新版本 $version" # 可选:更新说明
99+
if ([string]::IsNullOrWhiteSpace($Notes)) {
100+
$jsonContent.notes = "更新版本 $version"
101+
} else {
102+
$jsonContent.notes = $Notes
103+
}
87104

88105
# 构建下载 URL (假设服务器路径固定)
89106
$encodedName = [Uri]::EscapeDataString($exeName)
@@ -100,13 +117,35 @@ if ($LASTEXITCODE -eq 0) {
100117
Write-Host " 已更新 updater_win.json (所有平台)" -ForegroundColor Green
101118

102119
# 保存 JSON (2 空格缩进)
103-
$jsonOptions = @{
104-
Depth = 10
105-
Compress = $false
120+
$jsonRaw = $jsonContent | ConvertTo-Json -Depth 10 -Compress
121+
122+
# 尝试用 Python 进行格式化 (最稳定)
123+
$pythonPath = Join-Path $projectRoot ".venv\Scripts\python.exe"
124+
if (-not (Test-Path $pythonPath)) { $pythonPath = "python" }
125+
126+
try {
127+
# 使用 Base64 传递数据以规避转义问题
128+
$bytes = [System.Text.Encoding]::UTF8.GetBytes($jsonRaw)
129+
$base64 = [System.Convert]::ToBase64String($bytes)
130+
$pyCmd = "import json, base64, sys; data=json.loads(base64.b64decode('$base64').decode('utf-8')); print(json.dumps(data, indent=2, ensure_ascii=False))"
131+
# 使用 Out-String 确保保留换行符,避免变成单行
132+
$newJson = & $pythonPath -c $pyCmd | Out-String
133+
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($newJson)) { throw "Python 格式化失败" }
134+
} catch {
135+
# 备用方案:暴力正则修复
136+
Write-Host " ⚠ 警告: Python 格式化失败,使用备用正则修复缩进" -ForegroundColor Yellow
137+
$newJson = $jsonContent | ConvertTo-Json -Depth 10
138+
$newJson = [regex]::Replace($newJson, "(?m)^( +)", {
139+
param($m)
140+
$len = $m.Value.Length
141+
# 尝试将大缩进压缩 (假设 11 -> 4, 22 -> 6 等)
142+
# 这里简单处理:超过 4 的都减半再减半
143+
$newLen = [int]($len / 4) * 2
144+
if ($newLen -lt 2) { $newLen = 2 }
145+
return " " * $newLen
146+
})
147+
$newJson = $newJson -replace '": +', '": '
106148
}
107-
$newJson = $jsonContent | ConvertTo-Json @jsonOptions
108-
# 将 PowerShell 默认的 4 空格缩进替换为 2 空格
109-
$newJson = $newJson -replace '(?m)^((?: )*) ', '$1'
110149

111150
# 使用无 BOM 的 UTF-8 编码
112151
$utf8NoBom = New-Object System.Text.UTF8Encoding $false

0 commit comments

Comments
 (0)