From 97187b246b94dd58cb585ebaed7e8644d2f00119 Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期一, 03 四月 2023 00:26:04 +0800 Subject: [PATCH] update 调整代码格式 --- src/views/system/config/index.vue | 280 +++--- src/views/monitor/cache/index.vue | 129 +- src/views/system/user/profile/userAvatar.vue | 202 ++-- src/views/system/user/profile/index.vue | 56 src/views/tool/gen/basicInfoForm.vue | 46 src/layout/index.vue | 106 +- src/components/SvgIcon/index.vue | 48 src/components/SizeSelect/index.vue | 34 src/components/TreeSelect/index.vue | 116 +- src/layout/components/Sidebar/Link.vue | 70 src/components/IconSelect/index.vue | 90 +- src/views/tool/gen/genInfoForm.vue | 146 +- src/components/Hamburger/index.vue | 28 src/layout/components/IframeToggle/index.vue | 16 src/layout/components/Sidebar/Logo.vue | 38 src/views/system/user/profile/userInfo.vue | 80 +- src/components/iFrame/index.vue | 12 src/layout/components/TagsView/ScrollPane.vue | 104 +- src/views/system/user/profile/resetPwd.vue | 90 +- src/components/TopNav/index.vue | 32 src/layout/components/Sidebar/index.vue | 56 src/components/ImagePreview/index.vue | 90 +- src/layout/components/Settings/index.vue | 204 ++-- src/components/HeaderSearch/index.vue | 246 +++--- 24 files changed, 1,160 insertions(+), 1,159 deletions(-) diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue index a9ed788..fffcedf 100644 --- a/src/components/Hamburger/index.vue +++ b/src/components/Hamburger/index.vue @@ -1,17 +1,3 @@ -<script setup lang="ts"> -defineProps({ - isActive: { - type: Boolean, - default: false - } -}) - -const emit = defineEmits(['toggleClick']) -const toggleClick = () => { - emit('toggleClick'); -} -</script> - <template> <div style="padding: 0 15px;" @click="toggleClick"> <svg :class="{'is-active':isActive}" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"> @@ -22,6 +8,20 @@ </div> </template> +<script setup lang="ts"> +defineProps({ + isActive: { + type: Boolean, + default: false + } +}) + +const emit = defineEmits(['toggleClick']) +const toggleClick = () => { + emit('toggleClick'); +} +</script> + <style scoped> .hamburger { display: inline-block; diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue index a8fc1c8..60ebb9d 100644 --- a/src/components/HeaderSearch/index.vue +++ b/src/components/HeaderSearch/index.vue @@ -1,126 +1,3 @@ -<script setup lang="ts"> -import Fuse from 'fuse.js' -import { getNormalPath } from '@/utils/ruoyi' -import { isHttp } from '@/utils/validate' -import usePermissionStore from '@/store/modules/permission' -import { RouteOption } from 'vue-router' - -type Router = Array<{ - path: string; - title: string[]; -}> - -const search = ref(''); -const options = ref<any>([]); -const searchPool = ref<Router>([]); -const show = ref(false); -const fuse = ref(); -const headerSearchSelectRef = ref(ElSelect); -const router = useRouter(); -const routes = computed(() => usePermissionStore().routes); - -const click = () => { - show.value = !show.value - if (show.value) { - headerSearchSelectRef.value && headerSearchSelectRef.value.focus() - } -}; -const close = () => { - headerSearchSelectRef.value && headerSearchSelectRef.value.blur() - options.value = [] - show.value = false -} -const change = (val: any) => { - const path = val.path; - if (isHttp(path)) { - // http(s):// 璺緞鏂扮獥鍙f墦寮� - const pindex = path.indexOf("http"); - window.open(path.substr(pindex, path.length), "_blank"); - } else { - router.push(path) - } - search.value = '' - options.value = [] - nextTick(() => { - show.value = false - }) -} -const initFuse = (list: Router) => { - fuse.value = new Fuse(list, { - shouldSort: true, - threshold: 0.4, - location: 0, - distance: 100, - minMatchCharLength: 1, - keys: [{ - name: 'title', - weight: 0.7 - }, { - name: 'path', - weight: 0.3 - }] - }) -} -// Filter out the routes that can be displayed in the sidebar -// And generate the internationalized title -const generateRoutes = (routes: RouteOption[], basePath = '', prefixTitle: string[] = []) => { - let res: Router = [] - routes.forEach(r => { - // skip hidden router - if (!r.hidden) { - const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path; - const data = { - path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path, - title: [...prefixTitle] - } - if (r.meta && r.meta.title) { - data.title = [...data.title, r.meta.title]; - if (r.redirect !== 'noRedirect') { - // only push the routes with title - // special case: need to exclude parent router without redirect - res.push(data); - } - } - // recursive child routes - if (r.children) { - const tempRoutes = generateRoutes(r.children, data.path, data.title); - if (tempRoutes.length >= 1) { - res = [...res, ...tempRoutes]; - } - } - } - }) - return res; -} -const querySearch = (query: string) => { - if (query !== '') { - options.value = fuse.value.search(query) - } else { - options.value = [] - } -} - -onMounted(() => { - searchPool.value = generateRoutes(routes.value); -}) - -watchEffect(() => { - searchPool.value = generateRoutes(routes.value) -}) - -watch(show, (value) => { - if (value) { - document.body.addEventListener('click', close) - } else { - document.body.removeEventListener('click', close) - } -}) - -watch(searchPool, (list) => { - initFuse(list) -}) -</script> - <template> <div :class="{ 'show': show }" class="header-search"> <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> @@ -140,6 +17,129 @@ </div> </template> +<script setup lang="ts"> +import Fuse from 'fuse.js' +import { getNormalPath } from '@/utils/ruoyi' +import { isHttp } from '@/utils/validate' +import usePermissionStore from '@/store/modules/permission' +import { RouteOption } from 'vue-router' + +type Router = Array<{ + path: string; + title: string[]; +}> + +const search = ref(''); +const options = ref<any>([]); +const searchPool = ref<Router>([]); +const show = ref(false); +const fuse = ref(); +const headerSearchSelectRef = ref(ElSelect); +const router = useRouter(); +const routes = computed(() => usePermissionStore().routes); + +const click = () => { + show.value = !show.value + if (show.value) { + headerSearchSelectRef.value && headerSearchSelectRef.value.focus() + } +}; +const close = () => { + headerSearchSelectRef.value && headerSearchSelectRef.value.blur() + options.value = [] + show.value = false +} +const change = (val: any) => { + const path = val.path; + if (isHttp(path)) { + // http(s):// 璺緞鏂扮獥鍙f墦寮� + const pindex = path.indexOf("http"); + window.open(path.substr(pindex, path.length), "_blank"); + } else { + router.push(path) + } + search.value = '' + options.value = [] + nextTick(() => { + show.value = false + }) +} +const initFuse = (list: Router) => { + fuse.value = new Fuse(list, { + shouldSort: true, + threshold: 0.4, + location: 0, + distance: 100, + minMatchCharLength: 1, + keys: [{ + name: 'title', + weight: 0.7 + }, { + name: 'path', + weight: 0.3 + }] + }) +} +// Filter out the routes that can be displayed in the sidebar +// And generate the internationalized title +const generateRoutes = (routes: RouteOption[], basePath = '', prefixTitle: string[] = []) => { + let res: Router = [] + routes.forEach(r => { + // skip hidden router + if (!r.hidden) { + const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path; + const data = { + path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path, + title: [...prefixTitle] + } + if (r.meta && r.meta.title) { + data.title = [...data.title, r.meta.title]; + if (r.redirect !== 'noRedirect') { + // only push the routes with title + // special case: need to exclude parent router without redirect + res.push(data); + } + } + // recursive child routes + if (r.children) { + const tempRoutes = generateRoutes(r.children, data.path, data.title); + if (tempRoutes.length >= 1) { + res = [...res, ...tempRoutes]; + } + } + } + }) + return res; +} +const querySearch = (query: string) => { + if (query !== '') { + options.value = fuse.value.search(query) + } else { + options.value = [] + } +} + +onMounted(() => { + searchPool.value = generateRoutes(routes.value); +}) + +watchEffect(() => { + searchPool.value = generateRoutes(routes.value) +}) + +watch(show, (value) => { + if (value) { + document.body.addEventListener('click', close) + } else { + document.body.removeEventListener('click', close) + } +}) + +watch(searchPool, (list) => { + initFuse(list) +}) +</script> + <style lang="scss" scoped> .header-search { font-size: 0 !important; diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue index 63afe85..330c44f 100644 --- a/src/components/IconSelect/index.vue +++ b/src/components/IconSelect/index.vue @@ -1,48 +1,3 @@ -<script setup lang="ts"> -import icons from '@/components/IconSelect/requireIcons'; - -const props = defineProps({ - modelValue: { - type: String, - require: true - }, - width: { - type: String, - require: false, - default: '400px' - } -}); - -const emit = defineEmits(['update:modelValue']); -const visible = ref(false); -const { modelValue, width } = toRefs(props); -const iconNames = ref<string[]>(icons); - -const filterValue = ref(''); - -/** - * 绛涢�夊浘鏍� - */ -const filterIcons = () => { - if (filterValue.value) { - iconNames.value = icons.filter(iconName => - iconName.includes(filterValue.value) - ); - } else { - iconNames.value = icons; - } -} - -/** - * 閫夋嫨鍥炬爣 - * @param iconName 閫夋嫨鐨勫浘鏍囧悕绉� - */ -const selectedIcon = (iconName: string) => { - emit('update:modelValue', iconName); - visible.value = false; -} -</script> - <template> <div class="relative" :style="{ width: width }"> <el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="鐐瑰嚮閫夋嫨鍥炬爣"> @@ -74,6 +29,51 @@ </div> </template> +<script setup lang="ts"> +import icons from '@/components/IconSelect/requireIcons'; + +const props = defineProps({ + modelValue: { + type: String, + require: true + }, + width: { + type: String, + require: false, + default: '400px' + } +}); + +const emit = defineEmits(['update:modelValue']); +const visible = ref(false); +const { modelValue, width } = toRefs(props); +const iconNames = ref<string[]>(icons); + +const filterValue = ref(''); + +/** + * 绛涢�夊浘鏍� + */ +const filterIcons = () => { + if (filterValue.value) { + iconNames.value = icons.filter(iconName => + iconName.includes(filterValue.value) + ); + } else { + iconNames.value = icons; + } +} + +/** + * 閫夋嫨鍥炬爣 + * @param iconName 閫夋嫨鐨勫浘鏍囧悕绉� + */ +const selectedIcon = (iconName: string) => { + emit('update:modelValue', iconName); + visible.value = false; +} +</script> + <style scoped lang="scss"> .el-divider--horizontal { margin: 10px auto !important; diff --git a/src/components/ImagePreview/index.vue b/src/components/ImagePreview/index.vue index 9b244f8..57019e3 100644 --- a/src/components/ImagePreview/index.vue +++ b/src/components/ImagePreview/index.vue @@ -1,48 +1,3 @@ -<script setup lang="ts"> -const props = defineProps({ - src: { - type: String, - default: "" - }, - width: { - type: [Number, String], - default: "" - }, - height: { - type: [Number, String], - default: "" - } -}); - -const realSrc = computed(() => { - if (!props.src) { - return; - } - let real_src = props.src.split(",")[0]; - return real_src; -}); - -const realSrcList = computed(() => { - if (!props.src) { - return; - } - let real_src_list = props.src.split(","); - let srcList:string[] = []; - real_src_list.forEach(item => { - return srcList.push(item); - }); - return srcList; -}); - -const realWidth = computed(() => - typeof props.width == "string" ? props.width : `${props.width}px` -); - -const realHeight = computed(() => - typeof props.height == "string" ? props.height : `${props.height}px` -); -</script> - <template> <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported> <template #error> @@ -53,6 +8,51 @@ </el-image> </template> +<script setup lang="ts"> +const props = defineProps({ + src: { + type: String, + default: "" + }, + width: { + type: [Number, String], + default: "" + }, + height: { + type: [Number, String], + default: "" + } +}); + +const realSrc = computed(() => { + if (!props.src) { + return; + } + let real_src = props.src.split(",")[0]; + return real_src; +}); + +const realSrcList = computed(() => { + if (!props.src) { + return; + } + let real_src_list = props.src.split(","); + let srcList:string[] = []; + real_src_list.forEach(item => { + return srcList.push(item); + }); + return srcList; +}); + +const realWidth = computed(() => + typeof props.width == "string" ? props.width : `${props.width}px` +); + +const realHeight = computed(() => + typeof props.height == "string" ? props.height : `${props.height}px` +); +</script> + <style lang="scss" scoped> .el-image { border-radius: 5px; diff --git a/src/components/SizeSelect/index.vue b/src/components/SizeSelect/index.vue index 268a836..058ff71 100644 --- a/src/components/SizeSelect/index.vue +++ b/src/components/SizeSelect/index.vue @@ -1,20 +1,3 @@ -<script setup lang="ts"> -import useAppStore from "@/store/modules/app"; - -const appStore = useAppStore(); -const size = computed(() => appStore.size); - -const sizeOptions = ref([ - { label: "杈冨ぇ", value: "large" }, - { label: "榛樿", value: "default" }, - { label: "绋嶅皬", value: "small" }, -]); - -const handleSetSize = (size: string) => { - appStore.setSize(size); -} -</script> - <template> <div> <el-dropdown trigger="click" @command="handleSetSize"> @@ -32,6 +15,23 @@ </div> </template> +<script setup lang="ts"> +import useAppStore from "@/store/modules/app"; + +const appStore = useAppStore(); +const size = computed(() => appStore.size); + +const sizeOptions = ref([ + { label: "杈冨ぇ", value: "large" }, + { label: "榛樿", value: "default" }, + { label: "绋嶅皬", value: "small" }, +]); + +const handleSetSize = (size: string) => { + appStore.setSize(size); +} +</script> + <style lang="scss" scoped> .size-icon--style { font-size: 18px; diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue index 4a858bd..f3562d7 100644 --- a/src/components/SvgIcon/index.vue +++ b/src/components/SvgIcon/index.vue @@ -1,33 +1,33 @@ -<script setup lang="ts"> -const props = defineProps({ - iconClass: { - type: String, - required: true - }, - className: { - type: String, - default: '' - }, - color: { - type: String, - default: '' - }, -}) -const iconName = computed(() => `#icon-${props.iconClass}`); -const svgClass = computed(() => { - if (props.className) { - return `svg-icon ${props.className}` - } - return 'svg-icon' -}) -</script> - <template> <svg :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName" :fill="color" /> </svg> </template> +<script setup lang="ts"> +const props = defineProps({ + iconClass: { + type: String, + required: true + }, + className: { + type: String, + default: '' + }, + color: { + type: String, + default: '' + }, +}) +const iconName = computed(() => `#icon-${props.iconClass}`); +const svgClass = computed(() => { + if (props.className) { + return `svg-icon ${props.className}` + } + return 'svg-icon' +}) +</script> + <style scope lang="scss"> .sub-el-icon, .nav-icon { diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue index 41e3a11..79b7786 100644 --- a/src/components/TopNav/index.vue +++ b/src/components/TopNav/index.vue @@ -1,21 +1,21 @@ <template> - <el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false"> - <template v-for="(item, index) in topMenus"> - <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber" - ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item - > - </template> + <el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false"> + <template v-for="(item, index) in topMenus"> + <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber" + ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item + > + </template> - <!-- 椤堕儴鑿滃崟瓒呭嚭鏁伴噺鎶樺彔 --> - <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> - <template #title>鏇村鑿滃崟</template> - <template v-for="(item, index) in topMenus"> - <el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber" - ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item - > - </template> - </el-sub-menu> - </el-menu> + <!-- 椤堕儴鑿滃崟瓒呭嚭鏁伴噺鎶樺彔 --> + <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> + <template #title>鏇村鑿滃崟</template> + <template v-for="(item, index) in topMenus"> + <el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber" + ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item + > + </template> + </el-sub-menu> + </el-menu> </template> <script setup lang="ts"> diff --git a/src/components/TreeSelect/index.vue b/src/components/TreeSelect/index.vue index 0df87f0..8f80377 100644 --- a/src/components/TreeSelect/index.vue +++ b/src/components/TreeSelect/index.vue @@ -1,39 +1,69 @@ +<template> + <div class="el-tree-select"> + <el-select + style="width: 100%" + v-model="valueId" + ref="treeSelect" + :filterable="true" + :clearable="true" + @clear="clearHandle" + :filter-method="selectFilterData" + :placeholder="placeholder" + > + <el-option :value="valueId" :label="valueTitle"> + <el-tree + id="tree-option" + ref="selectTree" + :accordion="accordion" + :data="options" + :props="objMap" + :node-key="objMap.value" + :expand-on-click-node="false" + :default-expanded-keys="defaultExpandedKey" + :filter-node-method="filterNode" + @node-click="handleNodeClick" + ></el-tree> + </el-option> + </el-select> + </div> +</template> + <script setup lang="ts"> import { ElTreeSelect } from 'element-plus' const props = defineProps({ /* 閰嶇疆椤� */ objMap: { - type: Object, - default: () => { - return { - value: 'id', // ID瀛楁鍚� - label: 'label', // 鏄剧ず鍚嶇О - children: 'children' // 瀛愮骇瀛楁鍚� - } + type: Object, + default: () => { + return { + value: 'id', // ID瀛楁鍚� + label: 'label', // 鏄剧ず鍚嶇О + children: 'children' // 瀛愮骇瀛楁鍚� } + } }, /* 鑷姩鏀惰捣 */ accordion: { - type: Boolean, - default: () => { - return false - } + type: Boolean, + default: () => { + return false + } }, /**褰撳墠鍙屽悜鏁版嵁缁戝畾鐨勫�� */ value: { - type: [String, Number], - default: '' + type: [String, Number], + default: '' }, /**褰撳墠鐨勬暟鎹� */ options: { - type: Array, - default: () => [] + type: Array, + default: () => [] }, /**杈撳叆妗嗗唴閮ㄧ殑鏂囧瓧 */ placeholder: { - type: String, - default: '' + type: String, + default: '' } }) @@ -45,7 +75,7 @@ const valueId = computed({ get: () => props.value, set: (val) => { - emit('update:value', val) + emit('update:value', val) } }); const valueTitle = ref(''); @@ -53,17 +83,17 @@ function initHandle() { nextTick(() => { - const selectedValue = valueId.value; - if(selectedValue !== null && typeof (selectedValue) !== 'undefined') { - const node = selectTree.value.getNode(selectedValue) - if (node) { - valueTitle.value = node.data[props.objMap.label] - selectTree.value.setCurrentKey(selectedValue) // 璁剧疆榛樿閫変腑 - defaultExpandedKey.value = [selectedValue] // 璁剧疆榛樿灞曞紑 - } - } else { - clearHandle() + const selectedValue = valueId.value; + if(selectedValue !== null && typeof (selectedValue) !== 'undefined') { + const node = selectTree.value.getNode(selectedValue) + if (node) { + valueTitle.value = node.data[props.objMap.label] + selectTree.value.setCurrentKey(selectedValue) // 璁剧疆榛樿閫変腑 + defaultExpandedKey.value = [selectedValue] // 璁剧疆榛樿灞曞紑 } + } else { + clearHandle() + } }) } function handleNodeClick(node: any) { @@ -126,33 +156,3 @@ color: $--color-primary; } </style> - -<template> - <div class="el-tree-select"> - <el-select - style="width: 100%" - v-model="valueId" - ref="treeSelect" - :filterable="true" - :clearable="true" - @clear="clearHandle" - :filter-method="selectFilterData" - :placeholder="placeholder" - > - <el-option :value="valueId" :label="valueTitle"> - <el-tree - id="tree-option" - ref="selectTree" - :accordion="accordion" - :data="options" - :props="objMap" - :node-key="objMap.value" - :expand-on-click-node="false" - :default-expanded-keys="defaultExpandedKey" - :filter-node-method="filterNode" - @node-click="handleNodeClick" - ></el-tree> - </el-option> - </el-select> - </div> -</template> diff --git a/src/components/iFrame/index.vue b/src/components/iFrame/index.vue index 94d7b28..3d1cc7b 100644 --- a/src/components/iFrame/index.vue +++ b/src/components/iFrame/index.vue @@ -1,3 +1,9 @@ +<template> + <div v-loading="loading" :style="'height:' + height"> + <iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" /> + </div> +</template> + <script setup lang="ts"> const props = defineProps({ src: { @@ -19,9 +25,3 @@ }; }) </script> - -<template> - <div v-loading="loading" :style="'height:' + height"> - <iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" /> - </div> -</template> diff --git a/src/layout/components/IframeToggle/index.vue b/src/layout/components/IframeToggle/index.vue index e6e131e..1a24ba6 100644 --- a/src/layout/components/IframeToggle/index.vue +++ b/src/layout/components/IframeToggle/index.vue @@ -1,11 +1,3 @@ -<script setup lang="ts"> -import InnerLink from "../InnerLink/index.vue"; -import useTagsViewStore from '@/store/modules/tagsView'; - -const route = useRoute(); -const tagsViewStore = useTagsViewStore() -</script> - <template> <transition-group name="fade-transform" mode="out-in"> <inner-link @@ -17,3 +9,11 @@ ></inner-link> </transition-group> </template> + +<script setup lang="ts"> +import InnerLink from "../InnerLink/index.vue"; +import useTagsViewStore from '@/store/modules/tagsView'; + +const route = useRoute(); +const tagsViewStore = useTagsViewStore() +</script> \ No newline at end of file diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue index 7e9d8b3..bf62b14 100644 --- a/src/layout/components/Settings/index.vue +++ b/src/layout/components/Settings/index.vue @@ -1,105 +1,3 @@ -<script setup lang="ts"> -import { useDynamicTitle } from '@/utils/dynamicTitle' -import useAppStore from '@/store/modules/app' -import useSettingsStore from '@/store/modules/settings' -import usePermissionStore from '@/store/modules/permission' -import { handleThemeStyle } from '@/utils/theme' -import { ComponentInternalInstance } from "vue"; -import { SettingTypeEnum } from "@/enums/SettingTypeEnum"; - -const { proxy } = getCurrentInstance() as ComponentInternalInstance; -const appStore = useAppStore() -const settingsStore = useSettingsStore() -const permissionStore = usePermissionStore() - - -const showSettings = ref(false); -const theme = ref(settingsStore.theme); -const sideTheme = ref(settingsStore.sideTheme); -const storeSettings = computed(() => settingsStore); -const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]); - -/** 鏄惁闇�瑕乼opnav */ -const topNav = computed({ - get: () => storeSettings.value.topNav, - set: (val) => { - settingsStore.changeSetting({ key: SettingTypeEnum.TOP_NAV, value: val }) - if (!val) { - appStore.toggleSideBarHide(false); - permissionStore.setSidebarRouters(permissionStore.defaultRoutes); - } - } -}) -/** 鏄惁闇�瑕乼agview */ -const tagsView = computed({ - get: () => storeSettings.value.tagsView, - set: (val) => { - settingsStore.changeSetting({ key: SettingTypeEnum.TAGS_VIEW, value: val }) - } -}) -/**鏄惁闇�瑕佸浐瀹氬ご閮� */ -const fixedHeader = computed({ - get: () => storeSettings.value.fixedHeader, - set: (val) => { - settingsStore.changeSetting({ key: SettingTypeEnum.FIXED_HEADER, value: val }) - } -}) -/**鏄惁闇�瑕佷晶杈规爮鐨刲ogo */ -const sidebarLogo = computed({ - get: () => storeSettings.value.sidebarLogo, - set: (val) => { - settingsStore.changeSetting({ key: SettingTypeEnum.SIDEBAR_LOGO, value: val }) - } -}) -/**鏄惁闇�瑕佷晶杈规爮鐨勫姩鎬佺綉椤电殑title */ -const dynamicTitle = computed({ - get: () => storeSettings.value.dynamicTitle, - set: (val) => { - settingsStore.changeSetting({ key: SettingTypeEnum.DYNAMIC_TITLE, value: val }) - // 鍔ㄦ�佽缃綉椤垫爣棰� - useDynamicTitle() - } -}) - -const themeChange = (val: string | null) => { - settingsStore.changeSetting({ key: SettingTypeEnum.THEME, value: val }) - theme.value = val; - if (val) { - handleThemeStyle(val); - } -} -const handleTheme = (val: string) => { - settingsStore.changeSetting({ key: SettingTypeEnum.SIDE_THEME, value: val }) - sideTheme.value = val; -} -const saveSetting = () => { - proxy?.$modal.loading("姝e湪淇濆瓨鍒版湰鍦帮紝璇风◢鍊�..."); - let layoutSetting = { - "topNav": storeSettings.value.topNav, - "tagsView": storeSettings.value.tagsView, - "fixedHeader": storeSettings.value.fixedHeader, - "sidebarLogo": storeSettings.value.sidebarLogo, - "dynamicTitle": storeSettings.value.dynamicTitle, - "sideTheme": storeSettings.value.sideTheme, - "theme": storeSettings.value.theme - }; - localStorage.setItem("layout-setting", JSON.stringify(layoutSetting)); - setTimeout(() => {proxy?.$modal.closeLoading()}, 1000) -} -const resetSetting = () => { - proxy?.$modal.loading("姝e湪娓呴櫎璁剧疆缂撳瓨骞跺埛鏂帮紝璇风◢鍊�..."); - localStorage.removeItem("layout-setting") - setTimeout("window.location.reload()", 1000) -} -const openSetting = () => { - showSettings.value = true; -} - -defineExpose({ - openSetting, -}) -</script> - <template> <el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px" close-on-click-modal> <div class="setting-drawer-title"> @@ -183,6 +81,108 @@ </el-drawer> </template> +<script setup lang="ts"> +import { useDynamicTitle } from '@/utils/dynamicTitle' +import useAppStore from '@/store/modules/app' +import useSettingsStore from '@/store/modules/settings' +import usePermissionStore from '@/store/modules/permission' +import { handleThemeStyle } from '@/utils/theme' +import { ComponentInternalInstance } from "vue"; +import { SettingTypeEnum } from "@/enums/SettingTypeEnum"; + +const { proxy } = getCurrentInstance() as ComponentInternalInstance; +const appStore = useAppStore() +const settingsStore = useSettingsStore() +const permissionStore = usePermissionStore() + + +const showSettings = ref(false); +const theme = ref(settingsStore.theme); +const sideTheme = ref(settingsStore.sideTheme); +const storeSettings = computed(() => settingsStore); +const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]); + +/** 鏄惁闇�瑕乼opnav */ +const topNav = computed({ + get: () => storeSettings.value.topNav, + set: (val) => { + settingsStore.changeSetting({ key: SettingTypeEnum.TOP_NAV, value: val }) + if (!val) { + appStore.toggleSideBarHide(false); + permissionStore.setSidebarRouters(permissionStore.defaultRoutes); + } + } +}) +/** 鏄惁闇�瑕乼agview */ +const tagsView = computed({ + get: () => storeSettings.value.tagsView, + set: (val) => { + settingsStore.changeSetting({ key: SettingTypeEnum.TAGS_VIEW, value: val }) + } +}) +/**鏄惁闇�瑕佸浐瀹氬ご閮� */ +const fixedHeader = computed({ + get: () => storeSettings.value.fixedHeader, + set: (val) => { + settingsStore.changeSetting({ key: SettingTypeEnum.FIXED_HEADER, value: val }) + } +}) +/**鏄惁闇�瑕佷晶杈规爮鐨刲ogo */ +const sidebarLogo = computed({ + get: () => storeSettings.value.sidebarLogo, + set: (val) => { + settingsStore.changeSetting({ key: SettingTypeEnum.SIDEBAR_LOGO, value: val }) + } +}) +/**鏄惁闇�瑕佷晶杈规爮鐨勫姩鎬佺綉椤电殑title */ +const dynamicTitle = computed({ + get: () => storeSettings.value.dynamicTitle, + set: (val) => { + settingsStore.changeSetting({ key: SettingTypeEnum.DYNAMIC_TITLE, value: val }) + // 鍔ㄦ�佽缃綉椤垫爣棰� + useDynamicTitle() + } +}) + +const themeChange = (val: string | null) => { + settingsStore.changeSetting({ key: SettingTypeEnum.THEME, value: val }) + theme.value = val; + if (val) { + handleThemeStyle(val); + } +} +const handleTheme = (val: string) => { + settingsStore.changeSetting({ key: SettingTypeEnum.SIDE_THEME, value: val }) + sideTheme.value = val; +} +const saveSetting = () => { + proxy?.$modal.loading("姝e湪淇濆瓨鍒版湰鍦帮紝璇风◢鍊�..."); + let layoutSetting = { + "topNav": storeSettings.value.topNav, + "tagsView": storeSettings.value.tagsView, + "fixedHeader": storeSettings.value.fixedHeader, + "sidebarLogo": storeSettings.value.sidebarLogo, + "dynamicTitle": storeSettings.value.dynamicTitle, + "sideTheme": storeSettings.value.sideTheme, + "theme": storeSettings.value.theme + }; + localStorage.setItem("layout-setting", JSON.stringify(layoutSetting)); + setTimeout(() => {proxy?.$modal.closeLoading()}, 1000) +} +const resetSetting = () => { + proxy?.$modal.loading("姝e湪娓呴櫎璁剧疆缂撳瓨骞跺埛鏂帮紝璇风◢鍊�..."); + localStorage.removeItem("layout-setting") + setTimeout("window.location.reload()", 1000) +} +const openSetting = () => { + showSettings.value = true; +} + +defineExpose({ + openSetting, +}) +</script> + <style lang="scss" scoped> .setting-drawer-title { margin-bottom: 12px; diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue index c1c276f..4c6e8b3 100644 --- a/src/layout/components/Sidebar/Link.vue +++ b/src/layout/components/Sidebar/Link.vue @@ -1,40 +1,40 @@ -<script setup lang="ts"> -import { isExternal } from '@/utils/validate' - -const props = defineProps({ - to: { - type: [String, Object], - required: true - } -}) - -const isExt = computed(() => { - return isExternal(props.to as string) -}) - -const type = computed(() => { - if (isExt.value) { - return 'a' - } - return 'router-link' -}) - -function linkProps() { - if (isExt.value) { - return { - href: props.to, - target: '_blank', - rel: 'noopener' - } - } - return { - to: props.to - } -} -</script> - <template> <component :is="type" v-bind="linkProps()"> <slot /> </component> </template> + +<script setup lang="ts"> +import { isExternal } from '@/utils/validate' + +const props = defineProps({ + to: { + type: [String, Object], + required: true + } +}) + +const isExt = computed(() => { + return isExternal(props.to as string) +}) + +const type = computed(() => { + if (isExt.value) { + return 'a' + } + return 'router-link' +}) + +function linkProps() { + if (isExt.value) { + return { + href: props.to, + target: '_blank', + rel: 'noopener' + } + } + return { + to: props.to + } +} +</script> diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue index 4e6ec7a..a06158a 100644 --- a/src/layout/components/Sidebar/Logo.vue +++ b/src/layout/components/Sidebar/Logo.vue @@ -1,22 +1,3 @@ -<script setup lang="ts"> -import variables from '@/assets/styles/variables.module.scss' -import logo from '@/assets/logo/logo.png' -import useSettingsStore from '@/store/modules/settings' -import { ComponentInternalInstance } from "vue"; -const { proxy } = getCurrentInstance() as ComponentInternalInstance; - -defineProps({ - collapse: { - type: Boolean, - required: true - } -}) - -const title = ref('RuoYi-Vue-Plus'); -const settingsStore = useSettingsStore(); -const sideTheme = computed(() => settingsStore.sideTheme); -</script> - <template> <div class="sidebar-logo-container" @@ -40,6 +21,25 @@ </div> </template> +<script setup lang="ts"> +import variables from '@/assets/styles/variables.module.scss' +import logo from '@/assets/logo/logo.png' +import useSettingsStore from '@/store/modules/settings' +import { ComponentInternalInstance } from "vue"; +const { proxy } = getCurrentInstance() as ComponentInternalInstance; + +defineProps({ + collapse: { + type: Boolean, + required: true + } +}) + +const title = ref('RuoYi-Vue-Plus'); +const settingsStore = useSettingsStore(); +const sideTheme = computed(() => settingsStore.sideTheme); +</script> + <style lang="scss" scoped> .sidebarLogoFade-enter-active { transition: opacity 1.5s; diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue index a568c71..1c3dcb3 100644 --- a/src/layout/components/Sidebar/index.vue +++ b/src/layout/components/Sidebar/index.vue @@ -1,3 +1,25 @@ +<template> + <div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: bgColor }"> + <logo v-if="showLogo" :collapse="isCollapse" /> + <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> + <transition :enter-active-class="proxy?.animate.menuSearchAnimate.enter" mode="out-in"> + <el-menu + :default-active="activeMenu as string" + :collapse="isCollapse" + :background-color="bgColor" + :text-color="textColor" + :unique-opened="true" + :active-text-color="theme" + :collapse-transition="false" + mode="vertical" + > + <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> + </el-menu> + </transition> + </el-scrollbar> + </div> +</template> + <script setup lang="ts"> import Logo from './Logo.vue' import SidebarItem from './SidebarItem.vue' @@ -20,36 +42,14 @@ const isCollapse = computed(() => !appStore.sidebar.opened); const activeMenu = computed(() => { - const { meta, path } = route; - // if set path, the sidebar will highlight the path you set - if (meta.activeMenu) { - return meta.activeMenu; - } - return path; + const { meta, path } = route; + // if set path, the sidebar will highlight the path you set + if (meta.activeMenu) { + return meta.activeMenu; + } + return path; }) const bgColor = computed(() => sideTheme.value === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground); const textColor = computed(() => sideTheme.value === 'theme-dark' ? variables.menuColor : variables.menuLightColor); </script> - -<template> - <div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: bgColor }"> - <logo v-if="showLogo" :collapse="isCollapse" /> - <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> - <transition :enter-active-class="proxy?.animate.menuSearchAnimate.enter" mode="out-in"> - <el-menu - :default-active="activeMenu as string" - :collapse="isCollapse" - :background-color="bgColor" - :text-color="textColor" - :unique-opened="true" - :active-text-color="theme" - :collapse-transition="false" - mode="vertical" - > - <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> - </el-menu> - </transition> - </el-scrollbar> - </div> -</template> diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue index 6a96f75..e4624dc 100644 --- a/src/layout/components/TagsView/ScrollPane.vue +++ b/src/layout/components/TagsView/ScrollPane.vue @@ -1,3 +1,9 @@ +<template> + <el-scrollbar ref="scrollContainerRef" :vertical="false" class="scroll-container" @wheel.prevent="handleScroll"> + <slot /> + </el-scrollbar> +</template> + <script setup lang="ts"> import useTagsViewStore from '@/store/modules/tagsView' import { ElScrollbar } from 'element-plus'; @@ -8,83 +14,77 @@ const scrollWrapper = computed(() => scrollContainerRef.value.$refs.wrapRef); onMounted(() => { - scrollWrapper.value.addEventListener('scroll', emitScroll, true) + scrollWrapper.value.addEventListener('scroll', emitScroll, true) }) onBeforeUnmount(() => { - scrollWrapper.value.removeEventListener('scroll', emitScroll) + scrollWrapper.value.removeEventListener('scroll', emitScroll) }) const handleScroll = (e: WheelEvent) => { - const eventDelta = (e as any).wheelDelta || -e.deltaY * 40 - const $scrollWrapper = scrollWrapper.value; - $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 + const eventDelta = (e as any).wheelDelta || -e.deltaY * 40 + const $scrollWrapper = scrollWrapper.value; + $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 } const emits = defineEmits(['scroll']) const emitScroll = () => { - emits('scroll') + emits('scroll') } const tagsViewStore = useTagsViewStore() const visitedViews = computed(() => tagsViewStore.visitedViews); const moveToTarget = (currentTag: TagView) => { - const $container = scrollContainerRef.value.$el - const $containerWidth = $container.offsetWidth - const $scrollWrapper = scrollWrapper.value; + const $container = scrollContainerRef.value.$el + const $containerWidth = $container.offsetWidth + const $scrollWrapper = scrollWrapper.value; - let firstTag = null - let lastTag = null + let firstTag = null + let lastTag = null - // find first tag and last tag - if (visitedViews.value.length > 0) { - firstTag = visitedViews.value[0] - lastTag = visitedViews.value[visitedViews.value.length - 1] - } - - if (firstTag === currentTag) { - $scrollWrapper.scrollLeft = 0 - } else if (lastTag === currentTag) { - $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth - } else { - const tagListDom: any = document.getElementsByClassName('tags-view-item'); - const currentIndex = visitedViews.value.findIndex(item => item === currentTag) - let prevTag = null - let nextTag = null - - for (const k in tagListDom) { - if (k !== 'length' && Object.hasOwnProperty.call(tagListDom, k)) { - if (tagListDom[k].dataset.path === visitedViews.value[currentIndex - 1].path) { - prevTag = tagListDom[k]; - } - if (tagListDom[k].dataset.path === visitedViews.value[currentIndex + 1].path) { - nextTag = tagListDom[k]; - } - } + // find first tag and last tag + if (visitedViews.value.length > 0) { + firstTag = visitedViews.value[0] + lastTag = visitedViews.value[visitedViews.value.length - 1] } - // the tag's offsetLeft after of nextTag - const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing.value + if (firstTag === currentTag) { + $scrollWrapper.scrollLeft = 0 + } else if (lastTag === currentTag) { + $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth + } else { + const tagListDom: any = document.getElementsByClassName('tags-view-item'); + const currentIndex = visitedViews.value.findIndex(item => item === currentTag) + let prevTag = null + let nextTag = null - // the tag's offsetLeft before of prevTag - const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing.value - if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { - $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth - } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { - $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft + for (const k in tagListDom) { + if (k !== 'length' && Object.hasOwnProperty.call(tagListDom, k)) { + if (tagListDom[k].dataset.path === visitedViews.value[currentIndex - 1].path) { + prevTag = tagListDom[k]; + } + if (tagListDom[k].dataset.path === visitedViews.value[currentIndex + 1].path) { + nextTag = tagListDom[k]; + } + } + } + + // the tag's offsetLeft after of nextTag + const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing.value + + // the tag's offsetLeft before of prevTag + const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing.value + if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { + $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth + } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { + $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft + } } - } } defineExpose({ - moveToTarget, + moveToTarget, }) </script> - -<template> - <el-scrollbar ref="scrollContainerRef" :vertical="false" class="scroll-container" @wheel.prevent="handleScroll"> - <slot /> - </el-scrollbar> -</template> <style lang="scss" scoped> .scroll-container { diff --git a/src/layout/index.vue b/src/layout/index.vue index 8bc1c8b..fb59a13 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -1,56 +1,3 @@ -<script setup lang="ts"> -import SideBar from './components/Sidebar/index.vue' -import { AppMain, Navbar, Settings, TagsView } from './components' -import useAppStore from '@/store/modules/app' -import useSettingsStore from '@/store/modules/settings' - -const settingsStore = useSettingsStore() -const theme = computed(() => settingsStore.theme); -const sidebar = computed(() => useAppStore().sidebar); -const device = computed(() => useAppStore().device); -const needTagsView = computed(() => settingsStore.tagsView); -const fixedHeader = computed(() => settingsStore.fixedHeader); - -const classObj = computed(() => ({ - hideSidebar: !sidebar.value.opened, - openSidebar: sidebar.value.opened, - withoutAnimation: sidebar.value.withoutAnimation, - mobile: device.value === 'mobile' -})) - -const { width } = useWindowSize(); -const WIDTH = 992; // refer to Bootstrap's responsive design - -watchEffect(() => { - if (device.value === 'mobile' && sidebar.value.opened) { - useAppStore().closeSideBar({ withoutAnimation: false }) - } - if (width.value - 1 < WIDTH) { - useAppStore().toggleDevice('mobile') - useAppStore().closeSideBar({ withoutAnimation: true }) - } else { - useAppStore().toggleDevice('desktop') - } -}) - -const navbarRef = ref(Navbar); -const settingRef = ref(Settings); - -onMounted(() => { - nextTick(() => { - navbarRef.value.initTenantList(); - }) -}) - -const handleClickOutside = () => { - useAppStore().closeSideBar({ withoutAnimation: false }) -} - -const setLayout = () => { - settingRef.value.openSetting(); -} -</script> - <template> <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> @@ -66,6 +13,59 @@ </div> </template> +<script setup lang="ts"> +import SideBar from './components/Sidebar/index.vue' +import { AppMain, Navbar, Settings, TagsView } from './components' +import useAppStore from '@/store/modules/app' +import useSettingsStore from '@/store/modules/settings' + +const settingsStore = useSettingsStore() +const theme = computed(() => settingsStore.theme); +const sidebar = computed(() => useAppStore().sidebar); +const device = computed(() => useAppStore().device); +const needTagsView = computed(() => settingsStore.tagsView); +const fixedHeader = computed(() => settingsStore.fixedHeader); + +const classObj = computed(() => ({ + hideSidebar: !sidebar.value.opened, + openSidebar: sidebar.value.opened, + withoutAnimation: sidebar.value.withoutAnimation, + mobile: device.value === 'mobile' +})) + +const { width } = useWindowSize(); +const WIDTH = 992; // refer to Bootstrap's responsive design + +watchEffect(() => { + if (device.value === 'mobile' && sidebar.value.opened) { + useAppStore().closeSideBar({ withoutAnimation: false }) + } + if (width.value - 1 < WIDTH) { + useAppStore().toggleDevice('mobile') + useAppStore().closeSideBar({ withoutAnimation: true }) + } else { + useAppStore().toggleDevice('desktop') + } +}) + +const navbarRef = ref(Navbar); +const settingRef = ref(Settings); + +onMounted(() => { + nextTick(() => { + navbarRef.value.initTenantList(); + }) +}) + +const handleClickOutside = () => { + useAppStore().closeSideBar({ withoutAnimation: false }) +} + +const setLayout = () => { + settingRef.value.openSetting(); +} +</script> + <style lang="scss" scoped> @import "@/assets/styles/mixin.scss"; @import "@/assets/styles/variables.module.scss"; diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue index 9af7d50..8fd3bde 100644 --- a/src/views/monitor/cache/index.vue +++ b/src/views/monitor/cache/index.vue @@ -1,67 +1,3 @@ -<script setup name="Cache" lang="ts"> -import { getCache } from '@/api/monitor/cache'; -import * as echarts from 'echarts'; -import { ComponentInternalInstance } from "vue"; - -const cache = ref<any>({}); -const commandstats = ref(); -const usedmemory = ref(); -const { proxy } = getCurrentInstance() as ComponentInternalInstance; - -const getList = async () => { - proxy?.$modal.loading("姝e湪鍔犺浇缂撳瓨鐩戞帶鏁版嵁锛岃绋嶅�欙紒"); - const res = await getCache(); - proxy?.$modal.closeLoading(); - cache.value = res.data; - const commandstatsIntance = echarts.init(commandstats.value, "macarons"); - commandstatsIntance.setOption({ - tooltip: { - trigger: "item", - formatter: "{a} <br/>{b} : {c} ({d}%)" - }, - series: [ - { - name: "鍛戒护", - type: "pie", - roseType: "radius", - radius: [15, 95], - center: ["50%", "38%"], - data: res.data.commandStats, - animationEasing: "cubicInOut", - animationDuration: 1000 - } - ] - }); - - const usedmemoryInstance = echarts.init(usedmemory.value, "macarons"); - usedmemoryInstance.setOption({ - tooltip: { - formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human - }, - series: [ - { - name: "宄板��", - type: "gauge", - min: 0, - max: 1000, - detail: { - formatter: cache.value.info.used_memory_human - }, - data: [ - { - value: parseFloat(cache.value.info.used_memory_human), - name: "鍐呭瓨娑堣��" - } - ] - } - ] - }) -} - -onMounted(() => { - getList(); -}) -</script> <template> <div class="p-2"> <el-row> @@ -186,3 +122,68 @@ </el-row> </div> </template> + +<script setup name="Cache" lang="ts"> +import { getCache } from '@/api/monitor/cache'; +import * as echarts from 'echarts'; +import { ComponentInternalInstance } from "vue"; + +const cache = ref<any>({}); +const commandstats = ref(); +const usedmemory = ref(); +const { proxy } = getCurrentInstance() as ComponentInternalInstance; + +const getList = async () => { + proxy?.$modal.loading("姝e湪鍔犺浇缂撳瓨鐩戞帶鏁版嵁锛岃绋嶅�欙紒"); + const res = await getCache(); + proxy?.$modal.closeLoading(); + cache.value = res.data; + const commandstatsIntance = echarts.init(commandstats.value, "macarons"); + commandstatsIntance.setOption({ + tooltip: { + trigger: "item", + formatter: "{a} <br/>{b} : {c} ({d}%)" + }, + series: [ + { + name: "鍛戒护", + type: "pie", + roseType: "radius", + radius: [15, 95], + center: ["50%", "38%"], + data: res.data.commandStats, + animationEasing: "cubicInOut", + animationDuration: 1000 + } + ] + }); + + const usedmemoryInstance = echarts.init(usedmemory.value, "macarons"); + usedmemoryInstance.setOption({ + tooltip: { + formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human + }, + series: [ + { + name: "宄板��", + type: "gauge", + min: 0, + max: 1000, + detail: { + formatter: cache.value.info.used_memory_human + }, + data: [ + { + value: parseFloat(cache.value.info.used_memory_human), + name: "鍐呭瓨娑堣��" + } + ] + } + ] + }) +} + +onMounted(() => { + getList(); +}) +</script> \ No newline at end of file diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue index f461ecd..2f3efe0 100644 --- a/src/views/system/config/index.vue +++ b/src/views/system/config/index.vue @@ -1,143 +1,3 @@ -<script setup name="Config" lang="ts"> -import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config"; -import { ConfigForm, ConfigQuery, ConfigVO } from "@/api/system/config/types"; -import { ComponentInternalInstance } from "vue"; -import { DateModelType } from 'element-plus'; - -const { proxy } = getCurrentInstance() as ComponentInternalInstance; -const { sys_yes_no } = toRefs<any>(proxy?.useDict("sys_yes_no")); - -const configList = ref<ConfigVO[]>([]); -const loading = ref(true); -const showSearch = ref(true); -const ids = ref<Array<number | string>>([]); -const single = ref(true); -const multiple = ref(true); -const total = ref(0); -const dateRange = ref<[DateModelType, DateModelType]>(['', '']); - -const queryFormRef = ref(ElForm); -const configFormRef = ref(ElForm); -const dialog = reactive<DialogOption>({ - visible: false, - title: '' -}); -const initFormData: ConfigForm = { - configId: undefined, - configName: '', - configKey: '', - configValue: '', - configType: "Y", - remark: '' -} -const data = reactive<PageData<ConfigForm, ConfigQuery>>({ - form: {...initFormData}, - queryParams: { - pageNum: 1, - pageSize: 10, - configName: '', - configKey: '', - configType: '', - }, - rules: { - configName: [{ required: true, message: "鍙傛暟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }], - configKey: [{ required: true, message: "鍙傛暟閿悕涓嶈兘涓虹┖", trigger: "blur" }], - configValue: [{ required: true, message: "鍙傛暟閿�间笉鑳戒负绌�", trigger: "blur" }] - } -}); - -const { queryParams, form, rules } = toRefs(data); - -/** 鏌ヨ鍙傛暟鍒楄〃 */ -const getList = async () => { - loading.value = true; - const res = await listConfig(proxy?.addDateRange(queryParams.value, dateRange.value)); - configList.value = res.rows; - total.value = res.total; - loading.value = false; -} -/** 鍙栨秷鎸夐挳 */ -const cancel = () => { - reset(); - dialog.visible = false; -} -/** 琛ㄥ崟閲嶇疆 */ -const reset = () => { - form.value = {...initFormData}; - configFormRef.value.resetFields(); -} -/** 鎼滅储鎸夐挳鎿嶄綔 */ -const handleQuery = () => { - queryParams.value.pageNum = 1; - getList(); -} -/** 閲嶇疆鎸夐挳鎿嶄綔 */ -const resetQuery = () => { - dateRange.value = ['', '']; - queryFormRef.value.resetFields(); - handleQuery(); -} -/** 澶氶�夋閫変腑鏁版嵁 */ -const handleSelectionChange = (selection: ConfigVO[]) => { - ids.value = selection.map(item => item.configId); - single.value = selection.length != 1; - multiple.value = !selection.length; -} -/** 鏂板鎸夐挳鎿嶄綔 */ -const handleAdd = () => { - dialog.visible = true; - dialog.title = "娣诲姞鍙傛暟"; - nextTick(() => { - reset(); - }) -} -/** 淇敼鎸夐挳鎿嶄綔 */ -const handleUpdate = (row?: ConfigVO) => { - dialog.visible = true; - dialog.title = "淇敼鍙傛暟"; - const configId = row?.configId || ids.value[0]; - nextTick(async () => { - reset(); - const res = await getConfig(configId); - form.value = res.data; - }) -} -/** 鎻愪氦鎸夐挳 */ -const submitForm = () => { - configFormRef.value.validate(async (valid: boolean) => { - if (valid) { - form.value.configId ? await updateConfig(form.value) : await addConfig(form.value); - proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛"); - dialog.visible = false; - getList(); - } - }); -} -/** 鍒犻櫎鎸夐挳鎿嶄綔 */ -const handleDelete = async (row?: ConfigVO) => { - const configIds = row?.configId || ids.value; - await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍙傛暟缂栧彿涓�"' + configIds + '"鐨勬暟鎹」锛�'); - await delConfig(configIds); - getList(); - proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛"); -} -/** 瀵煎嚭鎸夐挳鎿嶄綔 */ -const handleExport = () => { - proxy?.download("system/config/export", { - ...queryParams.value - }, `config_${new Date().getTime()}.xlsx`); -} -/** 鍒锋柊缂撳瓨鎸夐挳鎿嶄綔 */ -const handleRefreshCache = async () => { - await refreshCache(); - proxy?.$modal.msgSuccess("鍒锋柊缂撳瓨鎴愬姛"); -} - -onMounted(() => { - getList(); -}) -</script> - <template> <div class="p-2"> <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> @@ -259,3 +119,143 @@ </el-dialog> </div> </template> + +<script setup name="Config" lang="ts"> +import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config"; +import { ConfigForm, ConfigQuery, ConfigVO } from "@/api/system/config/types"; +import { ComponentInternalInstance } from "vue"; +import { DateModelType } from 'element-plus'; + +const { proxy } = getCurrentInstance() as ComponentInternalInstance; +const { sys_yes_no } = toRefs<any>(proxy?.useDict("sys_yes_no")); + +const configList = ref<ConfigVO[]>([]); +const loading = ref(true); +const showSearch = ref(true); +const ids = ref<Array<number | string>>([]); +const single = ref(true); +const multiple = ref(true); +const total = ref(0); +const dateRange = ref<[DateModelType, DateModelType]>(['', '']); + +const queryFormRef = ref(ElForm); +const configFormRef = ref(ElForm); +const dialog = reactive<DialogOption>({ + visible: false, + title: '' +}); +const initFormData: ConfigForm = { + configId: undefined, + configName: '', + configKey: '', + configValue: '', + configType: "Y", + remark: '' +} +const data = reactive<PageData<ConfigForm, ConfigQuery>>({ + form: {...initFormData}, + queryParams: { + pageNum: 1, + pageSize: 10, + configName: '', + configKey: '', + configType: '', + }, + rules: { + configName: [{ required: true, message: "鍙傛暟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }], + configKey: [{ required: true, message: "鍙傛暟閿悕涓嶈兘涓虹┖", trigger: "blur" }], + configValue: [{ required: true, message: "鍙傛暟閿�间笉鑳戒负绌�", trigger: "blur" }] + } +}); + +const { queryParams, form, rules } = toRefs(data); + +/** 鏌ヨ鍙傛暟鍒楄〃 */ +const getList = async () => { + loading.value = true; + const res = await listConfig(proxy?.addDateRange(queryParams.value, dateRange.value)); + configList.value = res.rows; + total.value = res.total; + loading.value = false; +} +/** 鍙栨秷鎸夐挳 */ +const cancel = () => { + reset(); + dialog.visible = false; +} +/** 琛ㄥ崟閲嶇疆 */ +const reset = () => { + form.value = {...initFormData}; + configFormRef.value.resetFields(); +} +/** 鎼滅储鎸夐挳鎿嶄綔 */ +const handleQuery = () => { + queryParams.value.pageNum = 1; + getList(); +} +/** 閲嶇疆鎸夐挳鎿嶄綔 */ +const resetQuery = () => { + dateRange.value = ['', '']; + queryFormRef.value.resetFields(); + handleQuery(); +} +/** 澶氶�夋閫変腑鏁版嵁 */ +const handleSelectionChange = (selection: ConfigVO[]) => { + ids.value = selection.map(item => item.configId); + single.value = selection.length != 1; + multiple.value = !selection.length; +} +/** 鏂板鎸夐挳鎿嶄綔 */ +const handleAdd = () => { + dialog.visible = true; + dialog.title = "娣诲姞鍙傛暟"; + nextTick(() => { + reset(); + }) +} +/** 淇敼鎸夐挳鎿嶄綔 */ +const handleUpdate = (row?: ConfigVO) => { + dialog.visible = true; + dialog.title = "淇敼鍙傛暟"; + const configId = row?.configId || ids.value[0]; + nextTick(async () => { + reset(); + const res = await getConfig(configId); + form.value = res.data; + }) +} +/** 鎻愪氦鎸夐挳 */ +const submitForm = () => { + configFormRef.value.validate(async (valid: boolean) => { + if (valid) { + form.value.configId ? await updateConfig(form.value) : await addConfig(form.value); + proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛"); + dialog.visible = false; + getList(); + } + }); +} +/** 鍒犻櫎鎸夐挳鎿嶄綔 */ +const handleDelete = async (row?: ConfigVO) => { + const configIds = row?.configId || ids.value; + await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍙傛暟缂栧彿涓�"' + configIds + '"鐨勬暟鎹」锛�'); + await delConfig(configIds); + getList(); + proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛"); +} +/** 瀵煎嚭鎸夐挳鎿嶄綔 */ +const handleExport = () => { + proxy?.download("system/config/export", { + ...queryParams.value + }, `config_${new Date().getTime()}.xlsx`); +} +/** 鍒锋柊缂撳瓨鎸夐挳鎿嶄綔 */ +const handleRefreshCache = async () => { + await refreshCache(); + proxy?.$modal.msgSuccess("鍒锋柊缂撳瓨鎴愬姛"); +} + +onMounted(() => { + getList(); +}) +</script> diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue index 73496b3..341c08d 100644 --- a/src/views/system/user/profile/index.vue +++ b/src/views/system/user/profile/index.vue @@ -1,31 +1,3 @@ -<script setup name="Profile" lang="ts"> -import userAvatar from "./userAvatar.vue"; -import userInfo from "./userInfo.vue"; -import resetPwd from "./resetPwd.vue"; -import { getUserProfile } from "@/api/system/user"; - -const activeTab = ref("userinfo"); -const state = ref<{ user: any; roleGroup: string; postGroup: string}>({ - user: {}, - roleGroup: '', - postGroup: '' -}); - -const userForm = ref({}); - -const getUser = async () => { - const res = await getUserProfile(); - state.value.user = res.data.user; - userForm.value = { ...res.data.user } - state.value.roleGroup = res.data.roleGroup; - state.value.postGroup = res.data.postGroup; -}; - -onMounted(() => { - getUser(); -}) -</script> - <template> <div class="p-2"> <el-row :gutter="20"> @@ -89,3 +61,31 @@ </el-row> </div> </template> + +<script setup name="Profile" lang="ts"> +import userAvatar from "./userAvatar.vue"; +import userInfo from "./userInfo.vue"; +import resetPwd from "./resetPwd.vue"; +import { getUserProfile } from "@/api/system/user"; + +const activeTab = ref("userinfo"); +const state = ref<{ user: any; roleGroup: string; postGroup: string}>({ + user: {}, + roleGroup: '', + postGroup: '' +}); + +const userForm = ref({}); + +const getUser = async () => { + const res = await getUserProfile(); + state.value.user = res.data.user; + userForm.value = { ...res.data.user } + state.value.roleGroup = res.data.roleGroup; + state.value.postGroup = res.data.postGroup; +}; + +onMounted(() => { + getUser(); +}) +</script> diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue index 2f6551b..174e020 100644 --- a/src/views/system/user/profile/resetPwd.vue +++ b/src/views/system/user/profile/resetPwd.vue @@ -1,48 +1,3 @@ -<script setup lang="ts"> -import { updateUserPwd } from '@/api/system/user'; -import { ComponentInternalInstance } from 'vue'; -import { ResetPwdForm } from '@/api/system/user/types' -import { ElForm } from 'element-plus'; - -const { proxy } = getCurrentInstance() as ComponentInternalInstance; - - -const pwdRef = ref(ElForm); - -const user = ref<ResetPwdForm>({ - oldPassword: '', - newPassword: '', - confirmPassword: '' -}); - -const equalToPassword = (rule: any, value: string, callback: any) => { - if (user.value.newPassword !== value) { - callback(new Error("涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�")); - } else { - callback(); - } -}; -const rules = ref({ - oldPassword: [{ required: true, message: "鏃у瘑鐮佷笉鑳戒负绌�", trigger: "blur" }], - newPassword: [{ required: true, message: "鏂板瘑鐮佷笉鑳戒负绌�", trigger: "blur" }, { min: 6, max: 20, message: "闀垮害鍦� 6 鍒� 20 涓瓧绗�", trigger: "blur" }], - confirmPassword: [{ required: true, message: "纭瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }] -}); - -/** 鎻愪氦鎸夐挳 */ -const submit = () => { - pwdRef.value.validate(async (valid: boolean) => { - if (valid) { - await updateUserPwd(user.value.oldPassword, user.value.newPassword) - proxy?.$modal.msgSuccess("淇敼鎴愬姛"); - } - }); -}; -/** 鍏抽棴鎸夐挳 */ -const close = () => { - proxy?.$tab.closePage(); -}; -</script> - <template> <el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px"> <el-form-item label="鏃у瘑鐮�" prop="oldPassword"> @@ -60,3 +15,48 @@ </el-form-item> </el-form> </template> + +<script setup lang="ts"> +import { updateUserPwd } from '@/api/system/user'; +import { ComponentInternalInstance } from 'vue'; +import { ResetPwdForm } from '@/api/system/user/types' +import { ElForm } from 'element-plus'; + +const { proxy } = getCurrentInstance() as ComponentInternalInstance; + + +const pwdRef = ref(ElForm); + +const user = ref<ResetPwdForm>({ + oldPassword: '', + newPassword: '', + confirmPassword: '' +}); + +const equalToPassword = (rule: any, value: string, callback: any) => { + if (user.value.newPassword !== value) { + callback(new Error("涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�")); + } else { + callback(); + } +}; +const rules = ref({ + oldPassword: [{ required: true, message: "鏃у瘑鐮佷笉鑳戒负绌�", trigger: "blur" }], + newPassword: [{ required: true, message: "鏂板瘑鐮佷笉鑳戒负绌�", trigger: "blur" }, { min: 6, max: 20, message: "闀垮害鍦� 6 鍒� 20 涓瓧绗�", trigger: "blur" }], + confirmPassword: [{ required: true, message: "纭瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }] +}); + +/** 鎻愪氦鎸夐挳 */ +const submit = () => { + pwdRef.value.validate(async (valid: boolean) => { + if (valid) { + await updateUserPwd(user.value.oldPassword, user.value.newPassword) + proxy?.$modal.msgSuccess("淇敼鎴愬姛"); + } + }); +}; +/** 鍏抽棴鎸夐挳 */ +const close = () => { + proxy?.$tab.closePage(); +}; +</script> diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue index eaf8db3..0af8b28 100644 --- a/src/views/system/user/profile/userAvatar.vue +++ b/src/views/system/user/profile/userAvatar.vue @@ -1,104 +1,3 @@ -<script setup lang="ts"> -import "vue-cropper/dist/index.css"; -import { VueCropper } from "vue-cropper"; -import { uploadAvatar } from "@/api/system/user"; -import useUserStore from "@/store/modules/user"; -import { ComponentInternalInstance } from "vue"; - -interface Options { - img: string | ArrayBuffer | null // 瑁佸壀鍥剧墖鐨勫湴鍧� - autoCrop: boolean // 鏄惁榛樿鐢熸垚鎴浘妗� - autoCropWidth: number // 榛樿鐢熸垚鎴浘妗嗗搴� - autoCropHeight: number // 榛樿鐢熸垚鎴浘妗嗛珮搴� - fixedBox: boolean // 鍥哄畾鎴浘妗嗗ぇ灏� 涓嶅厑璁告敼鍙� - fileName: string - previews: any // 棰勮鏁版嵁 - outputType: string - visible: boolean -} - - -const userStore = useUserStore(); -const { proxy } = getCurrentInstance() as ComponentInternalInstance; - -const open = ref(false); -const visible = ref(false); -const title = ref("淇敼澶村儚"); - -const cropper = ref<any>({}); -//鍥剧墖瑁佸壀鏁版嵁 -const options = reactive<Options>({ - img: userStore.avatar, - autoCrop: true, - autoCropWidth: 200, - autoCropHeight: 200, - fixedBox: true, - outputType: "png", - fileName: '', - previews: {}, - visible: false -}); - -/** 缂栬緫澶村儚 */ -const editCropper = () => { - open.value = true; -} -/** 鎵撳紑寮瑰嚭灞傜粨鏉熸椂鐨勫洖璋� */ -const modalOpened = () => { - visible.value = true; -} -/** 瑕嗙洊榛樿涓婁紶琛屼负 */ -const requestUpload = (): any => {} -/** 鍚戝乏鏃嬭浆 */ -const rotateLeft = () => { - cropper.value.rotateLeft(); -} -/** 鍚戝彸鏃嬭浆 */ -const rotateRight = () => { - cropper.value.rotateRight(); -} -/** 鍥剧墖缂╂斁 */ -const changeScale = (num: number) => { - num = num || 1; - cropper.value.changeScale(num); -} -/** 涓婁紶棰勫鐞� */ -const beforeUpload = (file: any) => { - if (file.type.indexOf("image/") == -1) { - proxy?.$modal.msgError("鏂囦欢鏍煎紡閿欒锛岃涓婁紶鍥剧墖绫诲瀷,濡傦細JPG锛孭NG鍚庣紑鐨勬枃浠躲��"); - } else { - const reader = new FileReader(); - reader.readAsDataURL(file); - reader.onload = () => { - options.img = reader.result; - options.fileName = file.name; - }; - } -} -/** 涓婁紶鍥剧墖 */ -const uploadImg = async () => { - cropper.value.getCropBlob(async (data: any) => { - let formData = new FormData(); - formData.append("avatarfile", data, options.fileName); - const res = await uploadAvatar(formData); - open.value = false; - options.img = res.data.imgUrl; - userStore.avatar = options.img as string; - proxy?.$modal.msgSuccess("淇敼鎴愬姛"); - visible.value = false; - }); -} -/** 瀹炴椂棰勮 */ -const realTime = (data: any) => { - options.previews = data; -} -/** 鍏抽棴绐楀彛 */ -const closeDialog = () => { - options.img = userStore.avatar; - options.visible = false; -} -</script> - <template> <div class="user-info-head" @click="editCropper()"> <img :src="options.img as string" title="鐐瑰嚮涓婁紶澶村儚" class="img-circle img-lg" /> @@ -154,6 +53,107 @@ </div> </template> +<script setup lang="ts"> +import "vue-cropper/dist/index.css"; +import { VueCropper } from "vue-cropper"; +import { uploadAvatar } from "@/api/system/user"; +import useUserStore from "@/store/modules/user"; +import { ComponentInternalInstance } from "vue"; + +interface Options { + img: string | ArrayBuffer | null // 瑁佸壀鍥剧墖鐨勫湴鍧� + autoCrop: boolean // 鏄惁榛樿鐢熸垚鎴浘妗� + autoCropWidth: number // 榛樿鐢熸垚鎴浘妗嗗搴� + autoCropHeight: number // 榛樿鐢熸垚鎴浘妗嗛珮搴� + fixedBox: boolean // 鍥哄畾鎴浘妗嗗ぇ灏� 涓嶅厑璁告敼鍙� + fileName: string + previews: any // 棰勮鏁版嵁 + outputType: string + visible: boolean +} + + +const userStore = useUserStore(); +const { proxy } = getCurrentInstance() as ComponentInternalInstance; + +const open = ref(false); +const visible = ref(false); +const title = ref("淇敼澶村儚"); + +const cropper = ref<any>({}); +//鍥剧墖瑁佸壀鏁版嵁 +const options = reactive<Options>({ + img: userStore.avatar, + autoCrop: true, + autoCropWidth: 200, + autoCropHeight: 200, + fixedBox: true, + outputType: "png", + fileName: '', + previews: {}, + visible: false +}); + +/** 缂栬緫澶村儚 */ +const editCropper = () => { + open.value = true; +} +/** 鎵撳紑寮瑰嚭灞傜粨鏉熸椂鐨勫洖璋� */ +const modalOpened = () => { + visible.value = true; +} +/** 瑕嗙洊榛樿涓婁紶琛屼负 */ +const requestUpload = (): any => {} +/** 鍚戝乏鏃嬭浆 */ +const rotateLeft = () => { + cropper.value.rotateLeft(); +} +/** 鍚戝彸鏃嬭浆 */ +const rotateRight = () => { + cropper.value.rotateRight(); +} +/** 鍥剧墖缂╂斁 */ +const changeScale = (num: number) => { + num = num || 1; + cropper.value.changeScale(num); +} +/** 涓婁紶棰勫鐞� */ +const beforeUpload = (file: any) => { + if (file.type.indexOf("image/") == -1) { + proxy?.$modal.msgError("鏂囦欢鏍煎紡閿欒锛岃涓婁紶鍥剧墖绫诲瀷,濡傦細JPG锛孭NG鍚庣紑鐨勬枃浠躲��"); + } else { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + options.img = reader.result; + options.fileName = file.name; + }; + } +} +/** 涓婁紶鍥剧墖 */ +const uploadImg = async () => { + cropper.value.getCropBlob(async (data: any) => { + let formData = new FormData(); + formData.append("avatarfile", data, options.fileName); + const res = await uploadAvatar(formData); + open.value = false; + options.img = res.data.imgUrl; + userStore.avatar = options.img as string; + proxy?.$modal.msgSuccess("淇敼鎴愬姛"); + visible.value = false; + }); +} +/** 瀹炴椂棰勮 */ +const realTime = (data: any) => { + options.previews = data; +} +/** 鍏抽棴绐楀彛 */ +const closeDialog = () => { + options.img = userStore.avatar; + options.visible = false; +} +</script> + <style lang="scss" scoped> .user-info-head { position: relative; diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue index 9cf7c0f..0c3d6ef 100644 --- a/src/views/system/user/profile/userInfo.vue +++ b/src/views/system/user/profile/userInfo.vue @@ -1,43 +1,3 @@ -<script setup lang="ts"> -import { updateUserProfile } from "@/api/system/user"; -import { FormRules } from "element-plus"; -import { ComponentInternalInstance } from "vue"; -import { PropType } from "vue"; -import { ElForm } from "element-plus"; - -const props = defineProps({ - user: { - type: Object as PropType<any>, - } -}); -const userForm = computed(() => props.user); - -const { proxy } = getCurrentInstance() as ComponentInternalInstance; - -const userRef = ref(ElForm); - -const rules = ref<FormRules>({ - nickName: [{ required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" }], - email: [{ required: true, message: "閭鍦板潃涓嶈兘涓虹┖", trigger: "blur" }, { type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }], - phonenumber: [{ required: true, message: "鎵嬫満鍙风爜涓嶈兘涓虹┖", trigger: "blur" }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }], -}); - - -/** 鎻愪氦鎸夐挳 */ -const submit = () => { - userRef.value.validate(async (valid: boolean) => { - if (valid) { - await updateUserProfile(props.user) - proxy?.$modal.msgSuccess("淇敼鎴愬姛"); - } - }); -}; -/** 鍏抽棴鎸夐挳 */ -const close = () => { - proxy?.$tab.closePage(); -}; -</script> - <template> <el-form ref="userRef" :model="userForm" :rules="rules" label-width="80px"> <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName"> @@ -61,3 +21,43 @@ </el-form-item> </el-form> </template> + +<script setup lang="ts"> +import { updateUserProfile } from "@/api/system/user"; +import { FormRules } from "element-plus"; +import { ComponentInternalInstance } from "vue"; +import { PropType } from "vue"; +import { ElForm } from "element-plus"; + +const props = defineProps({ + user: { + type: Object as PropType<any>, + } +}); +const userForm = computed(() => props.user); + +const { proxy } = getCurrentInstance() as ComponentInternalInstance; + +const userRef = ref(ElForm); + +const rules = ref<FormRules>({ + nickName: [{ required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" }], + email: [{ required: true, message: "閭鍦板潃涓嶈兘涓虹┖", trigger: "blur" }, { type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }], + phonenumber: [{ required: true, message: "鎵嬫満鍙风爜涓嶈兘涓虹┖", trigger: "blur" }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }], +}); + + +/** 鎻愪氦鎸夐挳 */ +const submit = () => { + userRef.value.validate(async (valid: boolean) => { + if (valid) { + await updateUserProfile(props.user) + proxy?.$modal.msgSuccess("淇敼鎴愬姛"); + } + }); +}; +/** 鍏抽棴鎸夐挳 */ +const close = () => { + proxy?.$tab.closePage(); +}; +</script> diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue index 0f77a7c..5d8e781 100644 --- a/src/views/tool/gen/basicInfoForm.vue +++ b/src/views/tool/gen/basicInfoForm.vue @@ -1,26 +1,3 @@ -<script setup lang="ts"> -import { PropType } from 'vue'; - -const prop = defineProps({ - info: { - type: Object as PropType<any>, - default: () => { - return {}; - } - } -}); - -const infoForm = computed(() => prop.info) - -// 琛ㄥ崟鏍¢獙 -const rules = ref({ - tableName: [{ required: true, message: "璇疯緭鍏ヨ〃鍚嶇О", trigger: "blur" }], - tableComment: [{ required: true, message: "璇疯緭鍏ヨ〃鎻忚堪", trigger: "blur" }], - className: [{ required: true, message: "璇疯緭鍏ュ疄浣撶被鍚嶇О", trigger: "blur" }], - functionAuthor: [{ required: true, message: "璇疯緭鍏ヤ綔鑰�", trigger: "blur" }] -}); -</script> - <template> <el-form ref="basicInfoForm" :model="infoForm" :rules="rules" label-width="150px"> <el-row> @@ -52,3 +29,26 @@ </el-row> </el-form> </template> + +<script setup lang="ts"> +import { PropType } from 'vue'; + +const prop = defineProps({ + info: { + type: Object as PropType<any>, + default: () => { + return {}; + } + } +}); + +const infoForm = computed(() => prop.info) + +// 琛ㄥ崟鏍¢獙 +const rules = ref({ + tableName: [{ required: true, message: "璇疯緭鍏ヨ〃鍚嶇О", trigger: "blur" }], + tableComment: [{ required: true, message: "璇疯緭鍏ヨ〃鎻忚堪", trigger: "blur" }], + className: [{ required: true, message: "璇疯緭鍏ュ疄浣撶被鍚嶇О", trigger: "blur" }], + functionAuthor: [{ required: true, message: "璇疯緭鍏ヤ綔鑰�", trigger: "blur" }] +}); +</script> diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue index 70fb36f..d6efd61 100644 --- a/src/views/tool/gen/genInfoForm.vue +++ b/src/views/tool/gen/genInfoForm.vue @@ -1,76 +1,3 @@ -<script setup lang="ts"> -import { listMenu } from '@/api/system/menu'; -import { ComponentInternalInstance, PropType } from 'vue'; - -interface MenuOptionsType { - menuId: number; - menuName: string; - children: MenuOptionsType[] | undefined; -} - -const subColumns = ref<any>([]); -const menuOptions = ref<Array<MenuOptionsType>>([]); -const { proxy } = getCurrentInstance() as ComponentInternalInstance; - -const props = defineProps({ - info: { - type: Object as PropType<any>, - default: null - }, - tables: { - type: Array as PropType<any[]>, - default: null - } -}); - -const infoForm = computed(() => props.info); - -const table = computed(() => props.tables); - -// 琛ㄥ崟鏍¢獙 -const rules = ref({ - tplCategory: [{ required: true, message: "璇烽�夋嫨鐢熸垚妯℃澘", trigger: "blur" }], - packageName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愬寘璺緞", trigger: "blur" }], - moduleName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愭ā鍧楀悕", trigger: "blur" }], - businessName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愪笟鍔″悕", trigger: "blur" }], - functionName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愬姛鑳藉悕", trigger: "blur" }] -}); -const subSelectChange = () => { - infoForm.value.subTableFkName = ""; -} -const tplSelectChange = (value: string) => { - if (value !== "sub") { - infoForm.value.subTableName = ""; - infoForm.value.subTableFkName = ""; - } -} -const setSubTableColumns = (value: string) => { - table.value.forEach(item => { - const name = item.tableName; - if (value === name) { - subColumns.value = item.columns; - return; - } - }) -} -/** 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� */ -const getMenuTreeselect = async () => { - const res = await listMenu(); - const data = proxy?.handleTree<MenuOptionsType>(res.data, "menuId"); - if (data) { - menuOptions.value = data - } -} - -watch(() => props.info.subTableName, val => { - setSubTableColumns(val); -}); - -onMounted(() => { - getMenuTreeselect(); -}) -</script> - <template> <el-form ref="genInfoForm" :model="infoForm" :rules="rules" label-width="150px"> <el-row> @@ -287,3 +214,76 @@ </template> </el-form> </template> + +<script setup lang="ts"> +import { listMenu } from '@/api/system/menu'; +import { ComponentInternalInstance, PropType } from 'vue'; + +interface MenuOptionsType { + menuId: number; + menuName: string; + children: MenuOptionsType[] | undefined; +} + +const subColumns = ref<any>([]); +const menuOptions = ref<Array<MenuOptionsType>>([]); +const { proxy } = getCurrentInstance() as ComponentInternalInstance; + +const props = defineProps({ + info: { + type: Object as PropType<any>, + default: null + }, + tables: { + type: Array as PropType<any[]>, + default: null + } +}); + +const infoForm = computed(() => props.info); + +const table = computed(() => props.tables); + +// 琛ㄥ崟鏍¢獙 +const rules = ref({ + tplCategory: [{ required: true, message: "璇烽�夋嫨鐢熸垚妯℃澘", trigger: "blur" }], + packageName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愬寘璺緞", trigger: "blur" }], + moduleName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愭ā鍧楀悕", trigger: "blur" }], + businessName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愪笟鍔″悕", trigger: "blur" }], + functionName: [{ required: true, message: "璇疯緭鍏ョ敓鎴愬姛鑳藉悕", trigger: "blur" }] +}); +const subSelectChange = () => { + infoForm.value.subTableFkName = ""; +} +const tplSelectChange = (value: string) => { + if (value !== "sub") { + infoForm.value.subTableName = ""; + infoForm.value.subTableFkName = ""; + } +} +const setSubTableColumns = (value: string) => { + table.value.forEach(item => { + const name = item.tableName; + if (value === name) { + subColumns.value = item.columns; + return; + } + }) +} +/** 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� */ +const getMenuTreeselect = async () => { + const res = await listMenu(); + const data = proxy?.handleTree<MenuOptionsType>(res.data, "menuId"); + if (data) { + menuOptions.value = data + } +} + +watch(() => props.info.subTableName, val => { + setSubTableColumns(val); +}); + +onMounted(() => { + getMenuTreeselect(); +}) +</script> -- Gitblit v1.9.3