首次完整推送,
V:1.20240808.006
This commit is contained in:
@ -0,0 +1,136 @@
|
||||
const { userCollection, REAL_NAME_STATUS, frvLogsCollection } = require('../../common/constants')
|
||||
const { dataDesensitization, catchAwait } = require('../../common/utils')
|
||||
const { encryptData, decryptData } = require('../../common/sensitive-aes-cipher')
|
||||
const { ERROR } = require('../../common/error')
|
||||
|
||||
/**
|
||||
* 查询认证结果
|
||||
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-frv-auth-result
|
||||
* @param {Object} params
|
||||
* @param {String} params.certifyId 认证ID
|
||||
* @returns
|
||||
*/
|
||||
module.exports = async function (params) {
|
||||
const schema = {
|
||||
certifyId: 'string'
|
||||
}
|
||||
|
||||
this.middleware.validate(params, schema)
|
||||
|
||||
const { uid } = this.authInfo // 从authInfo中取出uid属性
|
||||
const { certifyId } = params // 从params中取出certifyId属性
|
||||
|
||||
const user = await userCollection.doc(uid).get() // 根据uid查询用户信息
|
||||
const userInfo = user.data && user.data[0] // 从查询结果中获取userInfo对象
|
||||
|
||||
// 如果用户不存在,抛出账户不存在的错误
|
||||
if (!userInfo) {
|
||||
throw {
|
||||
errCode: ERROR.ACCOUNT_NOT_EXISTS
|
||||
}
|
||||
}
|
||||
|
||||
const { realname_auth: realNameAuth = {} } = userInfo
|
||||
|
||||
// 如果用户已经实名认证,抛出已实名认证的错误
|
||||
if (realNameAuth.auth_status === REAL_NAME_STATUS.CERTIFIED) {
|
||||
throw {
|
||||
errCode: ERROR.REAL_NAME_VERIFIED
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化实人认证服务
|
||||
const frvManager = uniCloud.getFacialRecognitionVerifyManager({
|
||||
requestId: this.getUniCloudRequestId()
|
||||
})
|
||||
|
||||
// 调用frvManager的getAuthResult方法,获取认证结果
|
||||
const [error, res] = await catchAwait(frvManager.getAuthResult({
|
||||
certifyId
|
||||
}))
|
||||
|
||||
// 如果出现错误,抛出未知错误并打印日志
|
||||
if (error) {
|
||||
console.log(ERROR.UNKNOWN_ERROR, 'error: ', error)
|
||||
throw error
|
||||
}
|
||||
|
||||
// 如果认证状态为“PROCESSING”,抛出认证正在处理中的错误
|
||||
if (res.authState === 'PROCESSING') {
|
||||
throw {
|
||||
errCode: ERROR.FRV_PROCESSING
|
||||
}
|
||||
}
|
||||
|
||||
// 如果认证状态为“FAIL”,更新认证日志的状态并抛出认证失败的错误
|
||||
if (res.authState === 'FAIL') {
|
||||
await frvLogsCollection.where({
|
||||
certify_id: certifyId
|
||||
}).update({
|
||||
status: REAL_NAME_STATUS.CERTIFY_FAILED
|
||||
})
|
||||
|
||||
console.log(ERROR.FRV_FAIL, 'error: ', res)
|
||||
throw {
|
||||
errCode: ERROR.FRV_FAIL
|
||||
}
|
||||
}
|
||||
|
||||
// 如果认证状态不为“SUCCESS”,抛出未知错误并打印日志
|
||||
if (res.authState !== 'SUCCESS') {
|
||||
console.log(ERROR.UNKNOWN_ERROR, 'source res: ', res)
|
||||
throw {
|
||||
errCode: ERROR.UNKNOWN_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
// 根据certifyId查询认证记录
|
||||
const frvLogs = await frvLogsCollection.where({
|
||||
certify_id: certifyId
|
||||
}).get()
|
||||
|
||||
const log = frvLogs.data && frvLogs.data[0]
|
||||
|
||||
const updateData = {
|
||||
realname_auth: {
|
||||
auth_status: REAL_NAME_STATUS.CERTIFIED,
|
||||
real_name: log.real_name,
|
||||
identity: log.identity,
|
||||
auth_date: Date.now(),
|
||||
type: 0
|
||||
}
|
||||
}
|
||||
|
||||
// 如果获取到了认证照片的地址,则会对其进行下载,并使用uniCloud.uploadFile方法将其上传到云存储,并将上传后的fileID保存起来。
|
||||
if (res.pictureUrl) {
|
||||
const pictureRes = await uniCloud.httpclient.request(res.pictureUrl)
|
||||
if (pictureRes.status < 400) {
|
||||
const {
|
||||
fileID
|
||||
} = await uniCloud.uploadFile({
|
||||
cloudPath: `user/id-card/${uid}.b64`,
|
||||
cloudPathAsRealPath: true,
|
||||
fileContent: Buffer.from(encryptData.call(this, pictureRes.data.toString('base64')))
|
||||
})
|
||||
updateData.realname_auth.in_hand = fileID
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
// 更新用户认证状态
|
||||
userCollection.doc(uid).update(updateData),
|
||||
// 更新实人认证记录状态
|
||||
frvLogsCollection.where({
|
||||
certify_id: certifyId
|
||||
}).update({
|
||||
status: REAL_NAME_STATUS.CERTIFIED
|
||||
})
|
||||
])
|
||||
|
||||
return {
|
||||
errCode: 0,
|
||||
authStatus: REAL_NAME_STATUS.CERTIFIED,
|
||||
realName: dataDesensitization(decryptData.call(this, log.real_name), { onlyLast: true }), // 对姓名进行脱敏处理
|
||||
identity: dataDesensitization(decryptData.call(this, log.identity)) // 对身份证号进行脱敏处理
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
const { userCollection, REAL_NAME_STATUS, frvLogsCollection, dbCmd } = require('../../common/constants')
|
||||
const { ERROR } = require('../../common/error')
|
||||
const { encryptData } = require('../../common/sensitive-aes-cipher')
|
||||
const { getCurrentDateTimestamp } = require('../../common/utils')
|
||||
|
||||
// const CertifyIdExpired = 25 * 60 * 1000 // certifyId 过期时间为30分钟,在25分时置为过期
|
||||
|
||||
/**
|
||||
* 获取认证ID
|
||||
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-frv-certify-id
|
||||
* @param {Object} params
|
||||
* @param {String} params.realName 真实姓名
|
||||
* @param {String} params.idCard 身份证号码
|
||||
* @param {String} params.metaInfo 客户端初始化时返回的metaInfo
|
||||
* @returns
|
||||
*/
|
||||
module.exports = async function (params) {
|
||||
const schema = {
|
||||
realName: 'realName',
|
||||
idCard: 'idCard',
|
||||
metaInfo: 'string'
|
||||
}
|
||||
|
||||
this.middleware.validate(params, schema)
|
||||
|
||||
const { realName: originalRealName, idCard: originalIdCard, metaInfo } = params // 解构出传入参数的真实姓名、身份证号码、其他元数据
|
||||
const realName = encryptData.call(this, originalRealName) // 对真实姓名进行加密处理
|
||||
const idCard = encryptData.call(this, originalIdCard) // 对身份证号码进行加密处理
|
||||
|
||||
const { uid } = this.authInfo // 获取当前用户的 ID
|
||||
const idCardCertifyLimit = this.config.idCardCertifyLimit || 1 // 获取身份证认证限制次数,默认为1次
|
||||
const realNameCertifyLimit = this.config.realNameCertifyLimit || 5 // 获取实名认证限制次数,默认为5次
|
||||
const frvNeedAlivePhoto = this.config.frvNeedAlivePhoto || false // 是否需要拍摄活体照片,默认为 false
|
||||
|
||||
const user = await userCollection.doc(uid).get() // 获取用户信息
|
||||
const userInfo = user.data && user.data[0] // 获取用户信息对象中的实名认证信息
|
||||
const { realname_auth: realNameAuth = {} } = userInfo // 解构出实名认证信息中的认证状态对象,默认为空对象
|
||||
|
||||
// 如果用户已经实名认证过,不能再次认证
|
||||
if (realNameAuth.auth_status === REAL_NAME_STATUS.CERTIFIED) {
|
||||
throw {
|
||||
errCode: ERROR.REAL_NAME_VERIFIED
|
||||
}
|
||||
}
|
||||
|
||||
// 查询已经使用同一个身份证认证的账号数量,如果超过限制则不能认证
|
||||
const idCardAccount = await userCollection.where({
|
||||
realname_auth: {
|
||||
type: 0, // 用户认证状态是个人
|
||||
auth_status: REAL_NAME_STATUS.CERTIFIED, // 认证状态为已认证
|
||||
identity: idCard // 身份证号码和传入参数的身份证号码相同
|
||||
}
|
||||
}).get()
|
||||
if (idCardAccount.data.length >= idCardCertifyLimit) {
|
||||
throw {
|
||||
errCode: ERROR.ID_CARD_EXISTS
|
||||
}
|
||||
}
|
||||
|
||||
// 查询用户今天已经进行的实名认证次数,如果超过限制则不能认证
|
||||
const userFrvLogs = await frvLogsCollection.where({
|
||||
user_id: uid,
|
||||
created_date: dbCmd.gt(getCurrentDateTimestamp()) // 查询今天的认证记录
|
||||
}).get()
|
||||
|
||||
// 限制用户每日认证次数
|
||||
if (userFrvLogs.data && userFrvLogs.data.length >= realNameCertifyLimit) {
|
||||
throw {
|
||||
errCode: ERROR.REAL_NAME_VERIFY_UPPER_LIMIT
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化实人认证服务
|
||||
const frvManager = uniCloud.getFacialRecognitionVerifyManager({
|
||||
requestId: this.getUniCloudRequestId() // 获取当前
|
||||
})
|
||||
// 调用实人认证服务,获取认证 ID
|
||||
const res = await frvManager.getCertifyId({
|
||||
realName: originalRealName,
|
||||
idCard: originalIdCard,
|
||||
needPicture: frvNeedAlivePhoto,
|
||||
metaInfo
|
||||
})
|
||||
|
||||
// 将认证记录插入到实名认证日志中
|
||||
await frvLogsCollection.add({
|
||||
user_id: uid,
|
||||
certify_id: res.certifyId,
|
||||
real_name: realName,
|
||||
identity: idCard,
|
||||
status: REAL_NAME_STATUS.WAITING_CERTIFIED,
|
||||
created_date: Date.now()
|
||||
})
|
||||
|
||||
// 返回认证ID
|
||||
return {
|
||||
certifyId: res.certifyId
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
getFrvCertifyId: require('./get-certify-id'),
|
||||
getFrvAuthResult: require('./get-auth-result')
|
||||
}
|
Reference in New Issue
Block a user