feat:增加移动端布局
This commit is contained in:
@@ -220,49 +220,6 @@ const submitForm = async () => {
|
||||
.md-editor {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.generate-question {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
.generate-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.question-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
.question-card {
|
||||
.el-card__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.question-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.question-options {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.question-answer {
|
||||
color: #67c23a;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.question-action {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
</div>
|
||||
|
||||
<div class="card-actions">
|
||||
<el-button type="primary" :icon="Edit" @click="editClick(file)">编辑</el-button>
|
||||
<el-button type="primary" v-if="!appStore.isMobile"
|
||||
:icon="Edit" @click="editClick(file)">编辑</el-button>
|
||||
<el-button type="primary" :icon="Aim" @click="trainClick(file)">训练</el-button>
|
||||
<el-button type="danger" :icon="Delete">删除</el-button>
|
||||
<el-button type="danger" v-if="!appStore.isMobile"
|
||||
:icon="Delete">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,6 +32,7 @@ import { Delete, Edit, Picture, Document, Aim } from '@element-plus/icons-vue'
|
||||
import { useLibraryStore } from '@/stores/library.ts'
|
||||
import { usePracticeStore } from '@/stores/practice.ts'
|
||||
import { useQuestionStore } from '@/stores/question.ts'
|
||||
import { useAppStore } from '@/stores/app.ts'
|
||||
import type { ILibraryFile } from '@/types/library.ts'
|
||||
import LibraryFilter from '@/components/Library/LibraryFilter.vue'
|
||||
import { computed } from 'vue'
|
||||
@@ -40,6 +43,7 @@ import { ElLoading, ElMessage } from 'element-plus'
|
||||
const libraryStore = useLibraryStore()
|
||||
const practiceStore = usePracticeStore()
|
||||
const questionStore = useQuestionStore()
|
||||
const appStore = useAppStore()
|
||||
|
||||
const filterLibraryFileList = computed(() => {
|
||||
const subject = libraryStore.selectedSubject
|
||||
|
||||
@@ -119,7 +119,7 @@ const addMistakeList = async () => {
|
||||
gap: 16px;
|
||||
|
||||
.question-list {
|
||||
padding: 10px;
|
||||
padding: 0 10px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
|
||||
|
||||
16
src/layout/AppLogo.vue
Normal file
16
src/layout/AppLogo.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="logo" @click="refreshClick">
|
||||
<span v-if="!appStore.isCollapse">🧠 智能学习助手</span>
|
||||
<span v-else>🧠</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/stores/app.ts'
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const refreshClick = () => {
|
||||
location.reload()
|
||||
}
|
||||
</script>
|
||||
35
src/layout/AppMenu.vue
Normal file
35
src/layout/AppMenu.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<el-menu
|
||||
:default-active="route.path"
|
||||
:collapse="appStore.isCollapse"
|
||||
:collapse-transition="false"
|
||||
router
|
||||
class="side-menu"
|
||||
>
|
||||
<el-menu-item index="/library">
|
||||
<el-icon><Reading /></el-icon>
|
||||
<template #title>知识库</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/exam">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
<template #title>考试中心</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/mistakes">
|
||||
<el-icon><Notebook /></el-icon>
|
||||
<template #title>错题本</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/stats">
|
||||
<el-icon><DataLine /></el-icon>
|
||||
<template #title>数据统计</template>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DataLine, EditPen, Notebook, Reading } from '@element-plus/icons-vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useAppStore } from '@/stores/app.ts'
|
||||
|
||||
const route = useRoute()
|
||||
const appStore = useAppStore()
|
||||
</script>
|
||||
@@ -1,50 +1,29 @@
|
||||
<template>
|
||||
<el-container class="layout-container">
|
||||
<!-- 侧边栏 -->
|
||||
<el-aside :width="isCollapse ? '64px' : '150px'" class="aside">
|
||||
<!-- Logo -->
|
||||
<div class="logo" @click="refreshClick">
|
||||
<span v-if="!isCollapse">🧠 智能学习助手</span>
|
||||
<span v-else>🧠</span>
|
||||
</div>
|
||||
<el-drawer
|
||||
v-if="appStore.isMobile"
|
||||
v-model="appStore.drawerVisible"
|
||||
direction="ltr"
|
||||
size="180px"
|
||||
:with-header="false"
|
||||
>
|
||||
<app-logo />
|
||||
<app-menu />
|
||||
</el-drawer>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<el-menu
|
||||
:default-active="route.path"
|
||||
:collapse="isCollapse"
|
||||
:collapse-transition="false"
|
||||
router
|
||||
class="side-menu"
|
||||
>
|
||||
<el-menu-item index="/library">
|
||||
<el-icon><Reading /></el-icon>
|
||||
<template #title>知识库</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/exam">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
<template #title>考试中心</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/mistakes">
|
||||
<el-icon><Notebook /></el-icon>
|
||||
<template #title>错题本</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/stats">
|
||||
<el-icon><DataLine /></el-icon>
|
||||
<template #title>数据统计</template>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-aside v-else :width="appStore.isCollapse ? '64px' : '150px'" class="aside">
|
||||
<app-logo />
|
||||
<app-menu />
|
||||
</el-aside>
|
||||
|
||||
<el-container>
|
||||
<!-- 顶部栏 -->
|
||||
<el-header class="header">
|
||||
<div class="header-left">
|
||||
<!-- 折叠按钮 -->
|
||||
<el-icon class="collapse-btn" @click="isCollapse = !isCollapse">
|
||||
<Fold v-if="!isCollapse" />
|
||||
<el-icon class="collapse-btn" @click="collapseClick">
|
||||
<Fold v-if="!appStore.isCollapse" />
|
||||
<Expand v-else />
|
||||
</el-icon>
|
||||
<!-- 面包屑 -->
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{ route.meta.title }}</el-breadcrumb-item>
|
||||
@@ -52,13 +31,11 @@
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
<!-- 通知铃铛 -->
|
||||
<el-badge :value="3">
|
||||
<el-icon :size="18"><Bell /></el-icon>
|
||||
</el-badge>
|
||||
|
||||
<!-- 用户信息 -->
|
||||
<el-dropdown>
|
||||
<el-dropdown trigger="click">
|
||||
<el-avatar :size="32" class="avatar">潘</el-avatar>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
@@ -84,16 +61,33 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import AppLogo from '@/layout/AppLogo.vue'
|
||||
import AppMenu from '@/layout/AppMenu.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useAppStore } from '@/stores/app.ts'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { Reading, EditPen, Notebook, DataLine, Fold, Expand, Bell } from '@element-plus/icons-vue'
|
||||
import { Fold, Expand, Bell } from '@element-plus/icons-vue'
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const route = useRoute()
|
||||
const isCollapse = ref(false)
|
||||
const appStore = useAppStore()
|
||||
|
||||
const refreshClick = () => {
|
||||
location.reload()
|
||||
const checkScreen = () => {
|
||||
appStore.isMobile = window.innerWidth < 768
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkScreen()
|
||||
window.addEventListener('resize', checkScreen)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', checkScreen)
|
||||
})
|
||||
|
||||
const collapseClick = () => {
|
||||
// appStore.isCollapse = !appStore.isCollapse
|
||||
appStore.drawerVisible = !appStore.drawerVisible
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
@@ -116,21 +110,27 @@ const handleLogout = () => {
|
||||
border-right: 1px solid #e2e8f0;
|
||||
transition: width 0.3s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #14b8a6;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.logo {
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #14b8a6;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
border-right: none;
|
||||
.side-menu {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.el-drawer {
|
||||
.el-drawer__body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
src/stores/app.ts
Normal file
11
src/stores/app.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useAppStore = defineStore('app', {
|
||||
state: () => ({
|
||||
isMobile: false,
|
||||
isCollapse: false,
|
||||
drawerVisible: false
|
||||
}),
|
||||
actions: {
|
||||
}
|
||||
})
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="view-header">
|
||||
<div class="view-content">
|
||||
<h2 class="view-title">考试中心</h2>
|
||||
<p class="view-subtitle">按学科进行综合检验,模拟真实考试环境</p>
|
||||
<p class="view-subtitle">模拟真实考试环境</p>
|
||||
</div>
|
||||
<el-button type="primary" :icon="Aim" @click="examClick">开始考试</el-button>
|
||||
</div>
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
<div class="view-header">
|
||||
<div class="view-content">
|
||||
<h2 class="view-title">知识库</h2>
|
||||
<p class="view-subtitle">管理学习资料,查看 AI 解析结果</p>
|
||||
<p class="view-subtitle">管理学习资料</p>
|
||||
</div>
|
||||
<el-button type="primary" :icon="Plus" @click="addFileClick">新增资料</el-button>
|
||||
<el-button v-if="!appStore.isMobile"
|
||||
type="primary" :icon="Plus" @click="addFileClick">新增资料</el-button>
|
||||
</div>
|
||||
|
||||
<library-file-list />
|
||||
@@ -24,10 +25,12 @@ import LibraryFileDialog from '@/components/Library/LibraryFileDialog.vue'
|
||||
import LibraryFileTrainDialog from '@/components/Library/LibraryFileTrainDialog.vue'
|
||||
import LibraryFileContentDialog from '@/components/Library/LibraryFileContentDialog.vue'
|
||||
import { useLibraryStore } from '@/stores/library.ts'
|
||||
import { useAppStore } from '@/stores/app.ts'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
const libraryStore = useLibraryStore()
|
||||
const appStore = useAppStore()
|
||||
|
||||
onMounted(async () => {
|
||||
await libraryStore.queryFileList()
|
||||
|
||||
Reference in New Issue
Block a user