From 656696be4b70513e94f1341db8d1c2d3f43b3e6d Mon Sep 17 00:00:00 2001
From: Your Name <123456>
Date: 星期三, 13 七月 2022 09:18:47 +0800
Subject: [PATCH] 登录跳转首页

---
 src/views/system/role/index.vue                                                                                |   32 
 src/layout/navBars/breadcrumb/user.vue                                                                         |  561 ++++++++--------
 src/api/role/index.ts                                                                                          |   16 
 src/utils/request.ts                                                                                           |   10 
 src/views/system/department/component/deptDialog.vue                                                           |   36 
 src/router/backEnd.ts                                                                                          |    2 
 src/views/system/department/index.vue                                                                          |   30 
 src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue       |    1 
 .env.development                                                                                               |    2 
 /dev/null                                                                                                      |    6 
 src/components/iconSelector/index.vue                                                                          |  498 +++++++-------
 src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue |    2 
 src/views/system/role/component/roleDialog.vue                                                                 |   25 
 src/api/department/index.ts                                                                                    |   16 
 src/api/menu/index.ts                                                                                          |    2 
 src/views/loginPage/component/accountLogin.vue                                                                 |    1 
 src/router/index.ts                                                                                            |  135 +--
 src/views/homeMenu/homeMenu.vue                                                                                |  573 ++++++++++-------
 src/api/login/index.ts                                                                                         |    7 
 src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue           |    2 
 src/views/system/menu/component/menuDialog.vue                                                                 |    2 
 21 files changed, 1,052 insertions(+), 907 deletions(-)

diff --git a/.env.development b/.env.development
index ea1c589..0c99294 100644
--- a/.env.development
+++ b/.env.development
@@ -2,6 +2,6 @@
 ENV = 'development'
 
 # 本地环境接口地址
-VITE_API_URL = 'http://192.168.0.14:8008'
+VITE_API_URL = 'http://192.168.0.35:8008'
 
 # VITE_API_URL = 'http://192.168.0.8:8008'
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 03d9549..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0">
-    <option name="myName" value="Project Default" />
-    <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
-  </profile>
-</component>
\ No newline at end of file
diff --git a/src/api/department/index.ts b/src/api/department/index.ts
index 6f43002..3733527 100644
--- a/src/api/department/index.ts
+++ b/src/api/department/index.ts
@@ -2,14 +2,14 @@
 
 export function departmentApi() {
     return {
-        // v1
+        // v2
         getDepartmentList: () => {
             return request({
                 url: `/department/list`,
                 method: 'post'
             });
         },
-        // v1
+        // v2
         addDepartment: (data: object) => {
             return request({
                 url: `/department/add`,
@@ -17,13 +17,21 @@
                 data: data
             });
         },
-        // v1
+        // v2
         modDepartment: (data: object) => {
             return request({
                 url: `/department/mod`,
                 method: 'post',
                 data: data
             });
-        }
+        },
+        // v1
+        deleteDepartment: (value?: object) => {
+            return request({
+                url: `/department/del`,
+                method: 'post',
+                data: value
+            });
+        },
     };
 }
diff --git a/src/api/login/index.ts b/src/api/login/index.ts
index 0d27058..0cd50c5 100644
--- a/src/api/login/index.ts
+++ b/src/api/login/index.ts
@@ -16,11 +16,10 @@
             });
         },
         // v1
-        signOut: (params: object) => {
+        signOut: () => {
             return request({
-                url: '/user/signOut',
-                method: 'post',
-                data: params
+                url: '/auth/logout',
+                method: 'post'
             });
         }
     };
diff --git a/src/api/menu/index.ts b/src/api/menu/index.ts
index d92bc29..ddfda6c 100644
--- a/src/api/menu/index.ts
+++ b/src/api/menu/index.ts
@@ -8,7 +8,7 @@
  */
 export function useMenuApi() {
     return {
-        // v1
+        // v2
         getMenuAdmin: (value?: string) => {
             return request({
                 url: `/auth/menu?projectId= ${value}`,
diff --git a/src/api/role/index.ts b/src/api/role/index.ts
index e0b9151..3b85d45 100644
--- a/src/api/role/index.ts
+++ b/src/api/role/index.ts
@@ -2,14 +2,14 @@
 
 export function useRoleApi() {
     return {
-        // v1
+        // v2
         getRoleList: () => {
             return request({
                 url: `/role/list`,
                 method: 'post'
             });
         },
-        // v1
+        // v2
         addRole: (data: object) => {
             return request({
                 url: `/role/add`,
@@ -17,13 +17,21 @@
                 data: data
             });
         },
-        // v1
+        // v2
         modRole: (data: object) => {
             return request({
                 url: `/role/mod`,
                 method: 'post',
                 data: data
             });
-        }
+        },
+        // v2
+        deleteRole: (value?: object) => {
+            return request({
+                url: `/role/del`,
+                method: 'post',
+                data: value
+            });
+        },
     };
 }
diff --git a/src/components/iconSelector/index.vue b/src/components/iconSelector/index.vue
index 07de786..3010e16 100644
--- a/src/components/iconSelector/index.vue
+++ b/src/components/iconSelector/index.vue
@@ -1,252 +1,252 @@
-<template>
-	<div class="icon-selector w100 h100">
-		<el-popover
-			placement="bottom"
-			:width="fontIconWidth"
-			trigger="click"
-			transition="el-zoom-in-top"
-			popper-class="icon-selector-popper"
-			@show="onPopoverShow"
-		>
-			<template #reference>
-				<el-input
-					v-model="fontIconSearch"
-					:placeholder="fontIconPlaceholder"
-					:clearable="clearable"
-					:disabled="disabled"
-					:size="size"
-					ref="inputWidthRef"
-					@clear="onClearFontIcon"
-					@focus="onIconFocus"
-					@blur="onIconBlur"
-				>
-					<template #prepend>
-						<SvgIcon
-							:name="fontIconPrefix === '' ? prepend : fontIconPrefix"
-							class="font14"
-							v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1"
-						/>
-						<i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i>
-					</template>
-				</el-input>
-			</template>
-			<template #default>
-				<div class="icon-selector-warp">
-					<div class="icon-selector-warp-title flex">
-						<div class="flex-auto">{{ title }}</div>
-						<div class="icon-selector-warp-title-tab" v-if="type === 'all'">
-							<span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span>
-							<span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span>
-							<span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span>
-						</div>
-					</div>
-					<div class="icon-selector-warp-row">
-						<el-scrollbar ref="selectorScrollbarRef">
-							<el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">
-								<el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">
-									<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" />
-											</div>
-										</div>
-									</div>
-								</el-col>
-							</el-row>
-							<el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>
-						</el-scrollbar>
-					</div>
-				</div>
-			</template>
-		</el-popover>
-	</div>
-</template>
+<!--<template>-->
+<!--	<div class="icon-selector w100 h100">-->
+<!--		<el-popover-->
+<!--			placement="bottom"-->
+<!--			:width="fontIconWidth"-->
+<!--			trigger="click"-->
+<!--			transition="el-zoom-in-top"-->
+<!--			popper-class="icon-selector-popper"-->
+<!--			@show="onPopoverShow"-->
+<!--		>-->
+<!--			<template #reference>-->
+<!--				<el-input-->
+<!--					v-model="fontIconSearch"-->
+<!--					:placeholder="fontIconPlaceholder"-->
+<!--					:clearable="clearable"-->
+<!--					:disabled="disabled"-->
+<!--					:size="size"-->
+<!--					ref="inputWidthRef"-->
+<!--					@clear="onClearFontIcon"-->
+<!--					@focus="onIconFocus"-->
+<!--					@blur="onIconBlur"-->
+<!--				>-->
+<!--					<template #prepend>-->
+<!--						<SvgIcon-->
+<!--							:name="fontIconPrefix === '' ? prepend : fontIconPrefix"-->
+<!--							class="font14"-->
+<!--							v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1"-->
+<!--						/>-->
+<!--						<i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i>-->
+<!--					</template>-->
+<!--				</el-input>-->
+<!--			</template>-->
+<!--			<template #default>-->
+<!--				<div class="icon-selector-warp">-->
+<!--					<div class="icon-selector-warp-title flex">-->
+<!--						<div class="flex-auto">{{ title }}</div>-->
+<!--						<div class="icon-selector-warp-title-tab" v-if="type === 'all'">-->
+<!--							<span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span>-->
+<!--							<span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span>-->
+<!--							<span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span>-->
+<!--						</div>-->
+<!--					</div>-->
+<!--					<div class="icon-selector-warp-row">-->
+<!--						<el-scrollbar ref="selectorScrollbarRef">-->
+<!--							<el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">-->
+<!--								<el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">-->
+<!--									<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" />-->
+<!--											</div>-->
+<!--										</div>-->
+<!--									</div>-->
+<!--								</el-col>-->
+<!--							</el-row>-->
+<!--							<el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>-->
+<!--						</el-scrollbar>-->
+<!--					</div>-->
+<!--				</div>-->
+<!--			</template>-->
+<!--		</el-popover>-->
+<!--	</div>-->
+<!--</template>-->
 
-<script lang="ts">
-import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
-import initIconfont from '/@/utils/getStyleSheets';
+<!--<script lang="ts">-->
+<!--import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';-->
+<!--import initIconfont from '/@/utils/getStyleSheets';-->
 
-export default defineComponent({
-	name: 'iconSelector',
-	emits: ['update:modelValue', 'get', 'clear'],
-	props: {
-		// 输入框前置内容
-		prepend: {
-			type: String,
-			default: () => 'ele-Pointer',
-		},
-		// 输入框占位文本
-		placeholder: {
-			type: String,
-			default: () => '请输入内容搜索图标或者选择图标',
-		},
-		// 输入框占位文本
-		size: {
-			type: String,
-			default: () => 'default',
-		},
-		// 弹窗标题
-		title: {
-			type: String,
-			default: () => '请选择图标',
-		},
-		// icon 图标类型
-		type: {
-			type: String,
-			default: () => 'ele',
-		},
-		// 禁用
-		disabled: {
-			type: Boolean,
-			default: () => false,
-		},
-		// 是否可清空
-		clearable: {
-			type: Boolean,
-			default: () => true,
-		},
-		// 自定义空状态描述文字
-		emptyDescription: {
-			type: String,
-			default: () => '无相关图标',
-		},
-		// 双向绑定值,默认为 modelValue,
-		// 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
-		// 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A
-		modelValue: String,
-	},
-	setup(props, { emit }) {
-		const inputWidthRef = ref();
-		const selectorScrollbarRef = ref();
-		const state = reactive({
-			fontIconPrefix: '',
-			fontIconWidth: 0,
-			fontIconSearch: '',
-			fontIconTabsIndex: 0,
-			fontIconSheetsList: [],
-			fontIconPlaceholder: '',
-			fontIconType: 'ali',
-			fontIconShow: true,
-		});
-		// 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值
-		const onIconFocus = () => {
-			if (!props.modelValue) return false;
-			state.fontIconSearch = '';
-			state.fontIconPlaceholder = props.modelValue;
-		};
-		// 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值
-		const onIconBlur = () => {
-			setTimeout(() => {
-				const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch);
-				if (icon.length <= 0) state.fontIconSearch = '';
-			}, 300);
-		};
-		// 处理 icon 双向绑定数值回显
-		const initModeValueEcho = () => {
-			if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
-			(<string | undefined>state.fontIconPlaceholder) = props.modelValue;
-			(<string | undefined>state.fontIconPrefix) = props.modelValue;
-		};
-		// 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
-		const initFontIconTypeEcho = () => {
-			if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali');
-			else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele');
-			else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe');
-			else onIconChange('ali');
-		};
-		// 图标搜索及图标数据显示
-		const fontIconSheetsFilterList = computed(() => {
-			if (!state.fontIconSearch) return state.fontIconSheetsList;
-			let search = state.fontIconSearch.trim().toLowerCase();
-			return state.fontIconSheetsList.filter((item: any) => {
-				if (item.toLowerCase().indexOf(search) !== -1) return item;
-			});
-		});
-		// 获取 input 的宽度
-		const getInputWidth = () => {
-			nextTick(() => {
-				state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;
-			});
-		};
-		// 监听页面宽度改变
-		const initResize = () => {
-			window.addEventListener('resize', () => {
-				getInputWidth();
-			});
-		};
-		// 初始化数据
-		const initFontIconData = async (type: string) => {
-			state.fontIconSheetsList = [];
-			if (type === 'ali') {
-				await initIconfont.ali().then((res: any) => {
-					// 阿里字体图标使用 `iconfont xxx`
-					state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`);
-				});
-			} else if (type === 'ele') {
-				await initIconfont.ele().then((res: any) => {
-					state.fontIconSheetsList = res;
-				});
-			} else if (type === 'awe') {
-				await initIconfont.awe().then((res: any) => {
-					// fontawesome字体图标使用 `fa xxx`
-					state.fontIconSheetsList = res.map((i: string) => `fa ${i}`);
-				});
-			}
-			// 初始化 input 的 placeholder
-			// 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
-			state.fontIconPlaceholder = props.placeholder;
-			// 初始化双向绑定回显
-			initModeValueEcho();
-		};
-		// 图标点击切换
-		const onIconChange = (type: string) => {
-			state.fontIconType = type;
-			initFontIconData(type);
-		};
-		// 获取当前点击的 icon 图标
-		const onColClick = (v: any) => {
-			state.fontIconPlaceholder = v;
-			state.fontIconPrefix = v;
-			emit('get', state.fontIconPrefix);
-			emit('update:modelValue', state.fontIconPrefix);
-		};
-		// 清空当前点击的 icon 图标
-		const onClearFontIcon = () => {
-			state.fontIconPrefix = '';
-			emit('clear', state.fontIconPrefix);
-			emit('update:modelValue', state.fontIconPrefix);
-		};
-		// 监听 Popover 打开,用于双向绑定值回显
-		const onPopoverShow = () => {
-			initModeValueEcho();
-			initFontIconTypeEcho();
-		};
-		// 页面加载时
-		onMounted(() => {
-			initModeValueEcho();
-			initResize();
-			getInputWidth();
-		});
+<!--export default defineComponent({-->
+<!--	name: 'iconSelector',-->
+<!--	emits: ['update:modelValue', 'get', 'clear'],-->
+<!--	props: {-->
+<!--		// 输入框前置内容-->
+<!--		prepend: {-->
+<!--			type: String,-->
+<!--			default: () => 'ele-Pointer',-->
+<!--		},-->
+<!--		// 输入框占位文本-->
+<!--		placeholder: {-->
+<!--			type: String,-->
+<!--			default: () => '请输入内容搜索图标或者选择图标',-->
+<!--		},-->
+<!--		// 输入框占位文本-->
+<!--		size: {-->
+<!--			type: String,-->
+<!--			default: () => 'default',-->
+<!--		},-->
+<!--		// 弹窗标题-->
+<!--		title: {-->
+<!--			type: String,-->
+<!--			default: () => '请选择图标',-->
+<!--		},-->
+<!--		// icon 图标类型-->
+<!--		type: {-->
+<!--			type: String,-->
+<!--			default: () => 'ele',-->
+<!--		},-->
+<!--		// 禁用-->
+<!--		disabled: {-->
+<!--			type: Boolean,-->
+<!--			default: () => false,-->
+<!--		},-->
+<!--		// 是否可清空-->
+<!--		clearable: {-->
+<!--			type: Boolean,-->
+<!--			default: () => true,-->
+<!--		},-->
+<!--		// 自定义空状态描述文字-->
+<!--		emptyDescription: {-->
+<!--			type: String,-->
+<!--			default: () => '无相关图标',-->
+<!--		},-->
+<!--		// 双向绑定值,默认为 modelValue,-->
+<!--		// 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5-->
+<!--		// 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A-->
+<!--		modelValue: String,-->
+<!--	},-->
+<!--	setup(props, { emit }) {-->
+<!--		const inputWidthRef = ref();-->
+<!--		const selectorScrollbarRef = ref();-->
+<!--		const state = reactive({-->
+<!--			fontIconPrefix: '',-->
+<!--			fontIconWidth: 0,-->
+<!--			fontIconSearch: '',-->
+<!--			fontIconTabsIndex: 0,-->
+<!--			fontIconSheetsList: [],-->
+<!--			fontIconPlaceholder: '',-->
+<!--			fontIconType: 'ali',-->
+<!--			fontIconShow: true,-->
+<!--		});-->
+<!--		// 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值-->
+<!--		const onIconFocus = () => {-->
+<!--			if (!props.modelValue) return false;-->
+<!--			state.fontIconSearch = '';-->
+<!--			state.fontIconPlaceholder = props.modelValue;-->
+<!--		};-->
+<!--		// 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值-->
+<!--		const onIconBlur = () => {-->
+<!--			setTimeout(() => {-->
+<!--				const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch);-->
+<!--				if (icon.length <= 0) state.fontIconSearch = '';-->
+<!--			}, 300);-->
+<!--		};-->
+<!--		// 处理 icon 双向绑定数值回显-->
+<!--		const initModeValueEcho = () => {-->
+<!--			if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);-->
+<!--			(<string | undefined>state.fontIconPlaceholder) = props.modelValue;-->
+<!--			(<string | undefined>state.fontIconPrefix) = props.modelValue;-->
+<!--		};-->
+<!--		// 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题-->
+<!--		const initFontIconTypeEcho = () => {-->
+<!--			if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali');-->
+<!--			else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele');-->
+<!--			else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe');-->
+<!--			else onIconChange('ali');-->
+<!--		};-->
+<!--		// 图标搜索及图标数据显示-->
+<!--		const fontIconSheetsFilterList = computed(() => {-->
+<!--			if (!state.fontIconSearch) return state.fontIconSheetsList;-->
+<!--			let search = state.fontIconSearch.trim().toLowerCase();-->
+<!--			return state.fontIconSheetsList.filter((item: any) => {-->
+<!--				if (item.toLowerCase().indexOf(search) !== -1) return item;-->
+<!--			});-->
+<!--		});-->
+<!--		// 获取 input 的宽度-->
+<!--		const getInputWidth = () => {-->
+<!--			nextTick(() => {-->
+<!--				state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;-->
+<!--			});-->
+<!--		};-->
+<!--		// 监听页面宽度改变-->
+<!--		const initResize = () => {-->
+<!--			window.addEventListener('resize', () => {-->
+<!--				getInputWidth();-->
+<!--			});-->
+<!--		};-->
+<!--		// 初始化数据-->
+<!--		const initFontIconData = async (type: string) => {-->
+<!--			state.fontIconSheetsList = [];-->
+<!--			if (type === 'ali') {-->
+<!--				await initIconfont.ali().then((res: any) => {-->
+<!--					// 阿里字体图标使用 `iconfont xxx`-->
+<!--					state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`);-->
+<!--				});-->
+<!--			} else if (type === 'ele') {-->
+<!--				await initIconfont.ele().then((res: any) => {-->
+<!--					state.fontIconSheetsList = res;-->
+<!--				});-->
+<!--			} else if (type === 'awe') {-->
+<!--				await initIconfont.awe().then((res: any) => {-->
+<!--					// fontawesome字体图标使用 `fa xxx`-->
+<!--					state.fontIconSheetsList = res.map((i: string) => `fa ${i}`);-->
+<!--				});-->
+<!--			}-->
+<!--			// 初始化 input 的 placeholder-->
+<!--			// 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81-->
+<!--			state.fontIconPlaceholder = props.placeholder;-->
+<!--			// 初始化双向绑定回显-->
+<!--			initModeValueEcho();-->
+<!--		};-->
+<!--		// 图标点击切换-->
+<!--		const onIconChange = (type: string) => {-->
+<!--			state.fontIconType = type;-->
+<!--			initFontIconData(type);-->
+<!--		};-->
+<!--		// 获取当前点击的 icon 图标-->
+<!--		const onColClick = (v: any) => {-->
+<!--			state.fontIconPlaceholder = v;-->
+<!--			state.fontIconPrefix = v;-->
+<!--			emit('get', state.fontIconPrefix);-->
+<!--			emit('update:modelValue', state.fontIconPrefix);-->
+<!--		};-->
+<!--		// 清空当前点击的 icon 图标-->
+<!--		const onClearFontIcon = () => {-->
+<!--			state.fontIconPrefix = '';-->
+<!--			emit('clear', state.fontIconPrefix);-->
+<!--			emit('update:modelValue', state.fontIconPrefix);-->
+<!--		};-->
+<!--		// 监听 Popover 打开,用于双向绑定值回显-->
+<!--		const onPopoverShow = () => {-->
+<!--			initModeValueEcho();-->
+<!--			initFontIconTypeEcho();-->
+<!--		};-->
+<!--		// 页面加载时-->
+<!--		onMounted(() => {-->
+<!--			initModeValueEcho();-->
+<!--			initResize();-->
+<!--			getInputWidth();-->
+<!--		});-->
 
-		// 监听双向绑定 modelValue 的变化
-		watch(
-			() => props.modelValue,
-			() => {
-				initModeValueEcho();
-			}
-		);
-		return {
-			inputWidthRef,
-			selectorScrollbarRef,
-			fontIconSheetsFilterList,
-			onColClick,
-			onIconChange,
-			onClearFontIcon,
-			onIconFocus,
-			onIconBlur,
-			onPopoverShow,
-			...toRefs(state),
-		};
-	},
-});
-</script>
+<!--		// 监听双向绑定 modelValue 的变化-->
+<!--		watch(-->
+<!--			() => props.modelValue,-->
+<!--			() => {-->
+<!--				initModeValueEcho();-->
+<!--			}-->
+<!--		);-->
+<!--		return {-->
+<!--			inputWidthRef,-->
+<!--			selectorScrollbarRef,-->
+<!--			fontIconSheetsFilterList,-->
+<!--			onColClick,-->
+<!--			onIconChange,-->
+<!--			onClearFontIcon,-->
+<!--			onIconFocus,-->
+<!--			onIconBlur,-->
+<!--			onPopoverShow,-->
+<!--			...toRefs(state),-->
+<!--		};-->
+<!--	},-->
+<!--});-->
+<!--</script>-->
diff --git a/src/layout/navBars/breadcrumb/user.vue b/src/layout/navBars/breadcrumb/user.vue
index ca35a27..e0e0ba4 100644
--- a/src/layout/navBars/breadcrumb/user.vue
+++ b/src/layout/navBars/breadcrumb/user.vue
@@ -1,79 +1,85 @@
 <template>
-	<div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }">
-		<el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange">
-			<div class="layout-navbars-breadcrumb-user-icon">
-				<i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i>
-			</div>
-			<template #dropdown>
-				<el-dropdown-menu>
-					<el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item>
-					<el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{ $t('message.user.dropdownDefault') }}</el-dropdown-item>
-					<el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item>
-				</el-dropdown-menu>
-			</template>
-		</el-dropdown>
-		<el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange">
-			<div class="layout-navbars-breadcrumb-user-icon">
-				<i class="iconfont" :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'" :title="$t('message.user.title1')"></i>
-			</div>
-			<template #dropdown>
-				<el-dropdown-menu>
-					<el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item>
-					<el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item>
-					<el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item>
-				</el-dropdown-menu>
-			</template>
-		</el-dropdown>
-		<div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick">
-			<el-icon :title="$t('message.user.title2')">
-				<ele-Search />
-			</el-icon>
-		</div>
-		<div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick">
-			<i class="icon-skin iconfont" :title="$t('message.user.title3')"></i>
-		</div>
-		<div class="layout-navbars-breadcrumb-user-icon">
-			<el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
-				<template #reference>
-					<el-badge :is-dot="true">
-						<el-icon :title="$t('message.user.title4')">
-							<ele-Bell />
-						</el-icon>
-					</el-badge>
-				</template>
-				<template #default>
-					<UserNews />
-				</template>
-			</el-popover>
-		</div>
-		<div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick">
-			<i
-				class="iconfont"
-				:title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')"
-				:class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'"
-			></i>
-		</div>
-		<el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick">
-			<span class="layout-navbars-breadcrumb-user-link">
-				<img :src="userInfos.photo" class="layout-navbars-breadcrumb-user-link-photo mr5" />
-				{{ userInfos.userName }}
-				<el-icon class="el-icon--right">
-					<ele-ArrowDown />
-				</el-icon>
-			</span>
-			<template #dropdown>
-				<el-dropdown-menu>
-					<el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
-					<el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>
-					<el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
-					<el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>
-					<el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>
-					<el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
-				</el-dropdown-menu>
-			</template>
-		</el-dropdown>
-		<Search ref="searchRef" />
-	</div>
+    <div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }">
+        <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange">
+            <div class="layout-navbars-breadcrumb-user-icon">
+                <i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i>
+            </div>
+            <template #dropdown>
+                <el-dropdown-menu>
+                    <el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item>
+                    <el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{
+                        $t('message.user.dropdownDefault')
+                    }}</el-dropdown-item>
+                    <el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item>
+                </el-dropdown-menu>
+            </template>
+        </el-dropdown>
+        <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange">
+            <div class="layout-navbars-breadcrumb-user-icon">
+                <i
+                    class="iconfont"
+                    :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'"
+                    :title="$t('message.user.title1')"
+                ></i>
+            </div>
+            <template #dropdown>
+                <el-dropdown-menu>
+                    <el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item>
+                    <el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item>
+                    <el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item>
+                </el-dropdown-menu>
+            </template>
+        </el-dropdown>
+        <div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick">
+            <el-icon :title="$t('message.user.title2')">
+                <ele-Search />
+            </el-icon>
+        </div>
+        <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick">
+            <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i>
+        </div>
+        <div class="layout-navbars-breadcrumb-user-icon">
+            <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
+                <template #reference>
+                    <el-badge :is-dot="true">
+                        <el-icon :title="$t('message.user.title4')">
+                            <ele-Bell />
+                        </el-icon>
+                    </el-badge>
+                </template>
+                <template #default>
+                    <UserNews />
+                </template>
+            </el-popover>
+        </div>
+        <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick">
+            <i
+                class="iconfont"
+                :title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')"
+                :class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'"
+            ></i>
+        </div>
+        <el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick">
+            <span class="layout-navbars-breadcrumb-user-link">
+                <img :src="userInfos.photo" class="layout-navbars-breadcrumb-user-link-photo mr5" />
+                {{ userInfos.userName }}
+                <el-icon class="el-icon--right">
+                    <ele-ArrowDown />
+                </el-icon>
+            </span>
+            <template #dropdown>
+                <el-dropdown-menu>
+                    <el-dropdown-item command="/homeMenu">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
+                    <!--                    <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>-->
+                    <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
+                    <!--					<el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>-->
+                    <!--					<el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>-->
+                    <el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
+                </el-dropdown-menu>
+            </template>
+        </el-dropdown>
+        <Search ref="searchRef" />
+    </div>
 </template>
 
 <script lang="ts">
@@ -89,210 +95,219 @@
 import { Session, Local } from '/@/utils/storage';
 import UserNews from '/@/layout/navBars/breadcrumb/userNews.vue';
 import Search from '/@/layout/navBars/breadcrumb/search.vue';
+import { useLoginApi } from '/@/api/login';
 
 export default defineComponent({
-	name: 'layoutBreadcrumbUser',
-	components: { UserNews, Search },
-	setup() {
-		const { t } = useI18n();
-		const { proxy } = <any>getCurrentInstance();
-		const router = useRouter();
-		const stores = useUserInfo();
-		const storesThemeConfig = useThemeConfig();
-		const { userInfos } = storeToRefs(stores);
-		const { themeConfig } = storeToRefs(storesThemeConfig);
-		const searchRef = ref();
-		const state = reactive({
-			isScreenfull: false,
-			disabledI18n: 'zh-cn',
-			disabledSize: 'large',
-		});
-		// 设置分割样式
-		const layoutUserFlexNum = computed(() => {
-			let num: string | number = '';
-			const { layout, isClassicSplitMenu } = themeConfig.value;
-			const layoutArr: string[] = ['defaults', 'columns'];
-			if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1';
-			else num = '';
-			return num;
-		});
-		// 全屏点击时
-		const onScreenfullClick = () => {
-			if (!screenfull.isEnabled) {
-				ElMessage.warning('暂不不支持全屏');
-				return false;
-			}
-			screenfull.toggle();
-			screenfull.on('change', () => {
-				if (screenfull.isFullscreen) state.isScreenfull = true;
-				else state.isScreenfull = false;
-			});
-		};
-		// 布局配置 icon 点击时
-		const onLayoutSetingClick = () => {
-			proxy.mittBus.emit('openSetingsDrawer');
-		};
-		// 下拉菜单点击时
-		const onHandleCommandClick = (path: string) => {
-			if (path === 'logOut') {
-				ElMessageBox({
-					closeOnClickModal: false,
-					closeOnPressEscape: false,
-					title: t('message.user.logOutTitle'),
-					message: t('message.user.logOutMessage'),
-					showCancelButton: true,
-					confirmButtonText: t('message.user.logOutConfirm'),
-					cancelButtonText: t('message.user.logOutCancel'),
-					buttonSize: 'default',
-					beforeClose: (action, instance, done) => {
-						if (action === 'confirm') {
-							instance.confirmButtonLoading = true;
-							instance.confirmButtonText = t('message.user.logOutExit');
-							setTimeout(() => {
-								done();
-								setTimeout(() => {
-									instance.confirmButtonLoading = false;
-								}, 300);
-							}, 700);
-						} else {
-							done();
-						}
-					},
-				})
-					.then(async () => {
-						Session.clear(); // 清除缓存/token等
-						// 使用 reload 时,不需要调用 resetRoute() 重置路由
-						window.location.reload();
-					})
-					.catch(() => {});
-			} else if (path === 'wareHouse') {
-				window.open('https://gitee.com/lyt-top/vue-next-admin');
-			} else {
-				router.push(path);
-			}
-		};
-		// 菜单搜索点击
-		const onSearchClick = () => {
-			searchRef.value.openSearch();
-		};
-		// 组件大小改变
-		const onComponentSizeChange = (size: string) => {
-			Local.remove('themeConfig');
-			themeConfig.value.globalComponentSize = size;
-			Local.set('themeConfig', themeConfig.value);
-			initComponentSize();
-			window.location.reload();
-		};
-		// 语言切换
-		const onLanguageChange = (lang: string) => {
-			Local.remove('themeConfig');
-			themeConfig.value.globalI18n = lang;
-			Local.set('themeConfig', themeConfig.value);
-			proxy.$i18n.locale = lang;
-			initI18n();
-			other.useTitle();
-		};
-		// 设置 element plus 组件的国际化
-		const setI18nConfig = (locale: string) => {
-			proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]);
-		};
-		// 初始化言语国际化
-		const initI18n = () => {
-			switch (Local.get('themeConfig').globalI18n) {
-				case 'zh-cn':
-					state.disabledI18n = 'zh-cn';
-					setI18nConfig('zh-cn');
-					break;
-				case 'en':
-					state.disabledI18n = 'en';
-					setI18nConfig('en');
-					break;
-				case 'zh-tw':
-					state.disabledI18n = 'zh-tw';
-					setI18nConfig('zh-tw');
-					break;
-			}
-		};
-		// 初始化全局组件大小
-		const initComponentSize = () => {
-			switch (Local.get('themeConfig').globalComponentSize) {
-				case 'large':
-					state.disabledSize = 'large';
-					break;
-				case 'default':
-					state.disabledSize = 'default';
-					break;
-				case 'small':
-					state.disabledSize = 'small';
-					break;
-			}
-		};
-		// 页面加载时
-		onMounted(() => {
-			if (Local.get('themeConfig')) {
-				initI18n();
-				initComponentSize();
-			}
-		});
-		return {
-			userInfos,
-			onLayoutSetingClick,
-			onHandleCommandClick,
-			onScreenfullClick,
-			onSearchClick,
-			onComponentSizeChange,
-			onLanguageChange,
-			searchRef,
-			layoutUserFlexNum,
-			...toRefs(state),
-		};
-	},
+    name: 'layoutBreadcrumbUser',
+    components: { UserNews, Search },
+    setup() {
+        const { t } = useI18n();
+        const { proxy } = <any>getCurrentInstance();
+        const router = useRouter();
+        const stores = useUserInfo();
+        const storesThemeConfig = useThemeConfig();
+        const { userInfos } = storeToRefs(stores);
+        const { themeConfig } = storeToRefs(storesThemeConfig);
+        const searchRef = ref();
+        const state = reactive({
+            isScreenfull: false,
+            disabledI18n: 'zh-cn',
+            disabledSize: 'large'
+        });
+        // 设置分割样式
+        const layoutUserFlexNum = computed(() => {
+            let num: string | number = '';
+            const { layout, isClassicSplitMenu } = themeConfig.value;
+            const layoutArr: string[] = ['defaults', 'columns'];
+            if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1';
+            else num = '';
+            return num;
+        });
+        // 全屏点击时
+        const onScreenfullClick = () => {
+            if (!screenfull.isEnabled) {
+                ElMessage.warning('暂不不支持全屏');
+                return false;
+            }
+            screenfull.toggle();
+            screenfull.on('change', () => {
+                if (screenfull.isFullscreen) state.isScreenfull = true;
+                else state.isScreenfull = false;
+            });
+        };
+        // 布局配置 icon 点击时
+        const onLayoutSetingClick = () => {
+            proxy.mittBus.emit('openSetingsDrawer');
+        };
+        // 下拉菜单点击时
+        const onHandleCommandClick = (path: string) => {
+            if (path === 'logOut') {
+                ElMessageBox({
+                    closeOnClickModal: false,
+                    closeOnPressEscape: false,
+                    title: t('message.user.logOutTitle'),
+                    message: t('message.user.logOutMessage'),
+                    showCancelButton: true,
+                    confirmButtonText: t('message.user.logOutConfirm'),
+                    cancelButtonText: t('message.user.logOutCancel'),
+                    buttonSize: 'default',
+                    beforeClose: (action, instance, done) => {
+                        if (action === 'confirm') {
+                            instance.confirmButtonLoading = true;
+                            instance.confirmButtonText = t('message.user.logOutExit');
+                            setTimeout(() => {
+                                done();
+                                setTimeout(() => {
+                                    instance.confirmButtonLoading = false;
+                                }, 300);
+                            }, 700);
+                        } else {
+                            done();
+                        }
+                    }
+                })
+                    .then(async () => {
+                        let res = await useLoginApi().signOut();
+                        if (res.data.code === '200') {
+                            Session.clear(); // 清除缓存/token等
+                            // 使用 reload 时,不需要调用 resetRoute() 重置路由
+                            window.location.reload();
+                        } else {
+                            ElMessage({
+                                type: 'warning',
+                                message: res.data.msg
+                            });
+                        }
+                    })
+                    .catch(() => {});
+            } else if (path === 'wareHouse') {
+                window.open('https://gitee.com/lyt-top/vue-next-admin');
+            } else {
+                router.push(path);
+            }
+        };
+        // 菜单搜索点击
+        const onSearchClick = () => {
+            searchRef.value.openSearch();
+        };
+        // 组件大小改变
+        const onComponentSizeChange = (size: string) => {
+            Local.remove('themeConfig');
+            themeConfig.value.globalComponentSize = size;
+            Local.set('themeConfig', themeConfig.value);
+            initComponentSize();
+            window.location.reload();
+        };
+        // 语言切换
+        const onLanguageChange = (lang: string) => {
+            Local.remove('themeConfig');
+            themeConfig.value.globalI18n = lang;
+            Local.set('themeConfig', themeConfig.value);
+            proxy.$i18n.locale = lang;
+            initI18n();
+            other.useTitle();
+        };
+        // 设置 element plus 组件的国际化
+        const setI18nConfig = (locale: string) => {
+            proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]);
+        };
+        // 初始化言语国际化
+        const initI18n = () => {
+            switch (Local.get('themeConfig').globalI18n) {
+                case 'zh-cn':
+                    state.disabledI18n = 'zh-cn';
+                    setI18nConfig('zh-cn');
+                    break;
+                case 'en':
+                    state.disabledI18n = 'en';
+                    setI18nConfig('en');
+                    break;
+                case 'zh-tw':
+                    state.disabledI18n = 'zh-tw';
+                    setI18nConfig('zh-tw');
+                    break;
+            }
+        };
+        // 初始化全局组件大小
+        const initComponentSize = () => {
+            switch (Local.get('themeConfig').globalComponentSize) {
+                case 'large':
+                    state.disabledSize = 'large';
+                    break;
+                case 'default':
+                    state.disabledSize = 'default';
+                    break;
+                case 'small':
+                    state.disabledSize = 'small';
+                    break;
+            }
+        };
+        // 页面加载时
+        onMounted(() => {
+            if (Local.get('themeConfig')) {
+                initI18n();
+                initComponentSize();
+            }
+        });
+        return {
+            userInfos,
+            onLayoutSetingClick,
+            onHandleCommandClick,
+            onScreenfullClick,
+            onSearchClick,
+            onComponentSizeChange,
+            onLanguageChange,
+            searchRef,
+            layoutUserFlexNum,
+            ...toRefs(state)
+        };
+    }
 });
 </script>
 
 <style scoped lang="scss">
 .layout-navbars-breadcrumb-user {
-	display: flex;
-	align-items: center;
-	justify-content: flex-end;
-	&-link {
-		height: 100%;
-		display: flex;
-		align-items: center;
-		white-space: nowrap;
-		&-photo {
-			width: 25px;
-			height: 25px;
-			border-radius: 100%;
-		}
-	}
-	&-icon {
-		padding: 0 10px;
-		cursor: pointer;
-		color: var(--next-bg-topBarColor);
-		height: 50px;
-		line-height: 50px;
-		display: flex;
-		align-items: center;
-		&:hover {
-			background: var(--next-color-user-hover);
-			i {
-				display: inline-block;
-				animation: logoAnimation 0.3s ease-in-out;
-			}
-		}
-	}
-	::v-deep(.el-dropdown) {
-		color: var(--next-bg-topBarColor);
-	}
-	::v-deep(.el-badge) {
-		height: 40px;
-		line-height: 40px;
-		display: flex;
-		align-items: center;
-	}
-	::v-deep(.el-badge__content.is-fixed) {
-		top: 12px;
-	}
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    &-link {
+        height: 100%;
+        display: flex;
+        align-items: center;
+        white-space: nowrap;
+        &-photo {
+            width: 25px;
+            height: 25px;
+            border-radius: 100%;
+        }
+    }
+    &-icon {
+        padding: 0 10px;
+        cursor: pointer;
+        color: var(--next-bg-topBarColor);
+        height: 50px;
+        line-height: 50px;
+        display: flex;
+        align-items: center;
+        &:hover {
+            background: var(--next-color-user-hover);
+            i {
+                display: inline-block;
+                animation: logoAnimation 0.3s ease-in-out;
+            }
+        }
+    }
+    ::v-deep(.el-dropdown) {
+        color: var(--next-bg-topBarColor);
+    }
+    ::v-deep(.el-badge) {
+        height: 40px;
+        line-height: 40px;
+        display: flex;
+        align-items: center;
+    }
+    ::v-deep(.el-badge__content.is-fixed) {
+        top: 12px;
+    }
 }
 </style>
diff --git a/src/router/backEnd.ts b/src/router/backEnd.ts
index c109d30..cf08c07 100644
--- a/src/router/backEnd.ts
+++ b/src/router/backEnd.ts
@@ -30,7 +30,7 @@
 	if (window.nextLoading === undefined) NextLoading.start();
 	if (!Session.get('token')) return false;
 	const res = await getBackEndControlRoutes(Session.get('projectId') === null ? '' : Session.get('projectId'));
-	useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data.data)));
+	await useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data.data)));
 	dynamicRoutes[0].children = await backEndComponent(res.data.data);
 	await setAddRoute();
 	await setFilterMenuAndCacheTagsViewRoutes();
diff --git a/src/router/index.ts b/src/router/index.ts
index 112fa0f..5fe7e90 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -10,9 +10,7 @@
 import { staticRoutes } from '/@/router/route';
 import { initFrontEndControlRoutes } from '/@/router/frontEnd';
 import { initBackEndControlRoutes } from '/@/router/backEnd';
-import {useUserInfo} from "/@/stores/userInfo";
-
-
+import { useUserInfo } from '/@/stores/userInfo';
 
 // 读取 `/src/stores/themeConfig.ts` 是否开启后端控制路由配置
 const storesThemeConfig = useThemeConfig(pinia);
@@ -20,89 +18,86 @@
 const { isRequestRoutes } = themeConfig.value;
 if (isRequestRoutes) staticRoutes.splice(0, 1);
 
-
 export const router = createRouter({
-	history: createWebHashHistory(),
-	routes: staticRoutes,
+    history: createWebHashHistory(),
+    routes: staticRoutes
 });
 
-
 export function formatFlatteningRoutes(arr: any) {
-	if (arr.length <= 0) return false;
-	for (let i = 0; i < arr.length; i++) {
-		if (arr[i].children) {
-			arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
-		}
-	}
-	return arr;
+    if (arr.length <= 0) return false;
+    for (let i = 0; i < arr.length; i++) {
+        if (arr[i].children) {
+            arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
+        }
+    }
+    return arr;
 }
-
 
 export function formatTwoStageRoutes(arr: any) {
-	if (arr.length <= 0) return false;
-	const newArr: any = [];
-	const cacheList: Array<string> = [];
-	arr.forEach((v: any) => {
-		if (v.path === '/') {
-			newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] });
-		} else {
-			// 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用
-			// 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
-			if (v.path.indexOf('/:') > -1) {
-				v.meta['isDynamic'] = true;
-				v.meta['isDynamicPath'] = v.path;
-			}
-			newArr[0].children.push({ ...v });
-			// 存 name 值,keep-alive 中 include 使用,实现路由的缓存
-			// 路径:/@/layout/routerView/parent.vue
-			if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) {
-				cacheList.push(v.name);
-				const stores = useKeepALiveNames(pinia);
-				stores.setCacheKeepAlive(cacheList);
-			}
-		}
-	});
-	return newArr;
+    if (arr.length <= 0) return false;
+    const newArr: any = [];
+    const cacheList: Array<string> = [];
+    arr.forEach((v: any) => {
+        if (v.path === '/') {
+            newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] });
+        } else {
+            // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用
+            // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
+            if (v.path.indexOf('/:') > -1) {
+                v.meta['isDynamic'] = true;
+                v.meta['isDynamicPath'] = v.path;
+            }
+            newArr[0].children.push({ ...v });
+            // 存 name 值,keep-alive 中 include 使用,实现路由的缓存
+            // 路径:/@/layout/routerView/parent.vue
+            if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) {
+                cacheList.push(v.name);
+                const stores = useKeepALiveNames(pinia);
+                stores.setCacheKeepAlive(cacheList);
+            }
+        }
+    });
+    return newArr;
 }
 
-// isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts`
-if (!isRequestRoutes) initFrontEndControlRoutes();
+// // isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts`
+// if (!isRequestRoutes) initFrontEndControlRoutes();
 
 // 路由加载前
 router.beforeEach(async (to, from, next) => {
-	NProgress.configure({ showSpinner: false });
-	if (to.meta.title) NProgress.start();
-	const token = Session.get('token');
-	if (to.path === '/login' && !token) {
-		next();
-		NProgress.done();
-	} else {
-		if (!token) {
-			next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`);
-			Session.clear();
-			NProgress.done();
-		} else if (token && to.path === '/login') {
-			next('/home');
-			NProgress.done();
-		} else {
-			const storesRoutesList = useRoutesList(pinia);
-			const { routesList } = storeToRefs(storesRoutesList);
-			if (routesList.value.length === 0) {
-					// 后端控制路由:路由数据初始化,防止刷新时丢失
-				await initBackEndControlRoutes();
-					// 动态添加路由:防止非首页刷新时跳转回首页的问题
-					// 确保 addRoute() 时动态添加的路由已经被完全加载上去
-				next({ ...to, replace: true });
-			} else {
-				next();
-			}
-		}
-	}
+    NProgress.configure({ showSpinner: false });
+    if (to.meta.title) NProgress.start();
+    const token = Session.get('token');
+    if (to.path === '/login' && !token) {
+        next();
+        NProgress.done();
+    } else {
+        if (!token) {
+            next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`);
+            Session.clear();
+            NProgress.done();
+        } else if (token && to.path === '/login') {
+            next('/homeMenu');
+            NProgress.done();
+        } else {
+            const storesRoutesList = useRoutesList(pinia);
+            const { routesList } = storeToRefs(storesRoutesList);
+            if (routesList.value.length === 0) {
+                // 后端控制路由:路由数据初始化,防止刷新时丢失
+                await initBackEndControlRoutes();
+                // 动态添加路由:防止非首页刷新时跳转回首页的问题
+                // 确保 addRoute() 时动态添加的路由已经被完全加载上去
+                next({ ...to, replace: true });
+            } else {
+                next();
+            }
+        }
+    }
 });
 
 // 路由加载后
 router.afterEach(() => {
-	NProgress.done();
+    NProgress.done();
 });
 
 // 导出路由
diff --git a/src/utils/request.ts b/src/utils/request.ts
index c1b68b5..f8844cb 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -44,10 +44,16 @@
 service.interceptors.response.use(
     (response) => {
         // 对响应数据做点什么
-        if (response.data.code && (response.data.code === 'A0215' || response.data.code === 'A0214' || response.data.code === 'A0213')) {
+        if (response.data.code && response.data.code === 'A0213') {
+            ElMessage.error('用户uid不存在');
+            setTimeout(() => {
+                Session.clear();
+                window.location.href = '/';
+            }, 2000);
+        } else if (response.data.code && response.data.code === 'A0215') {
+            ElMessage.error('token失效');
             Session.clear();
             window.location.href = '/';
-            return Promise.reject(response);
         }
         // if(response.data.code && response.data.code !== '200'){
         return Promise.resolve(response);
diff --git a/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue b/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue
index 5fa3450..fc3be6a 100644
--- a/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue
+++ b/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue
@@ -23,7 +23,7 @@
                         <el-form-item label="所属部门" prop="depId">
                             <el-cascader
                                 :options="departmentList"
-                                :props="{ emitPath: false, checkStrictly: true, value: 'id', label: 'name' }"
+                                :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }"
                                 placeholder="请选择部门"
                                 clearable
                                 filterable
diff --git a/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue b/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue
index 71b95a8..85ea901 100644
--- a/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue
+++ b/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue
@@ -194,7 +194,6 @@
         };
 
         const changeClassifyTwoList = () => {
-            debugger;
             state.riskControlMeasureForm.classify2 = null;
             state.classifyTwoList = [];
             state.classifyTwoList = state.classifyTwoListAll.filter((item: any) => item.parentId === state.riskControlMeasureForm.classify1);
diff --git a/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue b/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue
index 117e9b5..9437517 100644
--- a/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue
+++ b/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue
@@ -49,7 +49,7 @@
                             <el-cascader
                                 @change="achieveUserList"
                                 :options="departmentList"
-                                :props="{ emitPath: false, checkStrictly: true, value: 'id', label: 'name' }"
+                                :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }"
                                 placeholder="请选择部门"
                                 clearable
                                 filterable
diff --git a/src/views/homeMenu/homeMenu.vue b/src/views/homeMenu/homeMenu.vue
index c16e22d..0e7d3d1 100644
--- a/src/views/homeMenu/homeMenu.vue
+++ b/src/views/homeMenu/homeMenu.vue
@@ -1,53 +1,91 @@
 <template>
-	<div class="login-container">
-		<div class="topPanel">
-			<div class="topPanelCont">
-				<div class="topTit">
-					<div>新疆国泰新华</div>
-					<span></span>
-					<div>安全风险预警监测系统</div>
-				</div>
-				<div class="userInfo">
-					<div class="avator">
-						<img src="../../assets/menu/admin.png">
-						<div>admin</div>
-					</div>
-					<span></span>
-					<div class="loginOut" @click="onLoginOut">退出登录</div>
-				</div>
-			</div>
-		</div>
+    <div class="login-container">
+        <div class="topPanel">
+            <div class="topPanelCont">
+                <div class="topTit">
+                    <div>新疆国泰新华</div>
+                    <span></span>
+                    <div>安全风险预警监测系统</div>
+                </div>
+                <div class="userInfo">
+                    <div class="avator">
+                        <img src="../../assets/menu/admin.png" />
+                        <div>admin</div>
+                    </div>
+                    <span></span>
+                    <div class="loginOut" @click="onLoginOut">退出登录</div>
+                </div>
+            </div>
+        </div>
 
-		<div class="menuGrid">
-			<div class="gridCont">
-				<el-row :gutter="20">
-					<el-col :span="6"><div class="grid-content" @click="renderMenu('2')"><div class="itemTit">双重预防系统</div><img class="iconImg" src="../../assets/menu/icon4.png"><img class="bgImg" src="../../assets/menu/card4.png"></div></el-col>
-					<el-col :span="6"><div class="grid-content" @click="renderMenu('3')"><div class="itemTit">特殊作业系统</div><img class="iconImg" src="../../assets/menu/icon7.png"><img class="bgImg" src="../../assets/menu/card7.png"></div></el-col>
-					<el-col :span="6"><div class="grid-content" @click="renderMenu('4')"><div class="itemTit">智能巡检系统</div><img class="iconImg" src="../../assets/menu/icon8.png"><img class="bgImg" src="../../assets/menu/card8.png"></div></el-col>
-					<el-col :span="6">
-						<div class="grid-content" @click="renderMenu('5')">
-							<div class="itemTit">安全风险综合
-								<br>预警预报平台
-							</div>
-							<img class="iconImg" src="../../assets/menu/icon1.png">
-							<img class="bgImg" src="../../assets/menu/card1.png">
-						</div>
-					</el-col>
-				</el-row>
-				<el-row :gutter="20">
-					<el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('6')"><div class="itemTit">应急管理系统</div><img class="iconImg" src="../../assets/menu/icon5.png"><img class="bgImg" src="../../assets/menu/card5.png"></div></el-col>
-					<el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('7')"><div class="itemTit">目标责任管理系统</div><img class="iconImg" src="../../assets/menu/icon2.png"><img class="bgImg" src="../../assets/menu/card2.png"></div></el-col>
-					<el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('8')"><div class="itemTit">事故管理系统</div><img class="iconImg" src="../../assets/menu/icon6.png"><img class="bgImg" src="../../assets/menu/card6.png"></div></el-col>
-					<el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('9')"><div class="itemTit">设备综合管控系统</div><img class="iconImg" src="../../assets/menu/icon9.png"><img class="bgImg" src="../../assets/menu/card9.png"></div></el-col>
-				</el-row>
-				<el-row :gutter="20">
-					<el-col :span="6"><div class="grid-content grid-content-3" @click="renderMenu('10')"><div class="itemTit">安全知识图谱系统</div><img class="iconImg" src="../../assets/menu/icon3.png"><img class="bgImg" src="../../assets/menu/card3.png"></div></el-col>
-					<el-col :span="9"><div class="grid-content grid-content-3" @click="renderMenu('11')"><div class="itemTit">危险化学品全生命周期安全<br>管理系统</div><img class="iconImg" src="../../assets/menu/icon10.png"><img class="bgImg" src="../../assets/menu/card10.png"></div></el-col>
-					<el-col :span="9"><div class="grid-content grid-content-3" @click="renderMenu('1')"><div class="itemTit">基础数据权限管理系统</div><img class="iconImg" src="../../assets/menu/icon11.png"><img class="bgImg" src="../../assets/menu/card11.png"></div></el-col>
-				</el-row>
-			</div>
-		</div>
-	</div>
+        <div class="menuGrid">
+            <div class="gridCont">
+                <el-row :gutter="20">
+                    <el-col :span="6"
+                        ><div class="grid-content" v-throttle @click="renderMenu('2')">
+                            <div class="itemTit">双重预防系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon4.png" /><img class="bgImg" src="../../assets/menu/card4.png" /></div
+                    ></el-col>
+                    <el-col :span="6"
+                        ><div class="grid-content" v-throttle @click="renderMenu('3')">
+                            <div class="itemTit">特殊作业系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon7.png" /><img class="bgImg" src="../../assets/menu/card7.png" /></div
+                    ></el-col>
+                    <el-col :span="6"
+                        ><div class="grid-content" v-throttle @click="renderMenu('4')">
+                            <div class="itemTit">智能巡检系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon8.png" /><img class="bgImg" src="../../assets/menu/card8.png" /></div
+                    ></el-col>
+                    <el-col :span="6">
+                        <div class="grid-content" v-throttle @click="renderMenu('5')">
+                            <div class="itemTit">安全风险综合 <br />预警预报平台</div>
+                            <img class="iconImg" src="../../assets/menu/icon1.png" />
+                            <img class="bgImg" src="../../assets/menu/card1.png" />
+                        </div>
+                    </el-col>
+                </el-row>
+                <el-row :gutter="20">
+                    <el-col :span="6"
+                        ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('6')">
+                            <div class="itemTit">应急管理系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon5.png" /><img class="bgImg" src="../../assets/menu/card5.png" /></div
+                    ></el-col>
+                    <el-col :span="6"
+                        ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('7')">
+                            <div class="itemTit">目标责任管理系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon2.png" /><img class="bgImg" src="../../assets/menu/card2.png" /></div
+                    ></el-col>
+                    <el-col :span="6"
+                        ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('8')">
+                            <div class="itemTit">事故管理系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon6.png" /><img class="bgImg" src="../../assets/menu/card6.png" /></div
+                    ></el-col>
+                    <el-col :span="6"
+                        ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('9')">
+                            <div class="itemTit">设备综合管控系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon9.png" /><img class="bgImg" src="../../assets/menu/card9.png" /></div
+                    ></el-col>
+                </el-row>
+                <el-row :gutter="20">
+                    <el-col :span="6"
+                        ><div class="grid-content grid-content-3" v-throttle @click="renderMenu('10')">
+                            <div class="itemTit">安全知识图谱系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon3.png" /><img class="bgImg" src="../../assets/menu/card3.png" /></div
+                    ></el-col>
+                    <el-col :span="9"
+                        ><div class="grid-content grid-content-3" v-throttle @click="renderMenu('11')">
+                            <div class="itemTit">危险化学品全生命周期安全<br />管理系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon10.png" /><img class="bgImg" src="../../assets/menu/card10.png" /></div
+                    ></el-col>
+                    <el-col :span="9"
+                        ><div class="grid-content grid-content-3" v-throttle @click="renderMenu('1')">
+                            <div class="itemTit">基础数据权限管理系统</div>
+                            <img class="iconImg" src="../../assets/menu/icon11.png" /><img class="bgImg" src="../../assets/menu/card11.png" /></div
+                    ></el-col>
+                </el-row>
+            </div>
+        </div>
+    </div>
 </template>
 
 <script lang="ts">
@@ -57,220 +95,281 @@
 import logoMini from '/@/assets/logo-mini.svg';
 import loginIconTwo from '/@/assets/login-icon-two.svg';
 import { NextLoading } from '/@/utils/loading';
-import {Session} from "/@/utils/storage";
-import {useRoute, useRouter} from "vue-router";
-import {initBackEndControlRoutes} from "/@/router/backEnd";
-import {useUserInfo} from "/@/stores/userInfo";
+import { Session } from '/@/utils/storage';
+import { useRoute, useRouter } from 'vue-router';
+import { initBackEndControlRoutes } from '/@/router/backEnd';
+import { useUserInfo } from '/@/stores/userInfo';
+import { useRoutesList } from '/@/stores/routesList';
+import pinia from '/@/stores';
+import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
+import { ElMessage } from 'element-plus';
+import { ElMessageBox } from 'element-plus/es';
+import { useLoginApi } from '/@/api/login';
+import { useI18n } from 'vue-i18n';
 
 // 定义接口来定义对象的类型
 interface LoginState {
-	tabsActiveName: string;
-	isScan: boolean;
+    tabsActiveName: string;
+    isScan: boolean;
 }
 
 export default defineComponent({
-	name: 'loginIndex',
-	components: {},
-	setup() {
-		const route = useRoute();
-		const router = useRouter();
-		const userInfo = useUserInfo()
-		const { userInfos } = storeToRefs(userInfo);
-		const storesThemeConfig = useThemeConfig();
-		const { themeConfig } = storeToRefs(storesThemeConfig);
-		const state = reactive<LoginState>({
-			tabsActiveName: 'account',
-			isScan: false,
-		});
-		// 获取布局配置信息
-		const getThemeConfig = computed(() => {
-			return themeConfig.value;
-		});
-		// 下拉菜单点击时
-		const onLoginOut = () => {
-			console.log('退出登录')
-		};
-		const renderMenu = async (value: string) => {
-			Session.set('projectId',value)
-			userInfos.value.projectId = value
-			await initBackEndControlRoutes();
-			router.push('/home')
-		};
-		// //点击进入特殊作业
-		// const toSpecialWorkSys = () => {
-		// 	router.push('/layoutPage');
-		// };
-		// 页面加载时
-		onMounted(() => {
-			NextLoading.done();
-			// loginBg();
-			// loginApp()
-		});
-		return {
-			logoMini,
-			loginIconTwo,
-			getThemeConfig,
-			renderMenu,
-			...toRefs(state),
-		};
-	},
+    name: 'loginIndex',
+    components: {},
+    setup() {
+        const { t } = useI18n();
+        const route = useRoute();
+        const router = useRouter();
+        const userInfo = useUserInfo();
+        const { userInfos } = storeToRefs(userInfo);
+        const routeToStore = useRoutesList(pinia);
+        const { routesList } = storeToRefs(routeToStore);
+        const storesThemeConfig = useThemeConfig();
+        const { themeConfig } = storeToRefs(storesThemeConfig);
+        const state = reactive<LoginState>({
+            tabsActiveName: 'account',
+            isScan: false
+        });
+        // 获取布局配置信息
+        const getThemeConfig = computed(() => {
+            return themeConfig.value;
+        });
+        // 下拉菜单点击时
+        const onLoginOut = () => {
+            ElMessageBox({
+                closeOnClickModal: false,
+                closeOnPressEscape: false,
+                title: t('message.user.logOutTitle'),
+                message: t('message.user.logOutMessage'),
+                showCancelButton: true,
+                confirmButtonText: t('message.user.logOutConfirm'),
+                cancelButtonText: t('message.user.logOutCancel'),
+                buttonSize: 'default',
+                beforeClose: (action, instance, done) => {
+                    if (action === 'confirm') {
+                        instance.confirmButtonLoading = true;
+                        instance.confirmButtonText = t('message.user.logOutExit');
+                        setTimeout(() => {
+                            done();
+                            setTimeout(() => {
+                                instance.confirmButtonLoading = false;
+                            }, 300);
+                        }, 700);
+                    } else {
+                        done();
+                    }
+                }
+            })
+                .then(async () => {
+                    let res = await useLoginApi().signOut();
+                    if (res.data.code === '200') {
+                        Session.clear(); // 清除缓存/token等
+                        // 使用 reload 时,不需要调用 resetRoute() 重置路由
+                        window.location.reload();
+                    } else {
+                        ElMessage({
+                            type: 'warning',
+                            message: res.data.msg
+                        });
+                    }
+                })
+                .catch(() => {});
+        };
+        const renderMenu = async (value: string) => {
+            Session.set('projectId', value);
+            userInfos.value.projectId = value;
+            await initBackEndControlRoutes().then(() => {
+                let linkToMenu = [...routesList.value];
+                if (linkToMenu && linkToMenu.length > 1) {
+                    router.push(linkToFirstMenu(JSON.parse(JSON.stringify(linkToMenu))[1]));
+                } else {
+                    ElMessage({ type: 'warning', message: '你没有该项目的权限' });
+                }
+            });
+        };
+        const linkToFirstMenu: any = (value: any) => {
+            let returnMenu = value;
+            if (returnMenu.children?.length > 0) {
+                return linkToFirstMenu(returnMenu.children[0]);
+            } else {
+                return returnMenu.path;
+            }
+        };
+        // //点击进入特殊作业
+        // const toSpecialWorkSys = () => {
+        // 	router.push('/layoutPage');
+        // };
+        // 页面加载时
+        onMounted(() => {
+            NextLoading.done();
+            // loginBg();
+            // loginApp()
+        });
+        return {
+            logoMini,
+            onLoginOut,
+            loginIconTwo,
+            getThemeConfig,
+            renderMenu,
+            ...toRefs(state)
+        };
+    }
 });
 </script>
 
 <style scoped lang="scss">
 .login-container {
-	width: 100%;
-	height: 100%;
-	position: relative;
-	background: url("../../assets/menu/bg_home1.jpg") no-repeat center;
-	.topPanel{
-		position: absolute;
-		width: 100%;
-		top: -100px;
-		left: 0;
-		height:100px;
-		background: #fff;
-		display: flex;
-		justify-content: center;
-		box-shadow: 0 8px 32px rgba(0,0,0,.1);
-		animation: showDown .6s 1 ease forwards;
+    width: 100%;
+    height: 100%;
+    position: relative;
+    background: url('../../assets/menu/bg_home1.jpg') no-repeat center;
+    .topPanel {
+        position: absolute;
+        width: 100%;
+        top: -100px;
+        left: 0;
+        height: 100px;
+        background: #fff;
+        display: flex;
+        justify-content: center;
+        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+        animation: showDown 0.6s 1 ease forwards;
 
-		@keyframes showDown {
-			100%{
-				position: absolute;
-				top: 0;
-			}
-		}
-		.topPanelCont{
-			width: 1200px;
-			height: 100%;
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
+        @keyframes showDown {
+            100% {
+                position: absolute;
+                top: 0;
+            }
+        }
+        .topPanelCont {
+            width: 1200px;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
 
-			.topTit{
-				font-size: 24px;
-				font-weight: bold;
-				display: flex;
-				align-items: center;
-				color: #333;
-				line-height: 28px;
+            .topTit {
+                font-size: 24px;
+                font-weight: bold;
+                display: flex;
+                align-items: center;
+                color: #333;
+                line-height: 28px;
 
-				&>div:last-of-type{
-					color: #006DF5;
-				}
+                & > div:last-of-type {
+                    color: #006df5;
+                }
 
-				span{
-					width: 1px;
-					height: 28px;
-					background: #999;
-					margin: 0 15px;
-				}
-			}
+                span {
+                    width: 1px;
+                    height: 28px;
+                    background: #999;
+                    margin: 0 15px;
+                }
+            }
 
-			.userInfo{
-				display: flex;
-				align-items: center;
+            .userInfo {
+                display: flex;
+                align-items: center;
 
-				.avator{
-					display: flex;
-					justify-content: right;
+                .avator {
+                    display: flex;
+                    justify-content: right;
 
-					img{
-						width: 20px;
-						height: 20px;
-						border-radius: 10px;
-					}
-					div{
-						font-size: 15px;
-						color: #333333;
-						line-height: 20px;
-						margin-left: 6px;
-					}
-				}
-				span{
-					width: 1px;
-					height: 20px;
-					background: #999;
-					margin: 0 15px;
-				}
-				.loginOut{
-					font-size: 15px;
-					color: #333;
-					line-height: 20px;
-					cursor: pointer;
+                    img {
+                        width: 20px;
+                        height: 20px;
+                        border-radius: 10px;
+                    }
+                    div {
+                        font-size: 15px;
+                        color: #333333;
+                        line-height: 20px;
+                        margin-left: 6px;
+                    }
+                }
+                span {
+                    width: 1px;
+                    height: 20px;
+                    background: #999;
+                    margin: 0 15px;
+                }
+                .loginOut {
+                    font-size: 15px;
+                    color: #333;
+                    line-height: 20px;
+                    cursor: pointer;
 
-					&:hover{
-						color: #006DF5;
-					}
-				}
-			}
-		}
-	}
+                    &:hover {
+                        color: #006df5;
+                    }
+                }
+            }
+        }
+    }
 
-	.menuGrid{
-		width: 100%;
-		position: absolute;
-		top: 150px;
-		display: flex;
-		justify-content: center;
-		.gridCont{
-			width: 1200px;
-			.el-row {
-				margin-bottom: 20px;
-			}
-			.el-row:last-child {
-				margin-bottom: 0;
-			}
-			.el-col {
-				border-radius: 8px;
-			}
+    .menuGrid {
+        width: 100%;
+        position: absolute;
+        top: 150px;
+        display: flex;
+        justify-content: center;
+        .gridCont {
+            width: 1200px;
+            .el-row {
+                margin-bottom: 20px;
+            }
+            .el-row:last-child {
+                margin-bottom: 0;
+            }
+            .el-col {
+                border-radius: 8px;
+            }
 
-			.grid-content {
-				border-radius: 10px;
-				height: 234px;
-				padding: 32px;
-				position: relative;
-				background-image: linear-gradient(135deg,#00C0F5,#44b1ff);
-				overflow: hidden;
-				cursor: pointer;
-				transition: .3s;
-				border: none;
+            .grid-content {
+                border-radius: 10px;
+                height: 234px;
+                padding: 32px;
+                position: relative;
+                background-image: linear-gradient(135deg, #00c0f5, #44b1ff);
+                overflow: hidden;
+                cursor: pointer;
+                transition: 0.3s;
+                border: none;
 
-				&:hover{
-					box-shadow: 0 8px 32px rgba(20,97,234,.4);
-				}
+                &:hover {
+                    box-shadow: 0 8px 32px rgba(20, 97, 234, 0.4);
+                }
 
-				.itemTit{
-					font-size: 24px;
-					line-height: 36px;
-					height: 40%;
-					font-family: "PingFang SC";
-					font-weight: lighter;
-					color: #fff;
-					margin-bottom: 25px;
-				}
-				.iconImg{
-					width: 80px;
-					height: 80px;
-				}
+                .itemTit {
+                    font-size: 24px;
+                    line-height: 36px;
+                    height: 40%;
+                    font-family: 'PingFang SC';
+                    font-weight: lighter;
+                    color: #fff;
+                    margin-bottom: 25px;
+                }
+                .iconImg {
+                    width: 80px;
+                    height: 80px;
+                }
 
-				.bgImg{
-					position: absolute;
-					right: 0;
-					bottom: 0;
-				}
-			}
+                .bgImg {
+                    position: absolute;
+                    right: 0;
+                    bottom: 0;
+                }
+            }
 
-			/*.grid-content-2{*/
-			/*	background-image: linear-gradient(135deg,#0098F5,#1461EA);*/
-			/*}*/
+            /*.grid-content-2{*/
+            /*	background-image: linear-gradient(135deg,#0098F5,#1461EA);*/
+            /*}*/
 
-			/*.grid-content-3{*/
-			/*	background-image: linear-gradient(135deg,#006DF5,#1450EA);*/
-			/*}*/
-		}
-
-	}
+            /*.grid-content-3{*/
+            /*	background-image: linear-gradient(135deg,#006DF5,#1450EA);*/
+            /*}*/
+        }
+    }
 }
 </style>
diff --git a/src/views/loginPage/component/accountLogin.vue b/src/views/loginPage/component/accountLogin.vue
index 60dca23..2508742 100644
--- a/src/views/loginPage/component/accountLogin.vue
+++ b/src/views/loginPage/component/accountLogin.vue
@@ -14,6 +14,7 @@
 				v-model="ruleForm.password"
 				autocomplete="off"
 				size="large"
+                @keyup.enter.native="onSignIn"
 			>
 				<template #prefix>
 					<el-icon class="el-input__icon" style="margin-right: 20px"><img src="../../../assets/loginPage/login_icon_password.png" style="width: 24px;height: 24px"></el-icon>
diff --git a/src/views/system/department/component/deptDialog.vue b/src/views/system/department/component/deptDialog.vue
index b1df6b5..e3757f2 100644
--- a/src/views/system/department/component/deptDialog.vue
+++ b/src/views/system/department/component/deptDialog.vue
@@ -7,23 +7,23 @@
 						<el-form-item label="上级部门">
 							<el-cascader
 								:options="deptData"
-								:props="{ checkStrictly: true, value: 'id', label: 'name' }"
+								:props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }"
 								placeholder="请选择部门"
 								clearable
 								class="w100"
-								v-model="departmentForm.struct"
+								v-model="departmentForm.parentDepId"
 							>
 							</el-cascader>
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
 						<el-form-item label="部门名称">
-							<el-input v-model="departmentForm.name" placeholder="请输入部门名称" clearable></el-input>
+							<el-input v-model="departmentForm.depName" placeholder="请输入部门名称" clearable></el-input>
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
 						<el-form-item label="部门描述">
-							<el-input v-model="departmentForm.info" type="textarea" placeholder="请输入部门描述" maxlength="150"></el-input>
+							<el-input v-model="departmentForm.depInfo" type="textarea" placeholder="请输入部门描述" maxlength="150"></el-input>
 						</el-form-item>
 					</el-col>
 				</el-row>
@@ -31,7 +31,7 @@
 			<template #footer>
 				<span class="dialog-footer">
 					<el-button @click="onCancel" size="default">取 消</el-button>
-					<el-button type="primary" @click="onSubmit" size="default">新 增</el-button>
+					<el-button type="primary" @click="onSubmit" size="default">确 定</el-button>
 				</span>
 			</template>
 		</el-dialog>
@@ -45,7 +45,6 @@
 
 // 定义接口来定义对象的类型
 interface TableDataRow {
-	struct: Array<string>;
 	name:string,
 	info:string,
 	parentId:string,
@@ -55,10 +54,9 @@
 	title:string;
 	isShowDialog: boolean;
 	departmentForm: {
-		struct: Array<string>;
-		name:string,
-		info:string,
-		parentId:string
+        depName:string,
+        depInfo:string,
+        parentDepId:string
 	};
 	deptData: Array<TableDataRow>;
 }
@@ -70,10 +68,9 @@
 			title:'',
 			isShowDialog: false,
 			departmentForm: {
-				name:'',
-				parentId:'',
-				info:'',
-				struct:[]
+                depName:'',
+                parentDepId:'',
+                depInfo:'',
 			},
 			deptData: [], // 部门数据
 		});
@@ -84,10 +81,9 @@
 			if(type === '新增'){
 				state.title = '新增部门'
 				state.departmentForm = {
-					name:'',
-					parentId:'',
-					info:'',
-					struct:[]
+                    depName:'',
+                    parentDepId:'',
+                    depInfo:'',
 				}
 			}else{
 				state.title = '修改部门'
@@ -104,10 +100,6 @@
 		};
 		// 新增
 		const onSubmit = async () => {
-			if(state.departmentForm.struct && state.departmentForm.struct !== []){
-				let departmentId = JSON.parse(JSON.stringify(state.departmentForm.struct))
-				state.departmentForm.parentId = departmentId[departmentId.length - 1]
-			}
 			if(state.title === '新增部门'){
 				let res = await departmentApi().addDepartment(state.departmentForm)
 				if(res.data.code === '200'){
diff --git a/src/views/system/department/index.vue b/src/views/system/department/index.vue
index ca69129..28464ce 100644
--- a/src/views/system/department/index.vue
+++ b/src/views/system/department/index.vue
@@ -19,11 +19,11 @@
 			<el-table
 				:data="tableData.data"
 				style="width: 100%"
-				row-key="id"
+				row-key="depId"
 				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
 			>
-				<el-table-column prop="name" label="部门名称" show-overflow-tooltip> </el-table-column>
-				<el-table-column prop="info" label="部门描述" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="depName" label="部门名称" show-overflow-tooltip> </el-table-column>
+				<el-table-column prop="depInfo" label="部门描述" show-overflow-tooltip></el-table-column>
 				<el-table-column label="操作" show-overflow-tooltip width="140">
 					<template #default="scope">
 						<el-button size="small" text type="primary" @click="onOpenDeptDialog('新增','')">新增</el-button>
@@ -42,6 +42,7 @@
 import { ElMessageBox, ElMessage } from 'element-plus';
 import deptDialog from '/@/views/system/department/component/deptDialog.vue';
 import {departmentApi} from "/@/api/department";
+import {useRoleApi} from "/@/api/role";
 
 // 定义接口来定义对象的类型
 interface TableDataRow {
@@ -49,7 +50,7 @@
 	status: boolean;
 	parentId: number;
 	info: string;
-	id: number;
+    depId: number;
 	children?: TableDataRow[];
 }
 interface TableDataState {
@@ -91,13 +92,26 @@
 		};
 		// 删除当前行
 		const onTabelRowDel = (row: TableDataRow) => {
-			ElMessageBox.confirm(`此操作将永久删除部门:${row.id}, 是否继续?`, '提示', {
+			ElMessageBox.confirm(`此操作将永久删除部门:${row.depId}, 是否继续?`, '提示', {
 				confirmButtonText: '删除',
 				cancelButtonText: '取消',
 				type: 'warning',
-			}).then(() => {
-					ElMessage.success('删除成功');
-			}).catch(() => {});
+			}).then(async () => {
+                let res = await departmentApi().deleteDepartment({depId:row.depId})
+                if(res.data.code ==='200'){
+                    ElMessage({
+                        type:'success',
+                        duration:2000,
+                        message:'删除成功'
+                    })
+                    await initTableData()
+                }else{
+                    ElMessage({
+                        type:'warning',
+                        message:res.data.msg
+                    })
+                }
+            }).catch(() => {});
 		};
 		// 页面加载时
 		onMounted(() => {
diff --git a/src/views/system/menu/component/menuDialog.vue b/src/views/system/menu/component/menuDialog.vue
index c5bb3fd..f223f93 100644
--- a/src/views/system/menu/component/menuDialog.vue
+++ b/src/views/system/menu/component/menuDialog.vue
@@ -38,7 +38,7 @@
                     </el-col>
                     <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                         <el-form-item label="菜单图标">
-                            <input placeholder="请输入菜单图标" v-model="ruleForm.meta.icon" type="all" />
+                            <el-input placeholder="请输入菜单图标" v-model="ruleForm.meta.icon" type="all" />
                             <!--							<IconSelector placeholder="请输入菜单图标" v-model="ruleForm.meta.icon" type="all" />-->
                         </el-form-item>
                     </el-col>
diff --git a/src/views/system/role/component/roleDialog.vue b/src/views/system/role/component/roleDialog.vue
index 9470bf4..d3b7c04 100644
--- a/src/views/system/role/component/roleDialog.vue
+++ b/src/views/system/role/component/roleDialog.vue
@@ -5,17 +5,17 @@
 				<el-row :gutter="35">
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						<el-form-item label="角色名称">
-							<el-input v-model="roleForm.name" placeholder="请输入角色名称" clearable></el-input>
+							<el-input v-model="roleForm.roleName" placeholder="请输入角色名称" clearable></el-input>
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						<el-form-item label="角色标识">
-							<el-input v-model="roleForm.code" placeholder="请输入角色标识" clearable></el-input>
+							<el-input v-model="roleForm.roleCode" placeholder="请输入角色标识" clearable></el-input>
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
 						<el-form-item label="角色描述">
-							<el-input v-model="roleForm.info" type="textarea" placeholder="请输入角色描述" maxlength="150"></el-input>
+							<el-input v-model="roleForm.roleInfo" type="textarea" placeholder="请输入角色描述" maxlength="150"></el-input>
 						</el-form-item>
 					</el-col>
 				</el-row>
@@ -33,7 +33,6 @@
 <script lang="ts">
 import { ElMessage } from 'element-plus';
 import { reactive, toRefs, defineComponent } from 'vue';
-import {departmentApi} from "/@/api/department";
 import {useRoleApi} from "/@/api/role";
 
 // 定义接口来定义对象的类型
@@ -47,9 +46,9 @@
 	buttonName:string,
 	isShowRoleDialog: boolean;
 	roleForm: {
-		name: string;
-		code: string;
-		info: string;
+		roleName: string;
+        roleCode: string;
+        roleInfo: string;
 	};
 	menuData: Array<MenuDataTree>;
 	menuProps: {
@@ -66,9 +65,9 @@
 			title:'',
 			buttonName:'',
 			roleForm: {
-				name: '', // 角色名称
-				code: '', // 角色标识
-				info: '', // 排序
+                roleName: '', // 角色名称
+                roleCode: '', // 角色标识
+                roleInfo: '', // 排序
 			},
 			menuData: [],
 			menuProps: {
@@ -83,9 +82,9 @@
 				state.title = '新增角色'
 				state.buttonName = '新增'
 				state.roleForm = {
-					name:'',
-					code:'',
-					info:'',
+                    roleName:'',
+                    roleCode:'',
+                    roleInfo:'',
 				}
 			}else{
 				state.title = '修改角色'
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index b05db16..93922e3 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -18,15 +18,15 @@
 			</div>
 			<el-table :data="tableData.data" style="width: 100%">
 				<el-table-column type="index" label="序号" width="60" />
-				<el-table-column prop="name" label="角色名称" show-overflow-tooltip></el-table-column>
-				<el-table-column prop="code" label="角色标识" show-overflow-tooltip></el-table-column>
-				<el-table-column prop="info" label="角色描述" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="roleName" label="角色名称" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="roleCode" label="角色标识" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="roleInfo" label="角色描述" show-overflow-tooltip></el-table-column>
 				<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column>
 				<el-table-column label="操作" width="150">
 					<template #default="scope">
 						<el-button size="small" text type="primary" @click="onOpenDialogRef('新增','')">新增</el-button>
 						<el-button size="small" text type="primary" @click="onOpenDialogRef('修改',scope.row)">修改</el-button>
-						<el-button size="small" text type="primary" @click="onTabelRowDel(scope.row)">删除</el-button>
+						<el-button size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
 					</template>
 				</el-table-column>
 			</el-table>
@@ -40,10 +40,13 @@
 import { ElMessageBox, ElMessage } from 'element-plus';
 import roleDialog from '/@/views/system/role/component/roleDialog.vue';
 import {useRoleApi} from "/@/api/role";
+import {useMenuApi} from "/@/api/menu";
+import {Session} from "/@/utils/storage";
+import {initBackEndControlRoutes} from "/@/router/backEnd";
 
 // 定义接口来定义对象的类型
 interface TableData {
-	roleName: string;
+    roleName: string;
 	roleSign: string;
 	describe: string;
 	sort: number;
@@ -100,9 +103,22 @@
 				confirmButtonText: '确认',
 				cancelButtonText: '取消',
 				type: 'warning',
-			}).then(() => {
-					ElMessage.success('删除成功');
-			}).catch(() => {});
+			}).then(async () => {
+                let res = await useRoleApi().deleteRole({roleId:row.roleId})
+                if(res.data.code ==='200'){
+                    ElMessage({
+                        type:'success',
+                        duration:2000,
+                        message:'删除成功'
+                    })
+                    await initRoleTableData()
+                }else{
+                    ElMessage({
+                        type:'warning',
+                        message:res.data.msg
+                    })
+                }
+            }).catch(() => {});
 		};
 		const handleSearch = () => {
 			initRoleTableData()

--
Gitblit v1.9.2