Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
quasar-web-base
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nguyễn Hải Sơn
quasar-web-base
Commits
e4fa99e4
Commit
e4fa99e4
authored
Apr 26, 2021
by
Võ Quang Thành Đạt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add new user
parent
8a73e130
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
496 additions
and
3 deletions
+496
-3
configurations.example.ts
src/assets/configurations.example.ts
+1
-0
functions.ts
src/boot/functions.ts
+10
-0
AddNewUserDialog.ts
...s/user-management/add-new-user-dialog/AddNewUserDialog.ts
+111
-0
index.vue
src/components/user-management/add-new-user-dialog/index.vue
+183
-0
UpdateUserDialog.ts
...ts/user-management/update-user-dialog/UpdateUserDialog.ts
+2
-0
index.vue
src/components/user-management/update-user-dialog/index.vue
+5
-0
index.ts
src/i18n/vi/index.ts
+38
-0
User.ts
src/pages/nguoi-dung/User.ts
+100
-1
index.vue
src/pages/nguoi-dung/index.vue
+46
-2
No files found.
src/assets/configurations.example.ts
View file @
e4fa99e4
...
...
@@ -27,4 +27,5 @@ export enum API_PATHS {
getUserGroupDetail
=
'/user/group/detail'
,
updateUserGroupInfo
=
'/user/group/update'
,
getListUsers
=
'/user/list'
,
addNewUser
=
'/user/add'
,
}
src/boot/functions.ts
0 → 100644
View file @
e4fa99e4
const
isEmail
=
(
str
:
string
)
=>
{
const
email
=
/^
(([^
<>()
\[\]\\
.,;:
\s
@"
]
+
(\.[^
<>()
\[\]\\
.,;:
\s
@"
]
+
)
*
)
|
(
".+"
))
@
((\[[
0-9
]{1,3}\.[
0-9
]{1,3}\.[
0-9
]{1,3}\.[
0-9
]{1,3}
]
)
|
(([
a-zA-Z
\-
0-9
]
+
\.)
+
[
a-zA-Z
]{2,}))
$/
;
return
email
.
test
(
str
);
};
const
isMobilePhone
=
(
str
:
string
)
=>
{
const
phoneNot84
=
/
[
0
]{1}[
0-9
]{9,11}
$/
;
const
phone84
=
/^
[
84
]{2}[
0-9
]{9,11}
$/
;
return
phoneNot84
.
test
(
str
)
||
phone84
.
test
(
str
);
};
export
{
isEmail
,
isMobilePhone
};
src/components/user-management/add-new-user-dialog/AddNewUserDialog.ts
0 → 100644
View file @
e4fa99e4
import
{
defineComponent
}
from
'vue'
;
import
{
i18n
}
from
'src/boot/i18n'
;
import
{
isEmail
}
from
'../../../boot/functions'
;
import
{
isMobilePhone
}
from
'../../../boot/functions'
;
export
default
defineComponent
({
props
:
{
showDialog
:
{
type
:
Boolean
,
required
:
true
,
},
userName
:
{
type
:
String
,
required
:
true
},
password
:
{
type
:
String
,
required
:
true
},
fullName
:
{
type
:
String
,
required
:
true
},
email
:
{
type
:
String
,
required
:
true
},
mobileNumber
:
{
type
:
String
,
required
:
true
},
address
:
{
type
:
String
,
required
:
true
},
phoneNumber
:
{
type
:
String
,
required
:
true
},
unit
:
{
type
:
String
,
required
:
true
},
sex
:
{
type
:
Number
,
required
:
true
},
sexOptions
:
{
type
:
Array
,
required
:
true
},
birthday
:
{
type
:
String
,
required
:
true
},
group
:
{
type
:
Number
,
required
:
true
},
listGroup
:
{
type
:
Array
,
required
:
true
},
scheduleAccess
:
{
type
:
String
,
required
:
true
},
listScheduleAccess
:
{
type
:
Array
,
required
:
true
},
status
:
{
type
:
Boolean
,
required
:
true
},
},
setup
()
{
const
userNameRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireUserName'
),
];
const
passwordRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requirePassword'
),
];
const
fullNameRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireFullName'
),
];
const
emailRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireEmail'
),
(
val
:
string
)
=>
isEmail
(
val
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.isEmail'
),
];
const
mobileNumberRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireMobileNumber'
),
(
val
:
string
)
=>
isMobilePhone
(
val
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.isMobilePhone'
),
];
const
addressRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireAddress'
),
];
const
unitRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireUnit'
),
];
const
sexRules
=
[
(
val
?:
number
)
=>
val
!==
undefined
||
i18n
.
global
.
t
(
'userPage.validateMessages.requireSex'
),
];
const
groupRules
=
[
(
val
?:
number
)
=>
val
!==
undefined
||
i18n
.
global
.
t
(
'userPage.validateMessages.requiredGroup'
),
];
return
{
userNameRules
,
passwordRules
,
fullNameRules
,
emailRules
,
mobileNumberRules
,
addressRules
,
unitRules
,
sexRules
,
groupRules
,
};
},
emits
:
[
'update:showDialog'
,
'click:CloseBtn'
,
'update:userName'
,
'update:password'
,
'update:fullName'
,
'update:email'
,
'update:mobileNumber'
,
'update:address'
,
'update:phoneNumber'
,
'update:unit'
,
'update:sex'
,
'update:birthday'
,
'update:group'
,
'update:scheduleAccess'
,
'update:status'
,
'addNewUser'
,
],
});
src/components/user-management/add-new-user-dialog/index.vue
0 → 100644
View file @
e4fa99e4
<
template
>
<q-dialog
persistent
:model-value=
"showDialog"
@
update:model-value=
"$emit('update:showDialog', $event)"
>
<q-card
style=
"min-width: 900px"
bordered
>
<q-form
greedy
@
submit
.
prevent=
"$emit('addNewUser')"
>
<q-card-section>
<q-item>
<q-item-section>
<q-item-label
class=
"text-h6 text-weight-regular"
>
{{
$t
(
'userPage.dialogLabel.title.addUser'
)
}}
</q-item-label>
</q-item-section>
</q-item>
</q-card-section>
<q-separator
/>
<q-card-section>
<div
class=
"row q-col-gutter-sm"
>
<div
class=
"col-6"
>
<q-input
:model-value=
"userName"
@
update:model-value=
"$emit('update:userName', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.userName')"
:rules=
"userNameRules"
hide-bottom-space
type=
"text"
class=
"q-my-sm"
outlined
></q-input>
<q-input
:model-value=
"password"
@
update:model-value=
"$emit('update:password', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.password')"
type=
"password"
class=
"q-my-sm"
outlined
:rules=
"passwordRules"
hide-bottom-space
></q-input>
<q-input
:model-value=
"fullName"
@
update:model-value=
"$emit('update:fullName', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.fullName')"
type=
"text"
class=
"q-my-sm"
outlined
:rules=
"fullNameRules"
hide-bottom-space
></q-input>
<q-input
:model-value=
"email"
@
update:model-value=
"$emit('update:email', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.email')"
type=
"text"
class=
"q-my-sm"
outlined
:rules=
"emailRules"
hide-bottom-space
></q-input>
<q-input
:model-value=
"mobileNumber"
@
update:model-value=
"$emit('update:mobileNumber', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.mobileNumber')"
type=
"number"
class=
"q-my-sm"
outlined
:rules=
"mobileNumberRules"
hide-bottom-space
></q-input>
<q-input
:model-value=
"address"
@
update:model-value=
"$emit('update:address', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.address')"
type=
"text"
class=
"q-my-sm"
outlined
:rules=
"addressRules"
hide-bottom-space
></q-input>
</div>
<div
class=
"col-6"
>
<q-input
:model-value=
"phoneNumber"
@
update:model-value=
"$emit('update:phoneNumber', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.phoneNumber')"
type=
"number"
class=
"q-my-sm"
outlined
></q-input>
<q-input
:model-value=
"unit"
@
update:model-value=
"$emit('update:unit', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.unit')"
type=
"text"
class=
"q-my-sm"
outlined
:rules=
"unitRules"
hide-bottom-space
></q-input>
<q-select
:model-value=
"sex"
emit-value
@
update:model-value=
"$emit('update:sex', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.sex')"
class=
"q-my-sm"
:options=
"sexOptions"
option-value=
"id"
option-label=
"text"
outlined
map-options
:rules=
"sexRules"
hide-bottom-space
></q-select>
<q-input
:model-value=
"birthday"
@
update:model-value=
"$emit('update:birthday', $event)"
type=
"date"
class=
"q-my-sm"
outlined
>
<template
v-slot:prepend
>
<div
class=
"text-body2"
>
{{
$t
(
'userPage.dialogLabel.fieldLabels.birthday'
)
}}
</div>
</
template
>
</q-input>
<q-select
:model-value=
"group"
@
update:model-value=
"$emit('update:group', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.group')"
class=
"q-my-sm"
outlined
:options=
"listGroup"
option-value=
"id"
option-label=
"groupName"
map-options
emit-value
:rules=
"groupRules"
hide-bottom-space
></q-select>
<q-select
:model-value=
"scheduleAccess"
@
update:model-value=
"$emit('update:scheduleAccess', $event)"
:label=
"$t('userPage.dialogLabel.fieldLabels.scheduleAccess')"
:options=
"listScheduleAccess"
class=
"q-my-sm"
outlined
></q-select>
</div>
<q-space></q-space>
<div
class=
"col-6"
>
<span
class=
"text-body1"
>
{{
$t('userPage.dialogLabel.fieldLabels.status')
}}
</span
><q-toggle
:model-value=
"status"
@
update:model-value=
"$emit('update:status', $event)"
/>
</div>
</div>
</q-card-section>
<q-card-actions
align=
"right"
>
<q-btn
type=
"submit"
color=
"primary"
:label=
"$t('userPage.crudActions.save')"
/>
<q-btn
color=
"black"
:label=
"$t('userPage.crudActions.cancel')"
@
click=
"$emit('click:CloseBtn')"
/>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<
script
lang=
"ts"
src=
"./AddNewUserDialog.ts"
></
script
>
src/components/user-management/update-user-dialog/UpdateUserDialog.ts
0 → 100644
View file @
e4fa99e4
import
{
defineComponent
}
from
'vue'
;
export
default
defineComponent
({});
src/components/user-management/update-user-dialog/index.vue
0 → 100644
View file @
e4fa99e4
<
template
>
<div>
My component
</div>
</
template
>
<
script
lang=
"ts"
src=
"./UpdateUserDialog.ts"
></
script
>
src/i18n/vi/index.ts
View file @
e4fa99e4
...
...
@@ -73,5 +73,43 @@ export default {
active
:
'Đang hoạt động'
,
inactive
:
'Ngừng hoạt động'
,
},
dialogLabel
:
{
title
:
{
addUser
:
'Thêm mới người dùng'
,
updateUser
:
'Cập nhật người dùng'
,
},
fieldLabels
:
{
userName
:
'Tên đăng nhập *'
,
password
:
'Mật khẩu *'
,
fullName
:
'Họ Tên *'
,
email
:
'Email *'
,
mobileNumber
:
'Số điện thoại *'
,
address
:
'Địa chỉ *'
,
phoneNumber
:
'Số máy bàn'
,
unit
:
'Đơn vị phòng ban *'
,
sex
:
'Giới tính *'
,
birthday
:
'Ngày sinh'
,
group
:
'Thuộc nhóm *'
,
scheduleAccess
:
'Lịch truy cập'
,
status
:
'Trạng thái'
,
},
},
crudActions
:
{
save
:
'Lưu'
,
cancel
:
'Đóng'
,
},
validateMessages
:
{
requireUserName
:
'Tên đăng nhập không hợp lệ'
,
requirePassword
:
'Vui lòng nhập mật khẩu'
,
requireFullName
:
'Vui lòng nhập họ tên'
,
requireEmail
:
'Vui lòng nhập Email'
,
isEmail
:
'Email không hợp lệ'
,
requireMobileNumber
:
'Vui lòng nhập số điện thoại'
,
isMobilePhone
:
'Số điện thoại không hợp lệ'
,
requireAddress
:
'Vui lòng nhập địa chỉ'
,
requireUnit
:
'Vui lòng nhập địa chỉ phòng ban'
,
requireSex
:
'Vui lòng chọn giới tính'
,
requiredGroup
:
'Vui lòng chọn nhóm người dùng'
,
},
},
};
src/pages/nguoi-dung/User.ts
View file @
e4fa99e4
import
{
AxiosResponse
}
from
'axios'
;
import
{
Notify
}
from
'quasar'
;
import
{
API_PATHS
,
config
}
from
'src/assets/configurations'
;
import
{
PaginationResponse
,
UserObject
}
from
'src/assets/type'
;
import
{
api
,
BaseResponseBody
}
from
'src/boot/axios'
;
import
{
i18n
}
from
'src/boot/i18n'
;
import
{
computed
,
defineComponent
,
onMounted
,
Ref
,
ref
}
from
'vue'
;
import
{
useStore
}
from
'../../store/index'
;
import
{
computed
,
defineComponent
,
onMounted
,
ref
,
Ref
}
from
'vue'
;
import
AddNewUserDialogComponent
from
'../../components/user-management/add-new-user-dialog/index.vue'
;
import
{
GroupInfoType
}
from
'../nhom-nguoi-dung/UserGroup'
;
export
default
defineComponent
({
components
:
{
AddNewUserDialogComponent
},
setup
()
{
const
totalPage
=
ref
(
0
);
const
pageIndex
=
ref
(
1
);
...
...
@@ -70,6 +75,27 @@ export default defineComponent({
];
const
userTableRows
:
Ref
<
UserObject
[]
>
=
ref
([]);
const
keyword
=
ref
(
''
);
const
showDialog
=
ref
(
false
);
const
userName
=
ref
(
''
);
const
password
=
ref
(
''
);
const
fullName
=
ref
(
''
);
const
birthday
:
Ref
<
string
|
undefined
>
=
ref
();
const
email
=
ref
(
''
);
const
phoneNumber
=
ref
(
''
);
const
mobileNumber
=
ref
(
''
);
const
sex
:
Ref
<
number
|
undefined
>
=
ref
();
const
sexOptions
=
ref
([
{
id
:
1
,
text
:
'Nam'
},
{
id
:
2
,
text
:
'Nữ'
},
]);
const
address
=
ref
(
''
);
const
unit
=
ref
(
''
);
const
status
:
Ref
<
boolean
>
=
ref
(
true
);
const
listGroup
:
Ref
<
{
id
:
number
;
groupName
:
string
}[]
>
=
ref
([]);
const
group
:
Ref
<
number
|
undefined
>
=
ref
();
const
scheduleAccess
=
ref
(
'Chưa có lịch truy cập'
);
const
listScheduleAccess
=
ref
([
'Chưa có lịch truy cập'
]);
const
getListUsers
=
async
()
=>
{
try
{
...
...
@@ -95,8 +121,62 @@ export default defineComponent({
);
});
const
$store
=
useStore
();
const
getListUserGroup
=
async
()
=>
{
await
$store
.
dispatch
(
'authentication/getListUsers'
).
then
((
response
)
=>
{
const
res
=
response
as
AxiosResponse
<
BaseResponseBody
<
GroupInfoType
[]
>
>
;
if
(
!
res
.
data
.
error
.
code
)
{
res
.
data
.
data
.
map
((
item
)
=>
{
listGroup
.
value
.
push
({
id
:
item
.
id
,
groupName
:
item
.
groupName
});
});
}
});
};
const
addNewUser
=
async
()
=>
{
try
{
const
response
=
(
await
api
({
url
:
API_PATHS
.
addNewUser
,
method
:
'POST'
,
data
:
{
user
:
{
id
:
2
,
userName
:
userName
.
value
,
password
:
password
.
value
,
fullName
:
fullName
.
value
,
birthday
:
birthday
.
value
,
email
:
email
.
value
,
phoneNumber
:
phoneNumber
.
value
,
mobileNumber
:
mobileNumber
.
value
,
sex
:
sex
.
value
,
address
:
address
.
value
,
unit
:
unit
.
value
,
status
:
status
.
value
?
1
:
0
,
},
groups
:
[{
id
:
group
.
value
}],
pageRoles
:
[],
},
}))
as
AxiosResponse
<
BaseResponseBody
<
unknown
>>
;
if
(
response
.
data
.
error
.
code
===
config
.
API_RES_CODE
.
OK
.
code
)
{
showDialog
.
value
=
false
;
Notify
.
create
({
type
:
'positive'
,
message
:
i18n
.
global
.
t
(
'userGroupPage.groupInfo.actionMessages.addNewSuccess'
),
});
void
getListUsers
();
}
}
catch
(
error
)
{}
};
onMounted
(()
=>
{
void
getListUsers
();
void
getListUserGroup
();
});
return
{
rows
:
userTableRows
,
...
...
@@ -106,6 +186,25 @@ export default defineComponent({
pageSize
,
keyword
,
filterListUser
,
showDialog
,
userName
,
password
,
fullName
,
birthday
,
email
,
phoneNumber
,
mobileNumber
,
sex
,
address
,
unit
,
status
,
group
,
scheduleAccess
,
sexOptions
,
listGroup
,
listScheduleAccess
,
addNewUser
,
getListUserGroup
,
};
},
});
src/pages/nguoi-dung/index.vue
View file @
e4fa99e4
...
...
@@ -22,13 +22,17 @@
</div>
<q-space></q-space>
<div
class=
"col-auto flex flex-center"
>
<q-btn
color=
"primary"
:label=
"$t('crudActions.add')"
></q-btn>
<q-btn
@
click=
"showDialog = true"
:label=
"$t('crudActions.add')"
color=
"primary"
></q-btn>
</div>
</div>
</q-th>
</
template
>
<
template
v-slot:body-cell-status=
"rowData"
>
<q-td
class=
"flex flex-center"
>
<q-td>
<q-chip
:color=
"rowData.value ? 'positive' : undefined"
text-color=
"white"
...
...
@@ -42,6 +46,24 @@
</q-chip>
</q-td>
</
template
>
<
template
v-slot:body-cell-action
>
<q-td
style=
"padding: 0"
class=
"flex flex-center"
>
<q-btn
flat
round
color=
"primary"
icon=
"mdi-account-edit-outline
"
></q-btn>
<q-btn
flat
round
color=
"primary"
icon=
"mdi-account-convert-outline"
></q-btn>
<q-btn
flat
round
color=
"primary"
icon=
"delete"
></q-btn>
</q-td>
</
template
>
</q-table>
</div>
<div
class=
"col-12 q-pa-lg flex flex-center"
>
...
...
@@ -56,6 +78,28 @@
icon-next=
"fast_forward"
/>
</div>
<AddNewUserDialogComponent
v-model:show-dialog=
"showDialog"
v-model:user-name=
"userName"
v-model:password=
"password"
v-model:full-name=
"fullName"
v-model:email=
"email"
v-model:mobile-number=
"mobileNumber"
v-model:address=
"address"
v-model:phone-number=
"phoneNumber"
v-model:unit=
"unit"
v-model:sex=
"sex"
:sex-options=
"sexOptions"
v-model:birthday=
"birthday"
v-model:group=
"group"
:list-group=
"listGroup"
v-model:schedule-access=
"scheduleAccess"
:list-schedule-access=
"listScheduleAccess"
v-model:status=
"status"
@
click:CloseBtn=
"showDialog = false"
@
addNewUser=
"addNewUser"
></AddNewUserDialogComponent>
</div>
</template>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment