Appearance
自定义登录注册页
在一些企业内没有统一认证系统,但是内部使用系统的成员比较多,收集账号资料的成本比较高,想要通过自定义的登录注册的方式访问系统。可以通过组件设计器开发包含登录注册的页面,替换系统的默认登录页面。
效果图
组件设置
创建一个组件设计器模块,具体的源码可参考功能演示应用中的【其他案例】->【自定义登录注册页】,下文中提供组件核心源码进行说明讲解。该组件依赖了HTML
、织信Web运行时
、Axios网路请求库
等组件库。将组件的访问地址作为登录地址设置到管理后台的登录地址
中,即可替换系统的默认登录页。
html
<div class="container" :class="{'active': type != 'login'}">
<div class="form-container sign-up-container">
<div class="form">
<h2>
注册
</h2>
<input v-model="regForm.userName" type="text" name="username" id="username" placeholder="用户名"></input>
<input v-model="regForm.email" type="email" name="email" id="email" placeholder="邮箱"></input>
<input v-model="regForm.password" type="password" name="password" id="password" placeholder="密码"></input>
<button class="signUp" v-on:click="reg">
注册
</button>
</div>
</div>
<div class="form-container sign-in-container">
<div class="form">
<h2>
登录
</h2>
<input v-model="loginForm.userName" type="text" name="username" id="email" placeholder="用户名/邮箱/手机号"></input>
<input v-model="loginForm.password" type="password" name="password" id="password" placeholder="密码"></input>
<button class="signIn" v-on:click="login">
登录
</button>
</div>
</div>
<div class="overlay_container">
<div class="overlay">
<div class="overlay_panel overlay_left_container">
<h2>
欢迎回来!
</h2>
<p>
为了与我们保持联系,请使用您的个人信息登录
</p>
<button id="sign-in" v-on:click="switchType('login')">
登录
</button>
</div>
<div class="overlay_panel overlay_right_container">
<h2>
你好!
</h2>
<p>
输入您的个人详细信息并开始我们的旅程
</p>
<button v-on:click="switchType('register')">
注册
</button>
</div>
</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: url(bg.jpg) center / cover no-repeat;
}
h2 {
margin-bottom: 10px;
font-size: 32px;
text-transform: capitalize;
}
.container {
position: relative;
width: 768px;
height: 480px;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.2);
border-radius: 10px;
overflow: hidden;
}
.form-container {
position: absolute;
top: 0;
width: 50%;
height: 100%;
background-color: rgba(255,255,255,.8);
transition: all 0.6s ease-in-out;
}
.form {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
padding: 0 50px;
}
input {
width: 100%;
margin: 8px 0!important;
padding: 12px;
background-color: #fff;
border: none;
border-radius: 30px;
}
.forget-password {
display: inline-block;
height: 20px;
text-decoration: none;
color: #bbb;
text-transform: capitalize;
font-size: 12px;
}
.forget-password:hover {
color: lightslategray;
border-bottom: 2px solid #ff4b2b;
}
button {
background: #ff4b2b;
padding: 10px 50px;
border: 1px solid transparent;
border-radius: 20px;
text-transform: uppercase;
color: white;
margin-top: 20px!important;
outline: none;
transition: transform 80;
cursor: pointer;
}
button:active {
transform: scale(0.95);
}
.overlay_container {
position: absolute;
top: 0;
width: 50%;
height: 100%;
z-index: 100;
right: 0;
overflow: hidden;
transition: all 0.6s ease-in-out;
}
.overlay {
position: absolute;
width: 200%;
height: 100%;
left: -100%;
background-color: rgba(255, 75, 43, .8);;
}
.overlay_panel {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 50%;
height: 100%;
color: white;
padding: 0 40px;
text-align: center;
}
.overlay_panel button {
background-color: transparent;
border: 1px solid white;
}
.overlay_panel p {
font-size: 12px;
margin: 10px 0 15px 0;
}
.overlay_right_container {
right: 0;
}
.container .sign-up-container {
opacity: 0;
}
.container .sign-in-container {
opacity: 1;
}
.container.active .sign-up-container {
transform: translateX(100%);
z-index: 5;
opacity: 1;
}
.container.active .sign-in-container {
transform: translateX(100%);
opacity: 0;
}
.container.active .overlay_container {
transform: translateX(-100%);
}
.container.active .overlay {
transform: translateX(50%);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
js
export default{
data(){
return{
type: 'login',
loginForm: {
userName: null,
password: null,
},
regForm: {
userName: null,
email: null,
password: null,
}
}
},
mounted() {
// 获取登录时的回跳地址,后续登录成功后进行回跳
const params = this.getQueryParams();
this.rdUrl = params.rdUrl || '/';
},
methods:{
switchType(type) {
this.type = type;
},
// 注册
async reg() {
const {userName, email, password} = this.regForm;
try {
const resp = await informatweb.callAutomatic({
automaticId: 'reg',
args:[
userName,
email,
password
]
});
const data = resp.returnValue;
if(data.success) {
alert('注册成功!请登录账号');
this.loginForm.userName = this.regForm.userName;
this.switchType('login');
} else {
alert(data.message || '未知错误')
}
} catch(e) {
alert(e)
}
},
// 密码登录
async login() {
const {userName, password} = this.loginForm;
try {
const resp = await informatweb.callAutomatic({
automaticId: 'login',
args:[
userName,
password,
'index'
]
});
this.loginResult(resp)
} catch(e) {
alert(e)
}
},
// 获取链接参数
getQueryParams() {
let params = {};
let url = window.location.search.substring(1);
let queryString = url.split("&");
queryString.forEach(param => {
let keyValue = param.split("=");
let key = decodeURIComponent(keyValue[0]);
let value = decodeURIComponent(keyValue[1]);
params[key] = value;
});
return params;
},
// 链接追加参数
addURLParam(url, param, value) {
// 如果 URL 中已经有查询参数,使用 & 否则使用 ?
let separator = url.indexOf('?') !== -1 ? '&' : '?';
// 组合新的 URL
return url + separator + param + '=' + encodeURIComponent(value);
},
// 登录成功后拼接token参数并回跳
loginResult(resp) {
const result = resp.returnValue;
if (!result.success) {
alert(`登录失败:${result.message || '未知错误'}`)
return;
}
// 通过在链接上拼接【_token】参数可以实现免密登录
window.location.href = this.addURLParam(this.rdUrl, '_token', result.token);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
自动化设置
在登录注册组件的脚本中我们通过织信Web运行时
调用了login
、reg
两个自动化。这两个自动化均只使用了代码片段来完成各自的业务逻辑。下面是具体的源码
TIP
由于组件中使用了织信Web运行时
是通过http调用的,所以自动化需要开启允许通过Http方式调用自动化
通过校验传入的账号密码是否正确来进行鉴权,鉴权成功后通过用户的ID创建Token,返回给前端页面
自动化入参
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
userName | String | 是 | 用户名 |
password | String | 是 | 密码 |
type | String | 是 | 登录类型,一般分为PC端登录: index ,手机端登录: mobile ,也支持自定义类型,同个类型,同个账号的token会相互挤占 |
代码片段
js
const userName = automatic.getVar('userName');
const password = automatic.getVar('password');
const type = automatic.getVar('type');
var accountList = informat.system.queryAccountList({
filter: {
conditionList: [{ 'fieldId': 'userName', 'opt': 'eq', 'value': userName }]
}
});
if(accountList.length < 1) {
informat.app.abort('账号或密码错误')
}
// 平台认证用户名密码并返回结果
var result = informat.system.validateAccount(userName, password);
if (!result) {
informat.app.abort('账号或密码错误')
} else {
// 通过用户ID创建Token
const token = informat.system.createToken(accountList[0].id, type);
automatic.setReturnValue({
success: true,
accountId: accountList[0].id,
token: token
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
通过环境变量registerEnable
控制是否开放注册功能。注册成功后将用户添加到当前团队,并设置团队角色为成员
自动化入参
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
userName | String | 是 | 用户名 |
String | 是 | 邮箱 | |
password | String | 是 | 密码 |
代码片段
js
const userName = automatic.getVar('userName');
const email = automatic.getVar('email');
const password = automatic.getVar('password');
const registerEnable = informat.app.appEnvProp('registerEnable');
if(registerEnable != '1') {
automatic.setReturnValue({
success: false,
message: '禁用注册功能。请修改环境变量启动注册功能'
});
} else {
const accountId = addAccount({
userName,
email,
password
})
addCompanyMember(accountId);
automatic.setReturnValue({
success: true,
message: '注册成功'
})
}
// 添加系统用户
function addAccount(item){
let accountList=informat.system.queryAccountList({
pageIndex: 1,
pageSize: 1,
filter: {
conditionList: [
{
fieldId: 'userName',
opt: 'eq',
value: item.userName
}
]
}
});
if(accountList.length > 0){
informat.app.abort('用户名已存在')
}
accountList=informat.system.queryAccountList({
pageIndex: 1,
pageSize: 1,
filter: {
conditionList: [
{
fieldId: 'email',
opt: 'eq',
value: item.email
}
]
}
});
if(accountList.length > 0){
informat.app.abort('邮箱已存在')
}
// 添加系统用户
const accountId=informat.system.addAccount({
name: userName,
avatar: 'pic15.png',
...item
});
return accountId;
}
// 添加团队成员
function addCompanyMember(accountId) {
// 获取部门根节点
const rootDeptId = (informat.dept.queryDeptList({
pageSize:1,
filter:{
conditionList:[
{"fieldId":"parentId","opt":"isnull"}
]
}
})[0] || {}).id;
// 添加团队成员
informat.company.addCompanyMember(accountId, [rootDeptId], ['member'])
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81