|
|
@ -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,6 +167,7 @@ async function chooseFacePictureBase64() { |
|
|
{ quality: 10, width: 128, height: 128 } |
|
|
{ quality: 10, width: 128, height: 128 } |
|
|
] |
|
|
] |
|
|
let lastBase64 = '' |
|
|
let lastBase64 = '' |
|
|
|
|
|
try { |
|
|
for (const option of compressOptions) { |
|
|
for (const option of compressOptions) { |
|
|
const compressed = await compressImage(path, option) |
|
|
const compressed = await compressImage(path, option) |
|
|
const base64 = await readFileBase64(compressed) |
|
|
const base64 = await readFileBase64(compressed) |
|
|
@ -147,6 +176,9 @@ async function chooseFacePictureBase64() { |
|
|
return base64 |
|
|
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) |
|
|
return '' |
|
|
return '' |
|
|
@ -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) { |
|
|
|