feat:认证步骤

This commit is contained in:
ctw committed 2025-12-12 18:45:52 +08:00
1 parent f179f6ab43
commit dfbc79f3ed
9 files changed
+756 -519

No files matched your search

+33 -2
View File
@@ -274,15 +274,46 @@
},
{
"path": "verify-status",
"style": {
"navigationBarTitleText": "人脸认证状态",
"navigationStyle": "custom"
}
},
{
"path": "face-verify/boy-verify",
"style": {
"navigationBarTitleText": "人脸认证",
"navigationStyle": "custom"
}
},
{
"path": "face-verify",
"path": "face-verify/girl-verify-1",
"style": {
"navigationBarTitleText": "人脸认证",
"navigationBarTitleText": "人脸认证-1",
"navigationStyle": "custom",
"app-plus": {
"softinputMode": "adjustResize"
}
}
},
{
"path": "face-verify/girl-verify-2",
"style": {
"navigationBarTitleText": "人脸认证-2",
"navigationStyle": "custom"
}
},
{
"path": "face-verify/girl-verify-3",
"style": {
"navigationBarTitleText": "人脸认证-3",
"navigationStyle": "custom"
}
},
{
"path": "face-verify/girl-verify-4",
"style": {
"navigationBarTitleText": "人脸认证-4",
"navigationStyle": "custom"
}
},
-509
View File
@@ -1,509 +0,0 @@
<template>
<wd-config-provider theme="dark">
<wd-navbar
:title="
userInfoStore.sex == 2 ? '魅力女生认证' : userInfoStore.sex == 1 ? '精英男士认证' : ''
"
safeAreaInsetTop
fixed
placeholder
:bordered="false"
style="z-index: 999"
>
<template #left>
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52" />
</navigator>
</template>
</wd-navbar>
<!-- 女 认证 -->
<view v-if="userInfoStore.sex == 2" class="pt-20" style="height: calc(100vh - 44rpx - 200rpx)">
<wd-steps :active="stepActive" align-center>
<wd-step v-for="index in 4" :key="index" />
</wd-steps>
<view class="h-30rpx"></view>
<view v-if="stepActive === 0">
<view class="text-xl my-2 mx-8 c-#FCFBFE">完善详细资料(必填)</view>
<view class="text-sm my-2 mx-8 c-#949494">认真填写,展现你的魅力~</view>
<view class="h-60rpx"></view>
<wd-picker
v-model="userinfo.height"
:columns="columnsHeight"
label="身高"
title="身高"
align-right
:default-value="180"
>
<capsule-cell title="身高" :value="userinfo.height ? userinfo.height + 'cm' : ''" />
</wd-picker>
<wd-picker
v-model="userinfo.weight"
:columns="columnsWeight"
label="体重"
title="体重"
align-right
:default-value="60"
>
<capsule-cell title="体重" :value="userinfo.weight ? userinfo.weight + 'kg' : ''" />
</wd-picker>
<wd-picker
v-model="userinfo.occ"
:columns="columnsOcc"
label="从事职业"
title="从事职业"
align-right
>
<capsule-cell title="职业" :value="userinfo.occ" />
</wd-picker>
<textarea
class="h-200rpx w-78% mx-auto my-4 rounded-10rpx bg-color-light p-24rpx text-32rpx text-color-theme"
v-model="userinfo.description"
:maxlength="100"
placeholder="个人简介(100字以内)"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
/>
</view>
<view v-if="stepActive === 1">
<view class="text-xl my-2 mx-8 c-#FCFBFE">请上传3-9张最美的照片</view>
<view class="text-sm my-2 mx-8 c-#949494">请上传本人真实照片,更容易受到男士青睐</view>
<view class="h-60rpx"></view>
<view class="mx-8">
<wd-upload
v-model:file-list="imageFileList"
:action="baseUrl + apiPath + '/infra/file/upload'"
:header="header"
image-mode="aspectFill"
accept="image"
multiple
:limit="9"
:max-size="3000000"
@success="uploadSuccess"
:before-remove="beforeRemove"
/>
</view>
</view>
<view v-if="stepActive === 2">
<view class="text-xl my-2 mx-8 c-#FCFBFE">添加联系方式</view>
<view class="text-sm my-2 mx-8 c-#949494">
我们会保护你的隐私,联系方式只展示给审核人员和付费后的VIP男生
</view>
<view class="h-60rpx"></view>
<input
class="h-100rpx mx-8 my-4 rounded-50rpx bg-color-light px-40rpx text-32rpx text-color-theme"
v-model="wxInfo.wechatNumber"
type="text"
placeholder="请输入您的微信号"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
:maxlength="20"
/>
<view class="flex-row-center my-6">
<s-uploader
v-model:url="wxInfo.wechatQrcode"
fileMediatype="image"
limit="1"
mode="grid"
:imageStyles="{
width: '268rpx',
height: '268rpx',
border: { width: '6rpx', color: '#D29E52', radius: '50rpx' },
}"
/>
</view>
<view class="text-sm mx-8 text-color-theme">
请上传与上方微信匹配的微信二维码以便客服核实
</view>
<view class="text-sm mx-8 text-color-theme">匹配不通过将不会认证通过哦~</view>
</view>
<view v-if="stepActive === 3">
<view class="text-xl my-2 mx-8 c-#FCFBFE">基本资料</view>
<view class="text-sm my-2 mx-8 c-#949494">上传清晰的五官头像,让更多用户发现你~</view>
<view class="h-60rpx"></view>
<view class="mx-8 flex items-center">
<s-uploader
class="flex-1"
v-model:url="userinfo.avatar"
fileMediatype="image"
limit="1"
mode="grid"
:imageStyles="{
width: '268rpx',
height: '268rpx',
border: { width: '6rpx', color: '#D29E52', radius: '50rpx' },
}"
/>
<view class="flex-1 flex-col-center">
<image class="w-160rpx h-180rpx" src="@/static/face-auth-prompt.png" mode="aspectFit" />
<view class="text-xs text-color-theme">确保本人头像</view>
<view class="text-xs text-color-theme">才能通过审核哦</view>
</view>
</view>
<wd-datetime-picker
v-model="userinfo.birthday"
label="生日"
title="生日"
type="date"
align-right
:default-value="Date.now()"
:min-date="new Date(1980, 1, 1).getTime()"
:max-date="Date.now()"
>
<capsule-cell title="生日" :value="formatDate(userinfo.birthday, 'YYYY-MM-DD')" />
</wd-datetime-picker>
<input
class="h-100rpx mx-8 my-4 rounded-50rpx bg-color-light px-40rpx text-32rpx text-color-theme"
v-model="userinfo.nickname"
type="text"
placeholder="请输入昵称"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
:maxlength="10"
/>
<capsule-cell title="位置权限" :value="'未允许'" />
</view>
<view class="flex-row-center mt-6 gap-8">
<view
v-if="stepActive > 0"
class="size-160rpx rounded-full bg-color-light text-center line-height-160rpx active:bg-color"
@click="stepActive--"
>
<uni-icons type="arrow-left" color="#D29E52" size="44" />
</view>
<view
v-if="stepActive < 3"
class="size-160rpx rounded-full bg-color-light text-center line-height-160rpx active:bg-color"
@click="nextStep"
>
<uni-icons type="arrow-right" color="#D29E52" size="44" />
</view>
</view>
<view
v-if="stepActive === 3"
class="mx-auto mt-6 w-200rpx rounded-full p-3 text-center bg-color-theme-dark active:bg-color-theme"
@click="createFaceVerify"
>
开始认证
</view>
</view>
<!-- 男 认证 -->
<view v-if="userInfoStore.sex == 1" class="py-10" style="height: calc(100vh - 44px - 50px)">
<view class="text-xl my-2 mx-8 c-#FCFBFE">基本资料</view>
<view class="text-sm my-2 mx-8 c-#949494">上传本人头像,女生更放心与你见面~</view>
<view class="h-60rpx"></view>
<view class="flex-col-center">
<s-uploader
v-model:url="userinfo.avatar"
fileMediatype="image"
limit="1"
mode="grid"
:imageStyles="{
width: '268rpx',
height: '268rpx',
border: { width: '6rpx', color: '#D29E52', radius: '50rpx' },
}"
/>
<image class="w-260rpx" src="@/static/face-auth-prompt.png" mode="aspectFit" />
</view>
<view
class="mx-auto w-200rpx rounded-full p-3 text-center bg-color-theme-dark active:bg-color-theme"
@click="createFaceVerify"
>
开始认证
</view>
<view class="text-sm mx-8 mt-6 text-color-theme text-center">
为保护您的隐私,您的信息只有认证过的女生可以看到,请放心认证
</view>
</view>
<wd-message-box />
</wd-config-provider>
</template>
<script setup lang="ts">
import RecentApi from '@/sheep/api/member/recent';
import SUploader from '@/sheep/components/s-uploader/s-uploader.vue';
import { computed, reactive, ref, watch } from 'vue';
// @ts-ignore
import sheep from '@/sheep/index';
// @ts-ignore
import { baseUrl, apiPath, tenantId } from '@/sheep/config';
// @ts-ignore
import { getAccessToken } from '@/sheep/request';
// @ts-ignore
import { formatDate } from '@/sheep/helper/utils';
import CapsuleCell from './components/capsule-cell.vue';
import { onLoad } from '@dcloudio/uni-app';
// @ts-ignore
import UserApi from '@/sheep/api/member/user';
import useAblum from './use-ablum';
import { useMessage } from '@/uni_modules/wot-design-uni';
const userInfoStore = computed(() => sheep.$store('user').userInfo);
const messageBox = useMessage();
const { ablumList, getUserAlbum } = useAblum();
const stepActive = ref(0);
const imageFileList = ref([]);
// 用户信息
const userinfo = reactive<any>({
avatar: '',
nickname: '',
birthday: '',
height: '',
weight: '',
occ: '',
description: '',
photo: [],
});
// 微信信息
const wxInfo = reactive({
wechatNumber: '',
wechatQrcode: '',
});
watch(
() => ablumList.value,
(val) => {
imageFileList.value = val.map((item: any) => ({ url: item.address, id: item.id }));
},
{ immediate: true },
);
const header = {
Accept: '*/*',
'tenant-id': tenantId,
Authorization: 'Bearer ' + getAccessToken(),
};
const uploadSuccess = async ({ file }: any) => {
await RecentApi.saveUserAlbum({
address: JSON.parse(file.response).data,
resourceType: 'IMAGE',
});
await getUserAlbum();
};
// 相册移除确认
const beforeRemove = ({ file, fileList, resolve }: any) => {
messageBox
.confirm({
msg: '是否移除',
title: '提示',
})
.then(async () => {
const { code } = await RecentApi.deleteUserAlbum(file.id);
if (code === 0) {
await getUserAlbum();
resolve(true);
}
});
};
onLoad(async () => {
const { data } = await UserApi.getUserInfo();
Object.assign(userinfo, {
avatar: data.avatar,
birthday: data.birthday ?? '',
description: data.description,
height: data.height ?? '',
weight: data.weight ?? '',
mobile: data.mobile,
nickname: data.nickname,
occ: data.occ ?? '',
sex: data.sex,
});
});
// 下一步
const nextStep = () => {
if (validate()) stepActive.value++;
};
// 创建人脸认证
const createFaceVerify = async () => {
// #ifndef APP-PLUS
uni.showToast({ title: '当前设备不支持', icon: 'error' });
// #endif
// #ifdef APP-PLUS
if (!userinfo.avatar) return uni.showToast({ title: '请先上传人脸照片', icon: 'error' });
const aliyunVerify = uni.requireNativePlugin('AP-FaceDetectModule');
const metaInfo = JSON.stringify(aliyunVerify.getMetaInfo());
let fvData = null;
if (userInfoStore.value.sex == 2) {
// 创建女生人脸认证
const { code, data } = await RecentApi.createGirlFaceVerify({
memberHeight: userinfo.height,
memberWeight: userinfo.weight,
memberWechatNumber: wxInfo.wechatNumber,
memberOcc: userinfo.occ,
memberDesc: userinfo.description,
authPic: userinfo.avatar,
metaInfoJson: metaInfo,
});
console.log('女 创建人脸认证接口responseData:', code, data);
if (code !== 0)
return uni.showToast({ title: '请上传包含人脸的头像', icon: 'none', duration: 6000 });
fvData = data;
}
if (userInfoStore.value.sex == 1) {
// 创建男生人脸认证
const { code, data } = await RecentApi.createBoyFaceVerify({
authPic: userinfo.avatar,
metaInfoJson: metaInfo,
});
console.log('男 创建人脸认证接口responseData:', code, data);
if (code !== 0)
return uni.showToast({ title: '请上传包含人脸的头像', icon: 'none', duration: 6000 });
fvData = data;
}
verify(fvData.bizId, fvData.id);
// #endif
};
/**
* @param certifyId 阿里人脸认证id
* @param authId 发起认证的id
*/
const verify = (certifyId: string, authId: string) => {
if (!certifyId) return uni.showToast({ title: 'certifyId不存在', icon: 'none' });
if (!authId) return uni.showToast({ title: 'authId不存在', icon: 'none' });
// const p = uni.getSystemInfoSync().platform;
// if (p === 'ios') {
// }
console.log('certifyId', certifyId);
const aliyunVerify = uni.requireNativePlugin('AP-FaceDetectModule');
aliyunVerify.verify(
{
certifyId,
useMsgBox: true,
extParams: null,
},
function (response: any) {
console.log('认证结果', response);
switch (response.code) {
case 2006:
uni.showToast({
title: '认证不通过,请上传与您本人人脸相同的头像图片',
icon: 'none',
duration: 10000,
});
break;
case 1000:
UserApi.updateUser(userinfo).then(() => {
const { code, data } = RecentApi.createWecahtAuth(wxInfo); // 创建微信认证
console.log('创建微信认证response:', code, data);
sheep.$store('user').getInfo(); // 认证完成再次获取用户信息
uni.showToast({ title: '您已认证成功', icon: 'none' });
setTimeout(() => {
uni.navigateBack();
}, 300);
});
break;
case 1001:
RecentApi.cancelFaceVerify({ authId });
uni.showToast({ title: '系统错误', icon: 'none' });
break;
case 1003:
RecentApi.cancelFaceVerify({ authId });
uni.showToast({ title: '验证中断', icon: 'none' });
break;
case 2002:
uni.showToast({ title: '网络错误', icon: 'none' });
break;
case 2003:
uni.showToast({ title: '客户端设备时间错误', icon: 'none' });
break;
default:
uni.showToast({ title: '未知错误', icon: 'none' });
}
},
);
};
const validate = () => {
switch (stepActive.value) {
case 0:
if (userinfo.height && userinfo.weight && userinfo.occ && userinfo.description) {
return true;
} else {
uni.showToast({ title: '请填写完整信息', icon: 'none' });
return false;
}
case 1:
if (imageFileList.value.length > 2 && imageFileList.value.length < 10) {
return true;
} else {
uni.showToast({ title: '请上传照片', icon: 'none' });
return false;
}
case 2:
if (wxInfo.wechatNumber && wxInfo.wechatQrcode) {
return true;
} else {
uni.showToast({ title: '请完善微信信息', icon: 'none' });
return false;
}
case 3:
if (userinfo.birthday && userinfo.nickname) {
return true;
} else {
uni.showToast({ title: '请完善微信信息', icon: 'none' });
return false;
}
default:
return true;
}
};
</script>
<script lang="ts">
// 身高选择器选项
const columnsHeight = Array.from({ length: 100 }, (_, i) => ({
label: i + 100 + 'cm',
value: i + 100,
})).reverse();
// 体重选择器选项
const columnsWeight = Array.from({ length: 80 }, (_, i) => ({
label: i + 20 + 'kg',
value: i + 20,
}));
// 职业选择器选项
const columnsOcc = [
{ text: '互联网', value: '互联网' },
{ text: '金融', value: '金融' },
{ text: '娱乐', value: '娱乐' },
{ text: 'CEO', value: 'CEO' },
{ text: '高管', value: '高管' },
{ text: '投资人', value: '投资人' },
{ text: '学生', value: '学生' },
{ text: '其他', value: '其他' },
{ text: '老师', value: '老师' },
{ text: '白领', value: '白领' },
{ text: '模特', value: '模特' },
{ text: '主播', value: '主播' },
{ text: '幼师', value: '幼师' },
{ text: 'coser', value: 'coser' },
{ text: '空乘', value: '空乘' },
{ text: '公关', value: '公关' },
{ text: '护士', value: '护士' },
];
</script>
@@ -0,0 +1,63 @@
import RecentApi from '@/sheep/api/member/recent';
// @ts-ignore
import sheep from '@/sheep/index';
/**
* @param certifyId 阿里人脸认证id
* @param authId 发起认证的id
*/
const verify = (certifyId: string, authId: string) => {
if (!certifyId) return uni.showToast({ title: 'certifyId不存在', icon: 'none' });
if (!authId) return uni.showToast({ title: 'authId不存在', icon: 'none' });
// const p = uni.getSystemInfoSync().platform;
// if (p === 'ios') {
// }
console.log('certifyId', certifyId);
const aliyunVerify = uni.requireNativePlugin('AP-FaceDetectModule');
aliyunVerify.verify(
{
certifyId,
useMsgBox: true,
extParams: null,
},
function (response: any) {
console.log('认证结果', response);
switch (response.code) {
case 2006:
uni.showToast({
title: '认证不通过,请上传与您本人人脸相同的头像图片',
icon: 'none',
duration: 10000,
});
break;
case 1000:
sheep.$store('user').getInfo(); // 认证完成再次获取用户信息
uni.showToast({ title: '您已认证成功', icon: 'none' });
setTimeout(() => {
uni.navigateBack();
}, 300);
break;
case 1001:
RecentApi.cancelFaceVerify({ authId });
uni.showToast({ title: '系统错误', icon: 'none' });
break;
case 1003:
RecentApi.cancelFaceVerify({ authId });
uni.showToast({ title: '验证中断', icon: 'none' });
break;
case 2002:
uni.showToast({ title: '网络错误', icon: 'none' });
break;
case 2003:
uni.showToast({ title: '客户端设备时间错误', icon: 'none' });
break;
default:
uni.showToast({ title: '未知错误', icon: 'none' });
}
},
);
};
export default verify;
@@ -0,0 +1,116 @@
<template>
<wd-config-provider theme="dark">
<wd-navbar
title="精英男士认证"
safeAreaInsetTop
fixed
placeholder
:bordered="false"
style="z-index: 999"
>
<template #left>
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52" />
</navigator>
</template>
</wd-navbar>
<view class="pt-20" style="height: calc(100vh - 44rpx - 200rpx)">
<view class="text-xl my-2 mx-8 c-#FCFBFE">基本资料</view>
<view class="text-sm my-2 mx-8 c-#949494">上传本人头像,女生更放心与你见面~</view>
<view class="h-60rpx"></view>
<view class="flex-col-center">
<s-uploader
v-model:url="userinfo.avatar"
fileMediatype="image"
limit="1"
mode="grid"
:imageStyles="{
width: '268rpx',
height: '268rpx',
border: { width: '6rpx', color: '#D29E52', radius: '50rpx' },
}"
/>
<image class="w-260rpx" src="@/static/face-auth-prompt.png" mode="aspectFit" />
</view>
<view
class="mx-auto w-200rpx rounded-full p-3 text-center bg-color-theme-dark active:bg-color-theme"
@click="createFaceVerify"
>
开始认证
</view>
<view class="text-sm mx-8 mt-6 text-color-theme text-center">
为保护您的隐私,您的信息只有认证过的女生可以看到,请放心认证
</view>
</view>
</wd-config-provider>
</template>
<script setup lang="ts">
import RecentApi from '@/sheep/api/member/recent';
import { onShow } from '@dcloudio/uni-app';
// @ts-ignore
import UserApi from '@/sheep/api/member/user';
import { reactive } from 'vue';
import verify from './ali-face-verify';
// 用户信息
const userinfo = reactive<any>({
avatar: '',
nickname: '',
birthday: '',
height: '',
weight: '',
occ: '',
description: '',
photo: [],
});
onShow(async () => {
uni.showLoading({ title: '加载中...' });
const { data } = await UserApi.getUserInfo();
Object.assign(userinfo, {
avatar: data.avatar,
birthday: data.birthday ?? '',
description: data.description,
height: data.height ?? '',
weight: data.weight ?? '',
mobile: data.mobile,
nickname: data.nickname,
occ: data.occ ?? '',
sex: data.sex,
});
uni.hideLoading();
});
// 创建人脸认证
const createFaceVerify = async () => {
// #ifndef APP-PLUS
uni.showToast({ title: '当前设备不支持', icon: 'error' });
// #endif
// #ifdef APP-PLUS
if (!userinfo.avatar) return uni.showToast({ title: '请先上传人脸照片', icon: 'error' });
const aliyunVerify = uni.requireNativePlugin('AP-FaceDetectModule');
const metaInfo = JSON.stringify(aliyunVerify.getMetaInfo());
// 创建男生人脸认证
const { code, data } = await RecentApi.createBoyFaceVerify({
authPic: userinfo.avatar,
metaInfoJson: metaInfo,
});
console.log('男 创建人脸认证接口responseData:', code, data);
if (code !== 0)
return uni.showToast({ title: '请上传包含人脸的头像', icon: 'none', duration: 6000 });
const { code: userResCode } = await UserApi.updateUser(userinfo);
if (userResCode !== 0) return;
verify(data.bizId, data.id);
// #endif
};
</script>
@@ -0,0 +1,151 @@
<template>
<wd-config-provider theme="dark">
<wd-navbar
title="魅力女生认证"
safeAreaInsetTop
fixed
placeholder
:bordered="false"
style="z-index: 999"
>
<template #left>
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52" />
</navigator>
</template>
</wd-navbar>
<view class="pt-20" style="height: calc(100vh - 44rpx - 200rpx)">
<wd-steps :active="0" align-center>
<wd-step v-for="index in 4" :key="index" />
</wd-steps>
<view class="h-30rpx"></view>
<view class="text-xl my-2 mx-8 c-#FCFBFE">完善详细资料(必填)</view>
<view class="text-sm my-2 mx-8 c-#949494">认真填写,展现你的魅力~</view>
<view class="h-60rpx"></view>
<wd-picker
v-model="userinfo.height"
:columns="columnsHeight"
label="身高"
title="身高"
align-right
:default-value="180"
>
<capsule-cell title="身高" :value="userinfo.height ? userinfo.height + 'cm' : ''" />
</wd-picker>
<wd-picker
v-model="userinfo.weight"
:columns="columnsWeight"
label="体重"
title="体重"
align-right
:default-value="60"
>
<capsule-cell title="体重" :value="userinfo.weight ? userinfo.weight + 'kg' : ''" />
</wd-picker>
<wd-picker
v-model="userinfo.occ"
:columns="columnsOcc"
label="从事职业"
title="从事职业"
align-right
>
<capsule-cell title="职业" :value="userinfo.occ" />
</wd-picker>
<textarea
class="h-200rpx w-78% mx-auto my-4 rounded-10rpx bg-color-light p-24rpx text-32rpx text-color-theme"
v-model="userinfo.description"
:maxlength="100"
placeholder="个人简介(100字以内)"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
/>
<view
class="size-160rpx rounded-full bg-color-light text-center mx-auto line-height-160rpx active:bg-color"
@click="nextStep"
>
<uni-icons type="arrow-right" color="#D29E52" size="44" />
</view>
</view>
</wd-config-provider>
</template>
<script setup lang="ts">
import { onShow } from '@dcloudio/uni-app';
import { reactive } from 'vue';
// @ts-ignore
import UserApi from '@/sheep/api/member/user';
import CapsuleCell from '../components/capsule-cell.vue';
// 用户信息
const userinfo = reactive<any>({
avatar: '',
nickname: '',
birthday: '',
height: '',
weight: '',
occ: '',
description: '',
photo: [],
});
onShow(async () => {
uni.showLoading({ title: '加载中...' });
const { data } = await UserApi.getUserInfo();
Object.assign(userinfo, {
avatar: data.avatar,
birthday: data.birthday ?? '',
description: data.description,
height: data.height ?? '',
weight: data.weight ?? '',
mobile: data.mobile,
nickname: data.nickname,
occ: data.occ ?? '',
sex: data.sex,
});
uni.hideLoading();
});
const nextStep = async () => {
if (userinfo.height && userinfo.weight && userinfo.occ && userinfo.description) {
const { code } = await UserApi.updateUser(userinfo);
if (code !== 0) return;
return uni.redirectTo({ url: '/pages/profile/face-verify/girl-verify-2' });
}
uni.showToast({ title: '请填写完整信息', icon: 'none' });
};
</script>
<script lang="ts">
// 身高选择器选项
const columnsHeight = Array.from({ length: 100 }, (_, i) => ({
label: i + 100 + 'cm',
value: i + 100,
})).reverse();
// 体重选择器选项
const columnsWeight = Array.from({ length: 80 }, (_, i) => ({
label: i + 20 + 'kg',
value: i + 20,
}));
// 职业选择器选项
const columnsOcc = [
{ text: '互联网', value: '互联网' },
{ text: '金融', value: '金融' },
{ text: '娱乐', value: '娱乐' },
{ text: 'CEO', value: 'CEO' },
{ text: '高管', value: '高管' },
{ text: '投资人', value: '投资人' },
{ text: '学生', value: '学生' },
{ text: '其他', value: '其他' },
{ text: '老师', value: '老师' },
{ text: '白领', value: '白领' },
{ text: '模特', value: '模特' },
{ text: '主播', value: '主播' },
{ text: '幼师', value: '幼师' },
{ text: 'coser', value: 'coser' },
{ text: '空乘', value: '空乘' },
{ text: '公关', value: '公关' },
{ text: '护士', value: '护士' },
];
</script>
@@ -0,0 +1,112 @@
<template>
<wd-config-provider theme="dark">
<wd-navbar
title="魅力女生认证"
safeAreaInsetTop
fixed
placeholder
:bordered="false"
style="z-index: 999"
>
<template #left>
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52" />
</navigator>
</template>
</wd-navbar>
<view class="pt-20" style="height: calc(100vh - 44rpx - 200rpx)">
<wd-steps :active="1" align-center>
<wd-step v-for="index in 4" :key="index" />
</wd-steps>
<view class="h-30rpx"></view>
<view class="text-xl my-2 mx-8 c-#FCFBFE">请上传3-9张最美的照片</view>
<view class="text-sm my-2 mx-8 c-#949494">请上传本人真实照片,更容易受到男士青睐</view>
<view class="h-60rpx"></view>
<view class="mx-8 mb-8">
<wd-upload
v-model:file-list="imageFileList"
:action="baseUrl + apiPath + '/infra/file/upload'"
:header="header"
image-mode="aspectFill"
accept="image"
multiple
:limit="9"
:max-size="3000000"
@success="uploadSuccess"
:before-remove="beforeRemove"
/>
</view>
<view
class="size-160rpx rounded-full bg-color-light text-center mx-auto line-height-160rpx active:bg-color"
@click="nextStep"
>
<uni-icons type="arrow-right" color="#D29E52" size="44" />
</view>
</view>
</wd-config-provider>
</template>
<script setup lang="ts">
// @ts-ignore
import { baseUrl, apiPath, tenantId } from '@/sheep/config';
// @ts-ignore
import { getAccessToken } from '@/sheep/request';
import RecentApi from '@/sheep/api/member/recent';
import { useMessage } from '@/uni_modules/wot-design-uni';
import useAblum from '../use-ablum';
import { ref, watch } from 'vue';
const messageBox = useMessage();
const { ablumList, getUserAlbum } = useAblum();
const imageFileList = ref([]);
watch(
() => ablumList.value,
(val) => {
imageFileList.value = val.map((item: any) => ({ url: item.address, id: item.id }));
},
{ immediate: true },
);
const header = {
Accept: '*/*',
'tenant-id': tenantId,
Authorization: 'Bearer ' + getAccessToken(),
};
const uploadSuccess = async ({ file }: any) => {
await RecentApi.saveUserAlbum({
address: JSON.parse(file.response).data,
resourceType: 'IMAGE',
});
await getUserAlbum();
};
// 相册移除确认
const beforeRemove = ({ file, fileList, resolve }: any) => {
messageBox
.confirm({
msg: '是否移除',
title: '提示',
})
.then(async () => {
const { code } = await RecentApi.deleteUserAlbum(file.id);
if (code === 0) {
await getUserAlbum();
resolve(true);
}
});
};
const nextStep = () => {
if (imageFileList.value.length > 2 && imageFileList.value.length < 10) {
return uni.redirectTo({ url: '/pages/profile/face-verify/girl-verify-3' });
}
uni.showToast({ title: '请上传照片', icon: 'none' });
};
</script>
@@ -0,0 +1,85 @@
<template>
<wd-config-provider theme="dark">
<wd-navbar
title="魅力女生认证"
safeAreaInsetTop
fixed
placeholder
:bordered="false"
style="z-index: 999"
>
<template #left>
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52" />
</navigator>
</template>
</wd-navbar>
<view class="pt-20" style="height: calc(100vh - 44rpx - 200rpx)">
<wd-steps :active="2" align-center>
<wd-step v-for="index in 4" :key="index" />
</wd-steps>
<view class="h-30rpx"></view>
<view class="text-xl my-2 mx-8 c-#FCFBFE">添加联系方式</view>
<view class="text-sm my-2 mx-8 c-#949494">
我们会保护你的隐私,联系方式只展示给审核人员和付费后的VIP男生
</view>
<view class="h-60rpx"></view>
<input
class="h-100rpx mx-8 my-4 rounded-50rpx bg-color-light px-40rpx text-32rpx text-color-theme"
v-model="wxInfo.wechatNumber"
type="text"
placeholder="请输入您的微信号"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
:maxlength="20"
/>
<view class="flex-row-center my-6">
<s-uploader
v-model:url="wxInfo.wechatQrcode"
fileMediatype="image"
limit="1"
mode="grid"
:imageStyles="{
width: '268rpx',
height: '268rpx',
border: { width: '6rpx', color: '#D29E52', radius: '50rpx' },
}"
/>
</view>
<view class="text-sm mx-8 text-color-theme">
请上传与上方微信匹配的微信二维码以便客服核实
</view>
<view class="text-sm mx-8 text-color-theme">匹配不通过将不会认证通过哦~</view>
<view
class="size-160rpx rounded-full bg-color-light text-center mx-auto my-8 line-height-160rpx active:bg-color"
@click="nextStep"
>
<uni-icons type="arrow-right" color="#D29E52" size="44" />
</view>
</view>
</wd-config-provider>
</template>
<script setup lang="ts">
import RecentApi from '@/sheep/api/member/recent';
import { reactive } from 'vue';
// 微信信息
const wxInfo = reactive({
wechatNumber: '',
wechatQrcode: '',
});
const nextStep = async () => {
if (wxInfo.wechatNumber && wxInfo.wechatQrcode) {
const { code, data } = await RecentApi.createWecahtAuth(wxInfo); // 创建微信认证
console.log('创建微信认证response:', code, data);
if (code !== 0) return;
return uni.redirectTo({ url: '/pages/profile/face-verify/girl-verify-4' });
}
uni.showToast({ title: '请完善微信信息', icon: 'none' });
};
</script>
@@ -0,0 +1,151 @@
<template>
<wd-config-provider theme="dark">
<wd-navbar
title="魅力女生认证"
safeAreaInsetTop
fixed
placeholder
:bordered="false"
style="z-index: 999"
>
<template #left>
<navigator open-type="navigateBack" hover-class="navigator-hover">
<uni-icons type="back" size="30" color="#D29E52" />
</navigator>
</template>
</wd-navbar>
<view class="pt-20" style="height: calc(100vh - 44rpx - 200rpx)">
<wd-steps :active="3" align-center>
<wd-step v-for="index in 4" :key="index" />
</wd-steps>
<view class="h-30rpx"></view>
<view class="text-xl my-2 mx-8 c-#FCFBFE">基本资料</view>
<view class="text-sm my-2 mx-8 c-#949494">上传清晰的五官头像,让更多用户发现你~</view>
<view class="h-60rpx"></view>
<view class="mx-8 flex items-center">
<s-uploader
class="flex-1"
v-model:url="userinfo.avatar"
fileMediatype="image"
limit="1"
mode="grid"
:imageStyles="{
width: '268rpx',
height: '268rpx',
border: { width: '6rpx', color: '#D29E52', radius: '50rpx' },
}"
/>
<view class="flex-1 flex-col-center">
<image class="w-160rpx h-180rpx" src="@/static/face-auth-prompt.png" mode="aspectFit" />
<view class="text-xs text-color-theme">确保本人头像</view>
<view class="text-xs text-color-theme">才能通过审核哦</view>
</view>
</view>
<wd-datetime-picker
v-model="userinfo.birthday"
label="生日"
title="生日"
type="date"
align-right
:default-value="Date.now()"
:min-date="new Date(1980, 1, 1).getTime()"
:max-date="Date.now()"
>
<capsule-cell title="生日" :value="formatDate(userinfo.birthday, 'YYYY-MM-DD')" />
</wd-datetime-picker>
<input
class="h-100rpx mx-8 my-4 rounded-50rpx bg-color-light px-40rpx text-32rpx text-color-theme"
v-model="userinfo.nickname"
type="text"
placeholder="请输入昵称"
placeholder-style="color: rgba(255, 255, 255, 0.6)"
:maxlength="10"
/>
<capsule-cell title="位置权限" :value="'未允许'" />
<view
class="mx-auto mt-6 w-200rpx rounded-full p-3 text-center bg-color-theme-dark active:bg-color-theme"
@click="createFaceVerify"
>
开始认证
</view>
</view>
</wd-config-provider>
</template>
<script setup lang="ts">
import { onShow } from '@dcloudio/uni-app';
import CapsuleCell from '../components/capsule-cell.vue';
// @ts-ignore
import { formatDate } from '@/sheep/helper/utils';
import { reactive } from 'vue';
// @ts-ignore
import UserApi from '@/sheep/api/member/user';
import RecentApi from '@/sheep/api/member/recent';
import verify from './ali-face-verify';
// 用户信息
const userinfo = reactive<any>({
avatar: '',
nickname: '',
birthday: '',
height: '',
weight: '',
occ: '',
description: '',
photo: [],
});
onShow(async () => {
uni.showLoading({ title: '加载中...' });
const { data } = await UserApi.getUserInfo();
Object.assign(userinfo, {
avatar: data.avatar,
birthday: data.birthday ?? '',
description: data.description,
height: data.height ?? '',
weight: data.weight ?? '',
mobile: data.mobile,
nickname: data.nickname,
occ: data.occ ?? '',
sex: data.sex,
});
uni.hideLoading();
});
const createFaceVerify = async () => {
// #ifndef APP-PLUS
uni.showToast({ title: '当前设备不支持', icon: 'error' });
// #endif
if (!userinfo.birthday || !userinfo.nickname) {
return uni.showToast({ title: '请完善信息', icon: 'none' });
}
// #ifdef APP-PLUS
if (!userinfo.avatar) return uni.showToast({ title: '请先上传人脸照片', icon: 'error' });
const aliyunVerify = uni.requireNativePlugin('AP-FaceDetectModule');
const metaInfo = JSON.stringify(aliyunVerify.getMetaInfo());
// 创建女生人脸认证
const { code, data } = await RecentApi.createGirlFaceVerify({
memberHeight: userinfo.height,
memberWeight: userinfo.weight,
memberWechatNumber: wxInfo.wechatNumber,
memberOcc: userinfo.occ,
memberDesc: userinfo.description,
authPic: userinfo.avatar,
metaInfoJson: metaInfo,
});
console.log('女 创建人脸认证接口responseData:', code, data);
if (code !== 0)
return uni.showToast({ title: '请上传包含人脸的头像', icon: 'none', duration: 6000 });
verify(data.bizId, data.id);
// #endif
};
</script>
+45 -8
View File
@@ -24,13 +24,11 @@
<view v-else>待认证</view>
</view>
<navigator url="/pages/profile/face-verify" open-type="navigate" hover-class="navigator-hover">
<view class="flex-row-center mt-40">
<wd-button size="large" :disabled="authData?.authStatus == '2'">
{{ authData?.authStatus == '3' ? '重新认证' : '开始认证' }}
</wd-button>
</view>
</navigator>
<view class="flex-row-center mt-40">
<wd-button size="large" :disabled="authData?.authStatus == '2'" @click="goAuth">
{{ authData?.authStatus == '3' ? '重新认证' : '开始认证' }}
</wd-button>
</view>
<button @click="test">测试按钮</button>
</wd-config-provider>
</template>
@@ -38,7 +36,11 @@
<script setup lang="ts">
import RecentApi from '@/sheep/api/member/recent';
import { onShow } from '@dcloudio/uni-app';
import { ref } from 'vue';
import { computed, ref } from 'vue';
// @ts-ignore
import sheep from '@/sheep/index';
const userInfo = computed(() => sheep.$store('user').userInfo);
const test = () => {
const system = uni.getSystemInfoSync();
@@ -55,6 +57,28 @@
} else {
console.log('GPS功能已开启');
}
} else if (system.platform === 'ios') {
const cllocationManger = plus.ios.import('CLLocationManager');
const enable = cllocationManger.locationServicesEnabled();
const status = cllocationManger.authorizationStatus();
plus.ios.deleteObject(cllocationManger);
if (enable && status != 2) {
console.log('手机系统的定位已经打开');
} else {
console.log('手机系统的定位没有打开');
const UIApplication = plus.ios.import('UIApplication');
const application2 = UIApplication.sharedApplication();
const NSURL2 = plus.ios.import('NSURL');
// const setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
// const setting2 = NSURL2.URLWithString("App-Prefs:root=LOCATION_SERVICES");
const setting2 = NSURL2.URLWithString('app-settings:');
//const setting2 = NSURL2.URLWithString("App-Prefs:root=Privacy&path=LOCATION");
// const setting2 = NSURL2.URLWithString("App-Prefs:root=Privacy&path=LOCATION_SERVICES");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
}
}
};
@@ -73,4 +97,17 @@
if (code !== 0) return uni.showToast({ title: '查询用户人脸认证失败', icon: 'none' });
authData.value = data;
};
const goAuth = () => {
if (userInfo.value.sex == 2)
uni.navigateTo({
url: '/pages/profile/face-verify/girl-verify-1',
});
if (userInfo.value.sex == 1) {
uni.navigateTo({
url: '/pages/profile/face-verify/boy-verify',
});
}
};
</script>