提交 e8dc8423 authored 作者: 王鹏飞's avatar 王鹏飞

feat: 新增权限控制;可以多次考试;

上级 0dae7da9
......@@ -32,29 +32,11 @@ export function getUser() {
export function updateUser(data) {
return httpRequest.post('/api/lms-financial/user/update-info', data)
}
// 绑定游客
export function bindVisitor(data) {
return httpRequest.post('/api/zy/user/bind-account', data)
}
// 获取是否VIP
export function getIsVip() {
return httpRequest.get('/api/zy/user/is-vip')
}
// 创建游客用户
export function createGuestUser() {
return httpRequest.get('/api/zy/user/create-guest-user')
}
// 校验验证码
export function checkCode(params) {
return httpRequest.get('/api/usercenter/user/check-code', { params })
}
// 选择用户角色
export function chooseRole(data) {
return httpRequest.post('/api/zy/user/choose-role', data)
}
// 获取所有权限
export function getPermissions() {
return httpRequest.get('/api/zy/user/get-permissions')
return httpRequest.get('/api/lms-financial/user/get-permissions')
}
......@@ -10,7 +10,7 @@
<el-progress :percentage="data.video_progress"></el-progress>
</div>
<div class="course-item__buttons">
<el-button type="primary" size="small" round>查看课程</el-button>
<el-button type="primary" size="small" round v-permission="'menu_course_view'">查看课程</el-button>
</div>
</div>
</div>
......
......@@ -10,7 +10,7 @@
</div>
<el-menu class="nav" :unique-opened="true" :default-active="defaultActive">
<template v-for="item in currentMenus">
<el-submenu :index="item.title" :key="item.title" v-if="item.children">
<el-submenu :index="item.title" :key="item.title" v-if="item.children" v-permission="item.tag">
<template #title>
<i class="iconfont" :class="item.icon"></i><span>{{ item.title }}</span>
</template>
......@@ -18,6 +18,7 @@
:index="item.path"
:key="item.title"
v-for="item in item.children"
v-permission="item.tag"
@click="handleClick(item.path, item)"
>
<template #title>
......@@ -28,7 +29,13 @@
</template>
</el-menu-item>
</el-submenu>
<el-menu-item :index="item.path" :key="item.title" @click="handleClick(item.path, item)" v-else>
<el-menu-item
:index="item.path"
:key="item.title"
@click="handleClick(item.path, item)"
v-permission="item.tag"
v-else
>
<i class="iconfont" :class="item.icon"></i>
<span slot="title">{{ item.title }}</span>
</el-menu-item>
......@@ -51,7 +58,6 @@ export default {
return {
studentMenus: [
{
tag: 'menu_help',
title: '学员须知',
icon: 'icon-bianzu8-hong',
path: '/notice'
......@@ -61,31 +67,31 @@ export default {
title: '我的课程',
icon: 'icon-bianzu6-hong',
path: '/course',
children: [{ tag: 'menu_course_learn', title: '课程学习', path: '/course/learn' }]
children: [{ tag: 'menu_course_list', title: '课程学习', path: '/course/learn' }]
},
{
tag: 'menu_exam',
title: '我的考试',
icon: 'icon-bianzuhong',
children: [
{ tag: 'menu_exam_paper_review', title: '试卷管理', path: '/exam/exam' },
{ tag: 'menu_exam_exercise_review', title: '考试记录', path: '/exam/record' }
{ tag: 'menu_exam_list', title: '试卷管理', path: '/exam/exam' },
{ tag: 'menu_exam_sheets', title: '考试记录', path: '/exam/record' }
]
},
{
tag: 'menu_training',
tag: 'menu_certificate',
title: '我的证书',
icon: 'icon-kaoshihong',
path: '/cert'
},
{
tag: 'menu_my',
tag: 'menu_basic_info',
title: '个人中心',
icon: 'icon-guanlizhongxinbeifen-hong',
children: [
{ tag: 'menu_my_info', title: '个人信息', path: '/account' },
{ tag: 'menu_my_password', title: '修改密码', path: '/account/password' },
{ tag: 'menu_my_safe', title: '安全设置', path: '/account/safe' }
{ title: '个人信息', path: '/account' },
{ title: '修改密码', path: '/account/password' },
{ title: '安全设置', path: '/account/safe' }
]
}
]
......@@ -104,12 +110,6 @@ export default {
avatar() {
return this.user.avatar || defaultAvatar
},
// 菜单权限
menuPermissions() {
// role: 1学生,2老师
// system_tag: 2教师,3学生
return this.$store.state.permissions
},
defaultActive() {
// 扁平菜单
const flatMenuList = this.currentMenus.reduce((result, item) => {
......
......@@ -3,6 +3,7 @@ import App from './App.vue'
import router from './router'
import store from './store'
import modules from './modules'
import directives from '@/utils/directives'
// 公共css
import './assets/css/base.css'
......@@ -26,6 +27,9 @@ Vue.component('AppContainer', AppContainer)
Vue.component('AppCard', AppCard)
Vue.component('AppList', AppList)
// 注册指令
Vue.use(directives)
// 注册模块
modules({ router, store })
......
......@@ -13,16 +13,16 @@ export default {
}
},
computed: {
role() {
// 1 学生 2 老师
return this.$store.state.user.role
},
title() {
return this.role === 2 ? '课程库' : ''
permissions() {
return this.$store.state.permissions || []
}
},
methods: {
handleClick(data) {
if (!this.permissions.find(item => item.tag === 'menu_course_view')) {
this.$message.error('暂无权限')
return
}
this.$router.push({ name: 'courseLearnItem', query: { id: data.course_id } })
},
// 搜索
......
......@@ -33,8 +33,7 @@ export default {
}
}
},
mounted() {
},
mounted() {},
computed: {
currentCompoent() {
const componentNames = {
......@@ -48,7 +47,6 @@ export default {
100: 'CourseRead', // 课程资料
101: 'CourseExam' // 课程考试
}
console.log(1123123)
return this.chapter ? componentNames[this.chapter.type] || '' : ''
},
pid() {
......
......@@ -170,7 +170,6 @@ export default {
if (this.throttled) {
this.throttled(time, durations)
} else {
console.log(11)
this.throttled = throttle(this.updateChapterVideoProgress, this.throttleWait * 1000, { leading: false })
}
},
......
......@@ -35,6 +35,13 @@
</div>
<div class="card-body__btn2" @click="startExam(item)" v-if="item.status == 102">继续考试</div>
<div class="card-body__btn3" @click="startExam(item)" v-if="item.status == 103">已完成</div>
<div
class="card-body__btn2"
@click="reStartExam(item)"
v-if="item.status == 103 && item.is_multiple_exams === 1"
>
重新考试
</div>
</div>
</div>
</div>
......@@ -92,6 +99,12 @@ export default {
}
})
},
// 重新考试
reStartExam(data) {
this.dialogVisible = true
this.curExamId = data.id
this.curExamTitle = data.paper_title
},
startExam(data) {
const num = parseInt(data.status)
const leaveTimes = data.leave_times || 0
......
import Vue from 'vue'
import Vuex from 'vuex'
import { getUser, logout, getPermissions } from '@/api/account'
import { getUser, logout, getIsVip, createGuestUser } from '@/api/account'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
user: {},
isVip: false,
isLogin: false,
isIos: /iphone|ipad|ipod/i.test(navigator.userAgent),
isAndroid: /android/i.test(navigator.userAgent),
isWeapp: /miniProgram/.test(navigator.userAgent),
guestUser: { user_id: '', student_id: '' },
permissions: []
},
mutations: {
setUser(state, user) {
state.user = user.data
},
setIsWeapp(state, isWeapp) {
state.isWeapp = isWeapp
},
setIsLogin(state, isLogin) {
state.isLogin = isLogin
},
setIsVip(state, isVip) {
state.isVip = isVip
},
setGuestUser(state, user) {
state.guestUser = user
window.localStorage.setItem('guestUser', JSON.stringify(user))
},
setPermissions(state, permissions) {
state.permissions = permissions
}
......@@ -46,12 +27,11 @@ const store = new Vuex.Store({
logout({ commit }) {
return logout().then(response => {
commit('setUser', {})
commit('setIsLogin', false)
return response
})
},
// 检测登录状态
async checkLogin({ commit }) {
async checkLogin({ commit, dispatch }) {
const isLogin = await getUser()
.then(response => {
commit('setUser', response)
......@@ -61,53 +41,18 @@ const store = new Vuex.Store({
commit('setUser', {})
return false
})
commit('setIsLogin', isLogin)
await dispatch('getPermissions')
return isLogin
},
// 检测是否付费
async checkIsVip({ commit, state }) {
if (!state.isVip) {
await getIsVip().then(response => commit('setIsVip', response.is_vip))
}
return state.isVip
},
// 创建游客用户
async createGuestUser({ commit, state }) {
const { user_id: userId, student_id: studentId } = state.guestUser
if (!userId || !studentId) {
await createGuestUser().then(response => commit('setGuestUser', response))
// 获取所有权限列表
getPermissions({ commit }) {
getPermissions({ type: 1 }).then(res => {
if (res.data && res.data.items) {
commit('setPermissions', res.data.items)
}
return state.guestUser
},
// 加载本地游客信息
loadGuestUser({ commit, state }) {
const localGuestUser = window.localStorage.getItem('guestUser')
let guestUser = { user_id: '', student_id: '' }
if (localGuestUser) {
try {
guestUser = JSON.parse(localGuestUser)
} catch (error) {
console.log(error)
}
}
commit('setGuestUser', guestUser)
})
}
// // 获取所有权限列表
// getPermissions({ commit }) {
// getPermissions({ type: 1 }).then(res => {
// if (res.data && res.data.items) {
// commit('setPermissions', res.data.items)
// }
// })
// }
}
})
// store.dispatch('getPermissions')
// 加载本地游客用户
// store.dispatch('loadGuestUser')
// 检测是否付费
// store.dispatch('checkIsVip')
export default store
import store from '@/store'
export default async function (to, from, next) {
const { user_id: userId, student_id: studentId } = to.query
if (userId && studentId) {
store.commit('setGuestUser', { user_id: userId, student_id: studentId })
}
// 创建游客用户
// await store.dispatch('createGuestUser')
// 登录白名单
const whiteList = ['/index', '/401']
if (whiteList.includes(to.path)) {
......@@ -15,7 +8,7 @@ export default async function (to, from, next) {
return
}
const isLogin = store.state.isLogin || (await store.dispatch('checkLogin'))
const isLogin = store.state.user.id || (await store.dispatch('checkLogin'))
if (to.meta.requiredLogin && !isLogin) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
return
......
import store from '@/store'
function checkPermission(el, binding) {
const { value } = binding
if (!value) return
const permissions = store.state.permissions || []
let hasPermission = false
if (Array.isArray(value)) {
hasPermission = permissions.some(item => value.includes(item.tag))
} else {
hasPermission = !!permissions.find(item => item.tag === value)
}
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
// 判断是否有权限
export default Vue => {
Vue.directive('permission', { inserted: checkPermission, update: checkPermission })
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论