Browse Source

Merge remote-tracking branch 'origin/master'

lanceJiang 1 year ago
parent
commit
eb1e7c0a34
41 changed files with 768 additions and 99 deletions
  1. 6 0
      README.md
  2. 2 1
      package.json
  3. 28 0
      src/api/system/message.ts
  4. 5 5
      src/components/FormConfig/index.vue
  5. 4 3
      src/components/IconSelect/index.vue
  6. 27 26
      src/components/RightPanel/index.vue
  7. 3 3
      src/hooks/useTheme.ts
  8. 6 6
      src/layout/LayoutLeft/index.scss
  9. 6 6
      src/layout/LayoutLeftMix/index.scss
  10. 3 3
      src/layout/LayoutTop/index.scss
  11. 2 1
      src/layout/LayoutTop/index.vue
  12. 4 4
      src/layout/LayoutTopMix/index.scss
  13. 8 13
      src/layout/components/Header/ToolBarRight.vue
  14. 132 0
      src/layout/components/Header/components/Message.vue
  15. 120 0
      src/layout/components/Header/components/SearchMenu.vue
  16. 4 3
      src/layout/components/Menu/SubMenu.vue
  17. 1 1
      src/router/index.ts
  18. 21 6
      src/store/modules/permission.ts
  19. 4 5
      src/styles/index.scss
  20. 6 0
      src/styles/project_normal.scss
  21. 3 1
      src/styles/sidebar.scss
  22. 1 0
      src/views/configure/index.vue
  23. 1 0
      src/views/demo/adminManage/index.vue
  24. 1 0
      src/views/demo/pageConfig/index.vue
  25. 74 1
      src/views/flow/create/components/ExtendSet.vue
  26. 6 5
      src/views/flow/create/index.vue
  27. 1 0
      src/views/flow/form/index.vue
  28. 1 0
      src/views/flow/group/index1.vue
  29. 0 2
      src/views/flow/modal/index.vue
  30. 79 0
      src/views/message/list/detail.vue
  31. 188 0
      src/views/message/list/index.vue
  32. 1 0
      src/views/setting/app/index.vue
  33. 1 0
      src/views/setting/configure/index.vue
  34. 1 0
      src/views/setting/department/index.vue
  35. 1 0
      src/views/setting/dict/index.vue
  36. 1 0
      src/views/setting/post/index.vue
  37. 1 0
      src/views/setting/region/index.vue
  38. 1 0
      src/views/setting/role/index.vue
  39. 1 1
      src/views/setting/user/assign-role.vue
  40. 12 2
      src/views/setting/user/index.vue
  41. 1 1
      src/views/setting/user/reset-pwd.vue

+ 6 - 0
README.md

@@ -38,3 +38,9 @@
   - 复制
   - 移动
   - 停用
+
+- 搜索折叠效果优化  暂时不调整
+- 流程创建接口调整【后台】
+- 用户部门设置【前台、后台】 - 等待后台提供
+- 创建流程、指定人员选择
+- 表单设计权限设置设计

+ 2 - 1
package.json

@@ -29,6 +29,7 @@
     "@element-plus/icons-vue": "^2.1.0",
     "@vueuse/core": "^10.1.2",
     "axios": "^1.4.0",
+    "colord": "^2.9.3",
     "dayjs": "^1.11.7",
     "echarts": "^5.4.2",
     "element-plus": "^2.3.4",
@@ -47,7 +48,7 @@
     "vuedraggable": "^4.1.0"
   },
   "devDependencies": {
-		"@types/js-md5": "^0.7.0",
+    "@types/js-md5": "^0.7.0",
     "@types/nprogress": "^0.2.0",
     "@types/path-browserify": "^1.0.0",
     "@types/vue-ls": "^3.2.3",

+ 28 - 0
src/api/system/message.ts

@@ -0,0 +1,28 @@
+import request from '@/utils/request'
+import { AxiosPromise } from 'axios'
+
+/**
+ * 获取路由列表
+ */
+export function getMessage() {
+	return request({
+		url: '/sys/message/inform',
+		method: 'get'
+		// extraConfig: { showFullscreenLoading: true }
+	})
+}
+
+export function getMessageInfo(data: any): AxiosPromise {
+	return request({
+		url: '/sys/message/page',
+		method: 'post',
+		data
+	})
+}
+
+export function getMessageInfoById(id: any): AxiosPromise {
+	return request({
+		url: '/sys/message/get?id=' + id,
+		method: 'get'
+	})
+}

+ 5 - 5
src/components/FormConfig/index.vue

@@ -506,12 +506,12 @@ const FormConfig = defineComponent({
 			const createFooter = () => {
 				return (
 					<div class="footer">
-						{showCancelBtn && (
-							<el-button class="cancel-button" size={size} onClick={cancelHandler}>
-								{t(cancelBtnText)}
-							</el-button>
-						)}
 						<div class="right-actions">
+							{showCancelBtn && (
+								<el-button class="cancel-button" size={size} onClick={cancelHandler}>
+									{t(cancelBtnText)}
+								</el-button>
+							)}
 							{showResetBtn && (
 								<el-button class="reset-button" plain size={size} onClick={resetHandler.bind(null, undefined)}>
 									{t(resetBtnText)}

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

@@ -1,8 +1,9 @@
 <template>
 	<div class="icon-select">
-		<el-input v-model="iconName" :disabled="disabled" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">
-			<template #suffix><i class="el-icon-search el-input__icon" /></template>
-		</el-input>
+		<!--		<el-input v-model="iconName" :disabled="disabled" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">-->
+		<!--			<template #suffix><i class="el-icon-search el-input__icon" /></template>-->
+		<!--		</el-input>-->
+		<svg-icon class="local_icon" :icon-class="iconName" />
 		<div class="icon-select__list">
 			<div
 				v-for="(item, index) in iconList"

+ 27 - 26
src/components/RightPanel/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<div ref="rightPanel" :class="{ show }" class="rightPanel-container">
+	<div ref="rightPanel" :class="{ show }" class="rightPanel-wrap">
 		<div class="rightPanel-background" />
 		<div class="rightPanel">
 			<div class="handle-button" :style="{ top: buttonTop + 'px', 'background-color': themeColor }" @click="show = !show">
@@ -77,26 +77,15 @@ onBeforeUnmount(() => {
 })
 </script>
 
-<style>
+<style lang="scss">
 .showRightPanel {
 	overflow: hidden;
 	position: relative;
 	//width: calc(100% - 15px);
-	width: 100%;
 }
 </style>
 
 <style lang="scss" scoped>
-.rightPanel-background {
-	position: fixed;
-	top: 0;
-	left: 0;
-	opacity: 0;
-	transition: opacity 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
-	background: rgba(0, 0, 0, 0.2);
-	z-index: -1;
-}
-
 .rightPanel {
 	width: 100%;
 	max-width: 280px;
@@ -104,29 +93,43 @@ onBeforeUnmount(() => {
 	position: fixed;
 	top: 0;
 	right: 0;
-	box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.05);
+	z-index: 99;
+	//box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.05);
 	//transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
 	transform: translate(100%);
-	//background: #fff;
 	//background-color: var(--el-drawer-bg-color);
 	background-color: var(--el-bg-color);
 	//box-shadow: var(--el-box-shadow-dark);
+	box-shadow: var(--el-box-shadow-lighter);
 	transition: all var(--el-transition-duration);
-	z-index: 99;
+	&-items {
+		display: none;
+		height: 100%;
+	}
+	&-background {
+		position: fixed;
+		top: 0;
+		left: 0;
+		opacity: 0;
+		transition: opacity 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
+		background: var(--el-fill-color-darker);
+		z-index: -1;
+	}
 }
-
 .show {
 	transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
 
-	.rightPanel-background {
-		z-index: 88;
-		opacity: 1;
-		width: 100%;
-		height: 100%;
-	}
-
 	.rightPanel {
 		transform: translate(0);
+		&-items {
+			display: block;
+		}
+		&-background {
+			z-index: 88;
+			opacity: 0.5;
+			width: 100%;
+			height: 100%;
+		}
 	}
 }
 
@@ -148,8 +151,6 @@ onBeforeUnmount(() => {
 	line-height: 32px;
 
 	.icon {
-		//font-size: 24px;
-		//line-height: 32px;
 		width: 18px;
 		height: 18px;
 	}

+ 3 - 3
src/hooks/useTheme.ts

@@ -13,7 +13,7 @@ import { footerTheme } from '@/styles/theme/footer'
  * */
 export const useTheme = () => {
 	const { setting } = useStore()
-	const { themeColor, layout, isDark, asideInverted, headerInverted, footerInverted /*isGrey, isWeak, */ } = storeToRefs(setting)
+	const { themeColor, layout, isDark, isGrey, isWeak, asideInverted, headerInverted, footerInverted } = storeToRefs(setting)
 
 	// 切换暗黑主题 ==> 同时修改主题颜色、侧边栏、头部颜色
 	const switchDark = () => {
@@ -103,8 +103,8 @@ export const useTheme = () => {
 	// init theme
 	const initTheme = () => {
 		switchDark()
-		// if (isGrey.value) changeGreyOrWeak('grey', true)
-		// if (isWeak.value) changeGreyOrWeak('weak', true)
+		if (isGrey.value) changeGreyOrWeak('grey', true)
+		if (isWeak.value) changeGreyOrWeak('weak', true)
 	}
 
 	return {

+ 6 - 6
src/layout/LayoutLeft/index.scss

@@ -5,10 +5,10 @@
 	.el-aside {
 		width: auto;
 		background-color: var(--el-menu-bg-color);
-		//border-right: 1px solid var(--el-aside-border-color);
-		box-shadow: 1px 0 2px var(--el-aside-border-color);
+		border-right: 1px solid var(--el-aside-border-color);
+		//box-shadow: 1px 0 2px var(--el-aside-border-color);
 		//box-shadow: 1px 0 4px -1px var(--el-aside-border-color);
-		z-index: $header_index + 1;
+		//z-index: $header_index + 1;
 		//box-shadow: 2px 0 8px #1d23290d;
 		.aside-box {
 			display: flex;
@@ -61,9 +61,9 @@
 		height: $header_height;
 		padding: 0;
 		background-color: var(--el-header-bg-color);
-		//border-bottom: 1px solid var(--el-header-border-color);
-		box-shadow: 0 1px 4px -1px var(--el-header-border-color);
-		z-index: $header_index;
+		border-bottom: 1px solid var(--el-header-border-color);
+		//box-shadow: 0 1px 4px -1px var(--el-header-border-color);
+		//z-index: $header_index;
 	}
 	.app-main {
 		min-height: 0;

+ 6 - 6
src/layout/LayoutLeftMix/index.scss

@@ -9,9 +9,9 @@
 		width: 70px;
 		height: 100%;
 		background-color: var(--el-menu-bg-color);
-		//border-right: 1px solid var(--el-aside-border-color);
-		box-shadow: 1px 0 2px var(--el-aside-border-color);
-		z-index: $header_index + 3;
+		border-right: 1px solid var(--el-aside-border-color);
+		//box-shadow: 1px 0 2px var(--el-aside-border-color);
+		//z-index: $header_index + 3;
 		.logo {
 			display: flex;
 			align-items: center;
@@ -89,9 +89,9 @@
 		height: 100%;
 		overflow: hidden;
 		background-color: var(--el-menu-bg-color);
-		//border-right: 1px solid var(--el-aside-border-color);
-		z-index: $header_index + 2;
-		box-shadow: 1px 0 2px var(--el-aside-border-color);
+		border-right: 1px solid var(--el-aside-border-color);
+		//z-index: $header_index + 2;
+		//box-shadow: 1px 0 2px var(--el-aside-border-color);
 		//box-shadow: 2px 0 8px #1d23290d;
 		//box-shadow: 1px 0 4px -1px var(--el-aside-border-color);
 		transition: width 0.3s ease;

+ 3 - 3
src/layout/LayoutTop/index.scss

@@ -10,9 +10,9 @@
 		height: $header_height;
 		padding: 0;
 		background-color: var(--el-header-bg-color);
-		//border-bottom: 1px solid var(--el-header-border-color);
-		box-shadow: 0 1px 4px -1px var(--el-header-border-color);
-		z-index: $header_index;
+		border-bottom: 1px solid var(--el-header-border-color);
+		//box-shadow: 0 1px 4px -1px var(--el-header-border-color);
+		//z-index: $header_index;
 		.logo {
 			display: flex;
 			align-items: center;

+ 2 - 1
src/layout/LayoutTop/index.vue

@@ -56,6 +56,7 @@ import SubMenu from '@/layout/components/Menu/SubMenu.vue'
 import MenuIcon from '@/layout/components/Menu/MenuIcon.vue'
 import useStore from '@/store'
 import { generateTitle } from '@/utils/i18n'
+import { isExternal } from '@/utils/validate.ts'
 
 const title = import.meta.env.VITE_APP_TITLE
 const { permission, setting, app } = useStore()
@@ -67,7 +68,7 @@ const menuList = computed(() => permission.showMenuList)
 const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string)
 
 const handleClickMenu = (subItem: Menu.MenuOptions) => {
-	if (subItem.meta.isLink) return window.open(subItem.meta.isLink, '_blank')
+	if (isExternal(subItem.path)) return window.open(subItem.path, '_blank')
 	router.push(subItem.path)
 }
 </script>

+ 4 - 4
src/layout/LayoutTopMix/index.scss

@@ -11,10 +11,10 @@
     //padding: 0 15px 0 0;
     padding: 0;
     background-color: var(--el-header-bg-color);
-		//border-bottom: 1px solid var(--el-header-border-color);
-		//box-shadow: 0 2px 8px var(--el-header-border-color);
-		box-shadow: 0 1px 4px -1px var(--el-header-border-color);
-		z-index: $header_index + 1;
+    border-bottom: 1px solid var(--el-header-border-color);
+    //box-shadow: 0 2px 8px var(--el-header-border-color);
+    //box-shadow: 0 1px 4px -1px var(--el-header-border-color);
+    //z-index: $header_index + 1;
     .header-lf {
       display: flex;
       align-items: center;

+ 8 - 13
src/layout/components/Header/ToolBarRight.vue

@@ -1,17 +1,14 @@
 <template>
 	<div class="tool-bar-right">
 		<div class="header-icon">
-			<!--			<AssemblySize id="assemblySize" />-->
-			<Screenfull id="screenfull" />
+			<ScreenFull />
 			<el-tooltip content="布局大小" effect="dark" placement="bottom">
-				<SizeSelect id="size-select" class="right-menu-item le-hover-effect--bg" />
+				<SizeSelect class="right-menu-item le-hover-effect--bg" />
 			</el-tooltip>
-			<Language id="language" class="right-menu-item le-hover-effect--bg" />
-			<!--      todo...搜索 -->
-			<!--			<SearchMenu id="searchMenu" />-->
+			<Language class="right-menu-item le-hover-effect--bg" />
+			<SearchMenu />
 			<!--			<ThemeSetting id="themeSetting" />-->
-			<!--			<Message id="message" />-->
-			<!--			<Fullscreen id="fullscreen" />-->
+			<Message class="right-menu-item le-hover-effect--bg" />
 		</div>
 		<Avatar />
 	</div>
@@ -19,13 +16,11 @@
 
 <script setup lang="ts">
 import { computed } from 'vue'
-// import AssemblySize from './components/AssemblySize.vue'
 import Language from './components/Language.vue'
-import Screenfull from '@/components/Screenfull/index.vue'
+import ScreenFull from '@/components/Screenfull/index.vue'
 import SizeSelect from '@/components/SizeSelect/index.vue'
-// import SearchMenu from './components/SearchMenu.vue'
-// import ThemeSetting from './components/ThemeSetting.vue'
-// import Message from './components/Message.vue'
+import SearchMenu from './components/SearchMenu.vue'
+import Message from './components/Message.vue'
 // import Fullscreen from './components/Fullscreen.vue'
 import Avatar from './components/Avatar.vue'
 

+ 132 - 0
src/layout/components/Header/components/Message.vue

@@ -0,0 +1,132 @@
+<template>
+	<el-popover placement="bottom" :width="310" trigger="click">
+		<template #reference>
+			<div class="right-menu-item le-hover-effect--bg">
+				<el-badge class="item" :value="total">
+					<i class="le-iconfont le-notice"></i>
+				</el-badge>
+			</div>
+		</template>
+		<el-tabs v-model="activeTab">
+			<el-tab-pane v-for="v of tabsConfig" :key="v.name" :name="v.name">
+				<template #label> {{ v.label }}({{ v.list.length }}) </template>
+				<template v-if="v.list.length">
+					<div class="message-list">
+						<div v-for="item of v.list" :key="item.id" class="message-item" @click="jumpMessageDetail(item.id)">
+							<!--<img src="" alt="" class="message-icon" />-->
+							<div class="message-content">
+								<div class="message-title">
+									<span class="txt text-overflow_ellipsis" :title="item.title">{{ item.title }}</span>
+									<span class="message-date">{{ item.createTime }}</span>
+								</div>
+								<span class="message-txt">{{ item.content }}</span>
+							</div>
+						</div>
+						<div class="message-fix-item" @click="jumpMessageInfo">查看更多</div>
+					</div>
+				</template>
+				<template v-else>
+					<LeNoData />
+				</template>
+			</el-tab-pane>
+		</el-tabs>
+	</el-popover>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive } from 'vue'
+import { getMessage } from '@/api/system/message'
+import router from '@/router'
+// noticeList  通知     messageList   消息     todoList   待办
+const tabsConfig = reactive({
+	noticeList: {
+		name: 'noticeList',
+		label: '通知',
+		list: []
+	},
+	messageList: {
+		name: 'messageList',
+		label: '消息',
+		list: []
+	},
+	todoList: {
+		name: 'todoList',
+		label: '待办',
+		list: []
+	}
+})
+const activeTab = ref('noticeList')
+const total = ref(0)
+getMessage().then(res => {
+	console.error(res, 'res///')
+	let _total = 0
+	Object.keys(tabsConfig).map(key => {
+		if (res[key]) {
+			tabsConfig[key].list = res[key]
+			_total += res[key].length
+		} else {
+			res[key].list = []
+		}
+	})
+	total.value = _total
+})
+
+const jumpMessageInfo = () => {
+	router.push('/message/list')
+}
+
+const jumpMessageDetail = (id: any) => {
+	router.push('/message/list?id=' + id)
+}
+</script>
+
+<style scoped lang="scss">
+.message-list {
+	display: flex;
+	flex-direction: column;
+	max-height: 390px;
+	overflow-y: auto;
+	.message-item {
+		display: flex;
+		align-items: center;
+		padding: 8px 0;
+		border-bottom: 1px solid var(--el-border-color-light);
+		cursor: pointer;
+		&:last-child {
+			border: none;
+		}
+		.message-content {
+			display: flex;
+			flex-direction: column;
+			width: 100%;
+			.message-title {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				margin-bottom: 5px;
+				font-weight: 600;
+				color: var(--el-text-color-primary);
+			}
+			.message-date {
+				font-size: 12px;
+				color: var(--el-text-color-secondary);
+				margin-left: 10px;
+				font-weight: 400;
+				flex-shrink: 0;
+			}
+			.message-txt {
+				//margin-bottom: 5px;
+				color: var(--el-text-color-regular);
+			}
+		}
+	}
+	.message-fix-item {
+		// flex 居中
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		height: 40px;
+		cursor: pointer;
+	}
+}
+</style>

+ 120 - 0
src/layout/components/Header/components/SearchMenu.vue

@@ -0,0 +1,120 @@
+<template>
+	<div class="search-menu-wrap">
+		<div class="right-menu-item le-hover-effect--bg" @click="handleOpen">
+			<LeIcon icon-class="le-search" />
+		</div>
+		<el-dialog v-model="isShowSearch" destroy-on-close :modal="false" :show-close="false" fullscreen @click="closeSearch">
+			<el-autocomplete
+				ref="menuInputRef"
+				v-model="searchMenu"
+				value-key="path"
+				placeholder="菜单搜索"
+				:fetch-suggestions="searchMenuList"
+				@select="handleClickMenu"
+				@click.stop
+			>
+				<template #prefix>
+					<LeIcon icon-class="le-search" />
+				</template>
+				<template #default="{ item }">
+					<MenuIcon v-if="item.meta?.icon" :icon-class="item.meta.icon" />
+					<span> {{ item.meta.local_title }} </span>
+				</template>
+			</el-autocomplete>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup lang="ts" name="SearchMenu">
+import { ref, computed, nextTick } from 'vue'
+import { AppRouteRecordRaw } from '@/router/types'
+import MenuIcon from '@/layout/components/Menu/MenuIcon.vue'
+import { useRouter } from 'vue-router'
+import { generateTitle } from '@/utils/i18n'
+import { isExternal } from '@/utils/validate'
+import useStore from '@/store'
+const router = useRouter()
+const { permission } = useStore()
+const menuList = computed(() => {
+	return permission.showMenuListFlat.map(v => {
+		return {
+			...v,
+			meta: {
+				...v.meta,
+				local_title: generateTitle(v.meta.title)
+			}
+		}
+	})
+})
+const searchMenuList = (queryString: string, cb: () => {}) => {
+	const _menuList = queryString ? menuList.value.filter(filterNodeMethod(queryString)) : menuList.value
+	cb(_menuList)
+}
+
+// 打开搜索框
+const isShowSearch = ref(false)
+const menuInputRef = ref()
+const searchMenu = ref('')
+const handleOpen = () => {
+	isShowSearch.value = true
+	nextTick(() => {
+		setTimeout(() => {
+			menuInputRef.value.focus()
+		})
+	})
+}
+
+// 搜索窗关闭
+const closeSearch = () => {
+	isShowSearch.value = false
+}
+
+// 筛选菜单
+const filterNodeMethod = (queryString: string) => {
+	return (restaurant: AppRouteRecordRaw) => {
+		return restaurant.meta.local_title.toLowerCase().indexOf(queryString.toLowerCase()) > -1
+	}
+}
+
+// 点击菜单跳转
+const handleClickMenu = (menuItem: AppRouteRecordRaw | Record<string, any>) => {
+	searchMenu.value = ''
+	if (isExternal(menuItem.path)) window.open(menuItem.path, '_blank')
+	else router.push(menuItem.path)
+	closeSearch()
+}
+</script>
+<style scoped lang="scss">
+.search-menu-wrap {
+	height: 100%;
+}
+:deep(.el-dialog) {
+	background-color: rgb(0 0 0 / 50%);
+	border-radius: 0 !important;
+	box-shadow: unset !important;
+	.el-dialog__header {
+		border-bottom: none !important;
+	}
+}
+:deep(.el-autocomplete) {
+	position: absolute;
+	top: 100px;
+	left: 50%;
+	width: 550px;
+	transform: translateX(-50%);
+	.el-input__wrapper {
+		background-color: var(--el-bg-color);
+	}
+}
+.el-autocomplete__popper {
+	.el-icon {
+		position: relative;
+		top: 2px;
+		font-size: 16px;
+	}
+	span {
+		margin: 0 0 0 10px;
+		font-size: 14px;
+	}
+}
+</style>

+ 4 - 3
src/layout/components/Menu/SubMenu.vue

@@ -1,6 +1,6 @@
 <template>
 	<template v-for="subItem in menuList" :key="subItem.path">
-		<el-sub-menu v-if="subItem.children?.length" popperClass="layout-menu-popper-wrap" :index="subItem.path">
+		<el-sub-menu v-if="subItem.children?.length" teleported popper-class="layout-menu-popper-wrap" :index="subItem.path">
 			<template #title>
 				<MenuIcon v-if="subItem.meta.icon" :icon-class="subItem.meta.icon" />
 				<!--				<el-icon v-if="subItem.meta.icon">
@@ -10,7 +10,7 @@
 			</template>
 			<SubMenu :menu-list="subItem.children" />
 		</el-sub-menu>
-		<el-menu-item v-else popperClass="layout-menu-popper-wrap" :index="subItem.path" @click="handleClickMenu(subItem)">
+		<el-menu-item v-else popper-class="layout-menu-popper-wrap" :index="subItem.path" @click="handleClickMenu(subItem)">
 			<MenuIcon v-if="subItem.meta.icon" :icon-class="subItem.meta.icon" />
 			<!--      <el-icon>
 				<component :is="subItem.meta.icon"></component>
@@ -26,12 +26,13 @@
 import { useRouter } from 'vue-router'
 import { generateTitle } from '@/utils/i18n'
 import MenuIcon from './MenuIcon.vue'
+import { isExternal } from '@/utils/validate'
 
 defineProps<{ menuList: Menu.MenuOptions[] }>()
 
 const router = useRouter()
 const handleClickMenu = (subItem: Menu.MenuOptions) => {
-	if (subItem.meta.isLink) return window.open(subItem.meta.isLink, '_blank')
+	if (isExternal(subItem.path)) return window.open(subItem.path, '_blank')
 	router.push(subItem.path)
 	// router.push({ name: subItem.name })
 	// router.push('/404')

+ 1 - 1
src/router/index.ts

@@ -19,7 +19,7 @@ type RouteMeta = {
 	// type: string;
 }
 // 是否展示示例相关菜单
-const showDemoRoutes = true
+const showDemoRoutes = !!import.meta.env.DEV
 export const constantRoutes: Array<AppRouteRecordRaw> = [
 	{
 		path: '/redirect',

+ 21 - 6
src/store/modules/permission.ts

@@ -8,7 +8,7 @@ import { getMenuList } from '@/api/system/menu'
 const modules = import.meta.glob('@/views/**/*.vue')
 export const Layout = () => import('@/layout/index.vue') // todo...
 // export const Layout = () => import('@/layout/index_old.vue.vue')
-// export const Test = () => import('@/layout/test.vue')
+// export const RouteView = () => import('@/layout/RouteView.vue')
 // export const Layout = () => import('@/layouts/index.vue')
 
 // const hasPermission = (roles: string[], route: AppRouteRecordRaw) => {
@@ -35,7 +35,7 @@ export const filterAsyncRoutes = (routes: AppRouteRecordRaw[], roles: string[])
 		// console.warn(tmp.component, 'tmp.component')
 		// 特殊Layout 配置 标识
 		/*if (!tmp.component) {
-			tmp.component = Test
+			tmp.component = RouteView
 		} else*/ if (!tmp.component || tmp.component === 'Layout') {
 			tmp.component = Layout
 		} else {
@@ -62,7 +62,8 @@ const getShowMenuList = (menuList: AppRouteRecordRaw[], parentPath = '') => {
 	return menuList.filter(item => {
 		// console.error(item, 'item')
 		item.meta = item.meta ? item.meta : {}
-		item.meta.icon = item.meta.icon || 'Menu'
+		// 默认icon
+		item.meta.icon = item.meta.icon || 'menu'
 		// path全链 重组
 		item.path = /\/.*/.test(item.path) ? item.path : `${parentPath}/${item.path}`
 		if (!item.meta.hidden) {
@@ -72,6 +73,14 @@ const getShowMenuList = (menuList: AppRouteRecordRaw[], parentPath = '') => {
 		return false
 	})
 }
+// 可展示的路由平铺
+const getMenuListFlat = (menuList: AppRouteRecordRaw[]) => {
+	const _menuList = JSON.parse(JSON.stringify(menuList))
+	return _menuList.flatMap((v: AppRouteRecordRaw) => {
+		const _children = v.children || []
+		return [v, ...getMenuListFlat(_children)]
+	})
+}
 
 const usePermissionStore = defineStore({
 	id: 'permission',
@@ -82,7 +91,7 @@ const usePermissionStore = defineStore({
 	}),
 	getters: {
 		// 有效的 菜单列表
-		showMenuList: state => getShowMenuList(JSON.parse(JSON.stringify([...constantMenuList, ...state.menuList])))
+		showMenuList: state => getShowMenuList(JSON.parse(JSON.stringify([...constantMenuList, ...state.menuList]))),
 		/*getShowMenuList([
 				...JSON.parse(JSON.stringify(state.menuList)),
 				// 测试
@@ -95,6 +104,10 @@ const usePermissionStore = defineStore({
 				}
 			])*/
 		// showMenuList: state => getShowMenuList(JSON.parse(JSON.stringify(state.routes)))
+		// 菜单权限列表 ==> 扁平化之后的一维数组菜单,主要用来添加动态路由
+		showMenuListFlat() {
+			return getMenuListFlat(this.showMenuList)
+		}
 	},
 	actions: {
 		setRoutes(menuList: AppRouteRecordRaw[]) {
@@ -119,8 +132,10 @@ const usePermissionStore = defineStore({
 		queryMenuList(roles: string[]) {
 			return getMenuList().then((data: any) => {
 				console.error(data, 'menuList')
-				const menuList = filterAsyncRoutes(data!.menu.filter((v: any) => /\/.*/.test(v.path)), roles)
-				console.warn(menuList, data, 'xxxxxxxxxxx')
+				const menuList = filterAsyncRoutes(
+					data!.menu.filter((v: any) => /\/.*/.test(v.path)),
+					roles
+				)
 				this.setRoutes(menuList)
 				return menuList
 			})

+ 4 - 5
src/styles/index.scss

@@ -12,6 +12,10 @@
 @import './lance-element-vue.scss';
 // 加入布局样式
 @import "./flex.scss";
+html {
+	height: 100%;
+	box-sizing: border-box;
+}
 body {
 	margin: 0;
 	padding: 0;
@@ -27,11 +31,6 @@ body {
 	font-weight: 700;
 }*/
 
-html {
-	height: 100%;
-	box-sizing: border-box;
-}
-
 #app {
 	height: 100%;
 }

+ 6 - 0
src/styles/project_normal.scss

@@ -1,6 +1,7 @@
 body {
 	font-family: $le-family;
 	font-size: 14px;
+	overflow-x: hidden;
 }
 // 页面公用样式 flex column 外壳
 .flex-column-page-wrap {
@@ -38,6 +39,11 @@ body {
 	}
 }
 
+// icon-图标变小手
+.ibt0 {
+	cursor: pointer;
+}
+
 // 全局滚动条样式
 ::-webkit-scrollbar{width:6px;height:6px}
 ::-webkit-scrollbar-track{border-radius:6px;background: $le-bg-color_1;}

+ 3 - 1
src/styles/sidebar.scss

@@ -69,8 +69,10 @@ $active_color: var(--el-menu-active-color);
 
 	// 子菜单太长时出现滚动条
 	> .el-menu--popup {
-		max-height: 100vh;
+		max-height: 60vh;
 		overflow-y: auto;
+		&::-webkit-scrollbar{width:2px;height:2px}
+		&::-webkit-scrollbar-track{border-radius:2px;background: $le-bg-color_1;}
 		& > li:first-child {
 			margin-top: 0;
 		}

+ 1 - 0
src/views/configure/index.vue

@@ -121,6 +121,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/demo/adminManage/index.vue

@@ -64,6 +64,7 @@ const state: any = reactive({
 			formConfig: {
 				labelWidth: 80,
 				itemWidth: '100%',
+				showCancelBtn: true,
 				submitLoading: false
 			}
 			// isEdit: false

+ 1 - 0
src/views/demo/pageConfig/index.vue

@@ -359,6 +359,7 @@ const formOptions = ref({
 	span,
 	showResetBtn,
 	formConfig: {
+		showCancelBtn: true,
 		submitLoading: false
 	}
 })

+ 74 - 1
src/views/flow/create/components/ExtendSet.vue

@@ -17,7 +17,58 @@ defineProps({
 					<div class="_1zQ9x381ImhBju8yBmxOez">提交人权限</div>
 					<div class="_2j8sMpwI4XNYcuEeV6f56-">
 						<div class="other-setting-checkbox-item">
-							<el-checkbox label="允许撤销审批中的申请" size="large" />
+							<el-checkbox label="允许撤销审批中的申请" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">第一个审批节点通过后,提交人仍可撤销申请(配置前已发起的申请不生效)</p>
+						</div>
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="允许撤销31天内通过的审批" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">员工可申请撤销已通过的审批(配置前已通过的审批不可撤销)</p>
+						</div>
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="允许修改31天内通过的审批" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">提交人可申请修改已通过的审批,用于销假等场景(仅可修改一次,配置前已发起的审批不可修改)</p>
+						</div>
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="允许代他人提交" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">代提人和实际提交人都需在该审批的发起范围内,提交后将共享审批单后续状态</p>
+						</div>
+					</div>
+				</div>
+
+				<div class="GS0bhCVCInEfL1rl9MMNr">
+					<div class="_1zQ9x381ImhBju8yBmxOez">审批人设置</div>
+					<div class="_2j8sMpwI4XNYcuEeV6f56-">
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="允许审批人批量处理" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">勾选后,审批人在处理此流程的任务时,可一次批量处理多个任务</p>
+						</div>
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="开启秒批提示" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">若审批人浏览单据小于3秒或通过快捷审批处理,系统会在审批记录中进行标记</p>
+						</div>
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="可在审批卡片上进行快捷审批" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">可在审批bot的消息卡片、移动端列表卡片上进行快捷操作,无需进入具体详情页操作</p>
+						</div>
+					</div>
+				</div>
+
+				<div class="GS0bhCVCInEfL1rl9MMNr">
+					<div class="_1zQ9x381ImhBju8yBmxOez">转发设置</div>
+					<div class="_2j8sMpwI4XNYcuEeV6f56-">
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="仅可转发给审批相关人员" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">审批单仅可被转发给申请人、审批人、抄送人,不能被转发给其他人</p>
+						</div>
+					</div>
+				</div>
+
+				<div class="GS0bhCVCInEfL1rl9MMNr">
+					<div class="_1zQ9x381ImhBju8yBmxOez">效率统计</div>
+					<div class="_2j8sMpwI4XNYcuEeV6f56-">
+						<div class="other-setting-checkbox-item">
+							<el-checkbox label="该流程数据不纳入效率统计" size="medium" />
+							<p class="revoke-setting-sub-text mtb10">在效率诊断(包括团队、个人、管理员看板)中排除该流程的审批耗时数据</p>
 						</div>
 					</div>
 				</div>
@@ -68,4 +119,26 @@ defineProps({
 	flex-direction: column;
 	align-items: center;
 }
+
+.revoke-setting-sub-text {
+	color: #646a73;
+	font-size: 14px;
+	margin-top: 4px;
+	line-height: 22px;
+	margin-left: 24px;
+	&.mtb10 {
+		margin-bottom: 10px;
+	}
+}
+
+:deep(.other-setting-checkbox-item) {
+	.el-checkbox {
+		height: var(--el-checkbox-height, 20px);
+		&.is-checked {
+			.el-checkbox__label {
+				color: var(--el-color-info-light);
+			}
+		}
+	}
+}
 </style>

+ 6 - 5
src/views/flow/create/index.vue

@@ -148,14 +148,15 @@ const currentComponent = computed(() => {
 			cursor: pointer;
 
 			&.active {
-				border-bottom-color: #3370ff;
-				color: #3370ff;
+				// var(--el-color-primary);
+				border-bottom-color: var(--el-color-primary);
+				color: var(--el-color-primary);
 				font-weight: 500;
 
 				.create-approval-header-tab-counter {
-					border-color: #3370ff;
-					background-color: #3370ff;
-					color: #fff;
+					border-color: var(--el-color-primary);
+					background-color: var(--el-color-primary);
+					color: var(--el-color-white);
 					font-weight: 400;
 				}
 			}

+ 1 - 0
src/views/flow/form/index.vue

@@ -93,6 +93,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/flow/group/index1.vue

@@ -172,6 +172,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 0 - 2
src/views/flow/modal/index.vue

@@ -34,10 +34,8 @@
 													</span>
 													<template #dropdown>
 														<el-dropdown-menu>
-															<el-dropdown-item>设计</el-dropdown-item>
 															<el-dropdown-item>修改</el-dropdown-item>
 															<el-dropdown-item>复制</el-dropdown-item>
-															<el-dropdown-item>移动</el-dropdown-item>
 															<el-dropdown-item>停用</el-dropdown-item>
 														</el-dropdown-menu>
 													</template>

+ 79 - 0
src/views/message/list/detail.vue

@@ -0,0 +1,79 @@
+<template>
+	<el-dialog v-model="visibleDialog" title="查看详情" @close="handleCancel">
+		<div>
+			<!--title-->
+			<div>
+				<div class="content-title">{{ formOptions.title }}</div>
+				<span>发布人:{{ formOptions.createBy }} 发布时间: {{ formOptions.createTime }}</span>
+
+				<div class="content-title mbt20">
+					<el-tag v-if="formOptions.category === 0" size="small" effect="plain">通知公告</el-tag>
+					<el-tag v-if="formOptions.category === 1" size="small" type="info" effect="plain">系统消息</el-tag>
+					<el-tag v-if="formOptions.category === 2" size="small" type="warning" effect="plain">待办通知</el-tag>
+				</div>
+				<span>通知时间: - </span>
+				<br />
+				<br />
+				<span>通知内容:{{ formOptions.content }}</span>
+			</div>
+			<!--content-->
+		</div>
+	</el-dialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import { getMessageInfoById } from '@/api/system/message'
+
+// 同步值
+const $myEmit = defineEmits(['update:modelValue'])
+
+const myProps = defineProps({
+	modelValue: {
+		type: Boolean,
+		default: false
+	},
+	messageId: {
+		type: String,
+		default: null
+	}
+})
+
+const formOptions = ref({})
+const handleCancel = () => {
+	$myEmit('update:modelValue', false)
+}
+
+const getMessageInfoDetail = async () => {
+	const { messageId } = myProps
+	const res = await getMessageInfoById(messageId)
+	formOptions.value = res
+}
+
+getMessageInfoDetail()
+
+// computed
+const visibleDialog = computed({
+	get() {
+		return myProps.modelValue
+	},
+	set(val) {
+		$myEmit('update:modelValue', val)
+	}
+})
+</script>
+
+<style scoped lang="scss">
+.content-title {
+	overflow: hidden;
+	color: #000000d9;
+	font-weight: 500;
+	font-size: 16px;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	margin-bottom: 20px;
+	&.mbt20 {
+		margin-top: 20px;
+	}
+}
+</style>

+ 188 - 0
src/views/message/list/index.vue

@@ -0,0 +1,188 @@
+<template>
+	<div class="pageWrap">
+		<div class="content-warp flex-column-page-wrap">
+			<!-- 公用搜索组件 -->
+			<LeSearchForm ref="searchForm" v-model:searchData="searchData" :forms="forms" :loading="tableOpts.options.loading"> </LeSearchForm>
+
+			<!--  LeTable 组件使用  -->
+			<LeTable
+				ref="tableRef"
+				v-model:searchParams="tableOpts.searchParams"
+				v-bind="tableOpts"
+				v-model:curRow="tableOpts.curRow"
+				v-model:checked-options="checkedColumns"
+				:columns="activeColumns"
+			>
+				<template #toolLeft>
+					<el-button type="primary">全部标记已读</el-button>
+				</template>
+
+				<template #categorySlot="scope">
+					<el-tag v-if="scope.row.category === 0" size="small" effect="plain">通知公告</el-tag>
+					<el-tag v-if="scope.row.category === 1" size="small" type="info" effect="plain">系统消息</el-tag>
+					<el-tag v-if="scope.row.category === 2" size="small" type="warning" effect="plain">待办通知</el-tag>
+				</template>
+
+				<template #actionSlot="scope">
+					<el-link type="primary" @click="openDetail(scope.row)">查看</el-link>
+				</template>
+			</LeTable>
+		</div>
+
+		<message-detail v-if="visibleDetail" v-model="visibleDetail" :message-id="currentId" @closed="visibleDetail = false"> </message-detail>
+	</div>
+</template>
+<script lang="tsx" setup>
+import { getMessageInfo } from '@/api/system/message'
+import { nextTick, ref, watch } from 'vue'
+import { useTablePage } from '@/hooks/useTablePage'
+import MessageDetail from './detail.vue'
+import { useRoute } from 'vue-router'
+const route = useRoute()
+
+const visibleDetail = ref(false) // 权限设置弹窗显示隐藏
+const currentId = ref(null)
+
+// 表格搜索条件
+const forms = ref([
+	{
+		prop: 'title',
+		label: '标题:',
+		itemType: 'input',
+		placeholder: '请输入标题'
+	},
+	{
+		prop: 'createBy',
+		label: '发布人:',
+		itemType: 'input',
+		placeholder: '请输入发布人'
+	}
+])
+
+// table列表数据请求
+const queryList = async () => {
+	const { options, searchParams } = tableOpts
+	options.loading = true
+	try {
+		const { records: list, total } = await getMessageInfo(searchParams)
+		tableOpts.total = total
+		tableOpts.list = list
+	} catch {
+		console.log('获取列表数据失败')
+		tableOpts.total = 0
+		tableOpts.list = []
+		options.loading = false // 更改加载中的 loading值
+	} finally {
+		options.loading = false
+	}
+}
+
+// table 参数
+const columns = [
+	{
+		prop: 'title',
+		label: '标题',
+		minWidth: 80
+	},
+	{
+		prop: 'category',
+		label: '消息类型',
+		minWidth: 100,
+		slots: {
+			default: 'categorySlot'
+		}
+	},
+	{
+		prop: 'createBy',
+		label: '发布人',
+		minWidth: 100
+	},
+	{
+		prop: 'createTime',
+		label: '发布时间',
+		minWidth: 126
+	},
+	{
+		prop: 'action',
+		label: '操作',
+		width: 100,
+		fixed: 'right',
+		slots: {
+			default: 'actionSlot'
+		}
+	}
+]
+
+const { searchData, tableOpts, checkedColumns, activeColumns } = useTablePage(
+	{
+		options: {
+			showIndex: false
+		},
+		// 需要展示的列
+		columns,
+		// 控制列配置
+		columnsConfig: {
+			columns
+		}
+	},
+	{
+		queryList,
+		fetchImmediate: false
+	}
+)
+
+const openDetail = (row: any) => {
+	currentId.value = row.id
+	visibleDetail.value = true
+}
+
+nextTick(() => {
+	queryList()
+})
+
+watch(
+	() => route.query,
+	(newPath, oldPath) => {
+		if (JSON.stringify(newPath) !== '{}') {
+			nextTick(() => {
+				openDetail(newPath)
+			})
+		}
+	},
+	{ immediate: true }
+)
+</script>
+<style scoped lang="scss">
+.pageWrap {
+	flex: 1;
+	display: flex;
+	height: 100%;
+	//background: #fff;
+}
+.content-warp {
+	flex: 1;
+	//width: calc(100% - 250px);
+	width: calc(100% - 210px);
+}
+// 单独自己写的
+/*:deep(.box-card) {
+	height: 100%;
+	.el-card__body {
+		padding: 0;
+	}
+}*/
+
+// 应用的树结构样式
+:deep(.menu-tree) {
+	.el-tree-node__content {
+		height: 36px;
+	}
+	.el-tree-node__content .el-tree-node__label .icon {
+		margin-right: 5px;
+	}
+}
+
+.nopadding {
+	padding: 0px;
+}
+</style>

+ 1 - 0
src/views/setting/app/index.vue

@@ -121,6 +121,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/setting/configure/index.vue

@@ -111,6 +111,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/setting/department/index.vue

@@ -126,6 +126,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/setting/dict/index.vue

@@ -165,6 +165,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/setting/post/index.vue

@@ -111,6 +111,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/setting/region/index.vue

@@ -113,6 +113,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 0
src/views/setting/role/index.vue

@@ -125,6 +125,7 @@ const formOptions = computed(() => {
 		span: 30,
 		showResetBtn: true,
 		formConfig: {
+			showCancelBtn: true,
 			submitLoading: false
 		}
 	}

+ 1 - 1
src/views/setting/user/assign-role.vue

@@ -1,5 +1,5 @@
 <template>
-	<el-dialog v-model="visibleDialog" title="密码重置" :width="550" destroy-on-close @closed="handleCancel">
+	<el-dialog v-model="visibleDialog" title="分配角色/部门" :width="550" destroy-on-close @closed="handleCancel">
 		<el-select v-model="roleIds" style="width: 500px" multiple filterable placeholder="请选择分配角色">
 			<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id">
 				<span style="float: left">{{ item.name }}</span>

+ 12 - 2
src/views/setting/user/index.vue

@@ -42,12 +42,13 @@
 							<Plus />
 						</el-icon>
 					</el-button>
-					<el-button type="danger" @click="batch_del" :disabled="curSelectionRows.length === 0">
+					<el-button type="danger" :disabled="curSelectionRows.length === 0" @click="batch_del">
 						<el-icon class="btn-icon">
 							<Delete />
 						</el-icon>
 					</el-button>
 					<el-button plain :disabled="curSelectionRows.length === 0" @click="assignRoleVisibile = true"> 分配角色 </el-button>
+					<el-button plain :disabled="curSelectionRows.length === 0"> 分配部门 </el-button>
 					<el-button plain :disabled="curSelectionRows.length === 0" @click="resetPwdVisibile = true"> 密码重置 </el-button>
 				</template>
 
@@ -175,6 +176,16 @@ const formsDialog = [
 		maxCollapseTags: 1,
 		filterable: true,
 		options: []
+	},
+	{
+		prop: 'roleIds1',
+		label: '所属部门',
+		itemType: 'select',
+		multiple: true,
+		collapseTags: true,
+		maxCollapseTags: 1,
+		filterable: true,
+		options: []
 	}
 ]
 // 新增的表单 和 编辑的表单
@@ -190,7 +201,6 @@ const formOptions = computed(() => {
 		labelWidth: 120,
 		span: 30,
 		formConfig: {
-			showResetBtn: true,
 			showCancelBtn: true,
 			submitLoading: false
 		}

+ 1 - 1
src/views/setting/user/reset-pwd.vue

@@ -1,5 +1,5 @@
 <template>
-	<el-dialog v-model="visibleDialog" title="分配角色" :width="550" destroy-on-close @closed="handleCancel">
+	<el-dialog v-model="visibleDialog" title="密码重置" :width="550" destroy-on-close @closed="handleCancel">
 		<el-form :label-position="'top'" label-width="100px" :model="formLabelAlign" style="max-width: 460px">
 			<el-form-item label="请输入新的密码">
 				<el-input v-model="formLabelAlign.password" />