362 lines
9.6 KiB
JavaScript
362 lines
9.6 KiB
JavaScript
import uniStarterConfig from '@/uni-starter.config.js';
|
||
//应用初始化页
|
||
// #ifdef APP
|
||
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
|
||
import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version';
|
||
|
||
// 实现,路由拦截。当应用无访问摄像头/相册权限,引导跳到设置界面 https://ext.dcloud.net.cn/plugin?id=5095
|
||
import interceptorChooseImage from '@/uni_modules/json-interceptor-chooseImage/js_sdk/main.js';
|
||
interceptorChooseImage()
|
||
|
||
// #endif
|
||
const db = uniCloud.database()
|
||
|
||
/**
|
||
* 跳转到登录页面
|
||
*/
|
||
function redirectToLogin() {
|
||
const loginPage = '/uni_modules/uni-id-pages/pages/login/login-withpwd'
|
||
const pages = getCurrentPages()
|
||
|
||
// 如果当前已经在登录页,不重复跳转
|
||
if (pages.length > 0) {
|
||
const currentPage = pages[pages.length - 1]
|
||
if (currentPage.route && currentPage.route.includes('login')) {
|
||
return
|
||
}
|
||
}
|
||
|
||
uni.reLaunch({
|
||
url: loginPage,
|
||
fail: (err) => {
|
||
console.error('跳转登录页失败:', err)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 检查是否为登录相关接口(不需要租户ID的接口)
|
||
*/
|
||
function isLoginApi(url) {
|
||
if (!url) return false
|
||
// 登录接口不需要租户ID
|
||
return url.includes('/api/sys/auth/login')
|
||
}
|
||
|
||
/**
|
||
* 设置全局 uni.request 拦截器,自动添加 X-Tenant-Id header 和 Authorization token
|
||
* 确保每次请求后端都携带 token 进行身份验证
|
||
*/
|
||
function setupRequestInterceptor() {
|
||
// 保存原始的 uni.request
|
||
const originalRequest = uni.request
|
||
|
||
// 重写 uni.request,自动添加 tenantId 和 token
|
||
uni.request = function(options = {}) {
|
||
const { url, header = {}, method = 'GET', ...restOptions } = options
|
||
|
||
// 详细的拦截器日志
|
||
console.log('[Request Interceptor] 开始拦截请求:', {
|
||
url: url,
|
||
method: method.toUpperCase(),
|
||
isLoginApi: isLoginApi(url),
|
||
originalOptions: options
|
||
})
|
||
|
||
// 获取 tenantId
|
||
let tenantId = ''
|
||
try {
|
||
tenantId = uni.getStorageSync('backend-tenant-id') || ''
|
||
} catch (e) {
|
||
console.error('[Request Interceptor] 获取 tenantId 失败:', e)
|
||
}
|
||
|
||
console.log('[Request Interceptor] tenantId状态:', {
|
||
tenantId: tenantId,
|
||
hasTenantId: !!tenantId
|
||
})
|
||
|
||
// 检查是否需要登录:如果不是登录接口且租户ID为空
|
||
// 在体验版中,不立即跳转到登录页面,而是让请求继续执行
|
||
// 由后端返回401状态码,前端再处理登录跳转
|
||
if (!isLoginApi(url) && !tenantId) {
|
||
console.warn('[Request Interceptor] 租户ID为空,但允许请求继续执行,由后端处理认证')
|
||
// 不阻止请求,让后端返回401,前端再处理
|
||
} else if (isLoginApi(url)) {
|
||
console.log('[Request Interceptor] 这是登录接口,跳过租户ID检查')
|
||
} else {
|
||
console.log('[Request Interceptor] 租户ID存在,正常处理请求')
|
||
}
|
||
|
||
// 构建新的 header(保留原有的 header,避免覆盖)
|
||
const newHeader = {
|
||
'Content-Type': 'application/json',
|
||
...header
|
||
}
|
||
|
||
// 添加 X-Tenant-Id header(如果存在 tenantId)
|
||
if (tenantId) {
|
||
newHeader['X-Tenant-Id'] = tenantId
|
||
}
|
||
|
||
// 每次请求都自动添加 token(登录接口除外)
|
||
// 全局拦截器确保所有通过 uni.request 的请求都携带 token
|
||
if (!isLoginApi(url)) {
|
||
try {
|
||
const token = uni.getStorageSync('backend-token') || ''
|
||
if (token) {
|
||
// 每次请求都添加 token 到 Authorization header
|
||
newHeader['Authorization'] = `Bearer ${token}`
|
||
} else {
|
||
// 如果没有 token,移除可能存在的旧 Authorization header
|
||
delete newHeader['Authorization']
|
||
}
|
||
} catch (e) {
|
||
console.error('获取 token 失败:', e)
|
||
}
|
||
}
|
||
|
||
// 添加 roleName 和 scenario 到 header(从登录响应中获取)
|
||
try {
|
||
const roleName = uni.getStorageSync('backend-role-name') || ''
|
||
if (roleName) {
|
||
newHeader['X-Role-Name'] = roleName
|
||
}
|
||
const scenario = uni.getStorageSync('backend-scenario') || ''
|
||
if (scenario) {
|
||
newHeader['X-Scenario'] = scenario
|
||
}
|
||
} catch (e) {
|
||
console.error('获取 roleName 或 scenario 失败:', e)
|
||
}
|
||
|
||
// 记录最终的请求参数
|
||
const finalRequestOptions = {
|
||
...restOptions,
|
||
url,
|
||
method,
|
||
header: newHeader
|
||
}
|
||
|
||
console.log('[Request Interceptor] 准备发送请求:', {
|
||
url: url,
|
||
method: method.toUpperCase(),
|
||
headers: newHeader,
|
||
hasData: !!restOptions.data
|
||
})
|
||
|
||
// 统一使用 Promise 方式,确保正确返回响应
|
||
// 这样无论调用方使用 await 还是回调,都能正常工作
|
||
return new Promise((resolve, reject) => {
|
||
console.log('[Request Interceptor] 开始调用原始 uni.request')
|
||
originalRequest.call(uni, {
|
||
...finalRequestOptions,
|
||
success: (res) => {
|
||
console.log('[Request Interceptor] 请求成功:', {
|
||
url: url,
|
||
method: method.toUpperCase(),
|
||
statusCode: res.statusCode,
|
||
hasData: !!res.data
|
||
})
|
||
|
||
// 如果提供了 success 回调,先执行它
|
||
if (options.success) {
|
||
options.success(res)
|
||
}
|
||
// 然后 resolve Promise(供 await 使用)
|
||
resolve(res)
|
||
},
|
||
fail: (err) => {
|
||
console.error('[Request Interceptor] 请求失败:', {
|
||
url: url,
|
||
method: method.toUpperCase(),
|
||
error: err,
|
||
errorMessage: err.errMsg || '未知错误'
|
||
})
|
||
// 如果提供了 fail 回调,先执行它
|
||
if (options.fail) {
|
||
options.fail(err)
|
||
}
|
||
// 然后 reject Promise(供 await 使用)
|
||
reject(err)
|
||
},
|
||
complete: (res) => {
|
||
console.log('[Request Interceptor] 请求完成:', {
|
||
url: url,
|
||
method: method.toUpperCase(),
|
||
hasResponse: !!res
|
||
})
|
||
// 如果提供了 complete 回调,执行它
|
||
if (options.complete) {
|
||
options.complete(res)
|
||
}
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
// 全局请求拦截器已设置,所有 uni.request 调用将自动添加 X-Tenant-Id header 和 Authorization token
|
||
}
|
||
|
||
export default async function() {
|
||
const debug = uniStarterConfig.debug;
|
||
|
||
// 设置全局请求拦截器(在所有请求之前)
|
||
setupRequestInterceptor()
|
||
|
||
// uniStarterConfig挂载到getApp().globalData.config
|
||
setTimeout(() => {
|
||
try {
|
||
const app = getApp({
|
||
allowDefault: true
|
||
});
|
||
if (app && app.globalData) {
|
||
app.globalData.config = uniStarterConfig;
|
||
}
|
||
} catch (e) {
|
||
console.warn('[appInit] 挂载配置失败:', e);
|
||
}
|
||
}, 1)
|
||
|
||
|
||
// 初始化appVersion(仅app生效)
|
||
initAppVersion();
|
||
|
||
//clientDB的错误提示
|
||
function onDBError({
|
||
code, // 错误码详见https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=returnvalue
|
||
message
|
||
}) {
|
||
console.log('onDBError', {
|
||
code,
|
||
message
|
||
});
|
||
// 处理错误
|
||
console.error(code, message);
|
||
}
|
||
// 绑定clientDB错误事件
|
||
db.on('error', onDBError)
|
||
|
||
|
||
//拦截云对象请求
|
||
uniCloud.interceptObject({
|
||
async invoke({
|
||
objectName, // 云对象名称
|
||
methodName, // 云对象的方法名称
|
||
params // 参数列表
|
||
}) {
|
||
// console.log('interceptObject',{
|
||
// objectName, // 云对象名称
|
||
// methodName, // 云对象的方法名称
|
||
// params // 参数列表
|
||
// });
|
||
if(objectName == "uni-id-co" && (methodName.includes('loginBy') || ['login','registerUser'].includes(methodName) )){
|
||
console.log('执行登录相关云对象');
|
||
params[0].inviteCode = await new Promise((callBack) => {
|
||
uni.getClipboardData({
|
||
success: function(res) {
|
||
console.log('剪切板内容:'+res.data);
|
||
if (res.data.slice(0, 18) == 'uniInvitationCode:') {
|
||
let uniInvitationCode = res.data.slice(18, 38)
|
||
console.log('当前用户是其他用户推荐下载的,推荐者的code是:' + uniInvitationCode);
|
||
// uni.showModal({
|
||
// content: '当前用户是其他用户推荐下载的,推荐者的code是:'+uniInvitationCode,
|
||
// showCancel: false
|
||
// });
|
||
callBack(uniInvitationCode)
|
||
//当前用户是其他用户推荐下载的。这里登记他的推荐者id 为当前用户的myInviteCode。判断如果是注册
|
||
} else {
|
||
callBack()
|
||
}
|
||
},
|
||
fail() {
|
||
console.log('error--');
|
||
callBack()
|
||
},
|
||
complete() {
|
||
// #ifdef MP-WEIXIN
|
||
uni.hideToast()
|
||
// #endif
|
||
}
|
||
});
|
||
})
|
||
// console.log(params);
|
||
}
|
||
// console.log(params);
|
||
},
|
||
success(e) {
|
||
console.log(e);
|
||
},
|
||
complete() {
|
||
|
||
},
|
||
fail(e){
|
||
console.error(e);
|
||
// if (debug) {
|
||
// uni.showModal({
|
||
// content: JSON.stringify(e),
|
||
// showCancel: false
|
||
// });
|
||
// }else{
|
||
// uni.showToast({
|
||
// title: '系统错误请稍后再试',
|
||
// icon:'error'
|
||
// });
|
||
// }
|
||
}
|
||
})
|
||
|
||
|
||
// #ifdef APP
|
||
// 监听并提示设备网络状态变化
|
||
uni.onNetworkStatusChange(res => {
|
||
console.log(res.isConnected);
|
||
console.log(res.networkType);
|
||
if (res.networkType != 'none') {
|
||
uni.showToast({
|
||
title: '当前网络类型:' + res.networkType,
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: '网络类型:' + res.networkType,
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
});
|
||
// #endif
|
||
|
||
}
|
||
/**
|
||
* // 初始化appVersion
|
||
*/
|
||
function initAppVersion() {
|
||
// #ifdef APP-PLUS
|
||
let appid = plus.runtime.appid;
|
||
plus.runtime.getProperty(appid, (wgtInfo) => {
|
||
let appVersion = plus.runtime;
|
||
let currentVersion = appVersion.versionCode > wgtInfo.versionCode ? appVersion : wgtInfo;
|
||
getApp({
|
||
allowDefault: true
|
||
}).appVersion = {
|
||
...currentVersion,
|
||
appid,
|
||
hasNew: false
|
||
}
|
||
// 检查更新小红点
|
||
callCheckVersion().then(res => {
|
||
// console.log('检查是否有可以更新的版本', res);
|
||
if (res.result.code > 0) {
|
||
// 有新版本
|
||
getApp({
|
||
allowDefault: true
|
||
}).appVersion.hasNew = true;
|
||
console.log(checkUpdate());
|
||
}
|
||
})
|
||
});
|
||
// 检查更新
|
||
// #endif
|
||
} |