From ed41a1c74389141e604c7fad680b79ec2252f9c2 Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Fri, 19 Jun 2026 15:09:27 +0800 Subject: [PATCH] 1 --- common/httpRequest.js | 100 ++++++++++++++++++++-------- common/ieApi.js | 2 +- common/ieRealNameAuth.js | 138 ++++++++++++++++++++++++++++----------- 3 files changed, 173 insertions(+), 67 deletions(-) diff --git a/common/httpRequest.js b/common/httpRequest.js index 8487441..e35f5b8 100644 --- a/common/httpRequest.js +++ b/common/httpRequest.js @@ -1,19 +1,55 @@ +import { hideLoading, showLoading } from '@/utils/loading.js' + +const NO_TOKEN_URL_PREFIXES = [ + '/mall/order/getOrdersByUserId/', + '/mall/delivery/page', + '/mall/delivery/countOrderByStatus', + '/mall/order/countByShop/', + '/app/shopArea/getByParentId/' +] + +function matchesNoTokenUrl(url, prefix) { + const path = String(url || '').split('?')[0] + if (String(prefix || '').endsWith('/')) { + return path.indexOf(prefix) === 0 + } + return path === prefix +} + +function shouldAttachToken(url) { + return !NO_TOKEN_URL_PREFIXES.some(prefix => matchesNoTokenUrl(url, prefix)) +} + +function getSafeDeviceInfo() { + if (uni.getDeviceInfo) { + return uni.getDeviceInfo() || {} + } + return uni.getSystemInfoSync() || {} +} + +function getSafeWindowInfo() { + if (uni.getWindowInfo) { + return uni.getWindowInfo() || {} + } + return uni.getSystemInfoSync() || {} +} + const tui = { //接口地址 interfaceUrl: function() { - // return 'https://hbkuaishi.com/hiver' //正式 - return 'http://192.168.100.54:8888/hiver' //测试 + return 'https://hbkuaishi.com/hiver' //正式 + // return 'http://127.0.0.1:8888/hiver' //测试 }, toast: function(text, duration, success) { uni.showToast({ - duration: duration || 2000, + duration: duration || 1000, title: text || "出错啦~", icon: success ? 'success' : 'none', mask:true }) }, modal: function(title, content, showCancel, callback, confirmColor, confirmText) { - uni.showModal({ + uni.showModal({ title: title || '提示', content: content, showCancel: showCancel, @@ -30,18 +66,15 @@ const tui = { }) }, isAndroid: function() { - const res = uni.getSystemInfoSync(); - return res.platform.toLocaleLowerCase() == "android" + const res = getSafeDeviceInfo() + const osName = String(res.osName || res.system || '').toLowerCase() + return osName.indexOf('android') !== -1 }, isPhoneX: function() { - const res = uni.getSystemInfoSync(); - let iphonex = false; - let models = ['iphonex', 'iphonexr', 'iphonexsmax', 'iphone11', 'iphone11pro', 'iphone11promax'] - const model = res.model.replace(/\s/g, "").toLowerCase() - if (models.includes(model)) { - iphonex = true; - } - return iphonex; + const res = getSafeWindowInfo() + const safeArea = res.safeArea || {} + const screenHeight = Number(res.screenHeight || res.windowHeight || 0) + return !!(safeArea.bottom && screenHeight && safeArea.bottom < screenHeight) }, constNum: function() { let time = 0; @@ -51,11 +84,14 @@ const tui = { delayed: null, loadding: false, showLoading: function(title, mask = true) { - uni.showLoading({ + showLoading({ mask: mask, title: title || '请稍候...' }) }, + hideLoading: function() { + hideLoading() + }, /** * 请求数据处理 * @param string url 请求地址 @@ -72,7 +108,7 @@ const tui = { */ request: async function(url, method, postData, isDelay, isForm, hideLoading) { //接口请求 - tui.loadding && uni.hideLoading(); + tui.loadding && tui.hideLoading(); tui.loadding = false; if (!hideLoading) { if (isDelay) { @@ -88,18 +124,22 @@ const tui = { return new Promise((resolve, reject) => { let executeRequest = () => { + const header = { + 'content-type': isForm ? 'application/x-www-form-urlencoded' : 'application/json' + } + const token = tui.getToken() + if (shouldAttachToken(url) && token && typeof token === 'string' && token.trim() && token !== 'null' && token !== 'undefined') { + header.accessToken = token.trim() + } wx.request({ url: tui.interfaceUrl() + url, data: postData, timeout:60000, - header: { - 'content-type': isForm ? 'application/x-www-form-urlencoded' : 'application/json', - 'accessToken': tui.getToken() - }, + header, method: method, //'GET','POST' dataType: 'json', success: (res) => { - if(res.data.code == 401){ + if(res.statusCode == 401 || (res.data && res.data.code == 401)){ if(uni.getStorageSync('codePage')){ uni.clearStorage() uni.setStorageSync('codePage',true) @@ -116,7 +156,7 @@ const tui = { clearTimeout(tui.delayed) tui.delayed = null; if (tui.loadding && !hideLoading) { - uni.hideLoading() + tui.hideLoading() } resolve(res.data) }, @@ -154,7 +194,7 @@ const tui = { const uploadTask = uni.uploadFile({ url: tui.interfaceUrl() + url, filePath: src, - name: 'imageFile', + name: 'file', header: { // 'Authorization': tui.getToken() 'accessToken': uni.getStorageSync("hiver_token") @@ -163,19 +203,21 @@ const tui = { // sizeArrayText:"" }, success: function(res) { - uni.hideLoading() - let d = JSON.parse(res.result.replace(/\ufeff/g, "") || "{}") + tui.hideLoading() + let responseText = res.result || res.data || "{}" + let d = JSON.parse(String(responseText).replace(/\ufeff/g, "") || "{}") if (d.code % 100 == 0) { - //返回图片地址 - let fileObj = d.result; + // 返回OSS文件地址 + let fileObj = d.result !== undefined ? d.result : d.data; resolve(fileObj) } else { - that.toast(res.message); + tui.toast(d.message || res.message || '上传失败'); } }, fail: function(res) { + tui.hideLoading() reject(res) - that.toast(res.message); + tui.toast(res.message || '上传失败'); } }) }) diff --git a/common/ieApi.js b/common/ieApi.js index 0f53fc0..aa07041 100644 --- a/common/ieApi.js +++ b/common/ieApi.js @@ -51,7 +51,7 @@ export function saveIeProfile(data) { } export function verifyIeRealName(data) { - return tui.request('/app/ie/real-name/verify', 'POST', data, false, false, false).then(unwrap) + return tui.request('/app/ie/real-name/verify', 'POST', data, false, false, true).then(unwrap) } export function verifyIeStudentCard(data) { diff --git a/common/ieRealNameAuth.js b/common/ieRealNameAuth.js index 504ecd9..4dcf2cf 100644 --- a/common/ieRealNameAuth.js +++ b/common/ieRealNameAuth.js @@ -5,6 +5,31 @@ function showLongToast(title, duration = 3200) { uni.showToast({ title, icon: 'none', duration }) } +function showAuthDialog(options = {}) { + return new Promise(resolve => { + let handled = false + const fallbackTimer = setTimeout(() => { + if (handled) return + uni.showModal({ + title: options.title || '提示', + content: options.content || '', + confirmText: options.confirmText || '继续', + cancelText: options.cancelText || '取消', + success: res => resolve(!!res.confirm), + fail: () => resolve(false) + }) + }, 80) + uni.$emit('ie-auth-dialog:show', { + ...options, + handled: () => { + handled = true + clearTimeout(fallbackTimer) + }, + resolve + }) + }) +} + function chooseImage(sourceType = ['camera'], camera = 'front') { return new Promise((resolve, reject) => { const success = res => { @@ -41,15 +66,17 @@ const MAX_CERT_PICTURE_BASE64_BYTES = 50 * 1024 const STUDENT_CARD_AUTH_DISABLED = true function confirmCameraCapture(title, content, confirmText = '开始拍摄') { - return new Promise(resolve => { - uni.showModal({ - title, - content, - confirmText, - cancelText: '取消', - success: res => resolve(!!res.confirm), - fail: () => resolve(false) - }) + return showAuthDialog({ + badge: '照片采集', + title, + content, + confirmText, + cancelText: '取消', + steps: [ + '请在光线充足处拍摄', + '保持画面清晰无遮挡', + '照片仅用于本次认证' + ] }) } @@ -129,6 +156,7 @@ async function chooseFacePictureBase64() { if (!confirmed) return '' const path = await chooseImage(['camera'], 'front') if (!path) return '' + uni.showLoading({ title: '照片处理中\n正在压缩图片', mask: true }) const compressOptions = [ { quality: 70, width: 480, height: 480 }, { quality: 55, width: 360, height: 360 }, @@ -139,13 +167,17 @@ async function chooseFacePictureBase64() { { quality: 10, width: 128, height: 128 } ] let lastBase64 = '' - for (const option of compressOptions) { - const compressed = await compressImage(path, option) - const base64 = await readFileBase64(compressed) - lastBase64 = base64 - if (base64.length <= MAX_CERT_PICTURE_BASE64_BYTES) { - return base64 + try { + for (const option of compressOptions) { + const compressed = await compressImage(path, option) + const base64 = await readFileBase64(compressed) + lastBase64 = base64 + if (base64.length <= MAX_CERT_PICTURE_BASE64_BYTES) { + return base64 + } } + } finally { + uni.hideLoading() } if (lastBase64.length > MAX_CERT_PICTURE_BASE64_BYTES) { showLongToast('人像照片Base64不能超过50KB,请靠近拍摄清晰正脸并减少背景后重试', 3800) @@ -155,28 +187,32 @@ async function chooseFacePictureBase64() { } function confirmAuth(actionText, cancelText) { - return new Promise(resolve => { - uni.showModal({ - title: '进阶实名认证', - content: `为满足未成年人保护与防沉迷要求,${actionText || '继续使用'}前需要完成身份证三要素核验。`, - confirmText: '去认证', - cancelText: cancelText || '暂不继续', - success: res => resolve(!!res.confirm), - fail: () => resolve(false) - }) + return showAuthDialog({ + badge: 'i/e 安全认证', + title: '进阶实名认证', + content: `为满足未成年人保护与防沉迷要求,${actionText || '继续使用'}前需要完成身份证三要素核验。`, + confirmText: '去认证', + cancelText: cancelText || '暂不继续', + steps: [ + '填写身份证上的姓名与号码', + '拍摄本人清晰正脸照', + '通过后继续完善 i/e 身份资料' + ] }) } function confirmStudentCardOnly(actionText, cancelText) { - return new Promise(resolve => { - uni.showModal({ - title: '学生身份认证', - content: `${actionText || '继续使用'}前需要完成学生证认证。`, - confirmText: '去认证', - cancelText: cancelText || '暂不继续', - success: res => resolve(!!res.confirm), - fail: () => resolve(false) - }) + return showAuthDialog({ + badge: '学生身份', + title: '学生身份认证', + content: `${actionText || '继续使用'}前需要完成学生证认证。`, + confirmText: '去认证', + cancelText: cancelText || '暂不继续', + steps: [ + '上传本人学生证照片', + '系统识别学生证信息', + '通过后继续 i/e 互动' + ] }) } @@ -219,7 +255,7 @@ async function ensureAliyunRealNameVerified(profile) { } const certPicture = await chooseFacePictureBase64() if (!certPicture) return false - uni.showLoading({ title: '实名认证中...', mask: true }) + uni.showLoading({ title: '实名认证中\n正在安全核验', mask: true }) let result = null try { result = await verifyIeRealName({ certName, certNo, certPicture }) @@ -234,10 +270,33 @@ async function ensureAliyunRealNameVerified(profile) { return true } +function needsProfileSetup(profile) { + return !profile || profile.exists === false || profile.profileCompleted !== 1 +} + +function goProfileSetup() { + uni.navigateTo({ + url: '/package1/ieBrowser/profileSetup', + fail: () => uni.redirectTo({ url: '/package1/ieBrowser/profileSetup' }) + }) +} + export async function ensureIeVerifiedBeforeAction(options = {}) { const profile = options.profile || {} - if (STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified) return true - if (!STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified && profile.studentCardVerified) return true + if (STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified) { + if (needsProfileSetup(profile)) { + goProfileSetup() + return false + } + return true + } + if (!STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified && profile.studentCardVerified) { + if (needsProfileSetup(profile)) { + goProfileSetup() + return false + } + return true + } const setting = await getIeRealNameAuditSetting().catch(() => null) const realNameAuditEnabled = !setting || setting.realNameAuditEnabled !== false if (!realNameAuditEnabled) return true @@ -257,8 +316,13 @@ export async function ensureIeVerifiedBeforeAction(options = {}) { // } const realNameOk = await ensureAliyunRealNameVerified(profile) if (!realNameOk) return false + let latestProfile = null if (typeof options.reload === 'function') { - await options.reload() + latestProfile = await options.reload() + } + if (needsProfileSetup(latestProfile || profile)) { + goProfileSetup() + return false } return true } catch (e) {