身份认证页面

This commit is contained in:
wkj 2024-05-17 22:12:55 +08:00
parent b7c95671a5
commit 085ec63909
12 changed files with 208 additions and 67 deletions

View File

@ -1,16 +1,11 @@
/** index.wxss **/
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.page-body {
height: 100vh;
height: 100%;
display: flex;
flex: 1;
flex-direction: column;
box-sizing: border-box;
align-items: stretch;
background-color: @oak-bg-color-page;
.safe-area-inset-bottom();
}
.container {

View File

@ -1,3 +1,4 @@
import { OakUserDisabledException } from '../../../types/Exception';
export default OakComponent({
entity: 'mobile',
@ -11,7 +12,6 @@ export default OakComponent({
filters: [
{
filter() {
// const token = this.features.token.getToken();
const userId = this.features.token.getUserId();
return {
userId,
@ -34,26 +34,50 @@ export default OakComponent({
deleteIdx: undefined,
},
properties: {
showBack: false,
onFinish: undefined as (() => void) | undefined
},
methods: {
async onRefreshMobile(e: any) {
async onRefreshMobile(e: WechatMiniprogram.Touch) {
const { onFinish } = this.props;
this.setState({
refreshing: true,
});
try {
const { code, errMsg } = e.detail;
if (errMsg !== 'getPhoneNumber:ok') {
console.error(errMsg);
this.setMessage({
title: '获取手机号失败',
type: 'warning',
});
// 用户拒绝不用管
console.warn(errMsg);
if (errMsg !== 'getPhoneNumber:fail user deny') {
this.setMessage({
content: '获取手机号失败',
type: 'warning',
});
return;
}
} else {
await this.features.token.getWechatMpUserPhoneNumber(code);
// await this.features.token.getWechatMpUserPhoneNumber(code);
if (onFinish) {
onFinish();
}
else if (process.env.OAK_PLATFORM === 'wechatMp') {
this.triggerEvent('finish', {})
}
}
} catch (err) {
} catch (err: any) {
console.error(err);
if (err instanceof OakUserDisabledException) {
this.setMessage({
content: err?.message,
type: 'error',
});
}
else {
this.setMessage({
content: err?.message || '获取手机号错误',
type: 'error',
});
}
}
this.setState({
refreshing: false,
@ -61,13 +85,8 @@ export default OakComponent({
},
goAddMobile() {
const eventLoggedIn = `mobile:me:login:${Date.now()}`;
this.subEvent(eventLoggedIn, () => {
this.navigateBack();
});
this.navigateTo({
url: '/mobile/login',
eventLoggedIn,
});
},

View File

@ -18,14 +18,14 @@
<view class="container container2">
<l-card type="primary" plaintext="{{true}}">
<view class="card">
您尚未授权手机号
您尚未授权手机号
</view>
</l-card>
</view>
</block>
<l-button type="default" block size="long" open-type="getPhoneNumber" bindgetphonenumber="onRefreshMobile">
授权手机号
<l-button type="default" block size="long" loading="{{ refreshing }}" open-type="getPhoneNumber" bindgetphonenumber="onRefreshMobile">
授权手机号
</l-button>
</view>

View File

@ -14,7 +14,6 @@ export default function render(
{
mobiles?: EntityDict['mobile']['OpSchema'][];
allowRemove: boolean;
showBack: boolean;
tokenMobileId?: string;
},
{
@ -22,10 +21,9 @@ export default function render(
}
>
) {
const { mobiles, allowRemove, tokenMobileId, showBack = false } = props.data;
const { mobiles, allowRemove, tokenMobileId } = props.data;
const { goAddMobile, removeItem, recoverItem, execute } = props.methods;
const [open, setOpen] = useState(false);
const eventLoggedIn = `user:info:login:${Date.now()}`;
return (
<>

View File

@ -18,6 +18,10 @@ export default OakComponent({
type: 1,
entity: 1,
entityId: 1,
fileType: 1,
sort: 1,
isBridge: 1,
uploadState: 1,
},
isList: true,
formData({ data: rows, features }) {
@ -42,8 +46,6 @@ export default OakComponent({
);
}
console.log(file1, file2)
return {
file1,
file2,

View File

@ -1,5 +1,5 @@
<block wx:if="{{ idCardType === 'ID-Card' }}" >
<view class="card-box">
<view class="card" bindtap="onPickMp" data-tag2="file1">
<block wx:if="{{file1Url}}">
@ -39,3 +39,4 @@
</view>
</view>
</block>

View File

@ -3,6 +3,7 @@
"l-loading": "@oak-frontend-base/miniprogram_npm/lin-ui/loading/index",
"l-input": "@oak-frontend-base/miniprogram_npm/lin-ui/input/index",
"l-picker": "@oak-frontend-base/miniprogram_npm/lin-ui/picker/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"idCard": "./idCard/index"
}
}

View File

@ -1,7 +1,22 @@
@import '../../../config/styles/mp/index.less';
.container {
background-color: #fff;
padding: 20rpx 20rpx;
.page-body {
height: 100%;
display: flex;
flex: 1;
flex-direction: column;
box-sizing: border-box;
align-items: stretch;
}
.container {
flex: 1;
display: flex;
flex-direction: column;
}
.inner {
background-color: #fff;
padding: 20rpx 0rpx;
}

View File

@ -1,6 +1,12 @@
import { EntityDict } from '../../../oak-app-domain';
import { generateNewId } from 'oak-domain/lib/utils/uuid';
import {
isIdCardNumber,
isHkCardNumber,
isTwCardNumber,
isAmCardNumber,
isPassportNumber,
} from 'oak-domain/lib/utils/validator';
export default OakComponent({
entity: 'user',
@ -32,11 +38,32 @@ export default OakComponent({
// },
isList: false,
formData({ data: row, features }) {
let file1;
let file2;
const idCardType = row?.idCardType;
if (idCardType === 'ID-Card') {
file1 = row?.extraFile$entity?.find(
(ele) =>
!ele.$$deleteAt$$ &&
ele.tag1 === idCardType &&
ele.tag2 === 'file1'
);
file2 = row?.extraFile$entity?.find(
(ele) =>
!ele.$$deleteAt$$ &&
ele.tag1 === idCardType &&
ele.tag2 === 'file2'
);
}
return {
name: row?.name,
idNumber: row?.idNumber,
idCardType: row?.idCardType,
idState: row?.idState,
file1,
file2,
};
},
data: {
@ -84,5 +111,77 @@ export default OakComponent({
idNumber: value,
});
},
async onConfirm() {
const { name, idCardType, idNumber, idState } = this.state;
if (!name) {
this.setMessage({
type: 'warning',
content: '请输入姓名',
});
return;
}
if (!idCardType) {
this.setMessage({
type: 'warning',
content: '请输入证件类型',
});
return;
}
if (!idNumber) {
this.setMessage({
type: 'warning',
content: '请输入证件号码',
});
return;
}
if (idCardType === 'ID-Card' && !isIdCardNumber(idNumber)) {
this.setMessage({
type: 'warning',
content: '身份证号输入不合法',
});
return;
}
if (idCardType === 'passport' && !isPassportNumber(idNumber)) {
this.setMessage({
type: 'warning',
content: '护照输入不合法',
});
return;
}
if (
idCardType === 'Mainland-passport' &&
!(
isHkCardNumber(idNumber) ||
isTwCardNumber(idNumber) ||
isAmCardNumber(idNumber)
)
) {
this.setMessage({
type: 'warning',
content: '港澳台通行证输入不合法',
});
return;
}
if (idCardType === 'ID-Card') {
const { file1, file2 } = this.state;
if (!file1) {
this.setMessage({
type: 'warning',
content: '请上传身份证人像面',
});
return;
} else if (!file2) {
this.setMessage({
type: 'warning',
content: '请上传身份证国徽面',
});
return;
}
}
// this.execute();
},
},
});

View File

@ -1,13 +1,18 @@
<view class="page-body">
<view class="container">
<l-input required value="{{ name }}" label="{{ t('user:attr.name') }}" placeholder="{{ t('please input name') }}" bind:lininput="setNameMp" />
<view class="inner">
<l-input required value="{{ name }}" label="{{ t('user:attr.name') }}" placeholder="{{ t('please input name') }}" bind:lininput="setNameMp" />
<l-picker required label="{{ t('user:attr.idCardType') }}" placeholder="{{ t('please choose idCardType') }}" range="{{ idCardTypeArr }}" rangeKey="label" value="{{idCardType}}" bind:linchange="setIdCardTypeMp" />
<l-input required disabled="{{!idCardType}}" type="idcard" label="{{ t('user:attr.idNumber') }}" placeholder="{{ t('please input idNumber') }}" bind:lininput="setIdNumberMp" />
<l-input required value="{{ idNumber }}" disabled="{{!idCardType}}" type="idcard" label="{{ t('user:attr.idNumber') }}" placeholder="{{ t('please input idNumber') }}" bind:lininput="setIdNumberMp" />
<block wx:if="{{oakId}}">
<idCard entity="user" entityId="{{oakId}}" origin="{{origin}}" idCardType="{{idCardType}}" oakPath="{{ oakFullpath + '.extraFile$entity' }}" />
<block wx:if="{{oakId && idCardType}}">
<idCard entity="user" entityId="{{oakId}}" origin="{{origin}}" idCardType="{{idCardType}}" oakPath="{{ oakFullpath + '.extraFile$entity' }}" />
</block>
</view>
</view>
<l-button type="default" block size="long" bind:lintap="onConfirm">
提交认证
</l-button>
</view>

View File

@ -6,5 +6,6 @@
"Identity national emblem profile": "身份证国徽面",
"Real name verification passed": "已通过实名验证",
"please upload identity witness profile": "请上传身份证人像面",
"please upload identity national emblem profile": "请上传身份证国徽面"
"please upload identity national emblem profile": "请上传身份证国徽面",
"commit": "提交认证"
}

View File

@ -44,14 +44,19 @@ export const UserActionDef: ActionDef<UserAction, UserState> = {
export type Action = UserAction | IdAction;
export const entityDesc: EntityDesc<Schema, Action, '', {
userState: UserState;
idState: IdState;
gender: Required<Schema>['gender'];
idCardType: Required<Schema>['idCardType'];
}> = {
export const entityDesc: EntityDesc<
Schema,
Action,
'',
{
userState: UserState;
idState: IdState;
gender: Required<Schema>['gender'];
idCardType: Required<Schema>['idCardType'];
}
> = {
locales: {
"zh_CN": {
zh_CN: {
name: '用户',
attr: {
name: '姓名',
@ -65,7 +70,7 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
ref: '指向用户',
files: '相关文件',
userState: '用户状态',
idState: '身份验证状态',
idState: '证状态',
codes: '微信分享二维码',
isRoot: '是否超级用户',
addresses: '收货地址',
@ -73,7 +78,7 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
action: {
activate: '激活',
accept: '同意',
verify: '证',
verify: '证',
reject: '拒绝',
enable: '启用',
disable: '禁用',
@ -88,21 +93,21 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
merged: '已被合并',
},
idState: {
unverified: '未证',
verifying: '证中',
verified: '已证',
unverified: '未证',
verifying: '证中',
verified: '已证',
},
gender: {
male: '男',
female: '女',
},
idCardType: {
"ID-Card": '身份证',
'ID-Card': '身份证',
passport: '护照',
"Mainland-passport": '港澳台通行证',
'Mainland-passport': '港澳台通行证',
},
}
}
},
},
},
indexes: [
{
@ -122,12 +127,12 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
},
{
name: 'nickname',
}
},
],
config: {
type: 'fulltext',
parser: 'ngram',
}
},
},
{
name: 'index_userState_refId',
@ -137,8 +142,8 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
},
{
name: 'ref',
}
]
},
],
},
],
style: {
@ -171,8 +176,8 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
idCardType: {
'ID-Card': '#E0FFFF',
'Mainland-passport': '#2E8B57',
'passport': '#2F4F4F',
passport: '#2F4F4F',
},
}
}
},
},
};