游戏页面权限控制

This commit is contained in:
yulixing 2019-05-22 20:16:48 +08:00
parent a261dc1e3d
commit 0e5a6dc0b8
10 changed files with 228 additions and 173 deletions

View File

@ -25,7 +25,6 @@ module.exports = {
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
"vue/no-reserved-keys": "off",
"vue/html-closing-bracket-spacing": ["error", {
"startTag": "never",
"endTag": "never",

View File

@ -25,7 +25,7 @@ const gamesRouter = {
meta: { title: '配置项管理' }
},
{
path: 'details/:_id?',
path: 'details/:uid?',
component: () => import('@/views/games/details/index'), // Parent router-view
redirect: '/games/details/profile',
name: 'GameDetails',

View File

@ -3,20 +3,17 @@
<div class="content clearfix">
<div class="l fl mgr-20">
<div class="icon-box">
<img
src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556621103986&di=8fc8cde8ba29344e835735e543348d35&imgtype=0&src=http%3A%2F%2Fimg.qqzhi.com%2Fuploads%2F2018-12-01%2F042647493.jpg"
class="icon img-fit"
>
<img :src="info.game_icon" class="icon img-fit">
</div>
</div>
<div class="r">
<h4 class="title c-t-2 fw-500 ell">
<router-link to>蔚蓝战纪</router-link>
<svg-icon icon-class="fire" style="color: #f56c6c"/>
<svg-icon icon-class="recommend" style="color: #e6a23c"/>
<router-link :to="`/games/details/${info._id}/profile`">{{info.game_name}}</router-link>
<svg-icon icon-class="fire" style="color: #f56c6c" v-if="info.is_hot"/>
<svg-icon icon-class="recommend" style="color: #e6a23c" v-if="info.is_recommend"/>
</h4>
<span class="type dis-b c-t-3 ell">策略养成</span>
<span class="status dis-b ell">已上线</span>
<span class="type dis-b c-t-3 ell">{{info.show_type}}</span>
<span class="status dis-b c-t-3 ell">{{info.status_show}}</span>
</div>
</div>
</div>
@ -24,7 +21,8 @@
<script>
export default {
name: 'GameCard'
name: 'GameCard',
props: ['info']
}
</script>

View File

@ -8,7 +8,7 @@
</div>
<div class="r">
<span class="greeting dis-b mgb-20">早安{{ userInfo.fullname }}祝你开心每一天</span>
<span class="text dis-b c-t-3">这个人很懒什么都没留下</span>
<span class="text dis-b c-t-3">{{userInfo.signature || '这个人很懒,什么都没留下'}}</span>
</div>
</div>
<div class="pd-20">
@ -17,20 +17,13 @@
<el-card class="games" shadow="never">
<div slot="header" class="clearfix">
<span>游戏概览</span>
<el-button style="float: right; padding: 0" type="text">游戏列表</el-button>
<el-button style="float: right; padding: 0" type="text">
<router-link to="/games/list">游戏列表</router-link>
</el-button>
</div>
<el-row :gutter="16">
<el-col :span="8">
<game-card/>
</el-col>
<el-col :span="8">
<game-card/>
</el-col>
<el-col :span="8">
<game-card/>
</el-col>
<el-col :span="8">
<game-card/>
<el-col :span="8" v-for="(item, index) in gameList" :key="index">
<game-card :info="item"/>
</el-col>
</el-row>
</el-card>
@ -64,16 +57,42 @@
import GameCard from './components/GameCard'
import NewsItem from './components/NewsItem'
import { mapGetters } from 'vuex'
import request from '@/utils/request'
export default {
name: 'Dashboard',
data() {
return {
gameList: []
}
},
mounted() {
this.getGameList()
},
components: {
GameCard,
NewsItem
},
computed: {
...mapGetters(['userInfo'])
},
methods: {
getGameList() {
request({
url: '/api/games/list',
method: 'get'
}).then(res => {
const { data } = res
if (data.errcode !== 0) {
this.$notify.error({
title: '错误',
message: data.errmsg
})
return
}
this.gameList = data.gameList
})
}
}
}
</script>

View File

@ -2,45 +2,45 @@
<div class="app-container has-nav p-game-details">
<!-- nav -->
<el-menu :default-active="activeIndex" mode="horizontal" router>
<el-menu-item v-if="_id !== 'new'" :index="`/games/details/${_id}/profile`">简介</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/info`">详情</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/settings`">配置</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/recommendation`">推荐</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/share`">分享</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/reward`">奖励</el-menu-item>
<el-submenu :index="`/games/details/${_id}/gm/servers`">
<el-menu-item v-if="uid !== 'new'" :index="`/games/details/${uid}/profile`">简介</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/info`">详情</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/settings`">配置</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/recommendation`">推荐</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/share`">分享</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/reward`">奖励</el-menu-item>
<el-submenu :index="`/games/details/${uid}/gm/servers`">
<template slot="title">GM 工具</template>
<el-menu-item :index="`/games/details/${_id}/gm/servers`">服务器管理</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/announces`">公告</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/scroll`">跑马灯</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/mails`">邮件</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/activities`">活动</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/codes`">兑换码</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/gifts`">礼包</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/recharge-record`">充值记录</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/recharge-request`">充值请求</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/users`">用户管理</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/forbid-account`">封禁记录</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/forbid-speak`">禁言记录</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/chat-logs`">聊天记录</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/gm/op-logs`">操作记录</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/servers`">服务器管理</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/announces`">公告</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/scroll`">跑马灯</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/mails`">邮件</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/activities`">活动</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/codes`">兑换码</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/gifts`">礼包</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/recharge-record`">充值记录</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/recharge-request`">充值请求</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/users`">用户管理</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/forbid-account`">封禁记录</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/forbid-speak`">禁言记录</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/chat-logs`">聊天记录</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/gm/op-logs`">操作记录</el-menu-item>
</el-submenu>
<el-submenu :index="`/games/details/${_id}/doll/dolls`">
<el-submenu :index="`/games/details/${uid}/doll/dolls`">
<template slot="title">织娃娃管理</template>
<el-menu-item :index="`/games/details/${_id}/doll/dolls/index`">公仔</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/doll/cards/index`">卡片</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/doll/exchange`">兑换记录</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/doll/points`">积分墙</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/doll/dolls/index`">公仔</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/doll/cards/index`">卡片</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/doll/exchange`">兑换记录</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/doll/points`">积分墙</el-menu-item>
</el-submenu>
<el-submenu :index="`/games/details/${_id}/puzzle/questions`">
<el-submenu :index="`/games/details/${uid}/puzzle/questions`">
<template slot="title">竞猜管理</template>
<el-menu-item :index="`/games/details/${_id}/puzzle/questions`">题库管理</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/puzzle/levels`">关卡</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/puzzle/questions`">题库管理</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/puzzle/levels`">关卡</el-menu-item>
</el-submenu>
<el-submenu :index="`/games/details/${_id}/emulate/games`">
<el-submenu :index="`/games/details/${uid}/emulate/games`">
<template slot="title">模拟器管理</template>
<el-menu-item :index="`/games/details/${_id}/emulate/games/index`">游戏列表</el-menu-item>
<el-menu-item :index="`/games/details/${_id}/emulate/recommend`">游戏推荐</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/emulate/games/index`">游戏列表</el-menu-item>
<el-menu-item :index="`/games/details/${uid}/emulate/recommend`">游戏推荐</el-menu-item>
</el-submenu>
</el-menu>
<router-view/>
@ -52,7 +52,7 @@ export default {
name: 'GameDetails',
data() {
return {
_id: ''
uid: ''
}
},
computed: {
@ -61,7 +61,7 @@ export default {
}
},
created() {
this._id = this.$route.params._id || 'new'
this.uid = this.$route.params.uid || 'new'
}
}
</script>

View File

@ -77,7 +77,7 @@
<el-input v-model="gameForm.comment" type="textarea"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('gameForm')">保存</el-button>
<el-button type="primary" @click="submitForm('gameForm')" v-if="permissionEdit">保存</el-button>
<el-button @click="goBack">返回</el-button>
</el-form-item>
</el-form>
@ -86,12 +86,14 @@
<script>
import request from '@/utils/request'
import { mapGetters } from 'vuex'
export default {
name: 'GameDetailsInfo',
data() {
return {
_id: '',
permissionEdit: false,
uid: '',
gameType: [],
platform: [],
statusList: [],
@ -130,12 +132,18 @@ export default {
}
}
},
computed: {
...mapGetters(['userInfo'])
},
mounted() {
this._id = this.$route.params._id
this.uid = this.$route.params.uid
this.permissionEdit =
this.userInfo.permissions.includes(`${this.uid}-edit`) ||
this.userInfo.permissions.includes(`${this.uid}-publish`)
this.getPlatform()
this.getGameType()
this.getStatusList()
if (this._id !== 'new') {
if (this.uid !== 'new') {
this.getData()
}
},
@ -145,7 +153,7 @@ export default {
url: '/api/games/list',
method: 'get',
params: {
_id: this._id
_id: this.uid
}
}).then(res => {
const { data } = res
@ -216,7 +224,7 @@ export default {
this.$message.error('图片上传失败!')
},
saveEdit() {
if (this._id === 'new') {
if (this.uid === 'new') {
request({
url: '/api/games/add',
method: 'post',
@ -229,7 +237,7 @@ export default {
}
this.$refs['gameForm'].clearValidate()
this.$message.success('已成功添加游戏!')
this.$route.params._id = data.userInfo._id
this.$route.params.uid = data.userInfo._id
this.$router.push(`/games/details/${data.userInfo._id}/info`)
})
} else {

View File

@ -3,10 +3,7 @@
<el-row :gutter="32">
<el-col :span="2">
<div class="icon-box">
<img
:src="gameInfo.game_icon"
class="img-fit"
>
<img :src="gameInfo.game_icon" class="img-fit">
</div>
</el-col>
<!-- TODO: 左侧文字两端对齐 -->
@ -45,17 +42,21 @@
</div>
<div class="info-item mgb-20 clearfix">
<span class="title mgr-20 fl">添加时间:</span>
<!-- <span class="info fl">{{moment(gameInfo.createdAt).format('YYYY-MM-DD HH:MM:SS')}}</span> -->
<span class="info fl">{{createdTime}}</span>
</div>
<!-- TODO:整理关联游戏 -->
<!-- <div class="info-item mgb-20 clearfix">
<span class="title mgr-20 fl">关联游戏:</span>
<span class="info fl">{{gameInfo.linked_games.join('')}}</span>
</div> -->
</div>-->
<div class="info-item clearfix">
<el-button type="success">详情</el-button>
<el-button v-if="hasEditPermission" type="warning">编辑</el-button>
<el-button type="danger">删除</el-button>
<el-button type="success">
<router-link :to="`/games/details/${uid}/info`">详情</router-link>
</el-button>
<el-button type="warning" v-if="permissionEdit">
<router-link :to="`/games/details/${uid}/info`">编辑</router-link>
</el-button>
<el-button type="danger" v-if="permissionEdit" @click="delGame">删除</el-button>
</div>
</el-col>
</el-row>
@ -65,30 +66,38 @@
<script>
import request from '@/utils/request'
import moment from 'moment'
import { mapGetters } from 'vuex'
export default {
name: 'GameDetailsProfile',
data() {
return {
_id: 'new',
uid: 'new',
gameInfo: {},
// TODO:
hasEditPermission: true
permissionEdit: false
}
},
computed: {
...mapGetters(['userInfo']),
createdTime() {
return moment(this.gameInfo.createdAt).format('YYYY-MM-DD HH:MM:SS')
}
},
mounted() {
this._id = this.$route.params._id
// TODO:
this.hasEditPermission = this.$store.getters.userInfo.permissions.includes(`${this._id}-publish`)
this.uid = this.$route.params.uid
this.getData()
this.permissionEdit =
this.userInfo.permissions.includes(`${this.uid}-edit`) ||
this.userInfo.permissions.includes(`${this.uid}-publish`)
},
methods: {
getData() {
request({
url: '/api/games/list',
method: 'get',
params: {
_id: this._id
_id: this.uid
}
}).then(res => {
const { data } = res
@ -101,6 +110,36 @@ export default {
}
this.gameInfo = data.gameList[0]
})
},
delGame() {
this.$confirm(`是否删除游戏:${this.gameInfo.game_name}`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
request({
url: '/api/games/del',
method: 'post',
data: {
gameList: [{ _id: this.uid }]
}
}).then(res => {
const { data } = res
if (data.errcode !== 0) {
this.$notify.error({
title: '错误',
message: data.errmsg
})
return
}
this.$message.success('已成功删除该游戏')
this.$router.push('/games/list')
})
})
.catch(() => {
this.$notify.info('已取消删除')
})
}
}
}

View File

@ -135,7 +135,7 @@ export default {
data() {
return {
_id: '',
uid: '',
gameInfo: {},
permissionEdit: false,
permissionPublish: false,
@ -176,12 +176,12 @@ export default {
...mapGetters(['userInfo'])
},
mounted() {
this._id = this.$route.params._id
this.uid = this.$route.params.uid
this.permissionEdit =
this.userInfo.permissions.includes(`${this._id}-edit`) ||
this.userInfo.permissions.includes(`${this._id}-publish`)
this.userInfo.permissions.includes(`${this.uid}-edit`) ||
this.userInfo.permissions.includes(`${this.uid}-publish`)
this.permissionPublish = this.userInfo.permissions.includes(
`${this._id}-publish`
`${this.uid}-publish`
)
this.getGameInfo(this.getGameSettings)
this.getSettingsList()
@ -193,7 +193,7 @@ export default {
url: '/api/games/list',
method: 'get',
params: {
_id: this._id
_id: this.uid
}
}).then(res => {
const { data } = res

View File

@ -46,7 +46,7 @@
<el-table-column prop="game_id" label="游戏 ID" show-overflow-tooltip sortable/>
<el-table-column label="游戏名称" show-overflow-tooltip sortable width="120">
<template slot-scope="scope">
<router-link :to="`/games/details/${scope.row._id}/info`">
<router-link :to="`/games/details/${scope.row._id}/profile`">
<img :src="scope.row.game_icon" class="game-icon">
{{ scope.row.game_name }}
</router-link>
@ -109,6 +109,7 @@
<script>
import request from '@/utils/request'
import moment from 'moment'
import {mapGetters} from 'vuex'
export default {
name: 'GameList',
@ -136,6 +137,9 @@ export default {
pageSize: 10
}
},
computed: {
...mapGetters(['userInfo'])
},
mounted() {
this.getData()
this.getGameType()
@ -280,9 +284,19 @@ export default {
return cellValue ? moment(cellValue).format('YYYY-MM-DD HH:MM:SS') : '-'
},
editGame(row) {
this.$router.push(`/games/details/${row._id}/info`)
const permissionEdit = this.userInfo.permissions.includes(`${row._id}-edit`) || this.userInfo.permissions.includes(`${row._id}-publish`)
if(!permissionEdit) {
this.$message.warning('您没有编辑权限!')
} else {
this.$router.push(`/games/details/${row._id}/info`)
}
},
delGame(row) {
const permissionEdit = this.userInfo.permissions.includes(`${row._id}-edit`) || this.userInfo.permissions.includes(`${row._id}-publish`)
if(!permissionEdit) {
this.$message.warning('您没有删除权限!')
return
}
this.$confirm(`是否删除游戏:${row.game_name}`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',

View File

@ -1,42 +1,45 @@
<template>
<div class="app-container">
<h2>{{ $route.meta.title }}</h2>
<el-form ref="ruleForm" :model="ruleForm" :rules="{}">
<el-form ref="userForm" :model="userForm">
<el-row>
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="ruleForm.name" style="width:100%" disabled/>
<el-form-item label="姓名" prop="fullname">
<el-input v-model="userForm.fullname" style="width:100%" disabled/>
</el-form-item>
<el-form-item label="用户名" prop="name">
<el-input v-model="ruleForm.name" style="width:100%" disabled/>
<el-form-item label="用户名" prop="username">
<el-input v-model="userForm.username" style="width:100%" disabled/>
</el-form-item>
<el-form-item label="账号ID" prop="name">
<el-input v-model="ruleForm.name" style="width:100%" disabled/>
<el-form-item label="角色">
<div class="w100" style="overflow: hidden;" v-if="userForm.length > 0">
<el-tag v-for="item in userForm.roles" :key="item" class="mgr-20">{{item}}</el-tag>
</div>
<div class="w100" style="overflow: hidden;" v-else>
<el-tag class="mgr-20">普通用户</el-tag>
</div>
</el-form-item>
<el-form-item label="新密码" prop="name">
<el-input v-model="ruleForm.name" style="width:100%"/>
</el-form-item>
<el-form-item label="确认密码" prop="name">
<el-input v-model="ruleForm.name" style="width:100%"/>
</el-form-item>
<el-form-item label="角色" prop="name">
<el-input v-model="ruleForm.name" style="width:100%"/>
</el-form-item>
<el-form-item label="签名" prop="name">
<el-input v-model="ruleForm.name" type="textarea" style="width:100%"/>
<el-form-item label="签名" prop="signature">
<el-input v-model="userForm.signature" type="textarea" style="width:100%"/>
</el-form-item>
<el-form-item>
<el-button>更新信息</el-button>
<el-button @click="saveEdit" type="primary">更新信息</el-button>
</el-form-item>
</el-col>
<el-col :span="6" :offset="2">
<el-form-item label="头像" prop="name" class="uploader-box">
<el-form-item label="头像" prop="avatar" class="uploader-box">
<el-upload
class="uploader"
action="https://jsonplaceholder.typicode.com/posts/"
action="/api/common/upload"
:show-file-list="false"
:on-success="uploadSuccess"
:on-error="uploadErr"
name="image-file"
:data="{
sub_path: '/admin-avatar/',
file_type: 'user_avatar'
}"
>
<img v-if="imageUrl" src="#" class="uploader-img">
<img v-if="userForm.avatar" :src="userForm.avatar" class="uploader-img">
<i v-else class="el-icon-plus uploader-icon"/>
</el-upload>
</el-form-item>
@ -47,72 +50,50 @@
</template>
<script>
import { mapGetters } from 'vuex'
import request from '@/utils/request'
export default {
data() {
return {
ruleForm: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
date1: [
{
type: 'date',
required: true,
message: '请选择日期',
trigger: 'change'
}
],
date2: [
{
type: 'date',
required: true,
message: '请选择时间',
trigger: 'change'
}
],
type: [
{
type: 'array',
required: true,
message: '请至少选择一个活动性质',
trigger: 'change'
}
],
resource: [
{ required: true, message: '请选择活动资源', trigger: 'change' }
],
desc: [{ required: true, message: '请填写活动形式', trigger: 'blur' }]
},
imageUrl: ''
userForm: {}
}
},
computed: {
...mapGetters(['userInfo'])
},
mounted() {
this.userForm = JSON.parse(JSON.stringify(this.userInfo))
},
methods: {
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
saveEdit() {
request({
url: '/api/user/edit',
method: 'post',
data: {
username: this.userForm.username,
signature: this.userForm.signature,
avatar: this.userForm.avatar
}
}).then(res => {
const { data } = res
if (data.errcode !== 0) {
this.$message.error({
title: '错误',
message: data.errmsg
})
return
}
this.$store.dispatch('user/getInfo')
this.$message.success('用户信息更新成功!')
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
uploadSuccess(res, file) {
this.userForm.avatar = res.url
this.$message.success('图片上传成功!')
},
uploadErr() {
this.$message.error('图片上传失败!')
}
}
}
@ -126,6 +107,3 @@ export default {
}
</style>
<style lang="scss" scoped>
</style>