This commit is contained in:
parent
789505fb34
commit
28d1b5d1c6
39
package-lock.json
generated
39
package-lock.json
generated
@ -8,6 +8,7 @@
|
|||||||
"name": "iboard",
|
"name": "iboard",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@huolala-tech/page-spy": "^1.5.7",
|
||||||
"@prisma/adapter-mariadb": "^7.9.1",
|
"@prisma/adapter-mariadb": "^7.9.1",
|
||||||
"@prisma/client": "^7.7.0",
|
"@prisma/client": "^7.7.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@ -279,6 +280,15 @@
|
|||||||
"@babel/core": "^7.0.0-0"
|
"@babel/core": "^7.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.29.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz",
|
||||||
|
"integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.29.7",
|
"version": "7.29.7",
|
||||||
"resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.29.7.tgz",
|
"resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.29.7.tgz",
|
||||||
@ -768,6 +778,20 @@
|
|||||||
"hono": "^4"
|
"hono": "^4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@huolala-tech/page-spy": {
|
||||||
|
"version": "1.5.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@huolala-tech/page-spy/-/page-spy-1.5.7.tgz",
|
||||||
|
"integrity": "sha512-M19WkH6K2taPpdi7gZ9Tz6v0vY/yW4ziffPXdU+p9+pdSmu1s0OhfxjcsWgERAYsaRLZNloSWqJZyWT5zsYIwA==",
|
||||||
|
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.13.0",
|
||||||
|
"copy-to-clipboard": "^3.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@img/sharp-darwin-arm64": {
|
"node_modules/@img/sharp-darwin-arm64": {
|
||||||
"version": "0.33.5",
|
"version": "0.33.5",
|
||||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
|
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
|
||||||
@ -2997,6 +3021,15 @@
|
|||||||
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
|
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/copy-to-clipboard": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"toggle-selection": "^1.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cors": {
|
"node_modules/cors": {
|
||||||
"version": "2.8.6",
|
"version": "2.8.6",
|
||||||
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz",
|
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz",
|
||||||
@ -5616,6 +5649,12 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/toggle-selection": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@huolala-tech/page-spy": "^1.5.7",
|
||||||
"@prisma/adapter-mariadb": "^7.9.1",
|
"@prisma/adapter-mariadb": "^7.9.1",
|
||||||
"@prisma/client": "^7.7.0",
|
"@prisma/client": "^7.7.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@ -29,8 +30,8 @@
|
|||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"marked": "^17.0.6",
|
|
||||||
"mariadb": "^3.5.3",
|
"mariadb": "^3.5.3",
|
||||||
|
"marked": "^17.0.6",
|
||||||
"prisma": "^7.7.0",
|
"prisma": "^7.7.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
@ -39,15 +39,25 @@ echo "VITE_API_BASE=$VITE_API_BASE"
|
|||||||
echo "=== 1. 构建前端 ==="
|
echo "=== 1. 构建前端 ==="
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
|
# 1.5 拷贝 dist/ 到 Android 工程 assets/, 绕过 Tauri CLI 时这步要做
|
||||||
|
# Tauri CLI 默认在 android build 前会干这事, 我们走直 gradle 要自己补上
|
||||||
|
ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets"
|
||||||
|
mkdir -p "$ANDROID_ASSETS"
|
||||||
|
# 清空旧的 (避免上次的残余)
|
||||||
|
find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} +
|
||||||
|
cp -r dist/. "$ANDROID_ASSETS/"
|
||||||
|
echo "前端 bundle 已拷贝到 $ANDROID_ASSETS"
|
||||||
|
ls -la "$ANDROID_ASSETS" | head -10
|
||||||
|
|
||||||
# 2. 走不同路径
|
# 2. 走不同路径
|
||||||
cd src-tauri
|
cd src-tauri
|
||||||
|
|
||||||
# 全部 4 个 Android 架构的 rustBuild 任务 (Tauri 2 默认会编 4 个)
|
# 全部 4 个 Android 架构的 rustBuild 任务 (Tauri 2 默认会编 4 个)
|
||||||
RUST_BUILD_TASKS=(
|
RUST_BUILD_TASKS=(
|
||||||
":app:rustBuildArm64Release"
|
":app:rustBuildArm64Release"
|
||||||
":app:rustBuildArmv7Release"
|
":app:rustBuildArmRelease"
|
||||||
":app:rustBuildX86_64Release"
|
":app:rustBuildX86_64Release"
|
||||||
":app:rustBuildI686Release"
|
":app:rustBuildX86Release"
|
||||||
)
|
)
|
||||||
SKIP_ARGS=()
|
SKIP_ARGS=()
|
||||||
for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done
|
for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done
|
||||||
@ -77,25 +87,51 @@ if [ "$VARIANT" = "release" ]; then
|
|||||||
./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}"
|
./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}"
|
||||||
|
|
||||||
APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release"
|
APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release"
|
||||||
echo
|
# Gradle 配了 signingConfig 就输出 app-universal-release.apk,
|
||||||
echo "=== 产物 (未签名) ==="
|
# 否则输出 app-universal-release-unsigned.apk, 按文件名判断是否已签名
|
||||||
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
|
SIGNED_APK="$APK_DIR/app-universal-release.apk"
|
||||||
|
UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk"
|
||||||
|
|
||||||
|
if [ -f "$SIGNED_APK" ]; then
|
||||||
|
APK_PATH="$SIGNED_APK"
|
||||||
|
APK_STATUS="已签名"
|
||||||
|
elif [ -f "$UNSIGNED_APK" ]; then
|
||||||
|
APK_PATH="$UNSIGNED_APK"
|
||||||
|
APK_STATUS="未签名"
|
||||||
|
else
|
||||||
|
APK_PATH=""
|
||||||
|
APK_STATUS="未找到"
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "=== Release 签名 (按需) ==="
|
echo "=== 产物 ($APK_STATUS) ==="
|
||||||
echo "1. 生成 keystore (一次性):"
|
if [ -n "$APK_PATH" ]; then
|
||||||
echo " keytool -genkey -v -keystore ~/iboard-release.keystore -alias iboard -keyalg RSA -keysize 2048 -validity 10000"
|
ls -lh "$APK_PATH"
|
||||||
echo "2. 在 ~/.gradle/gradle.properties 写:"
|
else
|
||||||
echo " IBOARD_UPLOAD_STORE_FILE=/home/$(whoami)/iboard-release.keystore"
|
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
|
||||||
echo " IBOARD_UPLOAD_KEY_ALIAS=iboard"
|
fi
|
||||||
echo " IBOARD_UPLOAD_STORE_PASSWORD=..."
|
|
||||||
echo " IBOARD_UPLOAD_KEY_PASSWORD=..."
|
if [ "$APK_STATUS" = "已签名" ]; then
|
||||||
echo "3. 重跑本脚本 (Gradle 读 gradle.properties 里的 IBOARD_UPLOAD_* 自动用 releaseSigning)"
|
echo
|
||||||
echo
|
echo "=== 安装到设备 ==="
|
||||||
echo "=== 临时用 debug keystore 手动签 (仅测试) ==="
|
echo " adb install -r $APK_PATH"
|
||||||
echo " \$ANDROID_HOME/build-tools/*/apksigner sign --ks ~/.android/debug.keystore \\"
|
elif [ "$APK_STATUS" = "未签名" ]; then
|
||||||
echo " --ks-pass pass:android --key-pass pass:android \\"
|
echo
|
||||||
echo " $APK_DIR/app-universal-release-unsigned.apk"
|
echo "=== Release 签名 (按需) ==="
|
||||||
|
echo "1. 生成 keystore (一次性):"
|
||||||
|
echo " keytool -genkey -v -keystore ~/iboard-release.keystore -alias iboard -keyalg RSA -keysize 2048 -validity 10000"
|
||||||
|
echo "2. 在 ~/.gradle/gradle.properties 写:"
|
||||||
|
echo " IBOARD_UPLOAD_STORE_FILE=/home/$(whoami)/iboard-release.keystore"
|
||||||
|
echo " IBOARD_UPLOAD_KEY_ALIAS=iboard"
|
||||||
|
echo " IBOARD_UPLOAD_STORE_PASSWORD=..."
|
||||||
|
echo " IBOARD_UPLOAD_KEY_PASSWORD=..."
|
||||||
|
echo "3. 重跑本脚本 (Gradle 读 gradle.properties 里的 IBOARD_UPLOAD_* 自动用 releaseSigning)"
|
||||||
|
echo
|
||||||
|
echo "=== 临时用 debug keystore 手动签 (仅测试) ==="
|
||||||
|
echo " \$ANDROID_HOME/build-tools/*/apksigner sign --ks ~/.android/debug.keystore \"
|
||||||
|
echo " --ks-pass pass:android --key-pass pass:android \"
|
||||||
|
echo " $APK_PATH"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "[debug] Tauri CLI debug 路径 (不传 --release 不会触发 bug), 直接走"
|
echo "[debug] Tauri CLI debug 路径 (不传 --release 不会触发 bug), 直接走"
|
||||||
npx tauri android build --apk
|
npx tauri android build --apk
|
||||||
|
|||||||
21
src/debug/pagespy.js
Normal file
21
src/debug/pagespy.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// 仅在 Tauri WebView 内启用 PageSpy, 用于生产环境远程调试.
|
||||||
|
// web 模式 (Vite dev / 浏览器) 通过检测 window.__TAURI_INTERNALS__ 直接跳过,
|
||||||
|
// 配合 dynamic import 让 page-spy 这个 chunk 在 web 模式下完全不下载.
|
||||||
|
// VITE_PAGESPY_API 留空可关闭连接 (例如本地调试不想连远端 PageSpy 服务时).
|
||||||
|
// 加载失败不阻塞应用启动, 仅 console.warn 提示.
|
||||||
|
|
||||||
|
const PAGESPY_API = import.meta.env.VITE_PAGESPY_API || 'http://bh.vps.honor3.com:6752'
|
||||||
|
const inTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window
|
||||||
|
|
||||||
|
if (inTauri && PAGESPY_API) {
|
||||||
|
// 动态 import: 仅在 Tauri 内才下载 page-spy chunk
|
||||||
|
import('@huolala-tech/page-spy')
|
||||||
|
.then(({ default: PageSpy }) => {
|
||||||
|
// PageSpy 默认会 hook fetch / XMLHttpRequest, 自动抓取网络请求和错误
|
||||||
|
const instance = new PageSpy({ api: PAGESPY_API })
|
||||||
|
window.__IBOARD_PAGESPY__ = instance
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.warn('[PageSpy] init failed:', err)
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,3 +1,6 @@
|
|||||||
|
// 远程调试: 仅在 Tauri WebView 内启用, web 模式自动跳过
|
||||||
|
import './debug/pagespy.js'
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
import { BrowserRouter } from 'react-router-dom'
|
import { BrowserRouter } from 'react-router-dom'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user