Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
德宏大魔王
uni-starter
提交
5e55a8d3
U
uni-starter
项目概览
德宏大魔王
/
uni-starter
与 Fork 源项目一致
Fork自
DCloud / uni-starter
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-starter
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5e55a8d3
编写于
9月 07, 2022
作者:
DCloud_JSON
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
修复已知问题
上级
bd7be1a7
变更
52
展开全部
隐藏空白更改
内联
并排
Showing
52 changed file
with
3064 addition
and
1491 deletion
+3064
-1491
lang/i18n.js
lang/i18n.js
+0
-6
lang/zh-Hans.js
lang/zh-Hans.js
+1
-1
pages.json
pages.json
+7
-6
pages/ucenter/settings/settings.vue
pages/ucenter/settings/settings.vue
+12
-42
pages/ucenter/ucenter.vue
pages/ucenter/ucenter.vue
+18
-17
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-open-bridge/config.json
...ions/common/uni-config-center/uni-open-bridge/config.json
+12
-0
uni_modules/uni-id-pages/changelog.md
uni_modules/uni-id-pages/changelog.md
+16
-0
uni_modules/uni-id-pages/common/common.js
uni_modules/uni-id-pages/common/common.js
+12
-0
uni_modules/uni-id-pages/common/login-page.mixin.js
uni_modules/uni-id-pages/common/login-page.mixin.js
+2
-2
uni_modules/uni-id-pages/common/login-page.scss
uni_modules/uni-id-pages/common/login-page.scss
+44
-13
uni_modules/uni-id-pages/common/password.js
uni_modules/uni-id-pages/common/password.js
+5
-33
uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue
...dules/uni-id-pages/components/cloud-image/cloud-image.vue
+2
-2
uni_modules/uni-id-pages/components/uni-id-pages-email-form/uni-id-pages-email-form.vue
...nents/uni-id-pages-email-form/uni-id-pages-email-form.vue
+246
-0
uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue
...ponents/uni-id-pages-fab-login/uni-id-pages-fab-login.vue
+66
-56
uni_modules/uni-id-pages/config.js
uni_modules/uni-id-pages/config.js
+10
-13
uni_modules/uni-id-pages/pages/login/login-smscode.vue
uni_modules/uni-id-pages/pages/login/login-smscode.vue
+4
-0
uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue
uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue
+15
-2
uni_modules/uni-id-pages/pages/login/login-withpwd.vue
uni_modules/uni-id-pages/pages/login/login-withpwd.vue
+12
-4
uni_modules/uni-id-pages/pages/register/register-by-email.vue
...modules/uni-id-pages/pages/register/register-by-email.vue
+216
-0
uni_modules/uni-id-pages/pages/register/register.vue
uni_modules/uni-id-pages/pages/register/register.vue
+53
-10
uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue
...modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue
+216
-0
uni_modules/uni-id-pages/pages/retrieve/retrieve.vue
uni_modules/uni-id-pages/pages/retrieve/retrieve.vue
+41
-3
uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue
...s/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue
+16
-1
uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue
...les/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue
+19
-3
uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate.vue
...les/uni-id-pages/pages/userinfo/deactivate/deactivate.vue
+24
-16
uni_modules/uni-id-pages/pages/userinfo/userinfo.js
uni_modules/uni-id-pages/pages/userinfo/userinfo.js
+166
-0
uni_modules/uni-id-pages/pages/userinfo/userinfo.vue
uni_modules/uni-id-pages/pages/userinfo/userinfo.vue
+229
-219
uni_modules/uni-id-pages/pages_init.json
uni_modules/uni-id-pages/pages_init.json
+87
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js
...ges/uniCloud/cloudfunctions/uni-id-co/common/validator.js
+40
-22
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.test.js
...niCloud/cloudfunctions/uni-id-co/common/validator.test.js
+209
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/config/permission.js
...es/uniCloud/cloudfunctions/uni-id-co/config/permission.js
+3
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js
...i-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js
+21
-3
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js
...ges/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js
+2
-2
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js
...ages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js
+15
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js
...ges/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js
+47
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js
...d-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js
+10
-7
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js
...s/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js
+16
-6
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js
...ges/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js
+1
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
...niCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
+44
-7
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js
...s/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js
+2
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js
...loud/cloudfunctions/uni-id-co/module/admin/update-user.js
+128
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js
...uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js
+3
-36
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/remove-authorized-app.js
...tions/uni-id-co/module/multi-end/remove-authorized-app.js
+1
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json
...i-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json
+1
-1
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js
...udfunctions/common/uni-open-bridge-common/bridge-error.js
+4
-4
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js
...ud/cloudfunctions/common/uni-open-bridge-common/config.js
+94
-94
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
...ud/cloudfunctions/common/uni-open-bridge-common/consts.js
+25
-18
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
...oud/cloudfunctions/common/uni-open-bridge-common/index.js
+218
-209
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
...d/cloudfunctions/common/uni-open-bridge-common/storage.js
+116
-116
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
...unctions/common/uni-open-bridge-common/uni-cloud-cache.js
+323
-323
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
...cloudfunctions/common/uni-open-bridge-common/validator.js
+30
-30
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
...dfunctions/common/uni-open-bridge-common/weixin-server.js
+160
-160
未找到文件。
lang/i18n.js
浏览文件 @
5e55a8d3
...
...
@@ -87,12 +87,6 @@ console.log(`
})
})
},
1
)
//更新 uni-starter.config agreements
let
agreementsTitle
=
$i18n
(
'
agreementsTitle
'
).
split
(
'
,
'
)
let
agreements
=
uniStarterConfig
.
about
.
agreements
agreements
[
0
].
title
=
agreementsTitle
[
0
]
agreements
[
1
].
title
=
agreementsTitle
[
1
]
uniStarterConfig
.
about
.
agreements
=
agreements
}
initLanguageAfter
()
uni
.
$on
(
'
changeLanguage
'
,
e
=>
{
...
...
lang/zh-Hans.js
浏览文件 @
5e55a8d3
...
...
@@ -108,7 +108,7 @@ export default {
},
settings
:{
navigationBarTitle
:
"
设置
"
,
userInfo
:
"
个人
资料
"
,
userInfo
:
"
账号
资料
"
,
changePassword
:
"
修改密码
"
,
clearTmp
:
"
清理缓存
"
,
pushServer
:
"
推送功能
"
,
...
...
pages.json
浏览文件 @
5e55a8d3
...
...
@@ -122,12 +122,13 @@
"style"
:
{
"navigationBarTitleText"
:
"注销账号"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/userinfo"
,
"style"
:
{
"navigationBarTitleText"
:
"个人资料"
}
},
{
},
{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/userinfo"
,
"style"
:
{
"navigationBarTitleText"
:
"个人资料"
}
},{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile"
,
"style"
:
{
"navigationBarTitleText"
:
"绑定手机号码"
...
...
pages/ucenter/settings/settings.vue
浏览文件 @
5e55a8d3
...
...
@@ -18,12 +18,8 @@
<uni-list-item
v-if=
"i18nEnable"
:title=
"$t('settings.changeLanguage')"
@
click=
"changeLanguage"
:rightText=
"currentLanguage"
link
></uni-list-item>
</uni-list>
<uni-list
class=
"mt10"
:border=
"false"
>
<uni-list-item
@
click=
"deactivate"
:title=
"$t('settings.deactivate')"
link=
"navigateTo"
></uni-list-item>
</uni-list>
<!-- 退出/登录 按钮 -->
<view
class=
"bottom-back"
@
click=
"c
lickLogout
"
>
<view
class=
"bottom-back"
@
click=
"c
hangeLoginState
"
>
<text
class=
"bottom-back-text"
v-if=
"hasLogin"
>
{{
$t
(
'
settings.logOut
'
)
}}
</text>
<text
class=
"bottom-back-text"
v-else
>
{{
$t
(
'
settings.login
'
)
}}
</text>
</view>
...
...
@@ -31,7 +27,8 @@
</
template
>
<
script
>
import
pushServer
from
'
./dc-push/push.js
'
;
import
pushServer
from
'
./dc-push/push.js
'
;
import
common
from
'
@/uni_modules/uni-id-pages/common/common.js
'
;
export
default
{
data
()
{
return
{
...
...
@@ -77,16 +74,15 @@
//#endif
},
methods
:
{
toEdit
()
{
uni
.
navigateTo
({
url
:
'
/pages/ucenter/userinfo/userinfo
'
});
},
deactivate
(){
uni
.
navigateTo
({
url
:
"
/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate
"
})
},
async
changeLoginState
(){
if
(
this
.
hasLogin
){
await
common
.
logout
()
}
else
{
uni
.
redirectTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
});
}
},
/**
* 开始生物认证
*/
...
...
@@ -163,32 +159,6 @@
})
})
},
clickLogout
()
{
if
(
this
.
hasLogin
)
{
uni
.
showModal
({
title
:
this
.
$t
(
'
settings.tips
'
),
content
:
this
.
$t
(
'
settings.exitLogin
'
),
cancelText
:
this
.
$t
(
'
settings.cancelText
'
),
confirmText
:
this
.
$t
(
'
settings.confirmText
'
),
success
:
res
=>
{
if
(
res
.
confirm
)
{
uni
.
removeStorageSync
(
'
uni_id_token
'
);
uni
.
setStorageSync
(
'
uni_id_token_expired
'
,
0
)
uni
.
redirectTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
});
}
}
});
}
else
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
6369696
,
e
);
}
});
}
},
clearTmp
()
{
uni
.
showLoading
({
title
:
this
.
$t
(
'
settings.clearing
'
),
...
...
pages/ucenter/ucenter.vue
浏览文件 @
5e55a8d3
...
...
@@ -2,7 +2,7 @@
<view
class=
"center"
>
<uni-sign-in
ref=
"signIn"
></uni-sign-in>
<view
class=
"userInfo"
@
click.capture=
"toUserInfo"
>
<cloud-image
width=
"150rpx"
height=
"150rpx"
v-if=
"userInfo.avatar_file&&userInfo.avatar_file.url"
:src=
"userInfo.avatar_file.url"
></cloud-image>
<cloud-image
width=
"150rpx"
height=
"150rpx"
v-if=
"
hasLogin&&
userInfo.avatar_file&&userInfo.avatar_file.url"
:src=
"userInfo.avatar_file.url"
></cloud-image>
<image
v-else
class=
"logo-img"
src=
"@/static/uni-center/defaultAvatarUrl.png"
></image>
<view
class=
"logo-title"
>
<text
class=
"uer-name"
v-if=
"hasLogin"
>
{{
userInfo
.
nickname
||
userInfo
.
username
||
userInfo
.
mobile
}}
</text>
...
...
@@ -133,7 +133,8 @@
"
radius
"
:
"
100%
"
// 边框圆角,支持百分比
}
},
userInfo
:{}
userInfo
:{},
hasLogin
:
false
}
},
onLoad
()
{
...
...
@@ -145,15 +146,25 @@
icon
:
'
loop
'
,
showBadge
:
this
.
appVersion
.
hasNew
})
//#endif
//#endif
},
onShow
()
{
console
.
log
(
'
this.hasLogin
'
,
this
.
hasLogin
);
this
.
hasLogin
=
uniCloud
.
getCurrentUserInfo
().
tokenExpired
>
Date
.
now
()
if
(
this
.
hasLogin
){
this
.
getUserInfo
()
}
},
computed
:
{
},
computed
:
{
test
:{
get
(){
console
.
log
(
this
.
_test
,
Date
.
now
());
this
.
_test
=
Date
.
now
()
return
''
},
set
(){
}
},
// #ifdef APP-PLUS
appVersion
()
{
return
getApp
().
appVersion
...
...
@@ -161,19 +172,10 @@
// #endif
appConfig
()
{
return
getApp
().
globalData
.
config
},
hasLogin
(){
return
uniCloud
.
getCurrentUserInfo
().
tokenExpired
>
Date
.
now
()
}
}
},
methods
:
{
setUserInfo
(
data
){
},
getUserInfo
(
e
)
{
uni
.
showLoading
({
mask
:
true
});
const
db
=
uniCloud
.
database
();
db
.
collection
(
'
uni-id-users
'
).
where
(
"
'_id' == $cloudEnv_uid
"
).
field
(
'
mobile,nickname,avatar_file
'
).
get
().
then
(
res
=>
{
console
.
log
({
res
});
...
...
@@ -184,7 +186,6 @@
console
.
log
(
e
.
message
,
e
.
errCode
);
}).
finally
(
e
=>
{
// console.log(e);
uni
.
hideLoading
()
})
},
toSettings
()
{
...
...
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-open-bridge/config.json
0 → 100644
浏览文件 @
5e55a8d3
{
"schedule"
:
{
"__UNI__xxxxxx"
:
{
"enable"
:
true
,
"h5-weixin"
:
{
"enable"
:
false
,
"tasks"
:
[
"ticket"
]
}
}
},
"ipWhitelist"
:
[
"0.0.0.0"
]
}
\ No newline at end of file
uni_modules/uni-id-pages/changelog.md
浏览文件 @
5e55a8d3
## 1.0.12(2022-09-07)
-
修复 getSupportedLoginType判断是否支持微信公众号、PC网页微信扫码登录方式报错的Bug
-
优化 适配pc端样式
-
新增 邮箱验证码注册
-
新增 邮箱验证码找回密码
-
新增 退出登录(全局)回调事件:
`uni-id-pages-logout`
,支持通过
[
uni.$on
](
https://uniapp.dcloud.net.cn/api/window/communication.html#on
)
监听;
-
调整 抽离退出登录方法至
`/uni_modules/uni-id-pages/common/common.js`
中,方便在项目其他页面中调用
-
调整 用户中心(路径:
`/uni_modules/uni-id-pages/pages/userinfo/userinfo`
)默认不再显示退出登录按钮。支持页面传参数
`showLoginManage=true`
恢复显示
## 1.0.11(2022-09-01)
-
修复 iOS端,一键登录功能卡在showLoading的问题
-
更新 合并密码强度与长度配置
[
详情
](
https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#config
)
-
uni-id-co 修复 调用 removeAuthorizedApp 接口报错的Bug
-
uni-id-co 新增 管理端接口 updateUser
[
详情
](
https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user
)
-
uni-id-co 调整 为兼容旧版本,未配置密码强度时提供最简单的密码规则校验(长度大于6即可)
-
uni-id-co 调整 注册、登录时如果携带了token则尝试对此token进行登出操作
-
uni-id-co 调整 管理端接口 addUser 增加 mobile、email等参数
[
详情
](
https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#add-user
)
## 1.0.10(2022-08-25)
-
修复 导入uni-id-pages插件时未自动导入uni-open-bridge-common的Bug
## 1.0.9(2022-08-23)
...
...
uni_modules/uni-id-pages/common/common.js
0 → 100644
浏览文件 @
5e55a8d3
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
)
export
default
{
async
logout
()
{
await
uniIdCo
.
logout
()
uni
.
removeStorageSync
(
'
uni_id_token
'
);
uni
.
setStorageSync
(
'
uni_id_token_expired
'
,
0
)
uni
.
redirectTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
});
uni
.
$emit
(
'
uni-id-pages-logout
'
)
},
}
\ No newline at end of file
uni_modules/uni-id-pages/common/login-page.mixin.js
浏览文件 @
5e55a8d3
...
...
@@ -9,11 +9,11 @@ let mixin = {
},
onUnload
()
{
// #ifdef H5
document
.
onkeydown
=
false
document
.
onkeydown
=
false
// #endif
},
mounted
()
{
this
.
isMounted
=
true
;
this
.
isMounted
=
true
;
},
onLoad
(
e
)
{
if
(
e
.
is_weixin_redirect
)
{
...
...
uni_modules/uni-id-pages/common/login-page.scss
浏览文件 @
5e55a8d3
...
...
@@ -2,20 +2,54 @@
padding
:
0
60rpx
;
}
.login-logo
{
display
:
none
;
}
/* #ifndef APP-NVUE */
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
0
;
max-width
:
400px
;
margin-left
:
calc
(
50%
-
200px
);
/* #ifndef H5 */
padding
:
0
;
max-width
:
300px
;
margin-left
:
calc
(
50%
-
200px
);
/* #endif */
/* #ifdef H5 */
margin
:
0
auto
;
position
:
relative
;
top
:
100px
;
padding
:
30px
40px
80px
40px
;
max-width
:
450px
;
max-height
:
450px
;
border-radius
:
10px
;
box-shadow
:
0
0
20px
#efefef
;
background-color
:
#FFF
;
/* #endif */
}
/* #ifdef H5 */
.login-logo
{
display
:
flex
;
justify-content
:
center
;
}
.login-logo
image
{
width
:
60px
;
height
:
60px
;
}
.register-back
{
display
:
none
;
}
/* #endif */
}
.uni-content
view
{
box-sizing
:
border-box
;
}
/* #endif */
.title
{
/* #ifndef APP-NVUE */
display
:
flex
;
...
...
@@ -61,12 +95,9 @@
margin
:
15px
0
0
0
;
color
:
#FFF
!
important
;
border-radius
:
5px
;
}
/*
.uni-btn::after{
display: none;
}
.uni-btn[disabled]{
background-color: $uni-color-primary !important;
opacity: 0.3;
}*/
\ No newline at end of file
}
.uni-body.uni_modules-uni-id-pages-pages-login-login-withoutpwd
{
height
:
auto
!
important
;
}
\ No newline at end of file
uni_modules/uni-id-pages/common/password.js
浏览文件 @
5e55a8d3
// 导入配置
import
config
from
'
@/uni_modules/uni-id-pages/config.js
'
const
passwordLength
=
config
.
password
.
length
const
passwordStrength
=
config
.
password
.
strength
const
{
passwordStrength
}
=
config
let
minPasswordLength
=
6
let
maxPasswordLength
=
20
if
(
passwordLength
)
{
if
(
passwordLength
[
0
])
{
minPasswordLength
=
passwordLength
[
0
]
}
if
(
passwordLength
[
1
])
{
maxPasswordLength
=
passwordLength
[
1
]
}
}
// 密码强度表达式
const
passwordRules
=
{
// 密码必须包含大小写字母、数字和特殊符号
...
...
@@ -33,15 +22,10 @@ const ERROR = {
rePwdErr
:
'
两次输入密码不一致
'
},
passwordStrengthError
:
{
superstrong
:
'
密码必须包含大小写字母、数字和特殊符号
'
,
strong
:
'
密码必须包含字母、数字和特殊符号
'
,
medium
:
'
密码必须为字母、数字和特殊符号任意两种的组合
'
,
weak
:
'
密码必须包含字母
'
},
passwordLengthError
:
{
normal
:
'
密码长度必须在
'
+
minPasswordLength
+
'
-
'
+
maxPasswordLength
+
'
位之间
'
,
minLimit
:
'
密码长度不得少于
'
+
minPasswordLength
+
'
位
'
,
maxLimit
:
'
密码长度不得超过
'
+
maxPasswordLength
+
'
位
'
super
:
'
密码必须包含大小写字母、数字和特殊符号,密码长度必须在8-16位之间
'
,
strong
:
'
密码必须包含字母、数字和特殊符号,密码长度必须在8-16位之间
'
,
medium
:
'
密码必须为字母、数字和特殊符号任意两种的组合,密码长度必须在8-16位之间
'
,
weak
:
'
密码必须包含字母,密码长度必须在6-16位之间
'
}
}
...
...
@@ -52,16 +36,6 @@ function validPwd(password) {
return
ERROR
.
passwordStrengthError
[
passwordStrength
]
}
}
//长度校验
if
(
passwordLength
)
{
if
(
passwordLength
[
0
]
&&
password
.
length
<
passwordLength
[
0
])
{
return
ERROR
.
passwordLengthError
.
minLimit
}
if
(
passwordLength
[
1
]
&&
password
.
length
>
passwordLength
[
1
])
{
return
ERROR
.
passwordLengthError
.
maxLimit
}
}
return
true
}
...
...
@@ -106,8 +80,6 @@ function getPwdRules(pwdName = 'password', rePwdName = 'password2') {
export
default
{
ERROR
,
minPasswordLength
,
maxPasswordLength
,
validPwd
,
getPwdRules
}
uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue
浏览文件 @
5e55a8d3
...
...
@@ -46,8 +46,8 @@
watch
:
{
src
:{
handler
(
src
)
{
//
console.log(src);
//
console.log(src.substring(0, 8));
console
.
log
(
src
);
console
.
log
(
src
.
substring
(
0
,
8
));
if
(
src
&&
src
.
substring
(
0
,
8
)
==
"
cloud://
"
)
{
uniCloud
.
getTempFileURL
({
fileList
:
[
src
]
...
...
uni_modules/uni-id-pages/components/uni-id-pages-email-form/uni-id-pages-email-form.vue
0 → 100644
浏览文件 @
5e55a8d3
<
template
>
<view>
<uni-captcha
:focus=
"focusCaptchaInput"
ref=
"captcha"
scene=
"send-email-code"
v-model=
"captcha"
/>
<view
class=
"box"
>
<uni-easyinput
:focus=
"focusEmailCodeInput"
@
blur=
"focusEmailCodeInput = false"
type=
"number"
class=
"input-box"
:inputBorder=
"false"
v-model=
"modelValue"
maxlength=
"6"
placeholder=
"请输入邮箱验证码"
>
</uni-easyinput>
<view
class=
"short-code-btn"
hover-class=
"hover"
@
click=
"start"
>
<text
class=
"inner-text"
:class=
"reverseNumber==0?'inner-text-active':''"
>
{{
innerText
}}
</text>
</view>
</view>
</view>
</
template
>
<
script
>
function
debounce
(
func
,
wait
)
{
let
timer
;
wait
=
wait
||
500
;
return
function
()
{
let
context
=
this
;
let
args
=
arguments
;
if
(
timer
)
clearTimeout
(
timer
);
let
callNow
=
!
timer
;
timer
=
setTimeout
(()
=>
{
timer
=
null
;
},
wait
)
if
(
callNow
)
func
.
apply
(
context
,
args
);
}
}
/**
* email-code-form
* @description 获取邮箱验证码组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=
* @property {Number} count 倒计时时长 s
* @property {String} email 邮箱
* @property {String} type = [login-by-email-code|reset-pwd-by-email-code|bind-email] 验证码类型,用于防止不同功能的验证码混用,目前支持的类型login登录、register注册、bind绑定邮箱、unbind解绑邮箱
* @property {false} focusCaptchaInput = [true|false] 验证码输入框是否默认获取焦点
*/
export
default
{
name
:
"
uni-email-code-form
"
,
model
:
{
prop
:
'
modelValue
'
,
event
:
'
update:modelValue
'
},
props
:
{
event
:
[
'
update:modelValue
'
],
/**
* 倒计时时长 s
*/
count
:
{
type
:
[
String
,
Number
],
default
:
60
},
/**
* 邮箱
*/
email
:
{
type
:
[
String
],
default
:
''
},
/*
验证码类型,用于防止不同功能的验证码混用,目前支持的类型login登录、register注册、bind绑定邮箱、unbind解绑邮箱
*/
type
:
{
type
:
String
,
default
()
{
return
'
register
'
}
},
/*
验证码输入框是否默认获取焦点
*/
focusCaptchaInput
:
{
type
:
Boolean
,
default
()
{
return
false
}
},
},
data
()
{
return
{
captcha
:
""
,
reverseNumber
:
0
,
reverseTimer
:
null
,
modelValue
:
""
,
focusEmailCodeInput
:
false
};
},
watch
:
{
captcha
(
value
,
oldValue
)
{
if
(
value
.
length
==
4
&&
oldValue
.
length
!=
4
)
{
this
.
start
()
}
},
modelValue
(
value
)
{
// TODO 兼容 vue2
this
.
$emit
(
'
input
'
,
value
);
// TODO 兼容 vue3
this
.
$emit
(
'
update:modelValue
'
,
value
)
}
},
computed
:
{
innerText
()
{
if
(
this
.
reverseNumber
==
0
)
return
"
获取邮箱验证码
"
;
return
"
重新发送
"
+
'
(
'
+
this
.
reverseNumber
+
'
s)
'
;
}
},
created
()
{
this
.
initClick
();
},
methods
:
{
getImageCaptcha
(
focus
)
{
this
.
$refs
.
captcha
.
getImageCaptcha
(
focus
)
},
initClick
()
{
this
.
start
=
debounce
(()
=>
{
if
(
this
.
reverseNumber
!=
0
)
return
;
this
.
sendMsg
();
})
},
sendMsg
()
{
if
(
this
.
captcha
.
length
!=
4
)
{
this
.
$refs
.
captcha
.
focusCaptchaInput
=
true
return
uni
.
showToast
({
title
:
'
请先输入图形验证码
'
,
icon
:
'
none
'
});
}
if
(
!
this
.
email
)
return
uni
.
showToast
({
title
:
"
请输入邮箱
"
,
icon
:
'
none
'
});
let
reg_email
=
/@/
;
if
(
!
reg_email
.
test
(
this
.
email
))
return
uni
.
showToast
({
title
:
"
邮箱格式错误
"
,
icon
:
'
none
'
});
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
,
{
customUI
:
true
})
console
.
log
(
'
uniIdCo
'
,
uniIdCo
)
console
.
log
(
'
sendEmailCode
'
,{
"
email
"
:
this
.
email
,
"
scene
"
:
this
.
type
,
"
captcha
"
:
this
.
captcha
});
uniIdCo
.
sendEmailCode
({
"
email
"
:
this
.
email
,
"
scene
"
:
this
.
type
,
"
captcha
"
:
this
.
captcha
}).
then
(
result
=>
{
console
.
log
(
result
.
code
);
uni
.
showToast
({
title
:
"
邮箱验证码发送成功
"
,
icon
:
'
none
'
});
this
.
reverseNumber
=
Number
(
this
.
count
);
this
.
getCode
();
}).
catch
(
e
=>
{
console
.
log
(
JSON
.
stringify
(
e
));
if
(
e
.
code
==
"
uni-id-invalid-mail-template
"
)
{
this
.
modelValue
=
"
123456
"
uni
.
showToast
({
title
:
'
已启动测试模式,详情【控制台信息】
'
,
icon
:
'
none
'
,
duration
:
3000
});
console
.
warn
(
e
.
message
);
}
else
{
this
.
getImageCaptcha
()
this
.
captcha
=
""
uni
.
showToast
({
title
:
e
.
message
,
icon
:
'
none
'
});
}
})
},
getCode
()
{
if
(
this
.
reverseNumber
==
0
)
{
clearTimeout
(
this
.
reverseTimer
);
this
.
reverseTimer
=
null
;
return
;
}
this
.
reverseNumber
--
;
this
.
reverseTimer
=
setTimeout
(()
=>
{
this
.
getCode
();
},
1000
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.box
{
position
:
relative
;
margin-top
:
10px
;
}
.short-code-btn
{
padding
:
0
;
position
:
absolute
;
top
:
0
;
right
:
8px
;
width
:
260rpx
;
max-width
:
130px
;
height
:
44px
;
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
justify-content
:
center
;
align-items
:
center
;
}
.inner-text
{
font-size
:
14px
;
color
:
#AAAAAA
;
}
.inner-text-active
{
color
:
#04498c
;
}
.captcha
{
width
:
350rpx
;
}
.input-box
{
margin
:
0
;
padding
:
4px
;
background-color
:
#F8F8F8
;
font-size
:
14px
;
}
.
box
:
:
v-deep
.
content-clear-icon
{
margin-right
:
100px
;
}
.box
{
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
flex-direction
:
row
;
}
</
style
>
uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue
浏览文件 @
5e55a8d3
...
...
@@ -15,12 +15,12 @@
<
script
>
import
config
from
'
@/uni_modules/uni-id-pages/config.js
'
//前一个窗口的页面地址。控制点击切换快捷登录方式是创建还是返回
import
loginSuccess
from
'
../../common/loginSuccess.js
'
;
import
loginSuccess
from
'
../../common/loginSuccess.js
'
;
const
db
=
uniCloud
.
database
();
const
usersTable
=
db
.
collection
(
'
uni-id-users
'
)
let
allServicesList
=
[]
let
allServicesList
=
[]
export
default
{
computed
:
{
agreements
()
{
...
...
@@ -42,17 +42,17 @@
]
},
agree
:
{
get
()
{
get
()
{
return
this
.
getParentComponent
().
agree
},
set
(
agree
)
{
console
.
log
(
'
setAgree
'
,
agree
);
set
(
agree
)
{
console
.
log
(
'
setAgree
'
,
agree
);
return
this
.
getParentComponent
().
agree
=
agree
}
}
},
data
()
{
return
{
data
()
{
return
{
servicesList
:
[{
"
id
"
:
"
username
"
,
"
text
"
:
"
账号登录
"
,
...
...
@@ -232,7 +232,7 @@
}
},
async
login_before
(
type
,
navigateBack
=
true
)
{
console
.
log
(
type
);
console
.
log
(
type
);
//提示空实现
if
([
"
qq
"
,
"
xiaomi
"
,
...
...
@@ -288,46 +288,46 @@
}
//判断是否需要弹出隐私协议授权框
console
.
log
(
type
,
this
.
agree
);
let
needAgreements
=
(
config
?.
agreements
?.
scope
||
[]).
includes
(
'
register
'
)
console
.
log
(
type
,
this
.
agree
);
let
needAgreements
=
(
config
?.
agreements
?.
scope
||
[]).
includes
(
'
register
'
)
console
.
log
({
needAgreements
});
if
(
type
!=
'
univerify
'
&&
needAgreements
&&
!
this
.
agree
)
{
if
(
type
!=
'
univerify
'
&&
needAgreements
&&
!
this
.
agree
)
{
let
agreementsRef
=
this
.
getParentComponent
().
$refs
.
agreements
return
agreementsRef
.
popup
(()
=>
{
return
agreementsRef
.
popup
(()
=>
{
console
.
log
(
type
,
navigateBack
);
this
.
login_before
(
type
,
navigateBack
)
})
}
// #ifdef H5
if
(
type
==
'
weixin
'
){
// console.log('开始微信网页登录');
let
redirectUrl
=
location
.
protocol
+
'
//
'
+
document
.
domain
+
(
window
.
location
.
href
.
includes
(
'
#
'
)?
'
/#
'
:
''
)
+
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd?is_weixin_redirect=true&type=weixin
'
console
.
log
(
'
redirectUrl----
'
,
redirectUrl
);
let
ua
=
window
.
navigator
.
userAgent
.
toLowerCase
();
if
(
ua
.
match
(
/MicroMessenger/i
)
==
'
micromessenger
'
){
// console.log('在微信公众号内');
return
window
.
open
(
`https://open.weixin.qq.com/connect/oauth2/authorize?
appid=
${
config
.
appid
.
weixin
.
h5
}
&redirect_uri=
${
encodeURIComponent
(
redirectUrl
)}
&response_type=code
&scope=snsapi_userinfo
&state=STATE&connect_redirect=1#wechat_redirect`
);
}
else
{
// console.log('非微信公众号内');
return
location
.
href
=
`https://open.weixin.qq.com/connect/qrconnect?appid=
${
config
.
appid
.
weixin
.
web
}
&redirect_uri=
${
encodeURIComponent
(
redirectUrl
)}
&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`
}
}
// #endif
}
// #ifdef H5
if
(
type
==
'
weixin
'
){
// console.log('开始微信网页登录');
let
redirectUrl
=
location
.
protocol
+
'
//
'
+
document
.
domain
+
(
window
.
location
.
href
.
includes
(
'
#
'
)?
'
/#
'
:
''
)
+
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd?is_weixin_redirect=true&type=weixin
'
console
.
log
(
'
redirectUrl----
'
,
redirectUrl
);
let
ua
=
window
.
navigator
.
userAgent
.
toLowerCase
();
if
(
ua
.
match
(
/MicroMessenger/i
)
==
'
micromessenger
'
){
// console.log('在微信公众号内');
return
window
.
open
(
`https://open.weixin.qq.com/connect/oauth2/authorize?
appid=
${
config
.
appid
.
weixin
.
h5
}
&redirect_uri=
${
encodeURIComponent
(
redirectUrl
)}
&response_type=code
&scope=snsapi_userinfo
&state=STATE&connect_redirect=1#wechat_redirect`
);
}
else
{
// console.log('非微信公众号内');
return
location
.
href
=
`https://open.weixin.qq.com/connect/qrconnect?appid=
${
config
.
appid
.
weixin
.
web
}
&redirect_uri=
${
encodeURIComponent
(
redirectUrl
)}
&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`
}
}
// #endif
uni
.
showLoading
({
mask
:
true
...
...
@@ -419,7 +419,7 @@
}
})
},
login
(
params
,
type
)
{
//联网验证登录
login
(
params
,
type
)
{
//联网验证登录
console
.
log
(
'
执行登录开始----
'
);
console
.
log
({
params
,
...
...
@@ -446,9 +446,9 @@
})
return
this
.
$refs
.
userProfile
.
open
(
result
.
uid
)
}
// #endif
// #ifdef H5
result
.
loginType
=
type
// #endif
// #ifdef H5
result
.
loginType
=
type
// #endif
loginSuccess
(
result
)
})
...
...
@@ -511,10 +511,17 @@
flex-wrap
:
wrap
;
width
:
750rpx
;
justify-content
:
space-around
;
position
:
fixed
;
bottom
:
10rpx
;
position
:
fixed
;
left
:
0
;
}
.item
{
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
height
:
200rpx
;
cursor
:
pointer
;
}
/* #ifndef APP-NVUE */
@media
screen
and
(
min-width
:
690px
)
{
...
...
@@ -522,17 +529,20 @@
max-width
:
500px
;
margin-left
:
calc
(
50%
-
250px
);
}
.item
{
height
:
160rpx
;
}
}
@media
screen
and
(
max-width
:
690px
)
{
.fab-login-box
{
bottom
:
10rpx
;
}
}
/* #endif */
.item
{
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
height
:
200rpx
;
cursor
:
pointer
;
}
.logo
{
width
:
60rpx
;
...
...
uni_modules/uni-id-pages/config.js
浏览文件 @
5e55a8d3
export
default
{
//调试模式
"
debug
"
:
tru
e
,
"
debug
"
:
fals
e
,
/*
登录类型 未列举到的或运行环境不支持的,将被自动隐藏。
如果需要在不同平台有不同的配置,直接用条件编译即可
...
...
@@ -43,16 +43,13 @@ export default {
"
web
"
:
"
xxxxxx
"
}
},
/**
* 密码强度
* superstrong(超强:密码必须包含大小写字母、数字和特殊符号)
* strong(强: 密码必须包含字母、数字和特殊符号)
* medium (中:密码必须为字母、数字和特殊符号任意两种的组合)
* weak(弱:密码必须包含字母)
* 为空或false则不验证密码强度
*/
"
password
"
:
{
// "strength": "strong",
"
length
"
:
[
6
,
20
]
//密码长度,默认在6-20位之间
}
/**
* 密码强度
* super(超强:密码必须包含大小写字母、数字和特殊符号,长度范围:8-16位之间)
* strong(强: 密密码必须包含字母、数字和特殊符号,长度范围:8-16位之间)
* medium (中:密码必须为字母、数字和特殊符号任意两种的组合,长度范围:8-16位之间)
* weak(弱:密码必须包含字母和数字,长度范围:6-16位之间)
* 为空或false则不验证密码强度
*/
"
passwordStrength
"
:
"
medium
"
}
uni_modules/uni-id-pages/pages/login/login-smscode.vue
浏览文件 @
5e55a8d3
<!-- 短信验证码登录页 -->
<
template
>
<view
class=
"uni-content"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title"
>
请输入验证码
</text>
<text
class=
"tip"
>
先输入图形验证码,再获取短信验证码
</text>
...
...
@@ -21,6 +24,7 @@
"
code
"
:
""
,
"
phone
"
:
""
,
"
captcha
"
:
""
,
"
logo
"
:
"
/static/logo.png
"
}
},
computed
:
{
...
...
uni_modules/uni-id-pages/pages/login/login-withoutpwd.vue
浏览文件 @
5e55a8d3
<!-- 免密登录页 -->
<
template
>
<view
class=
"uni-content"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title"
>
请选择登录方式
</text>
<!-- 快捷登录框 当url带参数时有效 -->
...
...
@@ -36,7 +39,8 @@
return
{
type
:
""
,
//快捷登录方式
phone
:
""
,
//手机号码
focusPhone
:
false
focusPhone
:
false
,
logo
:
"
/static/logo.png
"
}
},
computed
:
{
...
...
@@ -177,7 +181,7 @@
}
.quickLogin
{
width
:
650rpx
;
//
width: 650rpx;
height
:
350px
;
align-items
:
center
;
justify-content
:
center
;
...
...
@@ -186,6 +190,9 @@
.quickLoginBtn
{
margin
:
20px
0
;
width
:
450rpx
;
/* #ifndef APP-NVUE */
max-width
:
230px
;
/* #endif */
height
:
82rpx
;
}
...
...
@@ -193,4 +200,10 @@
margin-top
:
-15px
;
margin-bottom
:
20px
;
}
@media
screen
and
(
min-width
:
690px
)
{
.quickLogin
{
height
:
auto
;
}
}
</
style
>
uni_modules/uni-id-pages/pages/login/login-withpwd.vue
浏览文件 @
5e55a8d3
<!-- 账号密码登录页 -->
<
template
>
<view
class=
"uni-content"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
账号密码登录
</text>
<uni-forms>
<uni-forms-item
name=
"username"
>
<uni-easyinput
:focus=
"focusUsername"
@
blur=
"focusUsername = false"
class=
"input-box"
:inputBorder=
"false"
v-model=
"username"
placeholder=
"请输入手机号/用户名"
/>
<uni-easyinput
:focus=
"focusUsername"
@
blur=
"focusUsername = false"
class=
"input-box"
:inputBorder=
"false"
v-model=
"username"
placeholder=
"请输入手机号/用户名
/邮箱
"
/>
</uni-forms-item>
<uni-forms-item
name=
"password"
>
<uni-easyinput
:focus=
"focusPassword"
@
blur=
"focusPassword = false"
class=
"input-box"
clearable
type=
"password"
:inputBorder=
"false"
v-model=
"password"
...
...
@@ -45,7 +48,8 @@
"
captcha
"
:
""
,
"
needCaptcha
"
:
false
,
"
focusUsername
"
:
false
,
"
focusPassword
"
:
false
"
focusPassword
"
:
false
,
"
logo
"
:
"
/static/logo.png
"
}
},
onShow
()
{
...
...
@@ -84,7 +88,7 @@
if
(
!
this
.
username
.
length
){
this
.
focusUsername
=
true
return
uni
.
showToast
({
title
:
'
请输入手机号/用户名
'
,
title
:
'
请输入手机号/用户名
/邮箱
'
,
icon
:
'
none
'
});
}
...
...
@@ -107,6 +111,8 @@
if
(
/^1
\d{10}
$/
.
test
(
this
.
username
))
{
data
.
mobile
=
this
.
username
}
else
if
(
/@/
.
test
(
this
.
username
))
{
data
.
email
=
this
.
username
}
else
{
data
.
username
=
this
.
username
}
...
...
@@ -135,7 +141,9 @@
<
style
lang=
"scss"
scoped
>
@import
"@/uni_modules/uni-id-pages/common/login-page.scss"
;
@media
screen
and
(
min-width
:
690px
)
{
}
.forget
{
font-size
:
12px
;
color
:
#8a8f8b
;
...
...
uni_modules/uni-id-pages/pages/register/register-by-email.vue
0 → 100644
浏览文件 @
5e55a8d3
<!-- 邮箱验证码注册 -->
<
template
>
<view
class=
"uni-content"
>
<match-media
:min-width=
"690"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
邮箱验证码注册
</text>
</match-media>
<uni-forms
ref=
"form"
:value=
"formData"
:rules=
"rules"
validate-trigger=
"submit"
err-show-type=
"toast"
>
<uni-forms-item
name=
"email"
required
>
<uni-easyinput
:inputBorder=
"false"
:focus=
"focusEmail"
@
blur=
"focusEmail = false"
class=
"input-box"
placeholder=
"请输入邮箱"
v-model=
"formData.email"
trim=
"both"
/>
</uni-forms-item>
<uni-forms-item
name=
"nickname"
>
<uni-easyinput
:inputBorder=
"false"
:focus=
"focusNickname"
@
blur=
"focusNickname = false"
class=
"input-box"
placeholder=
"请输入用户昵称"
v-model=
"formData.nickname"
trim=
"both"
/>
</uni-forms-item>
<uni-forms-item
name=
"password"
v-model=
"formData.password"
required
>
<uni-easyinput
:inputBorder=
"false"
:focus=
"focusPassword"
@
blur=
"focusPassword = false"
class=
"input-box"
maxlength=
"20"
:placeholder=
"'请输入' + (config.passwordStrength == 'weak'?'6':'8') + '-16位密码'"
type=
"password"
v-model=
"formData.password"
trim=
"both"
/>
</uni-forms-item>
<uni-forms-item
name=
"password2"
v-model=
"formData.password2"
required
>
<uni-easyinput
:inputBorder=
"false"
:focus=
"focusPassword2"
@
blur=
"focusPassword2 =false"
class=
"input-box"
placeholder=
"再次输入密码"
maxlength=
"20"
type=
"password"
v-model=
"formData.password2"
trim=
"both"
/>
</uni-forms-item>
<uni-forms-item
name=
"code"
>
<uni-id-pages-email-form
ref=
"shortCode"
:email=
"formData.email"
type=
"register"
v-model=
"formData.code"
>
</uni-id-pages-email-form>
</uni-forms-item>
<uni-id-pages-agreements
scope=
"register"
ref=
"agreements"
></uni-id-pages-agreements>
<button
class=
"uni-btn"
type=
"primary"
@
click=
"submit"
>
注册
</button>
<button
@
click=
"navigateBack"
class=
"register-back"
>
返回
</button>
<match-media
:min-width=
"690"
>
<view
class=
"link-box"
>
<text
class=
"link"
@
click=
"registerByUserName"
>
用户名密码注册
</text>
<text
class=
"link"
@
click=
"toLogin"
>
已有账号?点此登录
</text>
</view>
</match-media>
</uni-forms>
</view>
</
template
>
<
script
>
import
rules
from
'
./validator.js
'
;
import
mixin
from
'
@/uni_modules/uni-id-pages/common/login-page.mixin.js
'
;
import
config
from
'
@/uni_modules/uni-id-pages/config.js
'
import
passwordMod
from
'
@/uni_modules/uni-id-pages/common/password.js
'
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
)
export
default
{
mixins
:
[
mixin
],
data
()
{
return
{
formData
:
{
email
:
""
,
nickname
:
""
,
password
:
""
,
password2
:
""
,
code
:
""
},
rules
:
{
email
:
{
rules
:
[{
required
:
true
,
errorMessage
:
'
请输入邮箱
'
,
},{
format
:
'
email
'
,
errorMessage
:
'
邮箱格式不正确
'
,
}
]
},
nickname
:
{
rules
:
[{
minLength
:
3
,
maxLength
:
32
,
errorMessage
:
'
昵称长度在 {minLength} 到 {maxLength} 个字符
'
,
},
{
validateFunction
:
function
(
rule
,
value
,
data
,
callback
)
{
// console.log(value);
if
(
/^1
\d{10}
$/
.
test
(
value
)
||
/^
(\w
-*
\.
*
)
+@
(\w
-
?)
+
(\.\w{2,})
+$/
.
test
(
value
))
{
callback
(
'
昵称不能是:手机号或邮箱
'
)
};
if
(
/^
\d
+$/
.
test
(
value
))
{
callback
(
'
昵称不能为纯数字
'
)
};
if
(
/
[\u
4E00-
\u
9FA5
\u
F900-
\u
FA2D
]{1,}
/
.
test
(
value
)){
callback
(
'
昵称不能包含中文
'
)
}
return
true
}
}
],
label
:
"
昵称
"
},
...
passwordMod
.
getPwdRules
(),
code
:
{
rules
:
[{
required
:
true
,
errorMessage
:
'
请输入邮箱验证码
'
,
},
{
pattern
:
/^.
{6}
$/
,
errorMessage
:
'
邮箱验证码不正确
'
,
}
]
}
},
focusEmail
:
false
,
focusNickname
:
false
,
focusPassword
:
false
,
focusPassword2
:
false
,
logo
:
"
/static/logo.png
"
}
},
onReady
()
{
this
.
$refs
.
form
.
setRules
(
this
.
rules
)
},
onShow
()
{
// #ifdef H5
document
.
onkeydown
=
event
=>
{
var
e
=
event
||
window
.
event
;
if
(
e
&&
e
.
keyCode
==
13
)
{
//回车键的键值为13
this
.
submit
()
}
};
// #endif
},
methods
:
{
/**
* 触发表单提交
*/
submit
()
{
this
.
$refs
.
form
.
validate
().
then
((
res
)
=>
{
if
(
this
.
needAgreements
&&
!
this
.
agree
)
{
return
this
.
$refs
.
agreements
.
popup
(()
=>
{
this
.
submitForm
(
res
)
})
}
this
.
submitForm
(
res
)
}).
catch
((
errors
)
=>
{
let
key
=
errors
[
0
].
key
key
=
key
.
replace
(
key
[
0
],
key
[
0
].
toUpperCase
())
console
.
log
(
key
);
this
[
'
focus
'
+
key
]
=
true
})
},
submitForm
(
params
)
{
uniIdCo
.
registerUserByEmail
(
this
.
formData
).
then
(
e
=>
{
console
.
log
(
e
);
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withpwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
e
);
}
})
})
.
catch
(
e
=>
{
console
.
log
(
e
);
console
.
log
(
e
.
message
);
})
},
navigateBack
()
{
uni
.
navigateBack
()
},
toLogin
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withpwd
'
})
},
registerByUserName
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/register/register
'
})
}
}
}
</
script
>
<
style
lang=
"scss"
>
@import
"@/uni_modules/uni-id-pages/common/login-page.scss"
;
@media
screen
and
(
max-width
:
690px
)
{
.uni-content
{
margin-top
:
15px
;
}
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
30px
40px
;
max-height
:
550px
;
}
.link-box
{
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
flex-direction
:
row
;
justify-content
:
space-between
;
margin-top
:
10px
;
}
.link
{
font-size
:
12px
;
}
}
.
uni-content
:
:
v-deep
.
uni-forms-item__label
{
position
:
absolute
;
left
:
-15px
;
}
button
{
margin-top
:
15px
;
}
</
style
>
uni_modules/uni-id-pages/pages/register/register.vue
浏览文件 @
5e55a8d3
<!-- 账号注册页 -->
<
template
>
<view
class=
"uni-content"
>
<match-media
:min-width=
"690"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
用户名密码注册
</text>
</match-media>
<uni-forms
ref=
"form"
:value=
"formData"
:rules=
"rules"
validate-trigger=
"submit"
err-show-type=
"toast"
>
<uni-forms-item
name=
"username"
required
>
<uni-easyinput
:inputBorder=
"false"
:focus=
"focusUsername"
@
blur=
"focusUsername = false"
...
...
@@ -12,7 +19,7 @@
</uni-forms-item>
<uni-forms-item
name=
"password"
v-model=
"formData.password"
required
>
<uni-easyinput
:inputBorder=
"false"
:focus=
"focusPassword"
@
blur=
"focusPassword = false"
class=
"input-box"
maxlength=
"20"
:placeholder=
"'请输入' +
passwordLength[0] + '-' + passwordLength[1] + '
位密码'"
type=
"password"
class=
"input-box"
maxlength=
"20"
:placeholder=
"'请输入' +
(config.passwordStrength == 'weak'?'6':'8') + '-16
位密码'"
type=
"password"
v-model=
"formData.password"
trim=
"both"
/>
</uni-forms-item>
<uni-forms-item
name=
"password2"
v-model=
"formData.password2"
required
>
...
...
@@ -25,7 +32,13 @@
</uni-forms-item>
<uni-id-pages-agreements
scope=
"register"
ref=
"agreements"
></uni-id-pages-agreements>
<button
class=
"uni-btn"
type=
"primary"
@
click=
"submit"
>
注册
</button>
<button
@
click=
"navigateBack"
>
返回
</button>
<button
@
click=
"navigateBack"
class=
"register-back"
>
返回
</button>
<match-media
:min-width=
"690"
>
<view
class=
"link-box"
>
<text
class=
"link"
@
click=
"registerByEmail"
>
邮箱验证码注册
</text>
<text
class=
"link"
@
click=
"toLogin"
>
已有账号?点此登录
</text>
</view>
</match-media>
</uni-forms>
</view>
</
template
>
...
...
@@ -50,12 +63,8 @@
focusUsername
:
false
,
focusNickname
:
false
,
focusPassword
:
false
,
focusPassword2
:
false
}
},
computed
:{
passwordLength
(){
return
config
.
password
.
length
focusPassword2
:
false
,
logo
:
"
/static/logo.png
"
}
},
onReady
()
{
...
...
@@ -111,6 +120,16 @@
},
navigateBack
()
{
uni
.
navigateBack
()
},
toLogin
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withpwd
'
})
},
registerByEmail
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/register/register-by-email
'
})
}
}
}
...
...
@@ -118,9 +137,33 @@
<
style
lang=
"scss"
>
@import
"@/uni_modules/uni-id-pages/common/login-page.scss"
;
.uni-content
{
margin-top
:
15px
;
@media
screen
and
(
max-width
:
690px
)
{
.uni-content
{
margin-top
:
15px
;
height
:
100%
;
background-color
:
#fff
;
}
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
30px
40px
60px
;
}
.link-box
{
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
flex-direction
:
row
;
justify-content
:
space-between
;
margin-top
:
10px
;
}
.link
{
font-size
:
12px
;
}
}
.
uni-content
:
:
v-deep
.
uni-forms-item__label
{
position
:
absolute
;
left
:
-15px
;
...
...
uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email.vue
0 → 100644
浏览文件 @
5e55a8d3
<!-- 找回密码页 -->
<
template
>
<view
class=
"uni-content"
>
<match-media
:min-width=
"690"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
通过邮箱验证码找回密码
</text>
</match-media>
<uni-forms
ref=
"form"
:value=
"formData"
err-show-type=
"toast"
>
<uni-forms-item
name=
"email"
>
<uni-easyinput
:focus=
"focusEmail"
@
blur=
"focusEmail = false"
class=
"input-box"
:disabled=
"lock"
:inputBorder=
"false"
v-model=
"formData.email"
placeholder=
"请输入邮箱"
>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item
name=
"code"
>
<uni-id-pages-email-form
ref=
"shortCode"
:email=
"formData.email"
type=
"reset-pwd-by-email"
v-model=
"formData.code"
>
</uni-id-pages-email-form>
</uni-forms-item>
<uni-forms-item
name=
"password"
>
<uni-easyinput
:focus=
"focusPassword"
@
blur=
"focusPassword = false"
class=
"input-box"
type=
"password"
:inputBorder=
"false"
v-model=
"formData.password"
placeholder=
"请输入新密码"
></uni-easyinput>
</uni-forms-item>
<uni-forms-item
name=
"password2"
>
<uni-easyinput
:focus=
"focusPassword2"
@
blur=
"focusPassword2 = false"
class=
"input-box"
type=
"password"
:inputBorder=
"false"
v-model=
"formData.password2"
placeholder=
"请再次输入新密码"
></uni-easyinput>
</uni-forms-item>
<button
class=
"uni-btn send-btn-box"
type=
"primary"
@
click=
"submit"
>
提交
</button>
<match-media
:min-width=
"690"
>
<view
class=
"link-box"
>
<text
class=
"link"
@
click=
"retrieveByPhone"
>
通过手机验证码找回密码
</text>
<view></view>
</view>
</match-media>
</uni-forms>
<uni-popup-captcha
@
confirm=
"submit"
v-model=
"formData.captcha"
scene=
"reset-pwd-by-sms"
ref=
"popup"
></uni-popup-captcha>
</view>
</
template
>
<
script
>
import
mixin
from
'
@/uni_modules/uni-id-pages/common/login-page.mixin.js
'
;
import
passwordMod
from
'
@/uni_modules/uni-id-pages/common/password.js
'
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
,{
errorOptions
:{
type
:
'
toast
'
}
})
export
default
{
mixins
:
[
mixin
],
data
()
{
return
{
lock
:
false
,
focusEmail
:
true
,
focusPassword
:
false
,
focusPassword2
:
false
,
formData
:
{
"
email
"
:
""
,
"
code
"
:
""
,
'
password
'
:
''
,
'
password2
'
:
''
,
"
captcha
"
:
""
},
rules
:
{
email
:
{
rules
:
[{
required
:
true
,
errorMessage
:
'
请输入邮箱
'
,
},
{
format
:
'
email
'
,
errorMessage
:
'
邮箱格式不正确
'
,
}
]
},
code
:
{
rules
:
[{
required
:
true
,
errorMessage
:
'
请输入邮箱验证码
'
,
},
{
pattern
:
/^.
{6}
$/
,
errorMessage
:
'
请输入6位验证码
'
,
}
]
},
...
passwordMod
.
getPwdRules
()
},
logo
:
"
/static/logo.png
"
}
},
computed
:
{
isEmail
()
{
let
reg_email
=
/@/
;
let
isEmail
=
reg_email
.
test
(
this
.
formData
.
email
);
return
isEmail
;
},
isPwd
()
{
let
reg_pwd
=
/^.
{6,20}
$/
;
let
isPwd
=
reg_pwd
.
test
(
this
.
formData
.
password
);
return
isPwd
;
},
isCode
()
{
let
reg_code
=
/^
\d{6}
$/
;
let
isCode
=
reg_code
.
test
(
this
.
formData
.
code
);
return
isCode
;
}
},
onLoad
(
event
)
{
if
(
event
&&
event
.
emailNumber
)
{
this
.
formData
.
email
=
event
.
emailNumber
;
if
(
event
.
lock
){
this
.
lock
=
event
.
lock
//如果是已经登录的账号,点击找回密码就锁定指定的账号绑定的邮箱码
this
.
focusEmail
=
true
}
}
},
onReady
()
{
if
(
this
.
formData
.
email
)
{
this
.
$refs
.
shortCode
.
start
();
}
this
.
$refs
.
form
.
setRules
(
this
.
rules
)
},
onShow
()
{
// #ifdef H5
document
.
onkeydown
=
event
=>
{
var
e
=
event
||
window
.
event
;
if
(
e
&&
e
.
keyCode
==
13
)
{
//回车键的键值为13
this
.
submit
()
}
};
// #endif
},
methods
:
{
/**
* 完成并提交
*/
submit
()
{
console
.
log
(
"
formData
"
,
this
.
formData
);
console
.
log
(
'
rules
'
,
this
.
rules
);
this
.
$refs
.
form
.
validate
()
.
then
(
res
=>
{
let
{
email
,
password
:
password
,
captcha
,
code
}
=
this
.
formData
uniIdCo
.
resetPwdByEmail
({
email
,
code
,
password
,
captcha
}).
then
(
e
=>
{
console
.
log
(
e
);
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withpwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
e
);
}
})
})
.
catch
(
e
=>
{
if
(
e
.
errCode
==
'
uni-id-captcha-required
'
)
{
this
.
$refs
.
popup
.
open
()
}
}).
finally
(
e
=>
{
this
.
formData
.
captcha
=
""
})
}).
catch
(
errors
=>
{
let
key
=
errors
[
0
].
key
if
(
key
==
'
code
'
){
console
.
log
(
this
.
$refs
.
shortCode
);
return
this
.
$refs
.
shortCode
.
focusSmsCodeInput
=
true
}
key
=
key
.
replace
(
key
[
0
],
key
[
0
].
toUpperCase
())
console
.
log
(
key
,
'
focus
'
+
key
);
this
[
'
focus
'
+
key
]
=
true
})
},
retrieveByPhone
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/retrieve/retrieve
'
})
}
}
}
</
script
>
<
style
lang=
"scss"
>
@import
"@/uni_modules/uni-id-pages/common/login-page.scss"
;
@media
screen
and
(
max-width
:
690px
)
{
.uni-content
{
margin-top
:
15px
;
}
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
30px
40px
40px
;
}
.link-box
{
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
flex-direction
:
row
;
justify-content
:
space-between
;
margin-top
:
10px
;
}
.link
{
font-size
:
12px
;
}
}
</
style
>
uni_modules/uni-id-pages/pages/retrieve/retrieve.vue
浏览文件 @
5e55a8d3
<!-- 找回密码页 -->
<
template
>
<view
class=
"uni-content"
>
<match-media
:min-width=
"690"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
通过手机验证码找回密码
</text>
</match-media>
<uni-forms
ref=
"form"
:value=
"formData"
err-show-type=
"toast"
>
<uni-forms-item
name=
"phone"
>
<uni-easyinput
:focus=
"focusPhone"
@
blur=
"focusPhone = false"
class=
"input-box"
:disabled=
"lock"
type=
"number"
:inputBorder=
"false"
...
...
@@ -20,6 +27,12 @@
placeholder=
"请再次输入新密码"
></uni-easyinput>
</uni-forms-item>
<button
class=
"uni-btn send-btn-box"
type=
"primary"
@
click=
"submit"
>
提交
</button>
<match-media
:min-width=
"690"
>
<view
class=
"link-box"
>
<text
class=
"link"
@
click=
"retrieveByEmail"
>
通过邮箱验证码找回密码
</text>
<view></view>
</view>
</match-media>
</uni-forms>
<uni-popup-captcha
@
confirm=
"submit"
v-model=
"formData.captcha"
scene=
"reset-pwd-by-sms"
ref=
"popup"
></uni-popup-captcha>
</view>
...
...
@@ -101,7 +114,8 @@
}
]
}
}
},
logo
:
"
/static/logo.png
"
}
},
computed
:
{
...
...
@@ -187,6 +201,11 @@
console
.
log
(
key
,
'
focus
'
+
key
);
this
[
'
focus
'
+
key
]
=
true
})
},
retrieveByEmail
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email
'
})
}
}
}
...
...
@@ -195,7 +214,26 @@
<
style
lang=
"scss"
>
@import
"@/uni_modules/uni-id-pages/common/login-page.scss"
;
.uni-content
{
margin-top
:
15px
;
@media
screen
and
(
max-width
:
690px
)
{
.uni-content
{
margin-top
:
15px
;
}
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
30px
40px
40px
;
}
.link-box
{
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
flex-direction
:
row
;
justify-content
:
space-between
;
margin-top
:
10px
;
}
.link
{
font-size
:
12px
;
}
}
</
style
>
uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile.vue
浏览文件 @
5e55a8d3
<!-- 绑定手机号码页 -->
<
template
>
<view
class=
"uni-content"
>
<match-media
:min-width=
"690"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
绑定手机号
</text>
</match-media>
<!-- 登录框 (选择手机号所属国家和地区需要另行实现) -->
<uni-easyinput
clearable
:focus=
"focusMobile"
@
blur=
"focusMobile = false"
type=
"number"
class=
"input-box"
:inputBorder=
"false"
v-model=
"formData.mobile"
maxlength=
"11"
placeholder=
"请输入手机号"
></uni-easyinput>
...
...
@@ -20,7 +27,8 @@
code
:
""
,
captcha
:
""
},
focusMobile
:
true
focusMobile
:
true
,
logo
:
"
/static/logo.png
"
}
},
computed
:
{
...
...
@@ -90,6 +98,13 @@
padding
:
50rpx
;
padding-top
:
10px
;
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
30px
40px
40px
;
}
}
/* #ifndef APP-NVUE || VUE3 */
.
uni-content
:
:
v-deep
.
uni-easyinput__content
{}
...
...
uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd.vue
浏览文件 @
5e55a8d3
<!-- 修改密码 -->
<
template
>
<view
class=
"uni-content"
>
<match-media
:min-width=
"690"
>
<view
class=
"login-logo"
>
<image
:src=
"logo"
></image>
</view>
<!-- 顶部文字 -->
<text
class=
"title title-box"
>
修改密码
</text>
</match-media>
<uni-forms
ref=
"form"
:value=
"formData"
err-show-type=
"toast"
>
<uni-forms-item
name=
"oldPassword"
>
<uni-easyinput
:focus=
"focusOldPassword"
@
blur=
"focusOldPassword = false"
class=
"input-box"
...
...
@@ -81,7 +88,8 @@
}
]
}
}
},
logo
:
"
/static/logo.png
"
}
},
onReady
()
{
...
...
@@ -140,7 +148,15 @@
<
style
lang=
"scss"
>
@import
"@/uni_modules/uni-id-pages/common/login-page.scss"
;
.uni-content
{
margin-top
:
15px
;
@media
screen
and
(
max-width
:
690px
)
{
.uni-content
{
margin-top
:
15px
;
}
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
30px
40px
40px
;
}
}
</
style
>
uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate.vue
浏览文件 @
5e55a8d3
<!-- 注销(销毁)账号 -->
<
template
>
<view
class=
"content"
>
<view
class=
"
uni-
content"
>
<text
class=
"words"
space=
"emsp"
>
一、注销是不可逆操作,注销后:\n
1.帐号将无法登录、无法找回。\n
...
...
@@ -64,7 +64,7 @@
</
script
>
<
style
>
.content
{
.
uni-
content
{
display
:
flex
;
flex-direction
:
column
;
font-size
:
28
rpx
;
...
...
@@ -77,20 +77,6 @@
margin-bottom
:
80px
;
}
.button-group
{
display
:
flex
;
flex-direction
:
row
;
position
:
fixed
;
height
:
50px
;
bottom
:
10px
;
width
:
750
rpx
;
justify-content
:
center
;
align-items
:
center
;
border-top
:
solid
1px
#e4e6ec
;
padding-top
:
10px
;
background-color
:
#FFFFFF
;
}
.button-group
button
{
border-radius
:
100px
;
border
:
none
;
...
...
@@ -108,4 +94,26 @@
color
:
#e64340
;
border
:
solid
1px
#e64340
;
}
.button-group
{
display
:
flex
;
flex-direction
:
row
;
position
:
fixed
;
height
:
50px
;
bottom
:
10px
;
width
:
750
rpx
;
justify-content
:
center
;
align-items
:
center
;
border-top
:
solid
1px
#e4e6ec
;
padding-top
:
10px
;
background-color
:
#FFFFFF
;
max-width
:
690px
;
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
max-width
:
690px
;
margin-left
:
calc
(
50%
-
345px
);
}
}
</
style
>
uni_modules/uni-id-pages/pages/userinfo/userinfo.js
0 → 100644
浏览文件 @
5e55a8d3
const
db
=
uniCloud
.
database
();
const
usersTable
=
db
.
collection
(
'
uni-id-users
'
)
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
)
export
default
{
data
()
{
return
{
univerifyStyle
:
{
authButton
:
{
"
title
"
:
"
本机号码一键绑定
"
,
// 授权按钮文案
},
otherLoginButton
:
{
"
title
"
:
"
其他号码绑定
"
,
}
},
userInfo
:
{
mobile
:
''
,
nickname
:
''
},
hasLogin
:
false
,
hasPwd
:
false
}
},
async
onShow
()
{
this
.
univerifyStyle
.
authButton
.
title
=
"
本机号码一键绑定
"
this
.
univerifyStyle
.
otherLoginButton
.
title
=
"
其他号码绑定
"
},
async
onLoad
()
{
this
.
getUserInfo
()
//判断当前用户是否有密码,否则就不显示密码修改功能
let
res
=
await
uniIdCo
.
getAccountInfo
()
this
.
hasPwd
=
res
.
isPasswordSet
},
methods
:
{
login
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
e
);
}
})
},
async
logout
()
{
await
uniIdCo
.
logout
()
uni
.
removeStorageSync
(
'
uni_id_token
'
);
uni
.
setStorageSync
(
'
uni_id_token_expired
'
,
0
)
uni
.
redirectTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
});
},
changePassword
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
e
);
}
})
},
getUserInfo
(
e
)
{
uni
.
showLoading
({
mask
:
true
});
usersTable
.
where
(
"
'_id' == $cloudEnv_uid
"
).
field
(
'
mobile,nickname
'
).
get
().
then
(
res
=>
{
console
.
log
({
res
});
this
.
userInfo
=
res
.
result
.
data
[
0
]
console
.
log
(
'
this.userInfo
'
,
this
.
userInfo
);
this
.
hasLogin
=
true
}).
catch
(
e
=>
{
this
.
userInfo
=
{}
this
.
hasLogin
=
false
console
.
log
(
e
.
message
,
e
.
errCode
);
}).
finally
(
e
=>
{
// console.log(e);
uni
.
hideLoading
()
})
},
bindMobile
()
{
// #ifdef APP-PLUS
uni
.
preLogin
({
provider
:
'
univerify
'
,
success
:
this
.
univerify
(),
//预登录成功
fail
:
(
res
)
=>
{
// 预登录失败
// 不显示一键登录选项(或置灰)
console
.
log
(
res
)
this
.
bindMobileBySmsCode
()
}
})
// #endif
// #ifdef MP-WEIXIN
this
.
$refs
[
'
bind-mobile
'
].
open
()
// #endif
// #ifdef H5
//...去用验证码绑定
this
.
bindMobileBySmsCode
()
// #endif
},
univerify
()
{
uni
.
login
({
"
provider
"
:
'
univerify
'
,
"
univerifyStyle
"
:
this
.
univerifyStyle
,
success
:
async
e
=>
{
console
.
log
(
e
.
authResult
);
uniIdCo
.
bindMobileByUniverify
(
e
.
authResult
).
then
(
res
=>
{
console
.
log
(
res
);
this
.
getUserInfo
()
}).
catch
(
e
=>
{
console
.
log
(
e
);
}).
finally
(
e
=>
{
console
.
log
(
e
);
uni
.
closeAuthView
()
})
},
fail
:
(
err
)
=>
{
console
.
log
(
err
);
if
(
err
.
code
==
'
30002
'
||
err
.
code
==
'
30001
'
)
{
this
.
bindMobileBySmsCode
()
}
}
})
},
bindMobileBySmsCode
()
{
uni
.
navigateTo
({
url
:
'
./bind-mobile/bind-mobile
'
,
events
:
{
getUserInfo
:
()
=>
{
this
.
getUserInfo
()
}
},
complete
(
e
)
{
console
.
log
(
e
);
}
})
},
setNickname
(
nickname
)
{
console
.
log
(
nickname
);
if
(
nickname
)
{
usersTable
.
where
(
'
_id==$env.uid
'
).
update
({
nickname
}).
then
(
e
=>
{
console
.
log
(
e
);
if
(
e
.
result
.
updated
)
{
uni
.
showToast
({
title
:
"
更新成功
"
,
icon
:
'
none
'
});
this
.
userInfo
.
nickname
=
nickname
}
else
{
uni
.
showToast
({
title
:
"
没有改变
"
,
icon
:
'
none
'
});
}
})
this
.
$refs
.
dialog
.
close
()
}
else
{
this
.
$refs
.
dialog
.
open
()
}
},
deactivate
()
{
uni
.
navigateTo
({
url
:
"
/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate
"
})
}
}
}
uni_modules/uni-id-pages/pages/userinfo/userinfo.vue
浏览文件 @
5e55a8d3
<!-- 用户资料页 -->
<
template
>
<view
class=
"uni-content"
>
<view
class=
"avatar"
>
<uni-id-pages-avatar
width=
"260rpx"
height=
"260rpx"
></uni-id-pages-avatar>
</view>
<uni-list>
<uni-list-item
class=
"item"
@
click=
"setNickname('')"
title=
"昵称"
:rightText=
"userInfo.nickname||'未设置'"
link
>
</uni-list-item>
<
template
>
<view
class=
"uni-content"
>
<view
class=
"avatar"
>
<uni-id-pages-avatar
width=
"260rpx"
height=
"260rpx"
></uni-id-pages-avatar>
</view>
<uni-list>
<uni-list-item
class=
"item"
@
click=
"setNickname('')"
title=
"昵称"
:rightText=
"userInfo.nickname||'未设置'"
link
>
</uni-list-item>
<uni-list-item
class=
"item"
@
click=
"bindMobile"
title=
"手机号"
:rightText=
"userInfo.mobile||'未绑定'"
link
>
</uni-list-item>
<uni-list-item
v-if=
"hasPwd"
class=
"item"
@
click=
"changePassword"
title=
"修改密码"
link
>
</uni-list-item>
</uni-list>
<uni-list
class=
"mt10"
>
<uni-list-item
@
click=
"deactivate"
title=
"注销账号"
link=
"navigateTo"
></uni-list-item>
</uni-list>
<uni-popup
ref=
"dialog"
type=
"dialog"
>
<uni-popup-dialog
mode=
"input"
:value=
"userInfo.nickname"
@
confirm=
"setNickname"
title=
"设置昵称"
placeholder=
"请输入要设置的昵称"
>
</uni-popup-dialog>
</uni-popup>
<uni-id-pages-bind-mobile
ref=
"bind-mobile-by-sms"
@
success=
"getUserInfo"
></uni-id-pages-bind-mobile>
<button
v-if=
"hasLogin"
@
click=
"logout"
>
退出登录
</button>
<button
v-else
@
click=
"login"
>
去登录
</button>
</view>
</
template
>
<
script
>
const
db
=
uniCloud
.
database
();
const
usersTable
=
db
.
collection
(
'
uni-id-users
'
)
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
)
export
default
{
data
()
{
return
{
univerifyStyle
:
{
authButton
:
{
"
title
"
:
"
本机号码一键绑定
"
,
// 授权按钮文案
},
otherLoginButton
:
{
"
title
"
:
"
其他号码绑定
"
,
}
},
userInfo
:
{
mobile
:
''
,
nickname
:
''
},
</uni-list-item>
</uni-list>
<uni-list
class=
"mt10"
>
<uni-list-item
@
click=
"deactivate"
title=
"注销账号"
link=
"navigateTo"
></uni-list-item>
</uni-list>
<uni-popup
ref=
"dialog"
type=
"dialog"
>
<uni-popup-dialog
mode=
"input"
:value=
"userInfo.nickname"
@
confirm=
"setNickname"
title=
"设置昵称"
placeholder=
"请输入要设置的昵称"
>
</uni-popup-dialog>
</uni-popup>
<uni-id-pages-bind-mobile
ref=
"bind-mobile-by-sms"
@
success=
"getUserInfo"
></uni-id-pages-bind-mobile>
<template
v-if=
"showLoginManage"
>
<button
v-if=
"hasLogin"
@
click=
"logout"
>
退出登录
</button>
<button
v-else
@
click=
"login"
>
去登录
</button>
</
template
>
</view>
</template>
<
script
>
const
db
=
uniCloud
.
database
();
const
usersTable
=
db
.
collection
(
'
uni-id-users
'
)
const
uniIdCo
=
uniCloud
.
importObject
(
"
uni-id-co
"
)
import
common
from
'
@/uni_modules/uni-id-pages/common/common.js
'
;
export
default
{
data
()
{
return
{
univerifyStyle
:
{
authButton
:
{
"
title
"
:
"
本机号码一键绑定
"
,
// 授权按钮文案
},
otherLoginButton
:
{
"
title
"
:
"
其他号码绑定
"
,
}
},
userInfo
:
{
mobile
:
''
,
nickname
:
''
},
hasLogin
:
false
,
hasPwd
:
false
}
},
async
onShow
()
{
this
.
univerifyStyle
.
authButton
.
title
=
"
本机号码一键绑定
"
this
.
univerifyStyle
.
otherLoginButton
.
title
=
"
其他号码绑定
"
},
async
onLoad
()
{
hasPwd
:
false
,
showLoginManage
:
false
//通过页面传参隐藏登录&退出登录按钮
}
},
async
onShow
()
{
this
.
univerifyStyle
.
authButton
.
title
=
"
本机号码一键绑定
"
this
.
univerifyStyle
.
otherLoginButton
.
title
=
"
其他号码绑定
"
},
async
onLoad
(
e
)
{
if
(
e
.
showLoginManage
){
this
.
showLoginManage
=
true
//通过页面传参隐藏登录&退出登录按钮
}
this
.
getUserInfo
()
//判断当前用户是否有密码,否则就不显示密码修改功能
let
res
=
await
uniIdCo
.
getAccountInfo
()
this
.
hasPwd
=
res
.
isPasswordSet
},
methods
:
{
login
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
e
);
}
})
},
async
logout
()
{
await
uniIdCo
.
logout
()
uni
.
removeStorageSync
(
'
uni_id_token
'
);
uni
.
setStorageSync
(
'
uni_id_token_expired
'
,
0
)
uni
.
redirectTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
});
this
.
hasPwd
=
res
.
isPasswordSet
},
methods
:
{
login
()
{
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/login/login-withoutpwd
'
,
complete
:
(
e
)
=>
{
console
.
log
(
e
);
}
})
},
logout
:
common
.
logout
,
changePassword
(){
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd
'
,
...
...
@@ -82,155 +82,165 @@
console
.
log
(
e
);
}
})
},
getUserInfo
(
e
)
{
uni
.
showLoading
({
mask
:
true
});
},
getUserInfo
(
e
)
{
uni
.
showLoading
({
mask
:
true
});
usersTable
.
where
(
"
'_id' == $cloudEnv_uid
"
).
field
(
'
mobile,nickname
'
).
get
().
then
(
res
=>
{
console
.
log
({
res
});
this
.
userInfo
=
res
.
result
.
data
[
0
]
console
.
log
(
'
this.userInfo
'
,
this
.
userInfo
);
this
.
hasLogin
=
true
}).
catch
(
e
=>
{
this
.
userInfo
=
{}
this
.
hasLogin
=
false
console
.
log
(
e
.
message
,
e
.
errCode
);
}).
finally
(
e
=>
{
// console.log(e);
uni
.
hideLoading
()
})
},
bindMobile
()
{
// #ifdef APP-PLUS
uni
.
preLogin
({
provider
:
'
univerify
'
,
success
:
this
.
univerify
(),
//预登录成功
fail
:
(
res
)
=>
{
// 预登录失败
// 不显示一键登录选项(或置灰)
console
.
log
(
res
)
this
.
bindMobileBySmsCode
()
}
})
// #endif
// #ifdef MP-WEIXIN
this
.
$refs
[
'
bind-mobile
'
].
open
()
// #endif
// #ifdef H5
//...去用验证码绑定
this
.
bindMobileBySmsCode
()
// #endif
},
univerify
()
{
uni
.
login
({
"
provider
"
:
'
univerify
'
,
"
univerifyStyle
"
:
this
.
univerifyStyle
,
success
:
async
e
=>
{
console
.
log
(
e
.
authResult
);
uniIdCo
.
bindMobileByUniverify
(
e
.
authResult
).
then
(
res
=>
{
console
.
log
(
res
);
this
.
getUserInfo
()
}).
catch
(
e
=>
{
console
.
log
(
e
);
}).
finally
(
e
=>
{
console
.
log
(
e
);
uni
.
closeAuthView
()
})
},
fail
:
(
err
)
=>
{
console
.
log
(
err
);
if
(
err
.
code
==
'
30002
'
||
err
.
code
==
'
30001
'
)
{
this
.
bindMobileBySmsCode
()
}
}
})
},
bindMobileBySmsCode
()
{
uni
.
navigateTo
({
url
:
'
./bind-mobile/bind-mobile
'
,
events
:
{
getUserInfo
:
()
=>
{
this
.
getUserInfo
()
}
},
complete
(
e
)
{
console
.
log
(
e
);
}
})
},
setNickname
(
nickname
)
{
console
.
log
(
nickname
);
if
(
nickname
)
{
usersTable
.
where
(
'
_id==$env.uid
'
).
update
({
nickname
}).
then
(
e
=>
{
console
.
log
(
e
);
if
(
e
.
result
.
updated
)
{
uni
.
showToast
({
title
:
"
更新成功
"
,
icon
:
'
none
'
});
this
.
userInfo
.
nickname
=
nickname
}
else
{
uni
.
showToast
({
title
:
"
没有改变
"
,
icon
:
'
none
'
});
}
})
this
.
$refs
.
dialog
.
close
()
}
else
{
this
.
$refs
.
dialog
.
open
()
}
},
deactivate
(){
uni
.
navigateTo
({
url
:
"
/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate
"
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
@import
url("/uni_modules/uni-id-pages/common/login-page.scss")
;
.uni-content
{
padding
:
0
;
}
/* #ifndef APP-NVUE */
view
{
display
:
flex
;
box-sizing
:
border-box
;
flex-direction
:
column
;
}
/* #endif */
.avatar
{
align-items
:
center
;
justify-content
:
center
;
margin
:
22px
0
;
width
:
100%
;
}
.item
{
flex
:
1
;
flex-direction
:
row
;
justify-content
:
space-between
;
align-items
:
center
;
}
button
{
margin
:
10%
;
margin-top
:
40px
;
border-radius
:
0
;
background-color
:
#FFFFFF
;
width
:
80%
;
}
.mt10
{
margin-top
:
10px
;
}
</
style
>
console
.
log
({
res
});
this
.
userInfo
=
res
.
result
.
data
[
0
]
console
.
log
(
'
this.userInfo
'
,
this
.
userInfo
);
this
.
hasLogin
=
true
}).
catch
(
e
=>
{
this
.
userInfo
=
{}
this
.
hasLogin
=
false
console
.
log
(
e
.
message
,
e
.
errCode
);
}).
finally
(
e
=>
{
// console.log(e);
uni
.
hideLoading
()
})
},
bindMobile
()
{
// #ifdef APP-PLUS
uni
.
preLogin
({
provider
:
'
univerify
'
,
success
:
this
.
univerify
(),
//预登录成功
fail
:
(
res
)
=>
{
// 预登录失败
// 不显示一键登录选项(或置灰)
console
.
log
(
res
)
this
.
bindMobileBySmsCode
()
}
})
// #endif
// #ifdef MP-WEIXIN
this
.
$refs
[
'
bind-mobile
'
].
open
()
// #endif
// #ifdef H5
//...去用验证码绑定
this
.
bindMobileBySmsCode
()
// #endif
},
univerify
()
{
uni
.
login
({
"
provider
"
:
'
univerify
'
,
"
univerifyStyle
"
:
this
.
univerifyStyle
,
success
:
async
e
=>
{
console
.
log
(
e
.
authResult
);
uniIdCo
.
bindMobileByUniverify
(
e
.
authResult
).
then
(
res
=>
{
console
.
log
(
res
);
this
.
getUserInfo
()
}).
catch
(
e
=>
{
console
.
log
(
e
);
}).
finally
(
e
=>
{
console
.
log
(
e
);
uni
.
closeAuthView
()
})
},
fail
:
(
err
)
=>
{
console
.
log
(
err
);
if
(
err
.
code
==
'
30002
'
||
err
.
code
==
'
30001
'
)
{
this
.
bindMobileBySmsCode
()
}
}
})
},
bindMobileBySmsCode
()
{
uni
.
navigateTo
({
url
:
'
./bind-mobile/bind-mobile
'
,
events
:
{
getUserInfo
:
()
=>
{
this
.
getUserInfo
()
}
},
complete
(
e
)
{
console
.
log
(
e
);
}
})
},
setNickname
(
nickname
)
{
console
.
log
(
nickname
);
if
(
nickname
)
{
usersTable
.
where
(
'
_id==$env.uid
'
).
update
({
nickname
}).
then
(
e
=>
{
console
.
log
(
e
);
if
(
e
.
result
.
updated
)
{
uni
.
showToast
({
title
:
"
更新成功
"
,
icon
:
'
none
'
});
this
.
userInfo
.
nickname
=
nickname
}
else
{
uni
.
showToast
({
title
:
"
没有改变
"
,
icon
:
'
none
'
});
}
})
this
.
$refs
.
dialog
.
close
()
}
else
{
this
.
$refs
.
dialog
.
open
()
}
},
deactivate
(){
uni
.
navigateTo
({
url
:
"
/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate
"
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
@import
url("/uni_modules/uni-id-pages/common/login-page.scss")
;
.uni-content
{
padding
:
0
;
}
/* #ifndef APP-NVUE */
view
{
display
:
flex
;
box-sizing
:
border-box
;
flex-direction
:
column
;
}
@media
screen
and
(
min-width
:
690px
)
{
.uni-content
{
padding
:
0
;
max-width
:
690px
;
margin-left
:
calc
(
50%
-
345px
);
border
:
none
;
max-height
:
none
;
border-radius
:
0
;
box-shadow
:
none
;
}
}
/* #endif */
.avatar
{
align-items
:
center
;
justify-content
:
center
;
margin
:
22px
0
;
width
:
100%
;
}
.item
{
flex
:
1
;
flex-direction
:
row
;
justify-content
:
space-between
;
align-items
:
center
;
}
button
{
margin
:
10%
;
margin-top
:
40px
;
border-radius
:
0
;
background-color
:
#FFFFFF
;
width
:
80%
;
}
.mt10
{
margin-top
:
10px
;
}
</
style
>
uni_modules/uni-id-pages/pages_init.json
0 → 100644
浏览文件 @
5e55a8d3
{
"pages"
:
[
{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate"
,
"style"
:
{
"navigationBarTitleText"
:
"注销账号"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/userinfo"
,
"style"
:
{
"navigationBarTitleText"
:
"个人资料"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/bind-mobile/bind-mobile"
,
"style"
:
{
"navigationBarTitleText"
:
"绑定手机号码"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage"
,
"style"
:
{
"navigationBarTitleText"
:
""
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/login/login-withoutpwd"
,
"style"
:
{
"navigationBarTitleText"
:
""
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/login/login-withpwd"
,
"style"
:
{
"navigationBarTitleText"
:
""
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/login/login-smscode"
,
"style"
:
{
"navigationBarTitleText"
:
"手机验证码登录"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/register/register"
,
"style"
:
{
"navigationBarTitleText"
:
"注册"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/register/register-by-email"
,
"style"
:
{
"navigationBarTitleText"
:
"邮箱验证码注册"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/retrieve/retrieve"
,
"style"
:
{
"navigationBarTitleText"
:
"重置密码"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/retrieve/retrieve-by-email"
,
"style"
:
{
"navigationBarTitleText"
:
"通过邮箱重置密码"
}
},
{
"path"
:
"uni_modules/uni-id-pages/pages/common/webview/webview"
,
"style"
:
{
"navigationBarTitleText"
:
""
,
"enablePullDownRefresh"
:
false
}
}
,{
"path"
:
"uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd"
,
"style"
:
{
"navigationBarTitleText"
:
"修改密码"
,
"enablePullDownRefresh"
:
false
}
}
]
}
\ No newline at end of file
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js
浏览文件 @
5e55a8d3
...
...
@@ -29,6 +29,21 @@ baseValidator.username = function (username) {
}
}
baseValidator
.
password
=
function
(
password
)
{
const
errCode
=
ERROR
.
INVALID_PASSWORD
if
(
!
isValidString
(
password
))
{
return
{
errCode
}
}
if
(
password
.
length
<
6
)
{
// 密码长度不能小于6
return
{
errCode
}
}
}
baseValidator
.
mobile
=
function
(
mobile
)
{
const
errCode
=
ERROR
.
INVALID_MOBILE
if
(
!
isValidString
(
mobile
))
{
...
...
@@ -92,7 +107,7 @@ baseType.forEach((type) => {
}
})
function
tokenize
(
name
)
{
function
tokenize
(
name
)
{
let
i
=
0
const
result
=
[]
let
token
=
''
...
...
@@ -122,7 +137,7 @@ function tokenize (name) {
* 处理validator名
* @param {string} name
*/
function
parseValidatorName
(
name
)
{
function
parseValidatorName
(
name
)
{
const
tokenList
=
tokenize
(
name
)
let
i
=
0
let
currentToken
=
tokenList
[
i
]
...
...
@@ -172,7 +187,7 @@ function parseValidatorName (name) {
return
result
}
function
getRuleCategory
(
rule
)
{
function
getRuleCategory
(
rule
)
{
switch
(
rule
.
type
)
{
case
'
array
'
:
return
'
array
'
...
...
@@ -183,7 +198,7 @@ function getRuleCategory (rule) {
}
}
function
isMatchUnionType
(
val
,
rule
)
{
function
isMatchUnionType
(
val
,
rule
)
{
if
(
!
rule
.
children
||
rule
.
children
.
length
===
0
)
{
return
true
}
...
...
@@ -209,7 +224,7 @@ function isMatchUnionType (val, rule) {
return
false
}
function
isMatchBaseType
(
val
,
rule
)
{
function
isMatchBaseType
(
val
,
rule
)
{
if
(
typeof
baseValidator
[
rule
.
type
]
!==
'
function
'
)
{
throw
new
Error
(
`invalid schema type:
${
rule
.
type
}
`
)
}
...
...
@@ -220,7 +235,7 @@ function isMatchBaseType (val, rule) {
return
true
}
function
isMatchArrayType
(
arr
,
rule
)
{
function
isMatchArrayType
(
arr
,
rule
)
{
if
(
getType
(
arr
)
!==
'
array
'
)
{
return
false
}
...
...
@@ -249,11 +264,12 @@ const passwordRules = {
// 密码必须为字母、数字和特殊符号任意两种的组合
medium
:
/^
(?![
0-9
]
+$
)(?![
a-zA-Z
]
+$
)(?![
~!@#$%^&*_
\-
+=`|
\\
(){}[
\]
:;"'<>,.?
/]
+$
)[
0-9a-zA-Z~!@#$%^&*_
\-
+=`|
\\
(){}[
\]
:;"'<>,.?
/]{8,16}
$/
,
// 密码必须包含字母和数字
weak
:
/^
(?=
.*
[
0-9
])(?=
.*
[
a-zA-Z
])[
0-9a-zA-Z~!@#$%^&*_
\-
+=`|
\\
(){}[
\]
:;"'<>,.?
/]{6,16}
$/
weak
:
/^
(?=
.*
[
0-9
])(?=
.*
[
a-zA-Z
])[
0-9a-zA-Z~!@#$%^&*_
\-
+=`|
\\
(){}[
\]
:;"'<>,.?
/]{6,16}
$/
,
}
function
createPasswordVerifier
({
passwordStrength
=
'
medium
'
function
createPasswordVerifier
({
passwordStrength
=
''
}
=
{})
{
return
function
(
password
)
{
const
passwordRegExp
=
passwordRules
[
passwordStrength
]
...
...
@@ -275,28 +291,30 @@ function createPasswordVerifier ({
}
class
Validator
{
constructor
({
passwordStrength
=
'
medium
'
constructor
({
passwordStrength
=
''
}
=
{})
{
this
.
baseValidator
=
baseValidator
this
.
customValidator
=
Object
.
create
(
null
)
this
.
mixin
(
'
password
'
,
createPasswordVerifier
({
passwordStrength
})
)
if
(
passwordStrength
)
{
this
.
mixin
(
'
password
'
,
createPasswordVerifier
({
passwordStrength
})
)
}
}
mixin
(
type
,
handler
)
{
mixin
(
type
,
handler
)
{
this
.
customValidator
[
type
]
=
handler
}
getRealBaseValidator
(
type
)
{
getRealBaseValidator
(
type
)
{
return
this
.
customValidator
[
type
]
||
this
.
baseValidator
[
type
]
}
get
validator
()
{
get
validator
()
{
return
new
Proxy
({},
{
get
:
(
_
,
prop
)
=>
{
if
(
typeof
prop
!==
'
string
'
)
{
...
...
@@ -318,7 +336,7 @@ class Validator {
})
}
validate
(
value
=
{},
schema
=
{})
{
validate
(
value
=
{},
schema
=
{})
{
for
(
const
schemaKey
in
schema
)
{
let
schemaValue
=
schema
[
schemaKey
]
if
(
getType
(
schemaValue
)
===
'
string
'
)
{
...
...
@@ -358,7 +376,7 @@ class Validator {
}
}
function
checkClientInfo
(
clientInfo
)
{
function
checkClientInfo
(
clientInfo
)
{
const
stringNotRequired
=
{
required
:
false
,
type
:
'
string
'
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.test.js
0 → 100644
浏览文件 @
5e55a8d3
const
assert
=
require
(
'
assert
'
)
const
{
Validator
}
=
require
(
'
./validator
'
)
const
{
ERROR
}
=
require
(
'
./error
'
)
const
{
getType
}
=
require
(
'
./utils
'
)
const
testCaseList
=
[{
value
:
{
username
:
'
uname
'
},
schema
:
{
username
:
'
username
'
},
expected
:
undefined
},
{
value
:
{
username
:
'
123456
'
},
schema
:
{
username
:
'
username
'
},
expected
:
{
errCode
:
ERROR
.
INVALID_USERNAME
}
},
{
value
:
{
username
:
'
数字天堂
'
},
schema
:
{
username
:
'
username
'
},
expected
:
{
errCode
:
ERROR
.
INVALID_USERNAME
}
},
{
value
:
{
password
:
'
123456abc
'
},
schema
:
{
password
:
'
password
'
}
},
{
value
:
{
password
:
'
123456def
'
},
schema
:
{
password
:
'
password
'
},
mixin
:
[{
type
:
'
password
'
,
handler
:
function
(
password
)
{
if
(
typeof
password
!==
'
string
'
||
password
.
length
<
10
)
{
return
{
errCode
:
ERROR
.
INVALID_PASSWORD
}
}
}
}],
expected
:
{
errCode
:
ERROR
.
INVALID_PASSWORD
}
},
{
value
:
{
numberOrString
:
'
123456
'
},
schema
:
{
numberOrString
:
'
number|string
'
}
},
{
value
:
{
numberOrString
:
123456
},
schema
:
{
numberOrString
:
'
number|string
'
}
},
{
value
:
{
numberOrString
:
'
123456
'
},
schema
:
{
numberOrString
:
'
string|number
'
}
},
{
value
:
{
numberOrString
:
123456
},
schema
:
{
numberOrString
:
'
string|number
'
}
},
{
value
:
{
numberOrString
:
[
'
123456
'
]
},
schema
:
{
numberOrString
:
'
array<number|string>
'
}
},
{
value
:
{
numberOrString
:
[
123456
]
},
schema
:
{
numberOrString
:
'
array<number|string>
'
}
},
{
value
:
{
numberOrString
:
[
123456
,
'
123456
'
]
},
schema
:
{
numberOrString
:
'
array<number|string>
'
}
},
{
value
:
{
numberOrString
:
[
'
123456
'
]
},
schema
:
{
numberOrString
:
'
array<string|number>
'
}
},
{
value
:
{
numberOrString
:
[
123456
]
},
schema
:
{
numberOrString
:
'
array<string|number>
'
}
},
{
value
:
{
numberOrString
:
[
123456
,
'
123456
'
]
},
schema
:
{
numberOrString
:
'
array<string|number>
'
}
},
{
value
:
{
numberOrString
:
[
'
123456
'
]
},
mixin
:
[{
type
:
'
1to6
'
,
handler
:
function
(
val
)
{
if
(
val
!==
'
123456
'
)
{
return
{
errCode
:
ERROR
.
INVALID_PARAM
}
}
}
}],
schema
:
{
numberOrString
:
'
array<number|1to6>
'
}
}]
function
execTestCase
({
value
=
{},
schema
=
{},
mixin
=
[],
expected
=
undefined
,
error
=
''
}
=
{})
{
const
validator
=
new
Validator
()
for
(
let
i
=
0
;
i
<
mixin
.
length
;
i
++
)
{
const
{
type
,
handler
}
=
mixin
[
i
]
validator
.
mixin
(
type
,
handler
)
}
let
validateResult
,
validateError
try
{
validateResult
=
validator
.
validate
(
value
,
schema
)
}
catch
(
err
)
{
validateError
=
err
}
const
tag
=
JSON
.
stringify
({
value
,
schema
})
if
(
error
)
{
if
(
typeof
error
===
'
string
'
)
{
assert
.
strictEqual
(
validateError
.
message
.
indexOf
(
error
)
>
-
1
,
true
,
`[
${
tag
}
] error message error`
)
}
else
if
(
getType
(
error
)
===
'
regexp
'
)
{
assert
.
strictEqual
(
error
.
test
(
validateError
),
true
,
`[
${
tag
}
] error message error`
)
}
else
{
throw
new
Error
(
`[
${
tag
}
] invalid test case`
)
}
return
}
if
(
expected
===
undefined
)
{
assert
.
strictEqual
(
validateResult
,
undefined
,
`[
${
tag
}
] validate result error`
)
return
}
const
expectedKeys
=
Object
.
keys
(
expected
)
let
passResultCheck
=
true
for
(
let
i
=
0
;
i
<
expectedKeys
.
length
;
i
++
)
{
const
key
=
expectedKeys
[
i
]
if
(
expected
[
key
]
!==
validateResult
[
key
])
{
passResultCheck
=
false
break
}
}
assert
.
strictEqual
(
passResultCheck
,
true
,
`[
${
tag
}
] validate result error`
)
}
for
(
let
i
=
0
;
i
<
testCaseList
.
length
;
i
++
)
{
console
.
log
(
`test case:
${
i
}
`
)
execTestCase
(
testCaseList
[
i
])
console
.
log
(
`test case:
${
i
}
, pass`
)
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/config/permission.js
浏览文件 @
5e55a8d3
...
...
@@ -7,6 +7,9 @@ module.exports = {
// permission: [] // 允许进行此操作的权限,包含任一权限均可操作。
// 权限角色均配置时,用户拥有任一权限或任一角色均可操作
},
updateUser
:
{
role
:
[
'
admin
'
]
},
authorizeAppLogin
:
{
role
:
[
'
admin
'
]
},
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js
浏览文件 @
5e55a8d3
...
...
@@ -18,7 +18,8 @@ const {
registerUser
}
=
require
(
'
./module/register/index
'
)
const
{
addUser
addUser
,
updateUser
}
=
require
(
'
./module/admin/index
'
)
const
{
login
,
...
...
@@ -109,7 +110,7 @@ module.exports = {
this
.
hooks
=
this
.
configUtils
.
getHooks
()
this
.
validator
=
new
Validator
({
passwordStrength
:
this
.
config
.
passwordStrength
||
'
medium
'
passwordStrength
:
this
.
config
.
passwordStrength
})
/**
* 示例:覆盖密码验证规则
...
...
@@ -216,6 +217,23 @@ module.exports = {
* @returns
*/
addUser
,
/**
* 修改用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user
* @param {Object} params
* @param {String} params.id 要更新的用户id
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
updateUser
,
/**
* 授权用户登录应用
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#authorize-app-login
...
...
@@ -490,4 +508,4 @@ module.exports = {
* @returns
*/
getSupportedLoginType
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/config.js
浏览文件 @
5e55a8d3
...
...
@@ -4,8 +4,8 @@ const {
const
createConfig
=
require
(
'
uni-config-center
'
)
const
requiredConfig
=
{
'
web.
h5-weixin
'
:
[
'
appid
'
,
'
appsecret
'
],
'
web.we
b-weixin
'
:
[
'
appid
'
,
'
appsecret
'
],
'
web.
weixin-h5
'
:
[
'
appid
'
,
'
appsecret
'
],
'
web.we
ixin-web
'
:
[
'
appid
'
,
'
appsecret
'
],
'
app.weixin
'
:
[
'
appid
'
,
'
appsecret
'
],
'
mp-weixin.weixin
'
:
[
'
appid
'
,
'
appsecret
'
],
'
app.qq
'
:
[
'
appid
'
,
'
appsecret
'
],
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js
浏览文件 @
5e55a8d3
...
...
@@ -8,6 +8,9 @@ const {
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
logout
}
=
require
(
'
./logout
'
)
const
PasswordUtils
=
require
(
'
./password
'
)
async
function
realPreLogin
(
params
=
{})
{
...
...
@@ -173,10 +176,14 @@ async function postLogin (params = {}) {
extraData
,
isThirdParty
=
false
}
=
params
const
{
clientIP
,
uniIdToken
}
=
this
.
getClientInfo
()
const
uid
=
user
.
_id
const
updateData
=
{
last_login_date
:
Date
.
now
(),
last_login_ip
:
this
.
getClientInfo
().
clientIP
,
last_login_ip
:
clientIP
,
...
extraData
}
const
{
...
...
@@ -185,6 +192,13 @@ async function postLogin (params = {}) {
}
=
await
this
.
uniIdCommon
.
createToken
({
uid
})
if
(
uniIdToken
)
{
try
{
await
logout
.
call
(
this
)
}
catch
(
error
)
{}
}
await
userCollection
.
doc
(
uid
).
update
(
updateData
)
await
this
.
middleware
.
uniIdLog
({
data
:
{
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js
0 → 100644
浏览文件 @
5e55a8d3
const
{
dbCmd
,
LOG_TYPE
,
deviceCollection
,
userCollection
}
=
require
(
'
../../common/constants
'
)
async
function
logout
()
{
const
{
uniIdToken
,
deviceId
}
=
this
.
getClientInfo
()
const
{
uid
}
=
await
this
.
uniIdCommon
.
checkToken
(
uniIdToken
,
{
autoRefresh
:
false
}
)
// 删除token
await
userCollection
.
doc
(
uid
).
update
({
token
:
dbCmd
.
pull
(
uniIdToken
)
})
// 仅当device表的device_id和user_id均对应时才进行更新
await
deviceCollection
.
where
({
device_id
:
deviceId
,
user_id
:
uid
}).
update
({
token_expired
:
0
})
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
LOG_TYPE
.
LOGOUT
})
return
{
errCode
:
0
}
}
module
.
exports
=
{
logout
}
\ No newline at end of file
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/qq.js
浏览文件 @
5e55a8d3
...
...
@@ -5,7 +5,7 @@ const {
ERROR
}
=
require
(
'
../../common/error
'
)
function
getQQPlatform
()
{
function
getQQPlatform
()
{
const
platform
=
this
.
clientPlatform
switch
(
platform
)
{
case
'
app
'
:
...
...
@@ -18,7 +18,7 @@ function getQQPlatform () {
}
}
async
function
saveQQUserKey
({
async
function
saveQQUserKey
({
openid
,
sessionKey
,
// QQ小程序用户sessionKey
accessToken
,
// App端QQ用户accessToken
...
...
@@ -45,14 +45,17 @@ async function saveQQUserKey ({
await
this
.
uniOpenBridge
.
setUserAccessToken
(
keyObj
,
{
access_token
:
accessToken
,
access_token_expired
:
accessTokenExpired
},
Math
.
floor
((
accessTokenExpired
-
Date
.
now
())
/
1000
))
},
accessTokenExpired
?
Math
.
floor
((
accessTokenExpired
-
Date
.
now
())
/
1000
)
:
30
*
24
*
60
*
60
)
break
default
:
break
}
}
function
generateQQCache
({
function
generateQQCache
({
sessionKey
,
// QQ小程序用户sessionKey
accessToken
,
// App端QQ用户accessToken
accessTokenExpired
// App端QQ用户accessToken过期时间
...
...
@@ -81,7 +84,7 @@ function generateQQCache ({
}
}
function
getQQOpenid
({
function
getQQOpenid
({
userRecord
}
=
{})
{
const
qqPlatform
=
getQQPlatform
.
call
(
this
)
...
...
@@ -93,7 +96,7 @@ function getQQOpenid ({
return
qqOpenidObj
[
`
${
qqPlatform
}
_
${
appId
}
`
]
||
qqOpenidObj
[
qqPlatform
]
}
async
function
getQQCacheFallback
({
async
function
getQQCacheFallback
({
userRecord
,
key
}
=
{})
{
...
...
@@ -106,7 +109,7 @@ async function getQQCacheFallback ({
return
qqCache
&&
qqCache
[
key
]
}
async
function
getQQCache
({
async
function
getQQCache
({
uid
,
userRecord
,
key
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js
浏览文件 @
5e55a8d3
...
...
@@ -12,10 +12,13 @@ const {
getValidInviteCode
,
generateInviteInfo
}
=
require
(
'
./fission
'
)
const
{
logout
}
=
require
(
'
./logout
'
)
const
PasswordUtils
=
require
(
'
./password
'
)
const
merge
=
require
(
'
lodash.merge
'
)
async
function
realPreRegister
(
params
=
{})
{
async
function
realPreRegister
(
params
=
{})
{
const
{
user
}
=
params
...
...
@@ -30,7 +33,7 @@ async function realPreRegister (params = {}) {
}
}
async
function
preRegister
(
params
=
{})
{
async
function
preRegister
(
params
=
{})
{
try
{
await
realPreRegister
.
call
(
this
,
params
)
}
catch
(
error
)
{
...
...
@@ -42,7 +45,7 @@ async function preRegister (params = {}) {
}
}
async
function
preRegisterWithPassword
(
params
=
{})
{
async
function
preRegisterWithPassword
(
params
=
{})
{
const
{
user
,
password
...
...
@@ -69,7 +72,7 @@ async function preRegisterWithPassword (params = {}) {
}
}
async
function
thirdPartyRegister
({
async
function
thirdPartyRegister
({
user
=
{}
}
=
{})
{
return
{
...
...
@@ -78,7 +81,7 @@ async function thirdPartyRegister ({
}
}
async
function
postRegister
(
params
=
{})
{
async
function
postRegister
(
params
=
{})
{
const
{
user
,
extraData
=
{},
...
...
@@ -93,7 +96,8 @@ async function postRegister (params = {}) {
channel
,
scene
,
clientIP
,
osName
osName
,
uniIdToken
}
=
this
.
getClientInfo
()
merge
(
user
,
extraData
)
...
...
@@ -147,6 +151,12 @@ async function postRegister (params = {}) {
user
.
invite_time
=
inviteTime
}
if
(
uniIdToken
)
{
try
{
await
logout
.
call
(
this
)
}
catch
(
error
)
{}
}
const
beforeRegister
=
this
.
hooks
.
beforeRegister
let
userRecord
=
user
if
(
beforeRegister
)
{
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/weixin.js
浏览文件 @
5e55a8d3
...
...
@@ -78,7 +78,7 @@ async function saveWeixinUserKey ({
access_token
:
accessToken
,
refresh_token
:
refreshToken
,
access_token_expired
:
accessTokenExpired
},
30
*
24
*
360
0
)
},
30
*
24
*
60
*
6
0
)
break
default
:
break
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
浏览文件 @
5e55a8d3
...
...
@@ -18,6 +18,10 @@ const PasswordUtils = require('../../lib/utils/password')
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
...
...
@@ -35,6 +39,22 @@ module.exports = async function (params = {}) {
role
:
{
require
:
false
,
type
:
'
array<string>
'
},
mobile
:
{
required
:
false
,
type
:
'
mobile
'
},
email
:
{
required
:
false
,
type
:
'
email
'
},
tags
:
{
required
:
false
,
type
:
'
array<string>
'
},
status
:
{
required
:
false
,
type
:
'
number
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
...
...
@@ -43,11 +63,17 @@ module.exports = async function (params = {}) {
password
,
authorizedApp
,
nickname
,
role
role
,
mobile
,
email
,
tags
,
status
}
=
params
const
userMatched
=
await
findUser
({
userQuery
:
{
username
username
,
mobile
,
email
},
authorizedApp
})
...
...
@@ -65,17 +91,28 @@ module.exports = async function (params = {}) {
}
=
passwordUtils
.
generatePasswordHash
({
password
})
await
userCollection
.
add
({
const
data
=
{
username
,
password
:
passwordHash
,
password_secret_version
:
version
,
dcloud_appid
:
authorizedApp
||
[],
nickname
,
role
:
role
||
[]
})
role
:
role
||
[],
mobile
,
email
,
tags
:
tags
||
[],
status
}
if
(
email
)
{
data
.
email_confirmed
=
1
}
if
(
mobile
)
{
data
.
mobile_confirmed
=
1
}
await
userCollection
.
add
(
data
)
return
{
errCode
:
0
errCode
:
0
,
errMsg
:
''
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/index.js
浏览文件 @
5e55a8d3
module
.
exports
=
{
addUser
:
require
(
'
./add-user
'
)
addUser
:
require
(
'
./add-user
'
),
updateUser
:
require
(
'
./update-user
'
)
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js
0 → 100644
浏览文件 @
5e55a8d3
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 修改用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user
* @param {Object} params
* @param {String} params.uid 要更新的用户id
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
uid
:
'
string
'
,
username
:
'
username
'
,
password
:
{
required
:
false
,
type
:
'
password
'
},
authorizedApp
:
{
required
:
false
,
type
:
'
array<string>
'
},
// 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
role
:
{
require
:
false
,
type
:
'
array<string>
'
},
mobile
:
{
required
:
false
,
type
:
'
mobile
'
},
email
:
{
required
:
false
,
type
:
'
email
'
},
tags
:
{
required
:
false
,
type
:
'
array<string>
'
},
status
:
{
required
:
false
,
type
:
'
number
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
uid
,
username
,
password
,
authorizedApp
,
nickname
,
role
,
mobile
,
email
,
tags
,
status
}
=
params
// 更新的用户数据字段
const
data
=
{
username
,
dcloud_appid
:
authorizedApp
||
[],
nickname
,
role
:
role
||
[],
mobile
,
email
,
tags
:
tags
||
[],
status
}
// 更新用户名时验证用户名是否重新
if
(
username
)
{
const
userMatched
=
await
findUser
({
userQuery
:
{
username
},
authorizedApp
})
if
(
userMatched
.
filter
(
user
=>
user
.
_id
!==
uid
).
length
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
}
if
(
password
)
{
const
passwordUtils
=
new
PasswordUtils
({
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
})
data
.
password
=
passwordHash
data
.
password_secret_version
=
version
}
await
userCollection
.
doc
(
uid
).
update
(
data
)
return
{
errCode
:
0
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/logout/logout.js
浏览文件 @
5e55a8d3
const
{
dbCmd
,
LOG_TYPE
,
deviceCollection
,
userCollection
}
=
require
(
'
../../common/constants
'
)
logout
}
=
require
(
'
../../lib/utils/logout
'
)
/**
* 用户退出登录
...
...
@@ -11,37 +8,7 @@ const {
* @returns
*/
module
.
exports
=
async
function
()
{
const
{
uniIdToken
,
deviceId
}
=
this
.
getClientInfo
()
const
{
uid
}
=
await
this
.
uniIdCommon
.
checkToken
(
uniIdToken
,
{
autoRefresh
:
false
}
)
// 删除token
await
userCollection
.
doc
(
uid
).
update
({
token
:
dbCmd
.
pull
(
uniIdToken
)
})
// 仅当device表的device_id和user_id均对应时才进行更新
await
deviceCollection
.
where
({
device_id
:
deviceId
,
user_id
:
uid
}).
update
({
token_expired
:
0
})
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
LOG_TYPE
.
LOGOUT
})
await
logout
.
call
(
this
)
return
{
errCode
:
0
}
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/remove-authorized-app.js
浏览文件 @
5e55a8d3
...
...
@@ -16,7 +16,7 @@ module.exports = async function (params = {}) {
uid
:
'
string
'
,
appId
:
'
string
'
}
this
.
m
o
ddleware
.
validate
(
params
,
schema
)
this
.
m
i
ddleware
.
validate
(
params
,
schema
)
const
{
uid
,
appId
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json
浏览文件 @
5e55a8d3
{
"name"
:
"uni-id-co"
,
"version"
:
"1.0.1
0
"
,
"version"
:
"1.0.1
2
"
,
"description"
:
""
,
"main"
:
"index.js"
,
"keywords"
:
[],
...
...
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js
浏览文件 @
5e55a8d3
'
use strict
'
;
'
use strict
'
;
class
BridgeError
extends
Error
{
...
...
@@ -20,7 +20,7 @@ class BridgeError extends Error {
return
this
.
message
}
}
module
.
exports
=
{
BridgeError
module
.
exports
=
{
BridgeError
}
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js
浏览文件 @
5e55a8d3
'
use strict
'
;
const
{
PlatformType
}
=
require
(
'
./consts.js
'
)
const
configCenter
=
require
(
'
uni-config-center
'
)
const
OauthConfig
=
{
'
weixin-mp
'
:
[
'
mp-weixin
'
,
'
oauth
'
,
'
weixin
'
],
'
weixin-h5
'
:
[
'
web
'
,
'
oauth
'
,
'
weixin-h5
'
]
}
class
ConfigBase
{
constructor
()
{
this
.
_ready
=
false
this
.
_uniId
=
null
const
uniIdConfig
=
configCenter
({
pluginId
:
'
uni-id
'
})
this
.
_uniId
=
uniIdConfig
.
config
()
this
.
_ready
=
true
}
getAppConfig
(
appid
)
{
if
(
Array
.
isArray
(
this
.
_uniId
))
{
return
this
.
_uniId
.
find
((
item
)
=>
{
return
(
item
.
dcloudAppid
===
appid
)
})
}
return
this
.
_uniId
}
get
ready
()
{
return
this
.
_ready
}
}
class
AppConfig
extends
ConfigBase
{
constructor
()
{
super
()
}
get
(
appid
,
platform
)
{
if
(
!
this
.
isSupport
(
platform
))
{
return
null
}
let
appConfig
=
this
.
getAppConfig
(
appid
)
if
(
!
appConfig
)
{
return
null
}
return
this
.
getOauthConfig
(
appConfig
,
platform
)
}
isSupport
(
platformName
)
{
return
(
AppConfig
.
Support_Platforms
.
indexOf
(
platformName
)
>=
0
)
}
getOauthConfig
(
appConfig
,
platformName
)
{
let
tree
=
OauthConfig
[
platformName
]
let
node
=
appConfig
for
(
let
i
=
0
;
i
<
tree
.
length
;
i
++
)
{
let
nodeName
=
tree
[
i
]
if
(
node
[
nodeName
])
{
node
=
node
[
nodeName
]
}
else
{
node
=
null
break
}
}
if
(
node
&&
node
.
appid
&&
node
.
appsecret
)
{
return
{
appid
:
node
.
appid
,
secret
:
node
.
appsecret
}
}
return
null
}
}
AppConfig
.
Support_Platforms
=
[
PlatformType
.
WEIXIN_MP
,
PlatformType
.
WEIXIN_H5
]
module
.
exports
=
{
AppConfig
'
use strict
'
;
const
{
PlatformType
}
=
require
(
'
./consts.js
'
)
const
configCenter
=
require
(
'
uni-config-center
'
)
const
OauthConfig
=
{
'
weixin-mp
'
:
[
'
mp-weixin
'
,
'
oauth
'
,
'
weixin
'
],
'
weixin-h5
'
:
[
'
web
'
,
'
oauth
'
,
'
weixin-h5
'
]
}
class
ConfigBase
{
constructor
()
{
this
.
_ready
=
false
this
.
_uniId
=
null
const
uniIdConfig
=
configCenter
({
pluginId
:
'
uni-id
'
})
this
.
_uniId
=
uniIdConfig
.
config
()
this
.
_ready
=
true
}
getAppConfig
(
appid
)
{
if
(
Array
.
isArray
(
this
.
_uniId
))
{
return
this
.
_uniId
.
find
((
item
)
=>
{
return
(
item
.
dcloudAppid
===
appid
)
})
}
return
this
.
_uniId
}
get
ready
()
{
return
this
.
_ready
}
}
class
AppConfig
extends
ConfigBase
{
constructor
()
{
super
()
}
get
(
appid
,
platform
)
{
if
(
!
this
.
isSupport
(
platform
))
{
return
null
}
let
appConfig
=
this
.
getAppConfig
(
appid
)
if
(
!
appConfig
)
{
return
null
}
return
this
.
getOauthConfig
(
appConfig
,
platform
)
}
isSupport
(
platformName
)
{
return
(
AppConfig
.
Support_Platforms
.
indexOf
(
platformName
)
>=
0
)
}
getOauthConfig
(
appConfig
,
platformName
)
{
let
tree
=
OauthConfig
[
platformName
]
let
node
=
appConfig
for
(
let
i
=
0
;
i
<
tree
.
length
;
i
++
)
{
let
nodeName
=
tree
[
i
]
if
(
node
[
nodeName
])
{
node
=
node
[
nodeName
]
}
else
{
node
=
null
break
}
}
if
(
node
&&
node
.
appid
&&
node
.
appsecret
)
{
return
{
appid
:
node
.
appid
,
secret
:
node
.
appsecret
}
}
return
null
}
}
AppConfig
.
Support_Platforms
=
[
PlatformType
.
WEIXIN_MP
,
PlatformType
.
WEIXIN_H5
]
module
.
exports
=
{
AppConfig
};
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
浏览文件 @
5e55a8d3
'
use strict
'
;
const
HTTP_STATUS
=
{
SUCCESS
:
200
}
const
PlatformType
=
{
WEIXIN_MP
:
'
weixin-mp
'
,
WEIXIN_H5
:
'
weixin-h5
'
,
WEIXIN_APP
:
'
weixin-app
'
,
WEIXIN_WEB
:
'
weixin-web
'
,
QQ_MP
:
'
qq-mp
'
,
QQ_APP
:
'
qq-app
'
}
module
.
exports
=
{
HTTP_STATUS
,
PlatformType
'
use strict
'
;
const
TAG
=
"
UNI_OPEN_BRIDGE
"
const
HTTP_STATUS
=
{
SUCCESS
:
200
}
const
PlatformType
=
{
WEIXIN_MP
:
'
weixin-mp
'
,
WEIXIN_H5
:
'
weixin-h5
'
,
WEIXIN_APP
:
'
weixin-app
'
,
WEIXIN_WEB
:
'
weixin-web
'
,
QQ_MP
:
'
qq-mp
'
,
QQ_APP
:
'
qq-app
'
}
const
ErrorCodeType
=
{
SYSTEM_ERROR
:
TAG
+
"
_SYSTEM_ERROR
"
}
module
.
exports
=
{
HTTP_STATUS
,
PlatformType
,
ErrorCodeType
}
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
浏览文件 @
5e55a8d3
'
use strict
'
;
const
{
PlatformType
}
=
require
(
'
./consts.js
'
)
const
{
AppConfig
}
=
require
(
'
./config.js
'
)
const
{
Storage
,
Factory
}
=
require
(
'
./storage.js
'
)
const
{
BridgeError
}
=
require
(
'
./bridge-error.js
'
)
const
{
WeixinServer
}
=
require
(
'
./weixin-server.js
'
)
const
appConfig
=
new
AppConfig
()
class
AccessToken
extends
Storage
{
constructor
()
{
super
(
'
access-token
'
,
[
'
dcloudAppid
'
,
'
platform
'
])
}
async
fallback
(
parameters
)
{
const
oauthConfig
=
appConfig
.
get
(
parameters
.
dcloudAppid
,
parameters
.
platform
)
const
methodName
=
(
parameters
.
platform
===
PlatformType
.
WEIXIN_MP
)
?
'
GetMPAccessTokenData
'
:
'
GetH5AccessTokenData
'
const
responseData
=
await
WeixinServer
[
methodName
](
oauthConfig
)
const
duration
=
responseData
.
expires_in
delete
responseData
.
expires_in
return
{
value
:
responseData
,
duration
}
}
}
class
UserAccessToken
extends
Storage
{
constructor
()
{
super
(
'
user-access-token
'
,
[
'
dcloudAppid
'
,
'
platform
'
,
'
openid
'
])
}
}
class
SessionKey
extends
Storage
{
constructor
()
{
super
(
'
session-key
'
,
[
'
dcloudAppid
'
,
'
platform
'
,
'
openid
'
])
}
}
class
Encryptkey
extends
Storage
{
constructor
()
{
super
(
'
encrypt-key
'
,
[
'
dcloudAppid
'
,
'
platform
'
,
'
openid
'
])
}
getKeyString
(
key
)
{
return
`
${
super
.
getKeyString
(
key
)}
-
${
key
.
version
}
`
}
getExpiresIn
(
value
)
{
if
(
value
<=
0
)
{
return
60
}
return
value
}
async
fallback
(
parameters
)
{
const
accessToken
=
await
Factory
.
Get
(
AccessToken
,
parameters
)
const
userSession
=
await
Factory
.
Get
(
SessionKey
,
parameters
)
const
responseData
=
await
WeixinServer
.
GetUserEncryptKeyData
({
openid
:
parameters
.
openid
,
access_token
:
accessToken
.
access_token
,
session_key
:
userSession
.
session_key
})
const
keyInfo
=
responseData
.
key_info_list
.
find
((
item
)
=>
{
return
item
.
version
=
parameters
.
version
})
const
value
=
{
encrypt_key
:
keyInfo
.
encrypt_key
,
iv
:
keyInfo
.
iv
}
return
{
value
,
duration
:
keyInfo
.
expire_in
}
}
}
class
Ticket
extends
Storage
{
constructor
()
{
super
(
'
ticket
'
,
[
'
dcloudAppid
'
,
'
platform
'
])
}
async
fallback
(
parameters
)
{
const
accessToken
=
await
Factory
.
Get
(
AccessToken
,
{
dcloudAppid
:
parameters
.
dcloudAppid
,
platform
:
PlatformType
.
WEIXIN_H5
})
const
responseData
=
await
WeixinServer
.
GetH5TicketData
(
accessToken
)
const
duration
=
responseData
.
expires_in
delete
responseData
.
expires_in
return
{
value
:
responseData
,
duration
}
}
}
// exports
async
function
getAccessToken
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
AccessToken
,
key
,
fallback
)
}
async
function
setAccessToken
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
AccessToken
,
key
,
value
,
expiresIn
)
}
async
function
removeAccessToken
(
key
)
{
await
Factory
.
Remove
(
AccessToken
,
key
)
}
async
function
getUserAccessToken
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
UserAccessToken
,
key
,
fallback
)
}
async
function
setUserAccessToken
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
UserAccessToken
,
key
,
value
,
expiresIn
)
}
async
function
removeUserAccessToken
(
key
)
{
await
Factory
.
Remove
(
UserAccessToken
,
key
)
}
async
function
getSessionKey
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
SessionKey
,
key
,
fallback
)
}
async
function
setSessionKey
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
SessionKey
,
key
,
value
,
expiresIn
)
}
async
function
removeSessionKey
(
key
)
{
await
Factory
.
Remove
(
SessionKey
,
key
)
}
async
function
getEncryptKey
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
Encryptkey
,
key
,
fallback
)
}
async
function
setEncryptKey
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
Encryptkey
,
key
,
value
,
expiresIn
)
}
async
function
removeEncryptKey
(
key
)
{
await
Factory
.
Remove
(
Encryptkey
,
key
)
}
async
function
getTicket
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
Ticket
,
key
,
fallback
)
}
async
function
setTicket
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
Ticket
,
key
,
value
,
expiresIn
)
}
async
function
removeTicket
(
key
)
{
await
Factory
.
Remove
(
Ticket
,
key
)
}
module
.
exports
=
{
getAccessToken
,
setAccessToken
,
removeAccessToken
,
getUserAccessToken
,
setUserAccessToken
,
removeUserAccessToken
,
getSessionKey
,
setSessionKey
,
removeSessionKey
,
getEncryptKey
,
setEncryptKey
,
removeEncryptKey
,
getTicket
,
setTicket
,
removeTicket
,
PlatformType
,
WeixinServer
'
use strict
'
;
const
{
PlatformType
,
ErrorCodeType
}
=
require
(
'
./consts.js
'
)
const
{
AppConfig
}
=
require
(
'
./config.js
'
)
const
{
Storage
,
Factory
}
=
require
(
'
./storage.js
'
)
const
{
BridgeError
}
=
require
(
'
./bridge-error.js
'
)
const
{
WeixinServer
}
=
require
(
'
./weixin-server.js
'
)
const
appConfig
=
new
AppConfig
()
class
AccessToken
extends
Storage
{
constructor
()
{
super
(
'
access-token
'
,
[
'
dcloudAppid
'
,
'
platform
'
])
}
async
fallback
(
parameters
)
{
const
oauthConfig
=
appConfig
.
get
(
parameters
.
dcloudAppid
,
parameters
.
platform
)
let
methodName
if
(
parameters
.
platform
===
PlatformType
.
WEIXIN_MP
)
{
methodName
=
'
GetMPAccessTokenData
'
}
else
if
(
parameters
.
platform
===
PlatformType
.
WEIXIN_H5
)
{
methodName
=
'
GetH5AccessTokenData
'
}
else
{
throw
new
BridgeError
(
ErrorCodeType
.
SYSTEM_ERROR
,
"
platform invalid
"
)
}
const
responseData
=
await
WeixinServer
[
methodName
](
oauthConfig
)
const
duration
=
responseData
.
expires_in
delete
responseData
.
expires_in
return
{
value
:
responseData
,
duration
}
}
}
class
UserAccessToken
extends
Storage
{
constructor
()
{
super
(
'
user-access-token
'
,
[
'
dcloudAppid
'
,
'
platform
'
,
'
openid
'
])
}
}
class
SessionKey
extends
Storage
{
constructor
()
{
super
(
'
session-key
'
,
[
'
dcloudAppid
'
,
'
platform
'
,
'
openid
'
])
}
}
class
Encryptkey
extends
Storage
{
constructor
()
{
super
(
'
encrypt-key
'
,
[
'
dcloudAppid
'
,
'
platform
'
,
'
openid
'
])
}
getKeyString
(
key
)
{
return
`
${
super
.
getKeyString
(
key
)}
-
${
key
.
version
}
`
}
getExpiresIn
(
value
)
{
if
(
value
<=
0
)
{
return
60
}
return
value
}
async
fallback
(
parameters
)
{
const
accessToken
=
await
Factory
.
Get
(
AccessToken
,
parameters
)
const
userSession
=
await
Factory
.
Get
(
SessionKey
,
parameters
)
const
responseData
=
await
WeixinServer
.
GetUserEncryptKeyData
({
openid
:
parameters
.
openid
,
access_token
:
accessToken
.
access_token
,
session_key
:
userSession
.
session_key
})
const
keyInfo
=
responseData
.
key_info_list
.
find
((
item
)
=>
{
return
item
.
version
=
parameters
.
version
})
const
value
=
{
encrypt_key
:
keyInfo
.
encrypt_key
,
iv
:
keyInfo
.
iv
}
return
{
value
,
duration
:
keyInfo
.
expire_in
}
}
}
class
Ticket
extends
Storage
{
constructor
()
{
super
(
'
ticket
'
,
[
'
dcloudAppid
'
,
'
platform
'
])
}
async
fallback
(
parameters
)
{
const
accessToken
=
await
Factory
.
Get
(
AccessToken
,
{
dcloudAppid
:
parameters
.
dcloudAppid
,
platform
:
PlatformType
.
WEIXIN_H5
})
const
responseData
=
await
WeixinServer
.
GetH5TicketData
(
accessToken
)
const
duration
=
responseData
.
expires_in
delete
responseData
.
expires_in
return
{
value
:
responseData
,
duration
}
}
}
// exports
async
function
getAccessToken
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
AccessToken
,
key
,
fallback
)
}
async
function
setAccessToken
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
AccessToken
,
key
,
value
,
expiresIn
)
}
async
function
removeAccessToken
(
key
)
{
await
Factory
.
Remove
(
AccessToken
,
key
)
}
async
function
getUserAccessToken
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
UserAccessToken
,
key
,
fallback
)
}
async
function
setUserAccessToken
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
UserAccessToken
,
key
,
value
,
expiresIn
)
}
async
function
removeUserAccessToken
(
key
)
{
await
Factory
.
Remove
(
UserAccessToken
,
key
)
}
async
function
getSessionKey
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
SessionKey
,
key
,
fallback
)
}
async
function
setSessionKey
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
SessionKey
,
key
,
value
,
expiresIn
)
}
async
function
removeSessionKey
(
key
)
{
await
Factory
.
Remove
(
SessionKey
,
key
)
}
async
function
getEncryptKey
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
Encryptkey
,
key
,
fallback
)
}
async
function
setEncryptKey
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
Encryptkey
,
key
,
value
,
expiresIn
)
}
async
function
removeEncryptKey
(
key
)
{
await
Factory
.
Remove
(
Encryptkey
,
key
)
}
async
function
getTicket
(
key
,
fallback
)
{
return
await
Factory
.
Get
(
Ticket
,
key
,
fallback
)
}
async
function
setTicket
(
key
,
value
,
expiresIn
)
{
await
Factory
.
Set
(
Ticket
,
key
,
value
,
expiresIn
)
}
async
function
removeTicket
(
key
)
{
await
Factory
.
Remove
(
Ticket
,
key
)
}
module
.
exports
=
{
getAccessToken
,
setAccessToken
,
removeAccessToken
,
getUserAccessToken
,
setUserAccessToken
,
removeUserAccessToken
,
getSessionKey
,
setSessionKey
,
removeSessionKey
,
getEncryptKey
,
setEncryptKey
,
removeEncryptKey
,
getTicket
,
setTicket
,
removeTicket
,
PlatformType
,
WeixinServer
,
ErrorCodeType
}
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
浏览文件 @
5e55a8d3
'
use strict
'
;
const
{
Validator
}
=
require
(
'
./validator.js
'
)
const
{
CacheKeyCascade
}
=
require
(
'
./uni-cloud-cache.js
'
)
class
Storage
{
constructor
(
type
,
keys
)
{
this
.
_type
=
type
||
null
this
.
_keys
=
keys
||
[]
}
async
get
(
key
,
fallback
)
{
this
.
validateKey
(
key
)
const
result
=
await
this
.
create
(
key
,
fallback
).
get
()
return
result
.
value
}
async
set
(
key
,
value
,
expiresIn
)
{
this
.
validateKey
(
key
)
this
.
validateValue
(
value
)
const
expires_in
=
this
.
getExpiresIn
(
expiresIn
)
if
(
expires_in
!==
0
)
{
await
this
.
create
(
key
).
set
(
this
.
getValue
(
value
),
expires_in
)
}
}
async
remove
(
key
)
{
this
.
validateKey
(
key
)
await
this
.
create
(
key
).
remove
()
}
async
ttl
(
key
)
{
this
.
validateKey
(
key
)
// 后续考虑支持
}
getKeyString
(
key
)
{
const
keyArray
=
[
Storage
.
Prefix
]
this
.
_keys
.
forEach
((
name
)
=>
{
keyArray
.
push
(
key
[
name
])
})
keyArray
.
push
(
this
.
_type
)
return
keyArray
.
join
(
'
:
'
)
}
getValue
(
value
)
{
return
value
}
getExpiresIn
(
value
)
{
if
(
value
!==
undefined
)
{
return
value
}
return
-
1
}
validateKey
(
key
)
{
Validator
.
Key
(
this
.
_keys
,
key
)
}
validateValue
(
value
)
{
Validator
.
Value
(
value
)
}
create
(
key
,
fallback
)
{
const
keyString
=
this
.
getKeyString
(
key
)
const
options
=
{
layers
:
[{
type
:
'
database
'
,
key
:
keyString
},
{
type
:
'
redis
'
,
key
:
keyString
}]
}
if
(
fallback
!==
null
)
{
const
fallbackFunction
=
fallback
||
this
.
fallback
if
(
fallbackFunction
)
{
options
.
fallback
=
async
()
=>
{
return
await
fallbackFunction
(
key
)
}
}
}
return
new
CacheKeyCascade
(
options
)
}
}
Storage
.
Prefix
=
"
uni-id
"
const
Factory
=
{
async
Get
(
T
,
key
,
fallback
)
{
return
await
Factory
.
MakeUnique
(
T
).
get
(
key
,
fallback
)
},
async
Set
(
T
,
key
,
value
,
expiresIn
)
{
await
Factory
.
MakeUnique
(
T
).
set
(
key
,
value
,
expiresIn
)
},
async
Remove
(
T
,
key
)
{
await
Factory
.
MakeUnique
(
T
).
remove
(
key
)
},
MakeUnique
(
T
)
{
return
new
T
()
}
}
module
.
exports
=
{
Storage
,
Factory
'
use strict
'
;
const
{
Validator
}
=
require
(
'
./validator.js
'
)
const
{
CacheKeyCascade
}
=
require
(
'
./uni-cloud-cache.js
'
)
class
Storage
{
constructor
(
type
,
keys
)
{
this
.
_type
=
type
||
null
this
.
_keys
=
keys
||
[]
}
async
get
(
key
,
fallback
)
{
this
.
validateKey
(
key
)
const
result
=
await
this
.
create
(
key
,
fallback
).
get
()
return
result
.
value
}
async
set
(
key
,
value
,
expiresIn
)
{
this
.
validateKey
(
key
)
this
.
validateValue
(
value
)
const
expires_in
=
this
.
getExpiresIn
(
expiresIn
)
if
(
expires_in
!==
0
)
{
await
this
.
create
(
key
).
set
(
this
.
getValue
(
value
),
expires_in
)
}
}
async
remove
(
key
)
{
this
.
validateKey
(
key
)
await
this
.
create
(
key
).
remove
()
}
async
ttl
(
key
)
{
this
.
validateKey
(
key
)
// 后续考虑支持
}
getKeyString
(
key
)
{
const
keyArray
=
[
Storage
.
Prefix
]
this
.
_keys
.
forEach
((
name
)
=>
{
keyArray
.
push
(
key
[
name
])
})
keyArray
.
push
(
this
.
_type
)
return
keyArray
.
join
(
'
:
'
)
}
getValue
(
value
)
{
return
value
}
getExpiresIn
(
value
)
{
if
(
value
!==
undefined
)
{
return
value
}
return
-
1
}
validateKey
(
key
)
{
Validator
.
Key
(
this
.
_keys
,
key
)
}
validateValue
(
value
)
{
Validator
.
Value
(
value
)
}
create
(
key
,
fallback
)
{
const
keyString
=
this
.
getKeyString
(
key
)
const
options
=
{
layers
:
[{
type
:
'
database
'
,
key
:
keyString
},
{
type
:
'
redis
'
,
key
:
keyString
}]
}
if
(
fallback
!==
null
)
{
const
fallbackFunction
=
fallback
||
this
.
fallback
if
(
fallbackFunction
)
{
options
.
fallback
=
async
()
=>
{
return
await
fallbackFunction
(
key
)
}
}
}
return
new
CacheKeyCascade
(
options
)
}
}
Storage
.
Prefix
=
"
uni-id
"
const
Factory
=
{
async
Get
(
T
,
key
,
fallback
)
{
return
await
Factory
.
MakeUnique
(
T
).
get
(
key
,
fallback
)
},
async
Set
(
T
,
key
,
value
,
expiresIn
)
{
await
Factory
.
MakeUnique
(
T
).
set
(
key
,
value
,
expiresIn
)
},
async
Remove
(
T
,
key
)
{
await
Factory
.
MakeUnique
(
T
).
remove
(
key
)
},
MakeUnique
(
T
)
{
return
new
T
()
}
}
module
.
exports
=
{
Storage
,
Factory
};
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
浏览文件 @
5e55a8d3
const
db
=
uniCloud
.
database
()
function
getType
(
value
)
{
return
Object
.
prototype
.
toString
.
call
(
value
).
slice
(
8
,
-
1
).
toLowerCase
()
}
const
validator
=
{
key
:
function
(
value
)
{
const
err
=
new
Error
(
'
Invalid key
'
)
if
(
typeof
value
!==
'
string
'
)
{
throw
err
}
const
valueTrim
=
value
.
trim
()
if
(
!
valueTrim
||
valueTrim
!==
value
)
{
throw
err
}
},
value
:
function
(
value
)
{
// 仅作简单校验
const
type
=
getType
(
value
)
const
validValueType
=
[
'
null
'
,
'
number
'
,
'
string
'
,
'
array
'
,
'
object
'
]
if
(
validValueType
.
indexOf
(
type
)
===
-
1
)
{
throw
new
Error
(
'
Invalid value type
'
)
}
},
duration
:
function
(
value
)
{
const
err
=
new
Error
(
'
Invalid duration
'
)
if
(
value
===
undefined
)
{
return
}
if
(
typeof
value
!==
'
number
'
||
value
===
0
)
{
throw
err
}
}
}
/**
* 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示
* 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在
*/
class
DatabaseCache
{
constructor
({
collection
=
'
opendb-open-data
'
}
=
{})
{
this
.
type
=
'
db
'
this
.
collection
=
db
.
collection
(
collection
)
}
_serializeValue
(
value
)
{
return
value
===
undefined
?
null
:
JSON
.
stringify
(
value
)
}
_deserializeValue
(
value
)
{
return
value
?
JSON
.
parse
(
value
)
:
value
}
async
set
(
key
,
value
,
duration
)
{
validator
.
key
(
key
)
validator
.
value
(
value
)
validator
.
duration
(
duration
)
value
=
this
.
_serializeValue
(
value
)
await
this
.
collection
.
doc
(
key
).
set
({
value
,
expired
:
duration
&&
duration
!==
-
1
?
Date
.
now
()
+
duration
:
-
1
})
}
async
_getWithDuration
(
key
)
{
const
getKeyRes
=
await
this
.
collection
.
doc
(
key
).
get
()
const
record
=
getKeyRes
.
data
[
0
]
if
(
!
record
)
{
return
{
value
:
null
,
duration
:
-
2
}
}
const
value
=
this
.
_deserializeValue
(
record
.
value
)
const
expired
=
record
.
expired
if
(
expired
===
-
1
)
{
return
{
value
,
duration
:
-
1
}
}
const
duration
=
expired
-
Date
.
now
()
if
(
duration
<=
0
)
{
await
this
.
remove
(
key
)
return
{
value
:
null
,
duration
:
-
2
}
}
return
{
value
,
duration
:
Math
.
floor
(
duration
/
1000
)
}
}
async
get
(
key
,
{
withDuration
=
true
}
=
{})
{
const
result
=
await
this
.
_getWithDuration
(
key
)
if
(
!
withDuration
)
{
delete
result
.
duration
}
return
result
}
async
remove
(
key
)
{
await
this
.
collection
.
doc
(
key
).
remove
()
}
}
class
RedisCache
{
constructor
()
{
this
.
type
=
'
redis
'
this
.
redis
=
uniCloud
.
redis
()
}
_serializeValue
(
value
)
{
return
value
===
undefined
?
null
:
JSON
.
stringify
(
value
)
}
_deserializeValue
(
value
)
{
return
value
?
JSON
.
parse
(
value
)
:
value
}
async
set
(
key
,
value
,
duration
)
{
validator
.
key
(
key
)
validator
.
value
(
value
)
validator
.
duration
(
duration
)
value
=
this
.
_serializeValue
(
value
)
if
(
!
duration
||
duration
===
-
1
)
{
await
this
.
redis
.
set
(
key
,
value
)
}
else
{
await
this
.
redis
.
set
(
key
,
value
,
'
EX
'
,
duration
)
}
}
async
get
(
key
,
{
withDuration
=
false
}
=
{})
{
let
value
=
await
this
.
redis
.
get
(
key
)
value
=
this
.
_deserializeValue
(
value
)
if
(
!
withDuration
)
{
return
{
value
}
}
const
durationSecond
=
await
this
.
redis
.
ttl
(
key
)
let
duration
switch
(
durationSecond
)
{
case
-
1
:
duration
=
-
1
break
case
-
2
:
duration
=
-
2
break
default
:
duration
=
durationSecond
break
}
return
{
value
,
duration
}
}
async
remove
(
key
)
{
await
this
.
redis
.
del
(
key
)
}
}
class
Cache
{
constructor
({
type
,
collection
}
=
{})
{
if
(
type
===
'
database
'
)
{
return
new
DatabaseCache
({
collection
})
}
else
if
(
type
===
'
redis
'
)
{
return
new
RedisCache
()
}
else
{
throw
new
Error
(
'
Invalid cache type
'
)
}
}
}
class
CacheKey
{
constructor
({
type
,
collection
,
cache
,
key
,
fallback
}
=
{})
{
this
.
cache
=
cache
||
new
Cache
({
type
,
collection
})
this
.
key
=
key
this
.
fallback
=
fallback
}
async
set
(
value
,
duration
)
{
await
this
.
cache
.
set
(
this
.
key
,
value
,
duration
)
}
async
setWithSync
(
value
,
duration
,
syncMethod
)
{
await
Promise
.
all
([
this
.
set
(
this
.
key
,
value
,
duration
),
syncMethod
(
value
,
duration
)
])
}
async
get
()
{
let
{
value
,
duration
}
=
await
this
.
cache
.
get
(
this
.
key
)
if
(
value
!==
null
&&
value
!==
undefined
)
{
return
{
value
,
duration
}
}
if
(
!
this
.
fallback
)
{
return
{
value
:
null
,
duration
:
-
2
}
}
const
fallbackResult
=
await
this
.
fallback
()
value
=
fallbackResult
.
value
duration
=
fallbackResult
.
duration
if
(
value
!==
null
&&
duration
!==
undefined
)
{
await
this
.
cache
.
set
(
this
.
key
,
value
,
duration
)
}
return
{
value
,
duration
}
}
async
remove
()
{
await
this
.
cache
.
remove
(
this
.
key
)
}
}
class
CacheKeyCascade
{
constructor
({
layers
,
// [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey]
fallback
}
=
{})
{
this
.
layers
=
layers
this
.
cacheLayers
=
[]
let
lastCacheKey
for
(
let
i
=
0
;
i
<
layers
.
length
;
i
++
)
{
const
{
type
,
cache
,
collection
,
key
}
=
layers
[
i
]
const
lastCacheKeyTemp
=
lastCacheKey
try
{
const
currentCacheKey
=
new
CacheKey
({
type
,
collection
,
cache
,
key
,
fallback
:
i
===
0
?
fallback
:
function
()
{
return
lastCacheKeyTemp
.
get
()
}
})
this
.
cacheLayers
.
push
(
currentCacheKey
)
lastCacheKey
=
currentCacheKey
}
catch
(
e
)
{}
}
this
.
highLevelCache
=
lastCacheKey
}
async
set
(
value
,
duration
)
{
return
Promise
.
all
(
this
.
cacheLayers
.
map
(
item
=>
{
return
item
.
set
(
value
,
duration
)
})
)
}
async
setWithSync
(
value
,
duration
,
syncMethod
)
{
const
setPromise
=
this
.
cacheLayers
.
map
(
item
=>
{
return
item
.
set
(
value
,
duration
)
})
return
Promise
.
all
(
[
...
setPromise
,
syncMethod
(
value
,
duration
)
]
)
}
async
get
()
{
return
this
.
highLevelCache
.
get
()
}
async
remove
()
{
await
Promise
.
all
(
this
.
cacheLayers
.
map
(
cacheKeyItem
=>
{
return
cacheKeyItem
.
remove
()
})
)
}
}
module
.
exports
=
{
Cache
,
DatabaseCache
,
RedisCache
,
CacheKey
,
CacheKeyCascade
const
db
=
uniCloud
.
database
()
function
getType
(
value
)
{
return
Object
.
prototype
.
toString
.
call
(
value
).
slice
(
8
,
-
1
).
toLowerCase
()
}
const
validator
=
{
key
:
function
(
value
)
{
const
err
=
new
Error
(
'
Invalid key
'
)
if
(
typeof
value
!==
'
string
'
)
{
throw
err
}
const
valueTrim
=
value
.
trim
()
if
(
!
valueTrim
||
valueTrim
!==
value
)
{
throw
err
}
},
value
:
function
(
value
)
{
// 仅作简单校验
const
type
=
getType
(
value
)
const
validValueType
=
[
'
null
'
,
'
number
'
,
'
string
'
,
'
array
'
,
'
object
'
]
if
(
validValueType
.
indexOf
(
type
)
===
-
1
)
{
throw
new
Error
(
'
Invalid value type
'
)
}
},
duration
:
function
(
value
)
{
const
err
=
new
Error
(
'
Invalid duration
'
)
if
(
value
===
undefined
)
{
return
}
if
(
typeof
value
!==
'
number
'
||
value
===
0
)
{
throw
err
}
}
}
/**
* 入库时 expired 为过期时间对应的时间戳,永不过期用-1表示
* 返回结果时 与redis对齐,-1表示永不过期,-2表示已过期或不存在
*/
class
DatabaseCache
{
constructor
({
collection
=
'
opendb-open-data
'
}
=
{})
{
this
.
type
=
'
db
'
this
.
collection
=
db
.
collection
(
collection
)
}
_serializeValue
(
value
)
{
return
value
===
undefined
?
null
:
JSON
.
stringify
(
value
)
}
_deserializeValue
(
value
)
{
return
value
?
JSON
.
parse
(
value
)
:
value
}
async
set
(
key
,
value
,
duration
)
{
validator
.
key
(
key
)
validator
.
value
(
value
)
validator
.
duration
(
duration
)
value
=
this
.
_serializeValue
(
value
)
await
this
.
collection
.
doc
(
key
).
set
({
value
,
expired
:
duration
&&
duration
!==
-
1
?
Date
.
now
()
+
duration
:
-
1
})
}
async
_getWithDuration
(
key
)
{
const
getKeyRes
=
await
this
.
collection
.
doc
(
key
).
get
()
const
record
=
getKeyRes
.
data
[
0
]
if
(
!
record
)
{
return
{
value
:
null
,
duration
:
-
2
}
}
const
value
=
this
.
_deserializeValue
(
record
.
value
)
const
expired
=
record
.
expired
if
(
expired
===
-
1
)
{
return
{
value
,
duration
:
-
1
}
}
const
duration
=
expired
-
Date
.
now
()
if
(
duration
<=
0
)
{
await
this
.
remove
(
key
)
return
{
value
:
null
,
duration
:
-
2
}
}
return
{
value
,
duration
:
Math
.
floor
(
duration
/
1000
)
}
}
async
get
(
key
,
{
withDuration
=
true
}
=
{})
{
const
result
=
await
this
.
_getWithDuration
(
key
)
if
(
!
withDuration
)
{
delete
result
.
duration
}
return
result
}
async
remove
(
key
)
{
await
this
.
collection
.
doc
(
key
).
remove
()
}
}
class
RedisCache
{
constructor
()
{
this
.
type
=
'
redis
'
this
.
redis
=
uniCloud
.
redis
()
}
_serializeValue
(
value
)
{
return
value
===
undefined
?
null
:
JSON
.
stringify
(
value
)
}
_deserializeValue
(
value
)
{
return
value
?
JSON
.
parse
(
value
)
:
value
}
async
set
(
key
,
value
,
duration
)
{
validator
.
key
(
key
)
validator
.
value
(
value
)
validator
.
duration
(
duration
)
value
=
this
.
_serializeValue
(
value
)
if
(
!
duration
||
duration
===
-
1
)
{
await
this
.
redis
.
set
(
key
,
value
)
}
else
{
await
this
.
redis
.
set
(
key
,
value
,
'
EX
'
,
duration
)
}
}
async
get
(
key
,
{
withDuration
=
false
}
=
{})
{
let
value
=
await
this
.
redis
.
get
(
key
)
value
=
this
.
_deserializeValue
(
value
)
if
(
!
withDuration
)
{
return
{
value
}
}
const
durationSecond
=
await
this
.
redis
.
ttl
(
key
)
let
duration
switch
(
durationSecond
)
{
case
-
1
:
duration
=
-
1
break
case
-
2
:
duration
=
-
2
break
default
:
duration
=
durationSecond
break
}
return
{
value
,
duration
}
}
async
remove
(
key
)
{
await
this
.
redis
.
del
(
key
)
}
}
class
Cache
{
constructor
({
type
,
collection
}
=
{})
{
if
(
type
===
'
database
'
)
{
return
new
DatabaseCache
({
collection
})
}
else
if
(
type
===
'
redis
'
)
{
return
new
RedisCache
()
}
else
{
throw
new
Error
(
'
Invalid cache type
'
)
}
}
}
class
CacheKey
{
constructor
({
type
,
collection
,
cache
,
key
,
fallback
}
=
{})
{
this
.
cache
=
cache
||
new
Cache
({
type
,
collection
})
this
.
key
=
key
this
.
fallback
=
fallback
}
async
set
(
value
,
duration
)
{
await
this
.
cache
.
set
(
this
.
key
,
value
,
duration
)
}
async
setWithSync
(
value
,
duration
,
syncMethod
)
{
await
Promise
.
all
([
this
.
set
(
this
.
key
,
value
,
duration
),
syncMethod
(
value
,
duration
)
])
}
async
get
()
{
let
{
value
,
duration
}
=
await
this
.
cache
.
get
(
this
.
key
)
if
(
value
!==
null
&&
value
!==
undefined
)
{
return
{
value
,
duration
}
}
if
(
!
this
.
fallback
)
{
return
{
value
:
null
,
duration
:
-
2
}
}
const
fallbackResult
=
await
this
.
fallback
()
value
=
fallbackResult
.
value
duration
=
fallbackResult
.
duration
if
(
value
!==
null
&&
duration
!==
undefined
)
{
await
this
.
cache
.
set
(
this
.
key
,
value
,
duration
)
}
return
{
value
,
duration
}
}
async
remove
()
{
await
this
.
cache
.
remove
(
this
.
key
)
}
}
class
CacheKeyCascade
{
constructor
({
layers
,
// [{cache, type, collection, key}] 从低级到高级排序,[DbCacheKey, RedisCacheKey]
fallback
}
=
{})
{
this
.
layers
=
layers
this
.
cacheLayers
=
[]
let
lastCacheKey
for
(
let
i
=
0
;
i
<
layers
.
length
;
i
++
)
{
const
{
type
,
cache
,
collection
,
key
}
=
layers
[
i
]
const
lastCacheKeyTemp
=
lastCacheKey
try
{
const
currentCacheKey
=
new
CacheKey
({
type
,
collection
,
cache
,
key
,
fallback
:
i
===
0
?
fallback
:
function
()
{
return
lastCacheKeyTemp
.
get
()
}
})
this
.
cacheLayers
.
push
(
currentCacheKey
)
lastCacheKey
=
currentCacheKey
}
catch
(
e
)
{}
}
this
.
highLevelCache
=
lastCacheKey
}
async
set
(
value
,
duration
)
{
return
Promise
.
all
(
this
.
cacheLayers
.
map
(
item
=>
{
return
item
.
set
(
value
,
duration
)
})
)
}
async
setWithSync
(
value
,
duration
,
syncMethod
)
{
const
setPromise
=
this
.
cacheLayers
.
map
(
item
=>
{
return
item
.
set
(
value
,
duration
)
})
return
Promise
.
all
(
[
...
setPromise
,
syncMethod
(
value
,
duration
)
]
)
}
async
get
()
{
return
this
.
highLevelCache
.
get
()
}
async
remove
()
{
await
Promise
.
all
(
this
.
cacheLayers
.
map
(
cacheKeyItem
=>
{
return
cacheKeyItem
.
remove
()
})
)
}
}
module
.
exports
=
{
Cache
,
DatabaseCache
,
RedisCache
,
CacheKey
,
CacheKeyCascade
}
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
浏览文件 @
5e55a8d3
const
Validator
=
{
Key
(
keyArray
,
parameters
)
{
for
(
let
i
=
0
;
i
<
keyArray
.
length
;
i
++
)
{
const
keyName
=
keyArray
[
i
]
if
(
typeof
parameters
[
keyName
]
!==
'
string
'
)
{
Validator
.
ThrowNewError
(
`Invalid
${
keyName
}
`
)
}
if
(
parameters
[
keyName
].
length
<
1
)
{
Validator
.
ThrowNewError
(
`Invalid
${
keyName
}
`
)
}
}
},
Value
(
value
)
{
if
(
value
===
undefined
)
{
Validator
.
ThrowNewError
(
'
Invalid Value
'
)
}
if
(
typeof
value
!==
'
object
'
)
{
Validator
.
ThrowNewError
(
'
Invalid Value Type
'
)
}
},
ThrowNewError
(
message
)
{
throw
new
Error
(
message
)
}
}
module
.
exports
=
{
Validator
const
Validator
=
{
Key
(
keyArray
,
parameters
)
{
for
(
let
i
=
0
;
i
<
keyArray
.
length
;
i
++
)
{
const
keyName
=
keyArray
[
i
]
if
(
typeof
parameters
[
keyName
]
!==
'
string
'
)
{
Validator
.
ThrowNewError
(
`Invalid
${
keyName
}
`
)
}
if
(
parameters
[
keyName
].
length
<
1
)
{
Validator
.
ThrowNewError
(
`Invalid
${
keyName
}
`
)
}
}
},
Value
(
value
)
{
if
(
value
===
undefined
)
{
Validator
.
ThrowNewError
(
'
Invalid Value
'
)
}
if
(
typeof
value
!==
'
object
'
)
{
Validator
.
ThrowNewError
(
'
Invalid Value Type
'
)
}
},
ThrowNewError
(
message
)
{
throw
new
Error
(
message
)
}
}
module
.
exports
=
{
Validator
}
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
浏览文件 @
5e55a8d3
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录