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

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

上级 0dae7da9
...@@ -32,29 +32,11 @@ export function getUser() { ...@@ -32,29 +32,11 @@ export function getUser() {
export function updateUser(data) { export function updateUser(data) {
return httpRequest.post('/api/lms-financial/user/update-info', 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) { export function checkCode(params) {
return httpRequest.get('/api/usercenter/user/check-code', { 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() { export function getPermissions() {
return httpRequest.get('/api/zy/user/get-permissions') return httpRequest.get('/api/lms-financial/user/get-permissions')
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<el-progress :percentage="data.video_progress"></el-progress> <el-progress :percentage="data.video_progress"></el-progress>
</div> </div>
<div class="course-item__buttons"> <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> </div>
</div> </div>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</div> </div>
<el-menu class="nav" :unique-opened="true" :default-active="defaultActive"> <el-menu class="nav" :unique-opened="true" :default-active="defaultActive">
<template v-for="item in currentMenus"> <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> <template #title>
<i class="iconfont" :class="item.icon"></i><span>{{ item.title }}</span> <i class="iconfont" :class="item.icon"></i><span>{{ item.title }}</span>
</template> </template>
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
:index="item.path" :index="item.path"
:key="item.title" :key="item.title"
v-for="item in item.children" v-for="item in item.children"
v-permission="item.tag"
@click="handleClick(item.path, item)" @click="handleClick(item.path, item)"
> >
<template #title> <template #title>
...@@ -28,7 +29,13 @@ ...@@ -28,7 +29,13 @@
</template> </template>
</el-menu-item> </el-menu-item>
</el-submenu> </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> <i class="iconfont" :class="item.icon"></i>
<span slot="title">{{ item.title }}</span> <span slot="title">{{ item.title }}</span>
</el-menu-item> </el-menu-item>
...@@ -51,7 +58,6 @@ export default { ...@@ -51,7 +58,6 @@ export default {
return { return {
studentMenus: [ studentMenus: [
{ {
tag: 'menu_help',
title: '学员须知', title: '学员须知',
icon: 'icon-bianzu8-hong', icon: 'icon-bianzu8-hong',
path: '/notice' path: '/notice'
...@@ -61,31 +67,31 @@ export default { ...@@ -61,31 +67,31 @@ export default {
title: '我的课程', title: '我的课程',
icon: 'icon-bianzu6-hong', icon: 'icon-bianzu6-hong',
path: '/course', path: '/course',
children: [{ tag: 'menu_course_learn', title: '课程学习', path: '/course/learn' }] children: [{ tag: 'menu_course_list', title: '课程学习', path: '/course/learn' }]
}, },
{ {
tag: 'menu_exam', tag: 'menu_exam',
title: '我的考试', title: '我的考试',
icon: 'icon-bianzuhong', icon: 'icon-bianzuhong',
children: [ children: [
{ tag: 'menu_exam_paper_review', title: '试卷管理', path: '/exam/exam' }, { tag: 'menu_exam_list', title: '试卷管理', path: '/exam/exam' },
{ tag: 'menu_exam_exercise_review', title: '考试记录', path: '/exam/record' } { tag: 'menu_exam_sheets', title: '考试记录', path: '/exam/record' }
] ]
}, },
{ {
tag: 'menu_training', tag: 'menu_certificate',
title: '我的证书', title: '我的证书',
icon: 'icon-kaoshihong', icon: 'icon-kaoshihong',
path: '/cert' path: '/cert'
}, },
{ {
tag: 'menu_my', tag: 'menu_basic_info',
title: '个人中心', title: '个人中心',
icon: 'icon-guanlizhongxinbeifen-hong', icon: 'icon-guanlizhongxinbeifen-hong',
children: [ children: [
{ tag: 'menu_my_info', title: '个人信息', path: '/account' }, { title: '个人信息', path: '/account' },
{ tag: 'menu_my_password', title: '修改密码', path: '/account/password' }, { title: '修改密码', path: '/account/password' },
{ tag: 'menu_my_safe', title: '安全设置', path: '/account/safe' } { title: '安全设置', path: '/account/safe' }
] ]
} }
] ]
...@@ -104,12 +110,6 @@ export default { ...@@ -104,12 +110,6 @@ export default {
avatar() { avatar() {
return this.user.avatar || defaultAvatar return this.user.avatar || defaultAvatar
}, },
// 菜单权限
menuPermissions() {
// role: 1学生,2老师
// system_tag: 2教师,3学生
return this.$store.state.permissions
},
defaultActive() { defaultActive() {
// 扁平菜单 // 扁平菜单
const flatMenuList = this.currentMenus.reduce((result, item) => { const flatMenuList = this.currentMenus.reduce((result, item) => {
......
...@@ -3,6 +3,7 @@ import App from './App.vue' ...@@ -3,6 +3,7 @@ import App from './App.vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
import modules from './modules' import modules from './modules'
import directives from '@/utils/directives'
// 公共css // 公共css
import './assets/css/base.css' import './assets/css/base.css'
...@@ -26,6 +27,9 @@ Vue.component('AppContainer', AppContainer) ...@@ -26,6 +27,9 @@ Vue.component('AppContainer', AppContainer)
Vue.component('AppCard', AppCard) Vue.component('AppCard', AppCard)
Vue.component('AppList', AppList) Vue.component('AppList', AppList)
// 注册指令
Vue.use(directives)
// 注册模块 // 注册模块
modules({ router, store }) modules({ router, store })
......
<template> <template>
<course-list @on-click="handleClick" :searchValue="searchValue" /> <course-list @on-click="handleClick" :searchValue="searchValue" />
</template> </template>
<script> <script>
...@@ -13,16 +13,16 @@ export default { ...@@ -13,16 +13,16 @@ export default {
} }
}, },
computed: { computed: {
role() { permissions() {
// 1 学生 2 老师 return this.$store.state.permissions || []
return this.$store.state.user.role
},
title() {
return this.role === 2 ? '课程库' : ''
} }
}, },
methods: { methods: {
handleClick(data) { 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 } }) this.$router.push({ name: 'courseLearnItem', query: { id: data.course_id } })
}, },
// 搜索 // 搜索
......
...@@ -33,8 +33,7 @@ export default { ...@@ -33,8 +33,7 @@ export default {
} }
} }
}, },
mounted() { mounted() {},
},
computed: { computed: {
currentCompoent() { currentCompoent() {
const componentNames = { const componentNames = {
...@@ -48,7 +47,6 @@ export default { ...@@ -48,7 +47,6 @@ export default {
100: 'CourseRead', // 课程资料 100: 'CourseRead', // 课程资料
101: 'CourseExam' // 课程考试 101: 'CourseExam' // 课程考试
} }
console.log(1123123)
return this.chapter ? componentNames[this.chapter.type] || '' : '' return this.chapter ? componentNames[this.chapter.type] || '' : ''
}, },
pid() { pid() {
......
...@@ -170,7 +170,6 @@ export default { ...@@ -170,7 +170,6 @@ export default {
if (this.throttled) { if (this.throttled) {
this.throttled(time, durations) this.throttled(time, durations)
} else { } else {
console.log(11)
this.throttled = throttle(this.updateChapterVideoProgress, this.throttleWait * 1000, { leading: false }) this.throttled = throttle(this.updateChapterVideoProgress, this.throttleWait * 1000, { leading: false })
} }
}, },
......
...@@ -35,6 +35,13 @@ ...@@ -35,6 +35,13 @@
</div> </div>
<div class="card-body__btn2" @click="startExam(item)" v-if="item.status == 102">继续考试</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__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> </div>
</div> </div>
...@@ -92,6 +99,12 @@ export default { ...@@ -92,6 +99,12 @@ export default {
} }
}) })
}, },
// 重新考试
reStartExam(data) {
this.dialogVisible = true
this.curExamId = data.id
this.curExamTitle = data.paper_title
},
startExam(data) { startExam(data) {
const num = parseInt(data.status) const num = parseInt(data.status)
const leaveTimes = data.leave_times || 0 const leaveTimes = data.leave_times || 0
......
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { getUser, logout, getPermissions } from '@/api/account'
import { getUser, logout, getIsVip, createGuestUser } from '@/api/account'
Vue.use(Vuex) Vue.use(Vuex)
const store = new Vuex.Store({ const store = new Vuex.Store({
state: { state: {
user: {}, 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: [] permissions: []
}, },
mutations: { mutations: {
setUser(state, user) { setUser(state, user) {
state.user = user.data 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) { setPermissions(state, permissions) {
state.permissions = permissions state.permissions = permissions
} }
...@@ -46,12 +27,11 @@ const store = new Vuex.Store({ ...@@ -46,12 +27,11 @@ const store = new Vuex.Store({
logout({ commit }) { logout({ commit }) {
return logout().then(response => { return logout().then(response => {
commit('setUser', {}) commit('setUser', {})
commit('setIsLogin', false)
return response return response
}) })
}, },
// 检测登录状态 // 检测登录状态
async checkLogin({ commit }) { async checkLogin({ commit, dispatch }) {
const isLogin = await getUser() const isLogin = await getUser()
.then(response => { .then(response => {
commit('setUser', response) commit('setUser', response)
...@@ -61,53 +41,18 @@ const store = new Vuex.Store({ ...@@ -61,53 +41,18 @@ const store = new Vuex.Store({
commit('setUser', {}) commit('setUser', {})
return false return false
}) })
commit('setIsLogin', isLogin) await dispatch('getPermissions')
return isLogin return isLogin
}, },
// 检测是否付费 // 获取所有权限列表
async checkIsVip({ commit, state }) { getPermissions({ commit }) {
if (!state.isVip) { getPermissions({ type: 1 }).then(res => {
await getIsVip().then(response => commit('setIsVip', response.is_vip)) if (res.data && res.data.items) {
} commit('setPermissions', res.data.items)
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))
}
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 export default store
import store from '@/store' import store from '@/store'
export default async function (to, from, next) { 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'] const whiteList = ['/index', '/401']
if (whiteList.includes(to.path)) { if (whiteList.includes(to.path)) {
...@@ -15,7 +8,7 @@ export default async function (to, from, next) { ...@@ -15,7 +8,7 @@ export default async function (to, from, next) {
return 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) { if (to.meta.requiredLogin && !isLogin) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}` window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
return 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论