330 lines
9.5 KiB
Vue
330 lines
9.5 KiB
Vue
<template>
|
|
<section class="content">
|
|
<vue-good-table
|
|
mode="remote"
|
|
:rows="users"
|
|
:total-rows="totalRecords || users.length"
|
|
:columns="columns"
|
|
:search-options="tableOptions.search"
|
|
:pagination-options="tableOptions.pagination"
|
|
style-class="vgt-table striped"
|
|
@on-page-change="onPageChange"
|
|
@on-sort-change="onSortChange"
|
|
@on-search="onSearch"
|
|
@on-per-page-change="onPerPageChange"
|
|
>
|
|
<template slot="table-row" slot-scope="props">
|
|
<span v-if="props.column.field === 'email'">
|
|
{{ props.formattedRow[props.column.field] }}
|
|
<a :title="$t('admin.changeEmail')" data-test="email" @click="changeEmail(props.row)">
|
|
<i class="fas fa-edit btn-edit" />
|
|
</a>
|
|
</span>
|
|
<span v-else-if="props.column.field === 'nickname'">
|
|
{{ props.formattedRow[props.column.field] }}
|
|
<a :title="$t('admin.changeNickName')" data-test="nickname" @click="changeNickName(props.row)">
|
|
<i class="fas fa-edit btn-edit" />
|
|
</a>
|
|
</span>
|
|
<span v-else-if="props.column.field === 'score'">
|
|
{{ props.formattedRow[props.column.field] }}
|
|
<a :title="$t('admin.changeScore')" data-test="score" @click="changeScore(props.row)">
|
|
<i class="fas fa-edit btn-edit" />
|
|
</a>
|
|
</span>
|
|
<span v-else-if="props.column.field === 'players_count'">
|
|
<a
|
|
:href="props.row | playersLink"
|
|
:title="$t('admin.inspectHisPlayers')"
|
|
data-toggle="tooltip"
|
|
data-placement="right"
|
|
>{{ props.formattedRow[props.column.field] }}</a>
|
|
</span>
|
|
<span v-else-if="props.column.field === 'permission'">
|
|
<span>{{ props.row | humanizePermission }}</span>
|
|
<a
|
|
v-if="props.row.permission < 1 || (props.row.operations === 2 && props.row.permission < 2)"
|
|
:title="$t('admin.changePermission')"
|
|
data-test="permission"
|
|
@click="changePermission(props.row)"
|
|
>
|
|
<i class="fas fa-edit btn-edit" />
|
|
</a>
|
|
</span>
|
|
<span v-else-if="props.column.field === 'verified'">
|
|
<span v-if="props.row.verified" v-t="'admin.verified'" />
|
|
<span v-else v-t="'admin.unverified'" />
|
|
<a
|
|
:title="$t('admin.toggleVerification')"
|
|
data-test="verification"
|
|
@click="toggleVerification(props.row)"
|
|
>
|
|
<i
|
|
class="fas btn-edit"
|
|
:class="{ 'fa-toggle-on': props.row.verified, 'fa-toggle-off': !props.row.verified }"
|
|
style="font-size: 18px;"
|
|
/>
|
|
</a>
|
|
</span>
|
|
<div v-else-if="props.column.field === 'operations'">
|
|
<button
|
|
v-t="'admin.changePassword'"
|
|
class="btn btn-default"
|
|
@click="changePassword(props.row)"
|
|
/>
|
|
<button
|
|
v-t="'admin.deleteUser'"
|
|
:disabled="props.row.permission >= 2 || (props.row.operations === 1 && props.row.permission >= 1)"
|
|
class="btn btn-danger"
|
|
@click="deleteUser(props.row)"
|
|
/>
|
|
</div>
|
|
<span v-else v-text="props.formattedRow[props.column.field]" />
|
|
</template>
|
|
</vue-good-table>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
import { VueGoodTable } from 'vue-good-table'
|
|
import 'vue-good-table/dist/vue-good-table.min.css'
|
|
import toastr from 'toastr'
|
|
import { trans } from '../../js/i18n'
|
|
import { swal } from '../../js/notify'
|
|
import tableOptions from '../../components/mixins/tableOptions'
|
|
import serverTable from '../../components/mixins/serverTable'
|
|
|
|
export default {
|
|
name: 'UsersManagement',
|
|
components: {
|
|
VueGoodTable,
|
|
},
|
|
filters: {
|
|
humanizePermission(user) {
|
|
switch (user.permission) {
|
|
case -1:
|
|
return trans('admin.banned')
|
|
case 0:
|
|
return trans('admin.normal')
|
|
case 1:
|
|
return trans('admin.admin')
|
|
case 2:
|
|
return trans('admin.superAdmin')
|
|
default:
|
|
return ''
|
|
}
|
|
},
|
|
playersLink(user) {
|
|
return `${blessing.base_url}/admin/players?uid=${user.uid}`
|
|
},
|
|
},
|
|
mixins: [
|
|
tableOptions,
|
|
serverTable,
|
|
],
|
|
data() {
|
|
return {
|
|
users: [],
|
|
columns: [
|
|
{
|
|
field: 'uid', label: 'UID', type: 'number',
|
|
},
|
|
{ field: 'email', label: this.$t('general.user.email') },
|
|
{
|
|
field: 'nickname', label: this.$t('general.user.nickname'), width: '150px',
|
|
},
|
|
{
|
|
field: 'score', label: this.$t('general.user.score'), type: 'number', width: '102px',
|
|
},
|
|
{
|
|
field: 'players_count', label: this.$t('admin.playersCount'), type: 'number',
|
|
},
|
|
{
|
|
field: 'permission', label: this.$t('admin.permission'), globalSearchDisabled: true,
|
|
},
|
|
{
|
|
field: 'verified', label: this.$t('admin.verification'), type: 'boolean', globalSearchDisabled: true,
|
|
},
|
|
{ field: 'register_at', label: this.$t('general.user.register-at') },
|
|
{
|
|
field: 'operations', label: this.$t('admin.operationsTitle'), sortable: false, globalSearchDisabled: true,
|
|
},
|
|
],
|
|
serverParams: {
|
|
sortField: 'uid',
|
|
},
|
|
}
|
|
},
|
|
beforeMount() {
|
|
this.fetchData()
|
|
},
|
|
methods: {
|
|
async fetchData() {
|
|
const { data, totalRecords } = await this.$http.get(
|
|
`/admin/user-data${location.search}`,
|
|
!location.search && this.serverParams
|
|
)
|
|
this.totalRecords = totalRecords
|
|
this.users = data
|
|
},
|
|
async changeEmail(user) {
|
|
const { dismiss, value } = await swal({
|
|
text: this.$t('admin.newUserEmail'),
|
|
showCancelButton: true,
|
|
input: 'email',
|
|
inputValue: user.email,
|
|
inputValidator: val => !val && this.$t('auth.emptyEmail'),
|
|
})
|
|
if (dismiss) {
|
|
return
|
|
}
|
|
|
|
const { errno, msg } = await this.$http.post(
|
|
'/admin/users?action=email',
|
|
{ uid: user.uid, email: value }
|
|
)
|
|
if (errno === 0) {
|
|
user.email = value
|
|
toastr.success(msg)
|
|
} else {
|
|
toastr.warning(msg)
|
|
}
|
|
},
|
|
async toggleVerification(user) {
|
|
const { errno, msg } = await this.$http.post(
|
|
'/admin/users?action=verification',
|
|
{ uid: user.uid }
|
|
)
|
|
if (errno === 0) {
|
|
user.verified = !user.verified
|
|
toastr.success(msg)
|
|
} else {
|
|
toastr.warning(msg)
|
|
}
|
|
},
|
|
async changeNickName(user) {
|
|
const { dismiss, value } = await swal({
|
|
text: this.$t('admin.newUserNickname'),
|
|
showCancelButton: true,
|
|
input: 'text',
|
|
inputValue: user.nickname,
|
|
inputValidator: val => !val && this.$t('auth.emptyNickname'),
|
|
})
|
|
if (dismiss) {
|
|
return
|
|
}
|
|
|
|
const { errno, msg } = await this.$http.post(
|
|
'/admin/users?action=nickname',
|
|
{ uid: user.uid, nickname: value }
|
|
)
|
|
if (errno === 0) {
|
|
user.nickname = value
|
|
toastr.success(msg)
|
|
} else {
|
|
toastr.warning(msg)
|
|
}
|
|
},
|
|
async changePassword(user) {
|
|
const { dismiss, value } = await swal({
|
|
text: this.$t('admin.newUserPassword'),
|
|
showCancelButton: true,
|
|
input: 'password',
|
|
})
|
|
if (dismiss) {
|
|
return
|
|
}
|
|
|
|
const { errno, msg } = await this.$http.post(
|
|
'/admin/users?action=password',
|
|
{ uid: user.uid, password: value }
|
|
)
|
|
errno === 0 ? toastr.success(msg) : toastr.warning(msg)
|
|
},
|
|
async changeScore(user) {
|
|
const { dismiss, value } = await swal({
|
|
text: this.$t('admin.newScore'),
|
|
showCancelButton: true,
|
|
input: 'number',
|
|
inputValue: user.score,
|
|
})
|
|
if (dismiss) {
|
|
return
|
|
}
|
|
const score = Number.parseInt(value)
|
|
|
|
const { errno, msg } = await this.$http.post(
|
|
'/admin/users?action=score',
|
|
{ uid: user.uid, score }
|
|
)
|
|
if (errno === 0) {
|
|
user.score = score
|
|
toastr.success(msg)
|
|
} else {
|
|
toastr.warning(msg)
|
|
}
|
|
},
|
|
async changePermission(user) {
|
|
const operator = user.operations
|
|
const options = {
|
|
'-1': this.$t('admin.banned'),
|
|
0: this.$t('admin.normal'),
|
|
}
|
|
if (operator === 2) {
|
|
options[1] = this.$t('admin.admin')
|
|
}
|
|
|
|
const { dismiss, value } = await swal({
|
|
text: this.$t('admin.newPermission'),
|
|
input: 'radio',
|
|
inputOptions: options,
|
|
showCancelButton: true,
|
|
})
|
|
if (dismiss) {
|
|
return
|
|
}
|
|
|
|
const { errno, msg } = await this.$http.post('/admin/users?action=permission', {
|
|
uid: user.uid,
|
|
permission: value,
|
|
})
|
|
if (errno === 0) {
|
|
user.permission = +value
|
|
toastr.success(msg)
|
|
} else {
|
|
toastr.warning(msg)
|
|
}
|
|
},
|
|
async deleteUser({ uid, originalIndex }) {
|
|
const { dismiss } = await swal({
|
|
text: this.$t('admin.deleteUserNotice'),
|
|
type: 'warning',
|
|
showCancelButton: true,
|
|
})
|
|
if (dismiss) {
|
|
return
|
|
}
|
|
|
|
const { errno, msg } = await this.$http.post(
|
|
'/admin/users?action=delete',
|
|
{ uid }
|
|
)
|
|
if (errno === 0) {
|
|
this.$delete(this.users, originalIndex)
|
|
toastr.success(msg)
|
|
} else {
|
|
toastr.warning(msg)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="stylus">
|
|
.operations-menu
|
|
margin-left -35px
|
|
|
|
.row-at-bottom
|
|
margin-top -100px
|
|
</style>
|