Browse Source

菜单新增快捷入口,首页对接常用入口

zhangchong 2 years ago
parent
commit
3c4fe1e49f

+ 23 - 12
src/api/home/index.ts

@@ -4,31 +4,42 @@
  * @version:
  * @Date: 2022-08-26 14:43:12
  * @LastEditors: Please set LastEditors
- * @LastEditTime: 2022-11-10 11:49:34
+ * @LastEditTime: 2022-11-25 11:43:42
  */
 import request from '/@/utils/request';
 
 /**
- * @description: 获取分机列表
- * @param {object} params
+ * @description: 获取我的快捷入口
+ * @param {object} 
  * @return {*}
  */
-export const getTelsList = (params?: object) => {
+ export const geFastMenu = () => {
     return request({
-        url: '/api/v1/Tel/tels-frequency',
+        url: '/api/v1/Home/get-myfastmenu',
         method: 'get',
-        params: params,
     });
 };
 /**
- * @description: 根据设备自动同步分机数据到数据库
- * @param {object} params
+ * @description: 获取可选快捷入口
+ * @param {object} data
  * @return {*}
  */
-export const syncTel = (params?: object) => {
+ export const fastMenu = (data:object) => {
     return request({
-        url: '/api/v1/Pbx/sync-tels',
-        method: 'put',
-        data: params,
+        url: '/api/v1/Home/get-fastmenu',
+        method: 'post',
+        data
+    });
+};
+/**
+ * @description: 设置快捷入口
+ * @param {object} data
+ * @return {*}
+ */
+ export const setFastMenu = (data:object) => {
+    return request({
+        url: '/api/v1/Home/set-fastmenu',
+        method: 'post',
+        data
     });
 };

+ 4 - 3
src/components/AudioPlayer/index.vue

@@ -2,7 +2,9 @@
     <div class="glowe-audio">
         <div class="audio">
             <div class="icon-div">
-                <SvgIcon  @click="playPauseAudio" :name="audioData.playing ? 'ele-VideoPause' : 'ele-VideoPlay'" class="mr10 icon" size="24px" color="var(--el-color-primary)"/>
+                <SvgIcon  @click="playPauseAudio" :name="audioData.playing ? 'ele-VideoPause' : 'ele-VideoPlay'"
+                :title="audioData.playing ? '暂停' : '播放'"
+                class="mr10 icon" size="24px" color="var(--el-color-primary)"/>
                 <div class="time-wrap">
                     <span class="time">{{ formatDuraton(Math.round(audioData.currentTime)) }}/{{formatDuraton(Math.round(audioData.duration))}}</span>
                 </div>
@@ -20,8 +22,7 @@
                         </el-dropdown-menu>
                     </template>
             </el-dropdown>
- 
-            <SvgIcon name="ele-Download" class="download ml5" size="18px" color="var(--el-color-primary)" @click="downLoad"/>
+            <SvgIcon name="ele-Download" class="download ml5" size="18px" color="var(--el-color-primary)" @click="downLoad" title="下载"/>
         </div>
         <audio :src="audioData.url" preload="auto" @ended="audioEnded" @timeupdate="audioTimeupdate" @loadeddata="audioLoadeddata" ref="audioRef"></audio>
     </div>

+ 1 - 1
src/components/iconSelector/index.vue

@@ -48,7 +48,7 @@
 									<div class="icon-selector-warp-item" :class="{ 'icon-selector-active': fontIconPrefix === v }">
 										<div class="flex-margin">
 											<div class="icon-selector-warp-item-value">
-												<SvgIcon :name="v" class="mr5"/><span>{{v}}</span>
+												<SvgIcon :name="v" class="mr5"/>
 											</div>
 										</div>
 									</div>

+ 1 - 1
src/router/backEnd.ts

@@ -46,7 +46,7 @@ function formatRouter(arr:Array<any>){
 		v.meta.isAffix = v.isAffix;
 		v.meta.isLink = v.link;
 		v.meta.isIframe = v.isIframe;
-		if(v.children.length) {
+		if(v.children?.length) {
 			formatRouter(v.children)
 		}
 	});

+ 1 - 1
src/stores/themeConfig.ts

@@ -123,7 +123,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 			 * 后端控制路由
 			 */
 			// 是否开启后端控制路由
-			isRequestRoutes: false,
+			isRequestRoutes: true,
 
 			/**
 			 * 全局网站标题 / 副标题

+ 15 - 0
src/theme/app.scss

@@ -246,6 +246,10 @@ ul,li{
 	width: 100%;
 	overflow: hidden;
 }
+.flex-center-align{
+	display: flex;
+	align-items: center;
+}
 .flex-center-center{
 	display: flex;
 	align-items: center;
@@ -394,4 +398,15 @@ ul,li{
 //  表单内标题的字体大小
 .formTitle{
 	font-size: var(--el-font-size-medium);
+}
+// 选择图片下拉
+.item-Img{
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	height: 100%;
+	img{
+		width: 20px;
+		height: 20px;
+	}
 }

+ 3 - 1
src/views/deviceManagement/ivrCategroy/index.vue

@@ -52,7 +52,9 @@ export default {
         const { userInfos } = storeToRefs(storesUserInfo);
         if(!userInfos.value.authBtnList.includes('300301')){ // 没有授权直接跳转到401
             next('/401')
-        }
+        }else{
+			next();
+		}
    }
 }
 </script>

+ 49 - 116
src/views/home/component/entrance.vue

@@ -10,8 +10,8 @@
                                 v-for="(item, index) in entranceList" :key="index"
                                 class="entrance-list-box-item animate__animated animate__fadeInUp" :data-id="item.id"
                                 >
-                                <img v-lazy="getImageUrl(item.url)" alt="" class="my-handle"/>
-                                <p>{{ item.name }}</p>
+                                <img v-lazy="getImageUrl(item.fastIcon)" alt="" class="my-handle"/>
+                                <p class="entrance-list-box-item-name">{{ item.pageName }}</p>
                                 <SvgIcon name="ele-RemoveFilled" class="plus-icon location" color="#ccc" size="24px"
                                     @click="removeOne(item)" />
                             </li>
@@ -25,7 +25,7 @@
                     <span>系统功能</span>
                     <el-input v-model="searchKey" :prefix-icon="Search" placeholder="请输入关键字" class="input">
                         <template #suffix>
-                            <el-button type="primary" size="small" round @click="search">搜索</el-button>
+                            <el-button type="primary" size="small" round @click="getEntranceSelect">搜索</el-button>
                         </template>
                     </el-input>
                 </p>
@@ -33,8 +33,8 @@
                     <template v-if="entranceSelect.length">
                         <ul class="entrance-list-box">
                             <li class="entrance-list-box-item animate__animated animate__fadeInDown" v-for="(item, index) in entranceSelect" :key="index">
-                                <img v-lazy="getImageUrl(item.url)" alt="" />
-                                <p>{{ item.name }}</p>
+                                <img v-lazy="getImageUrl(item.fastIcon)" alt="" class="mb10"/>
+                                <p class="entrance-list-box-item-name">{{ item.pageName }}</p>
                                 <SvgIcon name="ele-CirclePlusFilled" class="remove-icon location" color="var(--el-color-primary)" size="24px" @click="plusOne(item)" />
                             </li>
                         </ul>
@@ -54,9 +54,10 @@
 
 <script lang="ts" setup>
 import { reactive, toRefs } from 'vue';
-// import {  ElMessage } from 'element-plus';
+import {  ElMessage } from 'element-plus';
 import { Search } from '@element-plus/icons-vue';
 import { getImageUrl } from "/@/utils/tools";
+import { geFastMenu,fastMenu,setFastMenu } from '/@/api/home';
 import Sortable from 'sortablejs';
 interface stateBacklist {
     isShowDialog: boolean;
@@ -70,114 +71,22 @@ interface stateBacklist {
 const state = reactive<stateBacklist>({
     isShowDialog: false,
     searchKey: '',
-    entranceList: [
-        {
-            name: "工单回访",
-            url: "home/gdhf.png",
-            id: Math.random()
-        },
-        {
-            name: "全部工单",
-			url: "home/qbgd.png",
-            id: Math.random()
-        },
-        {
-			name: "业务查询",
-			url: "home/ywcx.png",
-			id:Math.random()
-		},
-        {
-            name: "甄别管理",
-			url: "home/zbgl.png",
-            id: Math.random()
-        },
-        {
-            name: "工单回访",
-            url: "home/gdhf.png",
-            id: Math.random()
-        },
-        {
-            name: "受理列表",
-			url: "home/sllb.png",
-            id: Math.random()
-        },{
-            name: "工单回访",
-            url: "home/gdhf.png",
-            id: Math.random()
-        },
-        {
-            name: "全部工单",
-			url: "home/qbgd.png",
-            id: Math.random()
-        },
-        {
-            name: "甄别管理",
-			url: "home/zbgl.png",
-            id: Math.random()
-        },
-        {
-            name: "工单回访",
-            url: "home/gdhf.png",
-            id: Math.random()
-        },
-        {
-            name: "受理列表",
-			url: "home/sllb.png",
-            id: Math.random()
-        },
-    ],
+    entranceList: [],
     sortEntranceList:[],
-    entranceSelect: [
-        {
-            name: "受理列表",
-            url: "home/qbgd.png",
-            id: 2
-        },
-        {
-            name: "甄别管理",
-			url: "home/zbgl.png",
-            id: Math.random()
-        },
-        {
-            name: "工单回访",
-            url: "home/gdhf.png",
-            id: Math.random()
-        },
-        {
-			name: "业务查询",
-			url: "home/ywcx.png",
-			id:Math.random()
-		},
-        {
-            name: "受理列表",
-			url: "home/sllb.png",
-            id: Math.random()
-        },
-        {
-            name: "甄别管理",
-			url: "home/zbgl.png",
-            id: Math.random()
-        },
-        {
-            name: "工单回访",
-            url: "home/gdhf.png",
-            id: Math.random()
-        },
-        {
-            name: "受理列表",
-			url: "home/sllb.png",
-            id: Math.random()
-        },
-    ],
+    entranceSelect: [],
     loading: false,
     sortable:'',
 })
 const { isShowDialog, searchKey, entranceList, entranceSelect, loading } = toRefs(state);
-const emit = defineEmits(['updateList', 'openDialog', 'closeDialog'])
+const emit = defineEmits(['updateEntrance', 'openDialog', 'closeDialog'])
+// 打开弹窗
 const openDialog = () => {
     state.isShowDialog = true;
+    getEntrance();
+    getEntranceSelect();
     emit('openDialog')
 }
+// 打开完成
 const opened = ()=>{
     initSortable();
 }
@@ -205,6 +114,18 @@ const initSortable = ()=>{
         },
     });
 }
+// 获取我的入口
+const getEntrance = ()=>{
+    geFastMenu().then((res:any)=>{
+		state.entranceList = res?.result ?? [];
+	})
+}
+// 获取可选入口
+const getEntranceSelect = ()=>{
+    fastMenu({name:state.searchKey}).then((res:any)=>{
+		state.entranceSelect = res?.result ?? [];
+	})
+}
 // 移除
 const removeOne = (val: any) => {
     state.entranceList = state.entranceList.filter((i: any) => i.id !== val.id);
@@ -214,20 +135,26 @@ const removeOne = (val: any) => {
 const plusOne = (val: any) => {
     state.entranceList.push(val)
     state.entranceSelect = state.entranceSelect.filter((i: any) => i.id !== val.id);
-}
-// 搜索
-const search = () => {
-
 }
 // 保存
 const onSubmit = () => {
-
-    // addBlacklist(state.ruleForm).then(()=>{
-    //     ElMessage.success("新增成功")
-    //     emit("updateList");
-    //     isShowDialog.value = false;
-    // })
-
+    let req:string[];
+    if(state.sortEntranceList.length){
+       req = state.entranceList.map((item:any)=>{
+            return item.permissionCode;
+        })
+    }else{
+        req = state.entranceList.map((item:any)=>{
+            return item.permissionCode;
+        })
+    }
+    setFastMenu({fastMenuArr:req}).then(()=>{
+        ElMessage.success("操作成功")
+        emit("updateEntrance");
+        isShowDialog.value = false;
+    }).catch(()=>{
+        isShowDialog.value = false;
+    })
 }
 defineExpose({ closeDialog, openDialog }) //暴漏方法
 </script>
@@ -268,6 +195,12 @@ defineExpose({ closeDialog, openDialog }) //暴漏方法
                     right: -5px;
                     cursor: pointer;
                 }
+                &-name{
+                    width: 70px;
+                    overflow: hidden;
+                     white-space: nowrap;
+                    text-overflow:ellipsis;
+                }
             }
         }
     }

+ 30 - 82
src/views/home/index.vue

@@ -1,6 +1,5 @@
 <template>
 	<div class="home-container layout-pd">
-		<AudioPlayer :url="url"/>
 		<el-row :gutter="20">
 			<el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16" class="left-content">
 				<el-row :gutter="20">
@@ -95,9 +94,9 @@
 					</div>
 				</div>
 			</el-col>
-
+			<!-- 常用入口 -->
 			<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8" class="right-content">
-				<div class="right-entrance box w100" v-loading="loading">
+				<div class="right-entrance box w100" v-loading="entranceLoading">
 					<p class="right-entrance-title">常用入口
 						<span @click="customEntry">
 							<SvgIcon name="ele-Setting" class="mr5"/>自定义
@@ -105,9 +104,9 @@
 					</p>
 					<template v-if="entranceList.length">
 						<ul class="right-entrance-list">
-							<li class="right-entrance-list-item" v-for="(item, index) in entranceList" :key="index" :data-id="item.id">
-								<img v-lazy="getImageUrl(item.url)" alt="" class="my-handle"/>
-								<p>{{ item.name }}</p>
+							<li class="right-entrance-list-item" v-for="(item, index) in entranceList" :key="index" :data-id="item.id" @click="goLink(item.path)">
+								<img v-lazy="getImageUrl(item.fastIcon)" alt="" class="my-handle"/>
+								<p>{{ item.pageName }}</p>
 							</li>
 						</ul>
 					</template>
@@ -137,66 +136,22 @@
 				</div>
 			</el-col>
 		</el-row>
-		<Entrance ref="entranceRef" @updateList="getEntrance" />
+		<Entrance ref="entranceRef" @updateEntrance="getEntrance" />
 	</div>
 </template>
 
 <script lang="ts" setup name="home">
 import { defineAsyncComponent, reactive, toRefs, ref, onMounted } from "vue";
-import Sortable from 'sortablejs';
+import {useRouter} from "vue-router"
 import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
 import { getImageUrl } from "/@/utils/tools";
-import { formatDate } from '/@/utils/formatTime';// 引入api
-const Entrance = defineAsyncComponent(() => import('/@/views/home/component/entrance.vue'))
-const AudioPlayer = defineAsyncComponent(() => import('/@/components/AudioPlayer/index.vue'))
-const url = "http://music.163.com/song/media/outer/url?id=447925558.mp3";
+import { formatDate } from '/@/utils/formatTime';
+import { geFastMenu } from '/@/api/home';
+const Entrance = defineAsyncComponent(() => import('/@/views/home/component/entrance.vue'));
+
+const router = useRouter();
 const state = reactive({
-	entranceList: <any>[
-		{
-			name: "工单回访",
-			url: "home/gdhf.png",
-			id:Math.random()
-		},
-		{
-			name: "全部工单",
-			url: "home/qbgd.png",
-			id:Math.random()
-		},
-		{
-			name: "甄别管理",
-			url: "home/zbgl.png",
-			id:Math.random()
-		},
-		{
-			name: "受理列表",
-			url: "home/sllb.png",
-			id:Math.random()
-		},
-		{
-			name: "业务查询",
-			url: "home/ywcx.png",
-			id:Math.random()
-		},{
-			name: "工单回访",
-			url: "home/gdhf.png",
-			id:Math.random()
-		},
-		{
-			name: "全部工单",
-			url: "home/qbgd.png",
-			id:Math.random()
-		},
-		{
-			name: "甄别管理",
-			url: "home/zbgl1.png",
-			id:Math.random()
-		},
-		{
-			name: "受理列表",
-			url: "home/sllb.png",
-			id:Math.random()
-		}
-	],
+	entranceList: <any>[],
 	noticeList: [
 		{
 			title: "市城区迁改23处盲道优化446个临时停车泊位",
@@ -242,28 +197,10 @@ const state = reactive({
 		}
 	],
 	loading:false,
+	entranceLoading:false,
 	sortEntranceList:[],
 	sortable:<any>'',
 })
-// 入口可拖动排序
-const initSortable = ()=>{
-	const el = <HTMLElement>document.querySelector('.right-entrance-list');
-    if (!el) return false;
-    state.sortable.el && state.sortable.destroy();
-    state.sortable = Sortable.create(el, {
-        animation: 300,
-        handle:'.my-handle',
-        onEnd: () => {
-            const sortEndList: any = [];
-            state.sortable.toArray().map((val: any) => {
-                state.entranceList.map((v: any) => {
-                    if (v.id == val) sortEndList.push({ ...v });
-                });
-            });
-            state.sortEntranceList = sortEndList;
-        },
-    });
-}
 const entranceRef = ref();
 // 自定义入口
 const customEntry = () => {
@@ -271,9 +208,21 @@ const customEntry = () => {
 }
 //获取入口设置
 const getEntrance = () => {
-
+	state.entranceLoading = true;
+	geFastMenu().then((res:any)=>{
+		state.entranceList = res?.result ?? [];
+		setTimeout(() => {
+			state.entranceLoading = false;
+		}, 300);
+		
+	})
+}
+// 跳转
+const goLink = (val:string)=>{
+	router.push(val);
 }
-const changeList = (val: string) => { //切换列表
+ //切换列表
+const changeList = (val: string) => {
 	if (state.active === val) return;
 	state.active = val;
 }
@@ -291,9 +240,9 @@ const more = (val:string)=>{
 	}
 }
 onMounted(()=>{
-	initSortable();
+	getEntrance();
 })
-const { entranceList, noticeList, active, activities,loading } = toRefs(state);
+const { entranceList, noticeList, active, activities,loading,entranceLoading } = toRefs(state);
 </script>
 <style lang="scss" scoped>
 .box {
@@ -459,7 +408,6 @@ const { entranceList, noticeList, active, activities,loading } = toRefs(state);
 						height: 50px;
 						margin-top:15px;
 						margin-bottom: 13px;
-						cursor: grab;
 					}
 					&:hover {
 						color: var(--el-color-primary);

+ 2 - 2
src/views/system/institutionalUsers/roles/component/permission.vue

@@ -146,7 +146,7 @@ export default defineComponent({
 			if (!arr.length) return;
 			arr.forEach((v: any) => {
 				newArr.push(v.permissionCode)
-				if (v.children.length) {
+				if (v.children?.length) {
 					getAllMenuCode(v.children)
 				}
 			});
@@ -159,7 +159,7 @@ export default defineComponent({
 				for (let i of v.buttonArr) {
 					newArr1.push(i.permissionCode)
 				}
-				if (v.children.length) {
+				if (v.children?.length) {
 					getAllButtonCode(v.children)
 				}
 			});

+ 61 - 1
src/views/system/menu/component/addMenu.vue

@@ -1,7 +1,7 @@
 <template>
 	<div class="system-add-menu-container">
 		<el-dialog title="新增菜单" v-model="isShowDialog" width="769px" draggable>
-      <el-form :model="ruleForm" ref="ruleFormRef"  label-width="80px">
+      <el-form :model="ruleForm" ref="ruleFormRef"  label-width="90px" label-poistion="left">
         <el-row :gutter="35">
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
             <el-form-item label="上级菜单" prop="parentId" :rules="[{ required: false, message: '请选择上级菜单', trigger: 'change' }]">
@@ -62,6 +62,44 @@
               <el-input-number v-model="ruleForm.displayOrder" controls-position="right" placeholder="请输入排序" class="w100" />
             </el-form-item>
           </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+            <el-form-item label="快捷入口">
+              <el-switch
+                v-model="ruleForm.isFast"
+                inline-prompt
+                active-text="是"
+                inactive-text="否"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="ruleForm.isFast">
+            <el-form-item label="入口图片" prop="title"  :rules="[{ required: false, message: '请选择入口图片', trigger: 'blur' }]">
+              <template #label>
+                <p class="flex-center-align">入口图片
+                <el-tooltip
+                  content="首页快捷入口图标"
+                  placement="top-start"
+                  trigger="click"
+                >
+                  <svgIcon name="ele-QuestionFilled" class="cursor-help"></svgIcon>
+                </el-tooltip>
+                 </p>
+              </template>
+              <el-select v-model="ruleForm.fastIcon" placeholder="请选择入口图片" class="w100" clearable>
+                <el-option
+                  v-for="item in imgList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                  <div class="item-Img">
+                    <span>{{ item.label }}</span>
+                    <img v-lazy="getImageUrl(item.label)" alt="" />
+                  </div>
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
           <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
             <el-form-item label="是否隐藏">
               <el-switch
@@ -127,6 +165,7 @@
 <script lang="ts">
 import {  defineAsyncComponent,reactive, toRefs, onMounted, defineComponent, ref} from 'vue';
 import {  ElMessage } from 'element-plus';
+import { getImageUrl } from "/@/utils/tools";
 import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
 import {FormInstance} from "element-plus";
 import {addMenu, getMenuList} from "/@/api/system/menu";
@@ -156,9 +195,29 @@ export default defineComponent({
         link: '', // 外链/内嵌时链接地址(http:xxx.com),开启外链条件,`1、isLink: 链接地址不为空`
         isIframe: false, // 是否内嵌,开启条件,`1、isIframe:true 2、isLink:链接地址不为空`
         permissionCode:"", //权限编码
+        isFast:false, //是否是快捷入口
+        fastIcon:"", //入口图片
 			},
 			menuData: [], // 上级菜单数据
       loading:false,
+      imgList:[
+        {
+          label:'home/sllb.png',
+          value:'home/sllb.png'
+        },{
+          label:'home/gdhf.png',
+          value:'home/gdhf.png'
+        },{
+          label:'home/qbgd.png',
+          value:'home/qbgd.png'
+        },{
+          label:'home/ywcx.png',
+          value:'home/ywcx.png'
+        },{
+          label:'home/zbgl.png',
+          value:'home/zbgl.png'
+        },
+      ]
 		});
 		// 获取全部菜单
 		const getMenuData = (routes: any) => {
@@ -214,6 +273,7 @@ export default defineComponent({
 		});
 		return {
 			openDialog,
+      getImageUrl,
 			closeDialog,
 			onSelectIframeChange,
       ruleFormRef,

+ 61 - 1
src/views/system/menu/component/editMenu.vue

@@ -1,7 +1,7 @@
 <template>
 	<div class="system-edit-menu-container">
 		<el-dialog title="修改菜单" v-model="isShowDialog" width="769px" draggable>
-      <el-form :model="ruleForm" ref="ruleFormRef" label-width="80px">
+      <el-form :model="ruleForm" ref="ruleFormRef" label-width="90px">
         <el-row :gutter="35">
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
             <el-form-item label="上级菜单" prop="parentId" :rules="[{ required: false, message: '请选择上级菜单', trigger: 'change' }]">
@@ -62,6 +62,44 @@
               <el-input-number v-model="ruleForm.displayOrder" controls-position="right" placeholder="请输入排序" class="w100" />
             </el-form-item>
           </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+            <el-form-item label="快捷入口">
+              <el-switch
+                v-model="ruleForm.isFast"
+                inline-prompt
+                active-text="是"
+                inactive-text="否"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="ruleForm.isFast">
+            <el-form-item label="入口图片" prop="title"  :rules="[{ required: false, message: '请选择入口图片', trigger: 'blur' }]">
+              <template #label>
+                <p class="flex-center-align">入口图片
+                <el-tooltip
+                  content="首页快捷入口图标"
+                  placement="top-start"
+                  trigger="click"
+                >
+                  <svgIcon name="ele-QuestionFilled" class="cursor-help"></svgIcon>
+                </el-tooltip>
+                 </p>
+              </template>
+              <el-select v-model="ruleForm.fastIcon" placeholder="请选择入口图片" class="w100" clearable>
+                <el-option
+                  v-for="item in imgList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                  <div class="item-Img">
+                    <span>{{ item.label }}</span>
+                    <img v-lazy="getImageUrl(item.label)" alt="" />
+                  </div>
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
           <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
             <el-form-item label="是否隐藏">
               <el-switch
@@ -128,6 +166,7 @@
 import { defineAsyncComponent, reactive, toRefs, onMounted, defineComponent, ref} from 'vue';
 import {  ElMessage,FormInstance,ElNotification } from 'element-plus';
 import {storeToRefs} from 'pinia';
+import { getImageUrl } from "/@/utils/tools";
 import { useUserInfo } from '/@/stores/userInfo';
 import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
 import {updateMenu,getMenuList,getMenuById} from "/@/api/system/menu";
@@ -157,9 +196,29 @@ export default defineComponent({
         link: '', // 外链/内嵌时链接地址(http:xxx.com),开启外链条件,`1、isLink: 链接地址不为空`
         isIframe: false, // 是否内嵌,开启条件,`1、isIframe:true 2、isLink:链接地址不为空`
         permissionCode:"", //权限编码
+        isFast:false, //是否是快捷入口
+        fastIcon:"", //入口图片
       },
       menuData: [], // 上级菜单数据
       loading:false,
+      imgList:[
+        {
+          label:'home/sllb.png',
+          value:'home/sllb.png'
+        },{
+          label:'home/gdhf.png',
+          value:'home/gdhf.png'
+        },{
+          label:'home/qbgd.png',
+          value:'home/qbgd.png'
+        },{
+          label:'home/ywcx.png',
+          value:'home/ywcx.png'
+        },{
+          label:'home/zbgl.png',
+          value:'home/zbgl.png'
+        },
+      ]
 		});
     const storesUserInfo = useUserInfo();
 		const {userInfos} = storeToRefs(storesUserInfo);
@@ -235,6 +294,7 @@ export default defineComponent({
       ruleFormRef,
 			onCancel,
 			onSubmit,
+      getImageUrl,
 			...toRefs(state),
 		};
 	},

+ 34 - 4
src/views/system/menu/index.vue

@@ -11,24 +11,54 @@
 			</div>
 			<el-table :data="menuTableData" v-loading="loading" style="width: 100%" row-key="id"
 				:default-expand-all="true" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
-				<el-table-column label="菜单名称" show-overflow-tooltip>
+				<el-table-column label="菜单名称" show-overflow-tooltip width="200" fixed="left">
 					<template #default="scope">
 						<SvgIcon :name="scope.row.icon" />
 						<span class="ml10">{{ scope.row.pageName }}</span>
 					</template>
 				</el-table-column>
-				<el-table-column prop="path" label="路由路径" show-overflow-tooltip></el-table-column>
-				<el-table-column label="组件路径" show-overflow-tooltip>
+				<el-table-column prop="path" label="路由路径" show-overflow-tooltip width="400"></el-table-column>
+				<el-table-column label="组件路径" show-overflow-tooltip width="400">
 					<template #default="scope">
 						<span>{{ scope.row.component }}</span>
 					</template>
 				</el-table-column>
+				<el-table-column label="快捷入口" width="100">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.isFast">是</el-tag>
+						<el-tag type="info" v-else>否</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="是否隐藏" width="100">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.isHide">是</el-tag>
+						<el-tag type="info" v-else>否</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="是否缓存" width="100">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.isKeepAlive">是</el-tag>
+						<el-tag type="info" v-else>否</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="是否固定" width="100">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.isAffix">是</el-tag>
+						<el-tag type="info" v-else>否</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="是否外链" width="100">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.isLink">是</el-tag>
+						<el-tag type="info" v-else>否</el-tag>
+					</template>
+				</el-table-column>
 				<el-table-column label="排序" show-overflow-tooltip width="80">
 					<template #default="scope">
 						{{ scope.row.displayOrder }}
 					</template>
 				</el-table-column>
-				<el-table-column label="操作" show-overflow-tooltip width="100" align="center">
+				<el-table-column label="操作" fixed="right" width="100" align="center">
 					<template #default="scope">
 						<el-tooltip content="修改" placement="top-start">
 							<el-button text type="primary" @click="onOpenEditMenu(scope.row)" v-auth="'100402'">

+ 3 - 1
src/views/system/organizational/index.vue

@@ -58,7 +58,9 @@ export default {
         const { userInfos } = storeToRefs(storesUserInfo);
         if(!userInfos.value.authBtnList.includes('100504')){ // 没有授权直接跳转到401
             next('/401')
-        }
+        }else{
+			next();
+		}
    }
 }
 </script>