feat:修改分享url

This commit is contained in:
zheng020 2026-07-15 12:39:40 +08:00
parent c0b577dd40
commit 365f783ea0
6 changed files with 161 additions and 3 deletions

View File

@ -13,4 +13,4 @@ OSS_ROLE_ARN=acs:ram::1387642798143585:role/top-fans-oss-user
# H5 落地页 Base URL (生产环境)
# 分享服务生成的落地页链接前缀,生产域名
LANDING_BASE_URL=https://api.topfans.online
LANDING_BASE_URL=http://topfans.online

View File

@ -34,7 +34,7 @@ REDIS_DB=0
# ==================== H5 落地页 Base URL ====================
# 分享服务生成的落地页链接前缀 (landingBase + asset_id + from=sharer + s=system_type)
# 与 frontend/.env.production 的 VITE_LANDING_BASE_URL 保持一致
LANDING_BASE_URL=https://api.topfans.online
LANDING_BASE_URL=http://topfans.online
# ==================== 镭射卡生成器 ====================
# LASER_GEN_PROVIDER:

View File

@ -108,6 +108,9 @@ export default {
})
// #endif
// upgrade-popup.vue:_downloads/upgrade_*.wgt
this.cleanupUpgradePackages();
this.setPermissions();
// #ifdef APP-PLUS
@ -184,6 +187,62 @@ export default {
const globalSocket = getGlobalSocket();
globalSocket.closeAll();
},
/**
* 清理历史下载的更新包_downloads/upgrade_*.{wgt,apk,ipa}
* - uni-upgrade-center-app 插件的 plus.downloader 默认把包放在 _downloads/upgrade_${ts}.{wgt|apk}
* - 升级弹窗关闭/下载中断/未点击安装时,这些临时包不会自动清理,会持续累积
* - 已通过 saveFile() 持久化的包在 _doc/ 目录下(路径不同),由升级弹窗 checkLocalStoragePackage 控制
*
* 各平台实际会产生哪些文件:
* - Android 整包更新 .apk
* - Android wgt 热更新 .wgt
* - iOS wgt 热更新 .wgt (iOS 整包 (ipa) App Store,不下载本地)
* - ipa 加入正则仅作防御:防止后端配置错误/silent update 误推到本地
*
* 启动期清理一次即可(App 正常运行期间只要不离 _downloads/ 目录就不会有新遗留)
* APP-PLUS 有效
*/
cleanupUpgradePackages() {
// #ifdef APP-PLUS
try {
const dirUrl = plus.io.convertLocalFileSystemURL("_downloads/");
plus.io.resolveLocalFileSystemURL(
dirUrl,
(dirEntry) => {
const reader = dirEntry.createReader();
reader.readEntries(
(entries) => {
entries.forEach((entry) => {
// : uni-upgrade-center-app/pages/upgrade-popup.vue:_downloads/upgrade_${Date.now()}.{wgt|apk}
// ipa ,
if (!/^upgrade_\d+\.(wgt|apk|ipa)$/i.test(entry.name)) return;
entry.remove(
() => {},
(e) =>
console.warn(
"[UPGRADE-CLEANUP] 删包失败:",
entry.fullPath,
e?.message,
),
);
});
},
(e) =>
console.warn(
"[UPGRADE-CLEANUP] 枚举 _downloads 失败:",
e?.message,
),
);
},
() => {
// _downloads (),
},
);
} catch (e) {
console.warn("[UPGRADE-CLEANUP] 初始化失败:", e?.message);
}
// #endif
},
/**
* 处理"从后台切回前台"事件
* 通过 storage 中的上次隐藏时间判断本次 onShow 是否由后台返回触发

View File

@ -262,6 +262,43 @@ export function useShare(props) {
return true;
}
// iOS 相册权限预检:仅在用户触发保存动作时调用,不在 App 启动时弹
// iOS PHPhotoLibrary 授权状态:
// 0=NotDetermined(系统未问) 1=Restricted(家长控制/MDM,用户不能改)
// 2=Denied(用户拒绝) 3=Authorized(允许全部) 4=Limited(iOS14+ 部分照片)
// 返回true=可以继续保存false=被拒绝/受限,本次保存终止
async function ensureIosPhotoAlbumPermission() {
if (typeof plus === 'undefined' || plus.os.name !== 'iOS') return true;
const status = plus.ios.invoke('PHPhotoLibrary', 'authorizationStatus');
if (status === 3 || status === 4) return true; // Authorized / Limited
if (status === 0) return true; // NotDetermined由 uni.saveImageToPhotosAlbum 首次调用时系统自动弹
if (status === 1) {
// Restricted — 引导去设置页也无效,直接 toast 提示
uni.showToast({ title: '相册权限被限制,无法保存到相册', icon: 'none' });
return false;
}
// status === 2: Denied — 引导用户去设置页开启
return new Promise((resolve) => {
uni.showModal({
title: '相册权限开启提醒',
content: '您还没有开启相册权限,无法保存分享的卡片到相册,请前往设置开启!',
showCancel: false,
confirmText: '去设置',
success: (res) => {
if (res.confirm) {
const app = plus.ios.invoke('UIApplication', 'sharedApplication');
const setting = plus.ios.invoke('NSURL', 'URLWithString:', 'app-settings:');
plus.ios.invoke(app, 'openURL:', setting);
plus.ios.deleteObject(setting);
plus.ios.deleteObject(app);
}
// 本次保存终止;用户从设置页回来后需重新触发保存动作
resolve(false);
},
});
});
}
function startShareTimeout(action) {
const ms = SHARE_TIMEOUT[action] || 5000;
shareTimeoutTimer.value = setTimeout(() => {
@ -279,6 +316,26 @@ export function useShare(props) {
async function pick(action) {
if (!(await ensureLogin())) return;
// ★ iOS 相册权限预检:仅在用户触发保存动作时检查,不在 App 启动时弹
if (action === 'save_image') {
const canProceed = await ensureIosPhotoAlbumPermission();
if (!canProceed) {
// 跟踪为权限失败(与 fail_app_missing 同类语义)
const userId = getCurrentUser()?.uid;
if (userId) {
await trackShare({
asset_id: toInt64(typeof props.getAssetId === 'function' ? props.getAssetId() : props.assetId),
sharer_user_id: toInt64(userId),
system_type: systemType.value,
share_target: action,
result: 'fail_permission_denied',
client_ts: Date.now()
});
}
return;
}
}
state.value = 'composing';
errorMsg.value = '';

View File

@ -604,6 +604,10 @@ export default {
this.installing = false;
this.installed = true;
// , _doc/_downloads
// (App.vue _downloads/upgrade_*.wgt, save _doc/ )
this.cleanupAfterInstall(this.tempFilePath);
// wgt
if (this.isWGT) {
//
@ -694,6 +698,44 @@ export default {
filePath,
});
},
/**
* 安装成功后清理本地包文件
* 文件可能位于:
* - _doc/... (用户点过返回/手动 saveFile )
* - _downloads/upgrade_*.{wgt|apk} (裸下载,未走 saveFile;Android apk iOS/Android wgt)
* 两种位置都通过 plus.io.resolveLocalFileSystemURL 适配删除
* APP-PLUS 有效;Harmony/其他平台跳过( App.vue 启动清理兜底)
*
* :ipa 整包更新走 isApplicationStore 路径(跳转 App Store),不走 installPackage,
* 不会有 ipa 文件落到本地,这里不需要单独处理 ipa
*/
cleanupAfterInstall(filePath) {
if (!filePath) return;
// #ifdef APP-PLUS
try {
const fileUrl = plus.io.convertLocalFileSystemURL(filePath);
plus.io.resolveLocalFileSystemURL(
fileUrl,
(entry) => {
entry.remove(
() => {},
(e) =>
console.warn(
"[UPGRADE-CLEANUP] 删除已安装包失败:",
filePath,
e?.message,
),
);
},
() => {
// ,( _downloads/ )
},
);
} catch (e) {
console.warn("[UPGRADE-CLEANUP] 清理已安装包异常:", e?.message);
}
// #endif
},
copyDebugInfo() {
uni.setClipboardData({
data: this.debugInfo,

View File

@ -12,7 +12,7 @@
* 一旦两侧不一致,扫描二维码 / 复制链接就会跳错地址 env 务必同步后端 env
*/
export const LANDING_BASE = String(
import.meta.env.VITE_API_BASE_URL || 'https://api.topfans.online'
import.meta.env.VITE_API_BASE_URL || 'http://topfans.online'
).replace(/\/+$/, '');
/**