| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <template>
- <div class="app-container submenu-container">
- <div class="page-header">
- <h2>{{ moduleTitle }}</h2>
- <p>请选择具体功能</p>
- </div>
- <div class="submenu-grid">
- <div
- v-for="item in menuItems"
- :key="item.path"
- class="submenu-card"
- @click="handleItemClick(item)"
- >
- <div class="submenu-icon">
- <svg-icon v-if="item.meta && item.meta.icon" :icon-class="item.meta.icon" class="icon" />
- <i v-else class="el-icon-document icon"></i>
- </div>
- <div class="submenu-title">{{ item.meta ? item.meta.title : item.name }}</div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { mapGetters } from 'vuex'
- export default {
- name: 'ModuleSubmenu',
- data() {
- return {
- moduleTitle: '',
- menuItems: []
- }
- },
- computed: {
- ...mapGetters(['sidebarRouters'])
- },
- created() {
- this.loadMenuItems()
- },
- watch: {
- '$route.query': {
- handler() {
- this.loadMenuItems()
- },
- deep: true
- }
- },
- methods: {
- loadMenuItems() {
- const { modulePath, moduleTitle } = this.$route.query
- this.moduleTitle = moduleTitle || '功能菜单'
- // 查找对应的菜单项
- this.menuItems = this.findMenuItems(modulePath)
- },
- findMenuItems(modulePath) {
- // 从系统菜单查找
- if (this.sidebarRouters && this.sidebarRouters.length > 0) {
- for (const route of this.sidebarRouters) {
- if (route.path === modulePath && route.children) {
- // 返回系统模块的子菜单,确保路径完整
- return route.children
- .filter(child => !child.hidden)
- .map(child => {
- // 如果路径是相对路径,需要拼接父路径
- const fullPath = child.path.startsWith('/') ? child.path : `${route.path}/${child.path}`
- return {
- ...child,
- path: fullPath
- }
- })
- }
- }
- }
- return []
- },
- handleItemClick(item) {
- this.$router.push(item.path)
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .submenu-container {
- .page-header {
- text-align: center;
- margin-bottom: 48px;
- padding: 32px 24px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 16px;
- box-shadow: 0 8px 32px 0 rgba(102, 126, 234, 0.2);
- h2 {
- font-size: 32px;
- font-weight: 700;
- color: #ffffff;
- margin-bottom: 12px;
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- }
- p {
- font-size: 16px;
- color: rgba(255, 255, 255, 0.9);
- font-weight: 300;
- }
- }
- .submenu-grid {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
- gap: 24px;
- .submenu-card {
- background: #ffffff;
- border-radius: 12px;
- padding: 32px 24px;
- text-align: center;
- cursor: pointer;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- border: 2px solid transparent;
- box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.08);
- position: relative;
- overflow: hidden;
- &::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 4px;
- background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
- transform: scaleX(0);
- transition: transform 0.3s ease;
- }
- &:hover {
- background: #ffffff;
- border-color: transparent;
- transform: translateY(-8px);
- box-shadow: 0 12px 32px 0 rgba(102, 126, 234, 0.25);
- &::before {
- transform: scaleX(1);
- }
- .submenu-icon {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- transform: scale(1.1) rotate(5deg);
- box-shadow: 0 8px 24px rgba(102, 126, 234, 0.3);
- ::v-deep(.svg-icon),
- .icon {
- color: #ffffff;
- }
- }
- .submenu-title {
- color: #667eea;
- }
- }
- .submenu-icon {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 72px;
- height: 72px;
- border-radius: 16px;
- background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
- margin: 0 auto 20px;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
- ::v-deep(.svg-icon) {
- font-size: 36px;
- color: #606266;
- transition: color 0.3s ease;
- }
- .icon {
- font-size: 36px;
- color: #606266;
- transition: color 0.3s ease;
- }
- }
- .submenu-title {
- font-size: 17px;
- font-weight: 600;
- color: #303133;
- transition: color 0.3s ease;
- line-height: 1.5;
- }
- }
- }
- // 响应式布局
- @media (max-width: 1200px) {
- .submenu-grid {
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
- gap: 20px;
- }
- }
- @media (max-width: 768px) {
- .page-header {
- margin-bottom: 32px;
- padding: 24px 16px;
- h2 {
- font-size: 24px;
- }
- p {
- font-size: 14px;
- }
- }
- .submenu-grid {
- grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
- gap: 16px;
- .submenu-card {
- padding: 28px 20px;
- .submenu-icon {
- width: 60px;
- height: 60px;
- margin-bottom: 16px;
- ::v-deep(.svg-icon),
- .icon {
- font-size: 30px;
- }
- }
- .submenu-title {
- font-size: 15px;
- }
- }
- }
- }
- }
- </style>
|