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

chore: update

上级 d9677ec0
...@@ -2,7 +2,7 @@ import httpRequest from '@/utils/axios' ...@@ -2,7 +2,7 @@ import httpRequest from '@/utils/axios'
// 获取用户信息 // 获取用户信息
export function getUser() { export function getUser() {
return httpRequest.get('/api/resource/v1/util/info') return httpRequest.get('/api/lab/v1/common/permission/role')
} }
// 退出登录 // 退出登录
......
...@@ -77,5 +77,9 @@ textarea:focus { ...@@ -77,5 +77,9 @@ textarea:focus {
} }
:root { :root {
--main-color: #aa1941; --main-color: #ba143e;
}
.el-dialog__header {
margin-right: 0 !important;
border-bottom: 1px solid #e6e6e6;
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
@forward 'element-plus/theme-chalk/src/common/var.scss' with ( @forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: ( $colors: (
'primary': ( 'primary': (
'base': #aa1941 'base': #ba143e
) )
), ),
$dialog: ( $dialog: (
......
...@@ -20,10 +20,10 @@ defineProps<{ title?: string }>() ...@@ -20,10 +20,10 @@ defineProps<{ title?: string }>()
<style lang="scss"> <style lang="scss">
.app-card { .app-card {
background: #fff; // background: #fff;
box-shadow: 0 1px 6px 0 rgb(228 232 235 / 20%); // box-shadow: 0 1px 6px 0 rgb(228 232 235 / 20%);
border-radius: 6px; // border-radius: 6px;
padding: 20px; // padding: 20px;
} }
.app-card + .app-card { .app-card + .app-card {
margin-top: 20px; margin-top: 20px;
...@@ -33,11 +33,11 @@ defineProps<{ title?: string }>() ...@@ -33,11 +33,11 @@ defineProps<{ title?: string }>()
} }
.app-card-hd__title { .app-card-hd__title {
flex: 1; flex: 1;
padding-left: 5px; margin-bottom: 20px;
font-size: 18px; font-size: 20px;
font-weight: 500; font-family: Source Han Sans CN;
font-weight: bold;
line-height: 1; line-height: 1;
margin-bottom: 24px; color: #333333;
border-left: 3px solid #aa1941;
} }
</style> </style>
...@@ -224,10 +224,13 @@ defineExpose({ refetch, tableRef }) ...@@ -224,10 +224,13 @@ defineExpose({ refetch, tableRef })
.table-list-hd { .table-list-hd {
display: flex; display: flex;
margin-bottom: 10px; margin-bottom: 20px;
} }
.table-list-filter { .table-list-filter {
flex: 1; flex: 1;
padding: 30px 30px 10px;
background: #fff;
border-radius: 12px;
} }
.table-list-buttons { .table-list-buttons {
margin-bottom: 20px; margin-bottom: 20px;
......
...@@ -13,7 +13,8 @@ const route = useRoute() ...@@ -13,7 +13,8 @@ const route = useRoute()
const userStore = useUserStore() const userStore = useUserStore()
const userInfo = userStore.user const userInfo = userStore.user
const menus = useMenuStore().menus const menuStore = useMenuStore()
const menus = $computed(() => menuStore.menus)
const defaultActive = computed(() => { const defaultActive = computed(() => {
// 扁平菜单 // 扁平菜单
...@@ -126,17 +127,23 @@ const logout = async () => { ...@@ -126,17 +127,23 @@ const logout = async () => {
--el-menu-item-height: 63px; --el-menu-item-height: 63px;
--el-menu-item-font-size: 16px; --el-menu-item-font-size: 16px;
.el-menu--horizontal { .el-menu--horizontal {
font-weight: 500;
border-bottom: 0; border-bottom: 0;
> .el-menu-item {
margin-left: 40px;
padding: 0;
background-color: unset !important;
border-bottom: 0 !important;
}
} }
.el-sub-menu__title { .el-sub-menu__title {
margin-left: 40px;
padding: 0;
border-bottom: 0 !important; border-bottom: 0 !important;
} }
.el-sub-menu__icon-arrow { .el-sub-menu__icon-arrow {
display: none; display: none;
} }
.el-sub-menu {
font-weight: 500;
}
} }
.sub-menu-popper { .sub-menu-popper {
border: 0 !important; border: 0 !important;
......
...@@ -7,22 +7,37 @@ defineProps<Props>() ...@@ -7,22 +7,37 @@ defineProps<Props>()
<template> <template>
<div class="list-item"> <div class="list-item">
<div class="icon"></div> <div class="list-item-hd">
<div class="list-item-main"> <div class="icon-file"></div>
<div class="button-group">
<div class="button icon-view">
<router-link :to="`/admin/lab/book/${data.id}`" target="_blank"></router-link>
</div>
<div class="button icon-edit" @click="$emit('clickEdit', data)"></div>
</div>
</div>
<div class="list-item-title">
<h2>{{ data.name }}</h2> <h2>{{ data.name }}</h2>
<h6>{{ data.status_name }}</h6> <h6>{{ data.status_name }}</h6>
</div>
<div class="list-item-main">
<ol>
<li>
<p>文件大小:{{ data.size_name }}</p> <p>文件大小:{{ data.size_name }}</p>
</li>
<li>
<p>观看次数:{{ data.pv }}</p> <p>观看次数:{{ data.pv }}</p>
</li>
<li>
<p>创建人:{{ data.created_operator_name }}</p> <p>创建人:{{ data.created_operator_name }}</p>
</li>
<li>
<p>创建时间:{{ data.created_time }}</p> <p>创建时间:{{ data.created_time }}</p>
</div> </li>
<div class="cover"> <li>
<div class="cover-inner"> <p>更新时间:{{ data.updated_time }}</p>
<router-link :to="`/admin/lab/book/${data.id}`" target="_blank"> </li>
<el-button type="primary" round plain auto-insert-space>查看</el-button> </ol>
</router-link>
<el-button type="primary" round plain auto-insert-space @click="$emit('clickEdit', data)">编辑</el-button>
</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -30,39 +45,85 @@ defineProps<Props>() ...@@ -30,39 +45,85 @@ defineProps<Props>()
<style lang="scss" scoped> <style lang="scss" scoped>
.list-item { .list-item {
position: relative; position: relative;
display: flex; padding: 30px;
padding: 20px; background: linear-gradient(to bottom left, rgba(186, 20, 62, 0.1) 0%, rgba(255, 255, 255, 0.8) 60%);
background: #f2f2f2; border-radius: 12px;
border-radius: 5px;
overflow: hidden;
&:hover { &:hover {
.cover { box-shadow: 0 3px 18px rgba(0, 0, 0, 0.27);
}
.list-item-hd {
display: flex;
justify-content: space-between;
.button-group {
display: flex;
.button {
a {
display: block; display: block;
width: 100%;
height: 100%;
}
}
.button + .button {
margin-left: 12px;
}
}
}
.icon-file {
width: 30px;
height: 30px;
background: url(@/assets/images/icon_word.png) no-repeat;
background-size: contain;
} }
.icon-edit {
width: 16px;
height: 16px;
background: url(@/assets/images/icon_edit.png) no-repeat;
background-size: contain;
cursor: pointer;
}
.icon-view {
width: 16px;
height: 16px;
background: url(@/assets/images/icon_view.png) no-repeat;
background-size: contain;
cursor: pointer;
} }
.list-item-main { .list-item-main {
line-height: 30px; line-height: 30px;
ol {
margin-left: 20px;
} }
.cover { li {
display: none; margin-top: 24px;
position: absolute; font-size: 16px;
left: 0; line-height: 1;
right: 0; color: var(--main-color);
top: 0; list-style: disc;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
.el-button {
width: 130px;
margin: 10px;
} }
p {
color: #666;
} }
.cover-inner { }
width: 100%; .list-item-title {
height: 100%; margin: 26px 0 36px;
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
align-items: center; h2 {
justify-content: center; flex: 1;
font-size: 18px;
font-family: Source Han Sans CN;
font-weight: bold;
line-height: 20px;
color: #333333;
}
h6 {
margin-left: 20px;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 500;
line-height: 20px;
color: var(--main-color);
}
} }
} }
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import type { BookItem } from '../types' import type { BookItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import ListItem from '../components/ListItem.vue' import ListItem from '../components/ListItem.vue'
import { getBookList } from '../api' import { getBookList } from '../api'
...@@ -11,13 +11,15 @@ const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.v ...@@ -11,13 +11,15 @@ const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.v
const { experiments, updateExperiments } = useGetExperimentList() const { experiments, updateExperiments } = useGetExperimentList()
updateExperiments() updateExperiments()
const route = useRoute()
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置 // 列表配置
const listOptions = $computed(() => { const listOptions = $computed(() => {
return { return {
remote: { remote: {
httpRequest: getBookList, httpRequest: getBookList,
params: { name: '', experiment_id: '' } params: { name: '', experiment_id: route.query.experiment_id || '' }
}, },
filters: [ filters: [
{ type: 'input', prop: 'name', label: '实验指导书名称', placeholder: '请输入实验指导书名称' }, { type: 'input', prop: 'name', label: '实验指导书名称', placeholder: '请输入实验指导书名称' },
...@@ -57,7 +59,7 @@ function onUpdateSuccess() { ...@@ -57,7 +59,7 @@ function onUpdateSuccess() {
<AppCard title="实验指导书管理"> <AppCard title="实验指导书管理">
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="handleAdd">新增实验指导书</el-button> <el-button type="primary" :icon="CirclePlus" @click="handleAdd">新增实验指导书</el-button>
</template> </template>
<template #body="{ data }"> <template #body="{ data }">
<div class="list-card" v-if="data.length"> <div class="list-card" v-if="data.length">
......
<script setup lang="ts"> <script setup lang="ts">
import { VideoPlay } from '@element-plus/icons-vue'
interface Props { interface Props {
data: any data: any
} }
...@@ -7,16 +8,19 @@ defineProps<Props>() ...@@ -7,16 +8,19 @@ defineProps<Props>()
<template> <template>
<div class="list-item"> <div class="list-item">
<div class="list-item-main"> <div class="list-item-pic">
<router-link :to="`/admin/lab/video/${data.id}`" target="_blank">
<img :src="data.cover" /> <img :src="data.cover" />
<p>{{ data.name }}</p> <el-icon><VideoPlay /></el-icon>
</router-link>
</div> </div>
<div class="cover"> <div class="list-item-main">
<div class="cover-inner"> <p>{{ data.name }}</p>
<div class="buttons">
<router-link :to="`/admin/lab/video/${data.id}`" target="_blank"> <router-link :to="`/admin/lab/video/${data.id}`" target="_blank">
<el-button type="primary" round plain auto-insert-space>查看</el-button> <el-button type="primary" auto-insert-space>查看</el-button>
</router-link> </router-link>
<el-button type="primary" round plain auto-insert-space @click="$emit('clickEdit', data)">编辑</el-button> <el-button plain auto-insert-space @click="$emit('clickEdit', data)" style="margin-left: 10px">编辑</el-button>
</div> </div>
</div> </div>
</div> </div>
...@@ -25,57 +29,65 @@ defineProps<Props>() ...@@ -25,57 +29,65 @@ defineProps<Props>()
<style lang="scss" scoped> <style lang="scss" scoped>
.list-item { .list-item {
position: relative; position: relative;
display: flex; height: 185px;
background: #f2f2f2; transition: all 0.25s ease-in-out;
border-radius: 5px; border-radius: 6px;
overflow: hidden; overflow: hidden;
&:hover { &:hover {
.cover { overflow: unset;
transform: scale(1.2);
z-index: 1;
.el-icon {
display: block; display: block;
} }
}
.list-item-main { .list-item-main {
top: 100%;
bottom: unset;
padding: 20px;
background-color: #fff;
p {
color: #000;
}
}
.buttons {
display: block;
}
}
}
.list-item-pic {
position: relative; position: relative;
width: 100%; height: 185px;
img { img {
width: 100%; width: 100%;
height: 200px; height: 100%;
object-fit: cover; object-fit: cover;
} }
p { .el-icon {
display: none;
font-size: 40px;
color: #fff;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.list-item-main {
position: absolute; position: absolute;
left: 0; left: 0;
bottom: 0;
right: 0; right: 0;
line-height: 40px; bottom: 0;
padding: 10px 16px;
p {
line-height: 1;
color: #fff; color: #fff;
padding: 0 10px;
background-color: rgba(0, 0, 0, 0.5);
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
} }
} .buttons {
.cover { margin-top: 16px;
display: none; display: none;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
.el-button {
width: 130px;
margin: 10px;
}
}
.cover-inner {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
} }
} }
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import type { VideoItem } from '../types' import type { VideoItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import ListItem from '../components/ListItem.vue' import ListItem from '../components/ListItem.vue'
import { getVideoList } from '../api' import { getVideoList } from '../api'
...@@ -11,13 +11,15 @@ const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.v ...@@ -11,13 +11,15 @@ const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.v
const { experiments, updateExperiments } = useGetExperimentList() const { experiments, updateExperiments } = useGetExperimentList()
updateExperiments() updateExperiments()
const route = useRoute()
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置 // 列表配置
const listOptions = $computed(() => { const listOptions = $computed(() => {
return { return {
remote: { remote: {
httpRequest: getVideoList, httpRequest: getVideoList,
params: { name: '', experiment_id: '' } params: { name: '', experiment_id: route.query.experiment_id || '' }
}, },
filters: [ filters: [
{ type: 'input', prop: 'name', label: '实验操作视频名称', placeholder: '请输入实验操作视频名称' }, { type: 'input', prop: 'name', label: '实验操作视频名称', placeholder: '请输入实验操作视频名称' },
...@@ -57,7 +59,7 @@ function onUpdateSuccess() { ...@@ -57,7 +59,7 @@ function onUpdateSuccess() {
<AppCard title="实验操作视频管理"> <AppCard title="实验操作视频管理">
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="handleAdd">新增操作视频</el-button> <el-button type="primary" :icon="CirclePlus" @click="handleAdd">新增操作视频</el-button>
</template> </template>
<template #body="{ data }"> <template #body="{ data }">
<div class="list-card" v-if="data.length"> <div class="list-card" v-if="data.length">
...@@ -73,7 +75,7 @@ function onUpdateSuccess() { ...@@ -73,7 +75,7 @@ function onUpdateSuccess() {
<style lang="scss" scoped> <style lang="scss" scoped>
.list-card { .list-card {
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(5, 1fr);
gap: 20px; gap: 20px;
} }
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import type { ExperimentItem, ClassItem, GroupItem } from '../types' import type { ExperimentItem, ClassItem, GroupItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import StudentGroupFormDialog from './StudentGroupFormDialog.vue' import StudentGroupFormDialog from './StudentGroupFormDialog.vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getExperimentClassGroupsList } from '../api' import { getExperimentClassGroupsList } from '../api'
...@@ -46,7 +46,7 @@ function handleRefetch() { ...@@ -46,7 +46,7 @@ function handleRefetch() {
</el-descriptions> </el-descriptions>
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="dialogVisible = true">新增分组</el-button> <el-button type="primary" round :icon="CirclePlus" @click="dialogVisible = true">新增分组</el-button>
</template> </template>
<template #table-x="{ row }"> <template #table-x="{ row }">
<el-button type="primary" link> <el-button type="primary" link>
......
<script setup lang="ts"> <script setup lang="ts">
import type { GroupItem, StudentItem } from '../types' import type { GroupItem, StudentItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
...@@ -71,9 +71,7 @@ function handleRemoveStudent(row: StudentItem) { ...@@ -71,9 +71,7 @@ function handleRemoveStudent(row: StudentItem) {
</el-descriptions> </el-descriptions>
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="selectStudentVisible = true" <el-button type="primary" round :icon="CirclePlus" @click="selectStudentVisible = true">添加小组成员</el-button>
>添加小组成员</el-button
>
</template> </template>
<template #table-x="{ row }"> <template #table-x="{ row }">
<el-button type="primary" round @click="handleRemoveStudent(row)">移除</el-button> <el-button type="primary" round @click="handleRemoveStudent(row)">移除</el-button>
......
<script setup lang="ts"> <script setup lang="ts">
import type { ExperimentItem } from '../types' import type { ExperimentItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getExperimentList } from '../api' import { getExperimentList } from '../api'
...@@ -60,7 +60,7 @@ function onUpdateSuccess() { ...@@ -60,7 +60,7 @@ function onUpdateSuccess() {
<AppCard title="实验管理"> <AppCard title="实验管理">
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="handleAdd">新增实验</el-button> <el-button type="primary" :icon="CirclePlus" @click="handleAdd">新增实验</el-button>
</template> </template>
<template #table-x="{ row }: { row: ExperimentItem }"> <template #table-x="{ row }: { row: ExperimentItem }">
......
<script setup lang="ts"> <script setup lang="ts">
import type { ExperimentItem, ClassItem } from '../types' import type { ExperimentItem, ClassItem } from '../types'
import { CirclePlusFilled } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
...@@ -81,7 +81,7 @@ function handleRemoveClass(row: ClassItem) { ...@@ -81,7 +81,7 @@ function handleRemoveClass(row: ClassItem) {
</el-descriptions> </el-descriptions>
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" round :icon="CirclePlusFilled" @click="selectClassVisible = true">关联班级</el-button> <el-button type="primary" :icon="CirclePlus" @click="selectClassVisible = true">关联班级</el-button>
</template> </template>
<template #table-x="{ row }"> <template #table-x="{ row }">
<el-button type="primary" round @click="handleViewStudent(row)">查看学生</el-button> <el-button type="primary" round @click="handleViewStudent(row)">查看学生</el-button>
......
...@@ -4,3 +4,8 @@ import httpRequest from '@/utils/axios' ...@@ -4,3 +4,8 @@ import httpRequest from '@/utils/axios'
export function getTopInfo() { export function getTopInfo() {
return httpRequest.get('/api/lab/v1/common/permission/top') return httpRequest.get('/api/lab/v1/common/permission/top')
} }
// 获取实验列表
export function getExperimentList() {
return httpRequest.get('/api/lab/v1/teacher/index/index')
}
<script setup lang="ts"></script> <script setup lang="ts">
import type { ExperimentItem } from '../types'
import { getExperimentList } from '../api'
const router = useRouter()
let list = $ref<ExperimentItem[]>([])
function fetchList() {
getExperimentList().then(res => {
list = res.data.list
})
}
onMounted(() => {
fetchList()
})
function handleChange(id: string, type: number) {
if (type === 1) {
router.push({ path: '/admin/lab/book', query: { experiment_id: id } })
} else if (type === 2) {
router.push({ path: '/admin/lab/video', query: { experiment_id: id } })
}
}
</script>
<template> <template>
<div class="bg"></div> <div class="bg"></div>
<el-select placeholder="实验指导书"> </el-select> <div class="select-group">
<el-select placeholder="实验视频"> </el-select> <el-select size="large" placeholder="实验指导书" @change="handleChange($event, 1)">
<el-select placeholder="实验答疑"> </el-select> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
<el-select placeholder="实验成绩"> </el-select> </el-select>
<el-select placeholder="大赛评分"> </el-select> <el-select size="large" placeholder="实验视频" @change="handleChange($event, 2)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<!-- <el-select size="large" placeholder="实验答疑" @change="handleChange($event, 3)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-select size="large" placeholder="实验成绩" @change="handleChange($event, 4)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-select size="large" placeholder="大赛评分" @change="handleChange($event, 5)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> -->
</div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.bg { .bg {
margin: 40px; margin: 20px 0;
background: url(@/assets/images/home_bg.png) no-repeat center center; background: url(@/assets/images/home_bg.png) no-repeat center center;
background-size: contain; background-size: contain;
height: 636px; height: 636px;
} }
.select-group {
position: fixed;
bottom: 40px;
.el-select {
width: 144px;
:deep(.el-input__wrapper) {
box-shadow: none;
}
}
.el-select + .el-select {
margin-left: 20px;
}
}
</style> </style>
<script setup lang="ts"></script> <script setup lang="ts">
import type { ExperimentItem } from '../types'
import { getExperimentList } from '../api'
const router = useRouter()
let list = $ref<ExperimentItem[]>([])
function fetchList() {
getExperimentList().then(res => {
list = res.data.list
})
}
onMounted(() => {
fetchList()
})
function handleChange(id: string, type: number) {
if (type === 1) {
router.push({ path: '/admin/lab/book', query: { experiment_id: id } })
} else if (type === 2) {
router.push({ path: '/admin/lab/video', query: { experiment_id: id } })
}
}
</script>
<template> <template>
<div class="bg"></div> <div class="bg"></div>
<el-select placeholder="我的实验课程"> </el-select> <div class="select-group">
<el-select placeholder="我的陪练项目"> </el-select> <el-select size="large" placeholder="我的实验课程" @change="handleChange($event, 1)">
<el-select placeholder="我的大赛项目"> </el-select> <el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
<el-select placeholder="我的大赛成绩"> </el-select> </el-select>
<el-select size="large" placeholder="我的陪练项目" @change="handleChange($event, 2)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-select size="large" placeholder="我的大赛项目" @change="handleChange($event, 3)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-select size="large" placeholder="我的大赛成绩" @change="handleChange($event, 4)">
<el-option v-for="item in list" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.bg { .bg {
margin: 20px 0;
background: url(@/assets/images/home_bg.png) no-repeat center center; background: url(@/assets/images/home_bg.png) no-repeat center center;
background-size: contain; background-size: contain;
height: 636px; height: 636px;
} }
.select-group {
position: fixed;
bottom: 40px;
.el-select {
width: 144px;
:deep(.el-input__wrapper) {
box-shadow: none;
}
}
.el-select + .el-select {
margin-left: 20px;
}
}
</style> </style>
export interface ExperimentItem {
id: string
name: string
}
<script setup lang="ts"> <script setup lang="ts">
import Total from '../components/Total.vue' import Total from '../components/Total.vue'
// import StudentHome from '../components/StudentHome.vue' import { useUserStore } from '@/stores/user'
import AdminHome from '../components/AdminHome.vue' const userStore = useUserStore()
const StudentHome = defineAsyncComponent(() => import('../components/StudentHome.vue'))
const AdminHome = defineAsyncComponent(() => import('../components/AdminHome.vue'))
</script> </script>
<template> <template>
<div class="home">
<Total></Total> <Total></Total>
<AdminHome></AdminHome> <AdminHome v-if="userStore.role?.id === 5"></AdminHome>
<StudentHome v-else></StudentHome>
</div>
</template> </template>
<style lang="scss" scoped>
.home {
margin: 0 30px;
}
</style>
import type { IMenuItem } from '@/types' import type { IMenuItem } from '@/types'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { Notebook, VideoCamera, ChatSquare, Finished, ScaleToOriginal } from '@element-plus/icons-vue' import { Notebook, VideoCamera, ChatSquare, Finished, ScaleToOriginal } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
interface State { interface State {
studentMenus: IMenuItem[] studentMenus: IMenuItem[]
...@@ -13,6 +14,14 @@ const studentMenus: IMenuItem[] = [ ...@@ -13,6 +14,14 @@ const studentMenus: IMenuItem[] = [
name: '智能营销', name: '智能营销',
path: '/student/lab' path: '/student/lab'
}, },
{
name: '智能陪练',
path: '/student/ai'
},
{
name: '成绩分析',
path: '/admin/contest/score'
},
{ {
name: '技能大赛', name: '技能大赛',
path: '/student/contest' path: '/student/contest'
...@@ -46,14 +55,18 @@ const adminMenus: IMenuItem[] = [ ...@@ -46,14 +55,18 @@ const adminMenus: IMenuItem[] = [
} }
] ]
}, },
// { {
// name: '技能大赛', name: '智能陪练',
// path: '/admin/contest' path: '/admin/ai'
// }, },
// { {
// name: '大赛成绩', name: '成绩分析',
// path: '/admin/contest/score' path: '/admin/contest/score'
// }, },
{
name: '技能大赛',
path: '/admin/contest'
},
{ {
name: '系统管理', name: '系统管理',
path: '/admin/system', path: '/admin/system',
...@@ -74,7 +87,10 @@ export const useMenuStore = defineStore({ ...@@ -74,7 +87,10 @@ export const useMenuStore = defineStore({
adminMenus adminMenus
}), }),
getters: { getters: {
menus: state => state.adminMenus menus: state => {
const userStore = useUserStore()
return userStore.role?.id === 5 ? state.adminMenus : state.studentMenus
}
}, },
actions: {} actions: {}
}) })
...@@ -2,8 +2,14 @@ import { defineStore } from 'pinia' ...@@ -2,8 +2,14 @@ import { defineStore } from 'pinia'
import { getUser, logout } from '@/api/base' import { getUser, logout } from '@/api/base'
import type { UserType, ProjectType, OrganizationType, RoleType, PermissionType } from '@/types' import type { UserType, ProjectType, OrganizationType, RoleType, PermissionType } from '@/types'
// 角色信息(1学员;5教师)
interface Role {
id: 1 | 5
name: string
}
interface State { interface State {
user: UserType | null user: UserType | null
role: Role | null
project: ProjectType | null project: ProjectType | null
organization: OrganizationType | null organization: OrganizationType | null
roles: RoleType[] roles: RoleType[]
...@@ -14,6 +20,7 @@ export const useUserStore = defineStore({ ...@@ -14,6 +20,7 @@ export const useUserStore = defineStore({
id: 'user', id: 'user',
state: (): State => ({ state: (): State => ({
user: null, user: null,
role: null,
organization: null, organization: null,
project: null, project: null,
roles: [], roles: [],
...@@ -25,9 +32,10 @@ export const useUserStore = defineStore({ ...@@ -25,9 +32,10 @@ export const useUserStore = defineStore({
actions: { actions: {
async getUser() { async getUser() {
const res = await getUser() const res = await getUser()
const { info } = res.data const { info, role } = res.data
const { organization, project, roles, permissions } = res.data.permissions const { organization, project, roles = [], permissions = [] } = res.data.permissions || {}
this.user = info this.user = info
this.role = role
this.organization = organization this.organization = organization
this.project = project this.project = project
this.roles = roles this.roles = roles
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论