wangfukang 2 days ago
parent
commit
ed41a1c743
  1. 100
      common/httpRequest.js
  2. 2
      common/ieApi.js
  3. 138
      common/ieRealNameAuth.js

100
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 = { const tui = {
//接口地址 //接口地址
interfaceUrl: function() { interfaceUrl: function() {
// return 'https://hbkuaishi.com/hiver' //正式 return 'https://hbkuaishi.com/hiver' //正式
return 'http://192.168.100.54:8888/hiver' //测试 // return 'http://127.0.0.1:8888/hiver' //测试
}, },
toast: function(text, duration, success) { toast: function(text, duration, success) {
uni.showToast({ uni.showToast({
duration: duration || 2000, duration: duration || 1000,
title: text || "出错啦~", title: text || "出错啦~",
icon: success ? 'success' : 'none', icon: success ? 'success' : 'none',
mask:true mask:true
}) })
}, },
modal: function(title, content, showCancel, callback, confirmColor, confirmText) { modal: function(title, content, showCancel, callback, confirmColor, confirmText) {
uni.showModal({ uni.showModal({
title: title || '提示', title: title || '提示',
content: content, content: content,
showCancel: showCancel, showCancel: showCancel,
@ -30,18 +66,15 @@ const tui = {
}) })
}, },
isAndroid: function() { isAndroid: function() {
const res = uni.getSystemInfoSync(); const res = getSafeDeviceInfo()
return res.platform.toLocaleLowerCase() == "android" const osName = String(res.osName || res.system || '').toLowerCase()
return osName.indexOf('android') !== -1
}, },
isPhoneX: function() { isPhoneX: function() {
const res = uni.getSystemInfoSync(); const res = getSafeWindowInfo()
let iphonex = false; const safeArea = res.safeArea || {}
let models = ['iphonex', 'iphonexr', 'iphonexsmax', 'iphone11', 'iphone11pro', 'iphone11promax'] const screenHeight = Number(res.screenHeight || res.windowHeight || 0)
const model = res.model.replace(/\s/g, "").toLowerCase() return !!(safeArea.bottom && screenHeight && safeArea.bottom < screenHeight)
if (models.includes(model)) {
iphonex = true;
}
return iphonex;
}, },
constNum: function() { constNum: function() {
let time = 0; let time = 0;
@ -51,11 +84,14 @@ const tui = {
delayed: null, delayed: null,
loadding: false, loadding: false,
showLoading: function(title, mask = true) { showLoading: function(title, mask = true) {
uni.showLoading({ showLoading({
mask: mask, mask: mask,
title: title || '请稍候...' title: title || '请稍候...'
}) })
}, },
hideLoading: function() {
hideLoading()
},
/** /**
* 请求数据处理 * 请求数据处理
* @param string url 请求地址 * @param string url 请求地址
@ -72,7 +108,7 @@ const tui = {
*/ */
request: async function(url, method, postData, isDelay, isForm, hideLoading) { request: async function(url, method, postData, isDelay, isForm, hideLoading) {
//接口请求 //接口请求
tui.loadding && uni.hideLoading(); tui.loadding && tui.hideLoading();
tui.loadding = false; tui.loadding = false;
if (!hideLoading) { if (!hideLoading) {
if (isDelay) { if (isDelay) {
@ -88,18 +124,22 @@ const tui = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let executeRequest = () => { 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({ wx.request({
url: tui.interfaceUrl() + url, url: tui.interfaceUrl() + url,
data: postData, data: postData,
timeout:60000, timeout:60000,
header: { header,
'content-type': isForm ? 'application/x-www-form-urlencoded' : 'application/json',
'accessToken': tui.getToken()
},
method: method, //'GET','POST' method: method, //'GET','POST'
dataType: 'json', dataType: 'json',
success: (res) => { success: (res) => {
if(res.data.code == 401){ if(res.statusCode == 401 || (res.data && res.data.code == 401)){
if(uni.getStorageSync('codePage')){ if(uni.getStorageSync('codePage')){
uni.clearStorage() uni.clearStorage()
uni.setStorageSync('codePage',true) uni.setStorageSync('codePage',true)
@ -116,7 +156,7 @@ const tui = {
clearTimeout(tui.delayed) clearTimeout(tui.delayed)
tui.delayed = null; tui.delayed = null;
if (tui.loadding && !hideLoading) { if (tui.loadding && !hideLoading) {
uni.hideLoading() tui.hideLoading()
} }
resolve(res.data) resolve(res.data)
}, },
@ -154,7 +194,7 @@ const tui = {
const uploadTask = uni.uploadFile({ const uploadTask = uni.uploadFile({
url: tui.interfaceUrl() + url, url: tui.interfaceUrl() + url,
filePath: src, filePath: src,
name: 'imageFile', name: 'file',
header: { header: {
// 'Authorization': tui.getToken() // 'Authorization': tui.getToken()
'accessToken': uni.getStorageSync("hiver_token") 'accessToken': uni.getStorageSync("hiver_token")
@ -163,19 +203,21 @@ const tui = {
// sizeArrayText:"" // sizeArrayText:""
}, },
success: function(res) { success: function(res) {
uni.hideLoading() tui.hideLoading()
let d = JSON.parse(res.result.replace(/\ufeff/g, "") || "{}") let responseText = res.result || res.data || "{}"
let d = JSON.parse(String(responseText).replace(/\ufeff/g, "") || "{}")
if (d.code % 100 == 0) { if (d.code % 100 == 0) {
//返回图片地址 // 返回OSS文件地址
let fileObj = d.result; let fileObj = d.result !== undefined ? d.result : d.data;
resolve(fileObj) resolve(fileObj)
} else { } else {
that.toast(res.message); tui.toast(d.message || res.message || '上传失败');
} }
}, },
fail: function(res) { fail: function(res) {
tui.hideLoading()
reject(res) reject(res)
that.toast(res.message); tui.toast(res.message || '上传失败');
} }
}) })
}) })

2
common/ieApi.js

@ -51,7 +51,7 @@ export function saveIeProfile(data) {
} }
export function verifyIeRealName(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) { export function verifyIeStudentCard(data) {

138
common/ieRealNameAuth.js

@ -5,6 +5,31 @@ function showLongToast(title, duration = 3200) {
uni.showToast({ title, icon: 'none', duration }) 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') { function chooseImage(sourceType = ['camera'], camera = 'front') {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const success = res => { const success = res => {
@ -41,15 +66,17 @@ const MAX_CERT_PICTURE_BASE64_BYTES = 50 * 1024
const STUDENT_CARD_AUTH_DISABLED = true const STUDENT_CARD_AUTH_DISABLED = true
function confirmCameraCapture(title, content, confirmText = '开始拍摄') { function confirmCameraCapture(title, content, confirmText = '开始拍摄') {
return new Promise(resolve => { return showAuthDialog({
uni.showModal({ badge: '照片采集',
title, title,
content, content,
confirmText, confirmText,
cancelText: '取消', cancelText: '取消',
success: res => resolve(!!res.confirm), steps: [
fail: () => resolve(false) '请在光线充足处拍摄',
}) '保持画面清晰无遮挡',
'照片仅用于本次认证'
]
}) })
} }
@ -129,6 +156,7 @@ async function chooseFacePictureBase64() {
if (!confirmed) return '' if (!confirmed) return ''
const path = await chooseImage(['camera'], 'front') const path = await chooseImage(['camera'], 'front')
if (!path) return '' if (!path) return ''
uni.showLoading({ title: '照片处理中\n正在压缩图片', mask: true })
const compressOptions = [ const compressOptions = [
{ quality: 70, width: 480, height: 480 }, { quality: 70, width: 480, height: 480 },
{ quality: 55, width: 360, height: 360 }, { quality: 55, width: 360, height: 360 },
@ -139,13 +167,17 @@ async function chooseFacePictureBase64() {
{ quality: 10, width: 128, height: 128 } { quality: 10, width: 128, height: 128 }
] ]
let lastBase64 = '' let lastBase64 = ''
for (const option of compressOptions) { try {
const compressed = await compressImage(path, option) for (const option of compressOptions) {
const base64 = await readFileBase64(compressed) const compressed = await compressImage(path, option)
lastBase64 = base64 const base64 = await readFileBase64(compressed)
if (base64.length <= MAX_CERT_PICTURE_BASE64_BYTES) { lastBase64 = base64
return base64 if (base64.length <= MAX_CERT_PICTURE_BASE64_BYTES) {
return base64
}
} }
} finally {
uni.hideLoading()
} }
if (lastBase64.length > MAX_CERT_PICTURE_BASE64_BYTES) { if (lastBase64.length > MAX_CERT_PICTURE_BASE64_BYTES) {
showLongToast('人像照片Base64不能超过50KB,请靠近拍摄清晰正脸并减少背景后重试', 3800) showLongToast('人像照片Base64不能超过50KB,请靠近拍摄清晰正脸并减少背景后重试', 3800)
@ -155,28 +187,32 @@ async function chooseFacePictureBase64() {
} }
function confirmAuth(actionText, cancelText) { function confirmAuth(actionText, cancelText) {
return new Promise(resolve => { return showAuthDialog({
uni.showModal({ badge: 'i/e 安全认证',
title: '进阶实名认证', title: '进阶实名认证',
content: `为满足未成年人保护与防沉迷要求,${actionText || '继续使用'}前需要完成身份证三要素核验。`, content: `为满足未成年人保护与防沉迷要求,${actionText || '继续使用'}前需要完成身份证三要素核验。`,
confirmText: '去认证', confirmText: '去认证',
cancelText: cancelText || '暂不继续', cancelText: cancelText || '暂不继续',
success: res => resolve(!!res.confirm), steps: [
fail: () => resolve(false) '填写身份证上的姓名与号码',
}) '拍摄本人清晰正脸照',
'通过后继续完善 i/e 身份资料'
]
}) })
} }
function confirmStudentCardOnly(actionText, cancelText) { function confirmStudentCardOnly(actionText, cancelText) {
return new Promise(resolve => { return showAuthDialog({
uni.showModal({ badge: '学生身份',
title: '学生身份认证', title: '学生身份认证',
content: `${actionText || '继续使用'}前需要完成学生证认证。`, content: `${actionText || '继续使用'}前需要完成学生证认证。`,
confirmText: '去认证', confirmText: '去认证',
cancelText: cancelText || '暂不继续', cancelText: cancelText || '暂不继续',
success: res => resolve(!!res.confirm), steps: [
fail: () => resolve(false) '上传本人学生证照片',
}) '系统识别学生证信息',
'通过后继续 i/e 互动'
]
}) })
} }
@ -219,7 +255,7 @@ async function ensureAliyunRealNameVerified(profile) {
} }
const certPicture = await chooseFacePictureBase64() const certPicture = await chooseFacePictureBase64()
if (!certPicture) return false if (!certPicture) return false
uni.showLoading({ title: '实名认证中...', mask: true }) uni.showLoading({ title: '实名认证中\n正在安全核验', mask: true })
let result = null let result = null
try { try {
result = await verifyIeRealName({ certName, certNo, certPicture }) result = await verifyIeRealName({ certName, certNo, certPicture })
@ -234,10 +270,33 @@ async function ensureAliyunRealNameVerified(profile) {
return true 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 = {}) { export async function ensureIeVerifiedBeforeAction(options = {}) {
const profile = options.profile || {} const profile = options.profile || {}
if (STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified) return true if (STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified) {
if (!STUDENT_CARD_AUTH_DISABLED && profile.realNameVerified && profile.studentCardVerified) return true 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 setting = await getIeRealNameAuditSetting().catch(() => null)
const realNameAuditEnabled = !setting || setting.realNameAuditEnabled !== false const realNameAuditEnabled = !setting || setting.realNameAuditEnabled !== false
if (!realNameAuditEnabled) return true if (!realNameAuditEnabled) return true
@ -257,8 +316,13 @@ export async function ensureIeVerifiedBeforeAction(options = {}) {
// } // }
const realNameOk = await ensureAliyunRealNameVerified(profile) const realNameOk = await ensureAliyunRealNameVerified(profile)
if (!realNameOk) return false if (!realNameOk) return false
let latestProfile = null
if (typeof options.reload === 'function') { if (typeof options.reload === 'function') {
await options.reload() latestProfile = await options.reload()
}
if (needsProfileSetup(latestProfile || profile)) {
goProfileSetup()
return false
} }
return true return true
} catch (e) { } catch (e) {

Loading…
Cancel
Save