chore:微信小程序pdf正常打开
This commit is contained in:
@@ -1254,6 +1254,21 @@ export default {
|
|||||||
link.wap_url = resolvedUrl;
|
link.wap_url = resolvedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== 仅微信小程序: 装修"文件"链接直开, 不进 files/detail 中间页 =====
|
||||||
|
// 命中: page_key=PAGE_FILES_DETAIL / name=FILES_xx / wap_url 指向 files/detail
|
||||||
|
// 且能提取到 files_id。拉取或打开失败时自动降级回原详情页(openDiyFileDirect 内部处理)。
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if (link && (link.page_key === 'PAGE_FILES_DETAIL'
|
||||||
|
|| (link.name && /^FILES_\d+$/i.test(String(link.name)))
|
||||||
|
|| String(link.wap_url || '').indexOf('files/detail') !== -1)) {
|
||||||
|
const filesId = this._extractFilesIdFromLink(link);
|
||||||
|
if (filesId) {
|
||||||
|
this.openDiyFileDirect(link, filesId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
// 修复: 内部页面被后台存成【绝对 URL】(如 https://host/hwappx/common/pages_tool/form/formdata)
|
// 修复: 内部页面被后台存成【绝对 URL】(如 https://host/hwappx/common/pages_tool/form/formdata)
|
||||||
// 时,下方 `indexOf('http') != -1` 会把它误判为"外部链接":
|
// 时,下方 `indexOf('http') != -1` 会把它误判为"外部链接":
|
||||||
// - H5 走 window.location.href → 整页刷新,点返回时整个 App 重启、启动屏重播、状态/滚动丢失
|
// - H5 走 window.location.href → 整页刷新,点返回时整个 App 重启、启动屏重播、状态/滚动丢失
|
||||||
@@ -1427,6 +1442,123 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 从装修"文件"链接中提取 files_id(仅微信小程序直开链路使用)。
|
||||||
|
* 兼容三种位置: 顶层字段(files_id/file_id/id) / page_params(JSON字符串或对象) / wap_url query。
|
||||||
|
* @returns {String} 拿不到返回 ''
|
||||||
|
*/
|
||||||
|
_extractFilesIdFromLink(link) {
|
||||||
|
if (!link) return '';
|
||||||
|
let id = link.files_id || link.file_id || link.id || '';
|
||||||
|
if (!id) {
|
||||||
|
const params = _parsePageParams(link.page_params);
|
||||||
|
id = params.files_id || params.file_id || params.id || '';
|
||||||
|
}
|
||||||
|
if (!id) {
|
||||||
|
const url = String(link.wap_url || '');
|
||||||
|
const qIdx = url.indexOf('?');
|
||||||
|
if (qIdx !== -1) {
|
||||||
|
url.slice(qIdx + 1).split('&').forEach(kv => {
|
||||||
|
if (id) return;
|
||||||
|
const eq = kv.indexOf('=');
|
||||||
|
const k = eq === -1 ? kv : kv.slice(0, eq);
|
||||||
|
if (k === 'files_id' || k === 'file_id' || k === 'id') {
|
||||||
|
id = eq === -1 ? '' : kv.slice(eq + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id === '' || id === undefined || id === null ? '' : String(id);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 微信小程序: 装修"文件"链接直开, 不进 files/detail 中间页。
|
||||||
|
* 链路: /api/files/getfile(files_url 已由后端 img() 补全域名)
|
||||||
|
* → downloadFile → saveFile 用文件名重命名 → openDocument(原生 PDF 阅读器)
|
||||||
|
* 任一环节失败 → 降级跳原详情页(files/detail), 保持旧体验兜底。
|
||||||
|
* @param {Object} link 装修链接对象(用于取标题)
|
||||||
|
* @param {String} filesId 文件 id
|
||||||
|
*/
|
||||||
|
openDiyFileDirect(link, filesId) {
|
||||||
|
const fallback = () => {
|
||||||
|
this.redirectTo(PAGE_KEY_MAP.PAGE_FILES_DETAIL, {
|
||||||
|
files_id: filesId,
|
||||||
|
title: link.title || '',
|
||||||
|
enable_set_title: link.enable_set_title ? 1 : 0,
|
||||||
|
page_params: Object.assign({}, _parsePageParams(link.page_params), { files_id: filesId })
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const safeTitle = String(link.title || '').replace(/[\\/:*?"<>|\r\n\t]/g, '_');
|
||||||
|
Http.sendRequest({
|
||||||
|
url: '/api/files/getfile',
|
||||||
|
data: { files_id: filesId },
|
||||||
|
noRetry: true,
|
||||||
|
silentError: true,
|
||||||
|
success: res => {
|
||||||
|
if (!res || res.code !== 0 || !res.data || !res.data.files_url) {
|
||||||
|
fallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let url = String(res.data.files_url);
|
||||||
|
// 相对路径补全域名($util.img 对含逗号路径会按多图截断, 规避)
|
||||||
|
if (!/^https?:\/\//i.test(url) && url.indexOf(',') === -1) {
|
||||||
|
url = this.img(url);
|
||||||
|
}
|
||||||
|
if (!/^https?:\/\//i.test(url)) {
|
||||||
|
fallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rawTitle = String(res.data.files_title || safeTitle || 'file');
|
||||||
|
const title = rawTitle.replace(/[\\/:*?"<>|\r\n\t]/g, '_');
|
||||||
|
const matched = url.split('?')[0].match(/\.([a-zA-Z0-9]+)$/);
|
||||||
|
const ext = matched ? matched[1].toLowerCase() : 'pdf';
|
||||||
|
|
||||||
|
uni.showLoading({ title: Lang.lang('files.list.loading') || 'Loading', mask: true });
|
||||||
|
uni.downloadFile({
|
||||||
|
url,
|
||||||
|
success: dres => {
|
||||||
|
if (dres.statusCode !== 200) {
|
||||||
|
uni.hideLoading();
|
||||||
|
fallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fs = uni.getFileSystemManager();
|
||||||
|
const targetPath = `${wx.env.USER_DATA_PATH}/fs_${Date.now()}_${title}.${ext}`;
|
||||||
|
fs.saveFile({
|
||||||
|
tempFilePath: dres.tempFilePath,
|
||||||
|
filePath: targetPath,
|
||||||
|
success: r => {
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.openDocument({
|
||||||
|
filePath: r.savedFilePath,
|
||||||
|
fileType: ext,
|
||||||
|
showMenu: true,
|
||||||
|
fail: () => fallback(),
|
||||||
|
complete: () => {
|
||||||
|
try { fs.removeSavedFile({ filePath: r.savedFilePath }); } catch (e) { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
// saveFile 失败(配额等), 直接用临时文件打开兜底
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.openDocument({
|
||||||
|
filePath: dres.tempFilePath,
|
||||||
|
fileType: ext,
|
||||||
|
showMenu: true,
|
||||||
|
fail: () => fallback()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
uni.hideLoading();
|
||||||
|
fallback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: () => fallback()
|
||||||
|
});
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 获取默认图
|
* 获取默认图
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user