Browse Source

Merge branch 'develop'

陈凯龙 3 years ago
parent
commit
7f52d4cb1f

+ 1 - 1
.vscode/settings.json

@@ -5,7 +5,7 @@
     "source.fixAll.eslint": true
   },
   "[vue]": {
-    "editor.defaultFormatter": "johnsoncodehk.volar"
+    "editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
   },
   "i18n-ally.localesPaths": ["src/locales"],
   "i18n-ally.keystyle": "nested",

+ 10 - 10
package.json

@@ -46,7 +46,7 @@
     "pinia-plugin-persist": "^1.0.0",
     "qrcode": "^1.5.0",
     "qs": "^6.10.3",
-    "vue": "3.2.31",
+    "vue": "3.2.32",
     "vue-i18n": "9.1.9",
     "vue-router": "^4.0.14",
     "vue-types": "^4.1.1",
@@ -55,7 +55,7 @@
   "devDependencies": {
     "@commitlint/cli": "^16.2.3",
     "@commitlint/config-conventional": "^16.2.1",
-    "@iconify/json": "^2.1.27",
+    "@iconify/json": "^2.1.28",
     "@intlify/vite-plugin-vue-i18n": "^3.4.0",
     "@purge-icons/generated": "^0.8.1",
     "@types/intro.js": "^3.0.2",
@@ -64,10 +64,10 @@
     "@types/nprogress": "^0.2.0",
     "@types/qrcode": "^1.4.2",
     "@types/qs": "^6.9.7",
-    "@typescript-eslint/eslint-plugin": "^5.18.0",
-    "@typescript-eslint/parser": "^5.18.0",
+    "@typescript-eslint/eslint-plugin": "^5.19.0",
+    "@typescript-eslint/parser": "^5.19.0",
     "@vitejs/plugin-vue": "^2.3.1",
-    "@vitejs/plugin-vue-jsx": "^1.3.9",
+    "@vitejs/plugin-vue-jsx": "^1.3.10",
     "autoprefixer": "^10.4.4",
     "commitizen": "^4.2.4",
     "eslint": "^8.13.0",
@@ -80,7 +80,7 @@
     "lint-staged": "^12.3.7",
     "plop": "^3.0.5",
     "postcss": "^8.4.12",
-    "postcss-html": "^1.3.0",
+    "postcss-html": "^1.3.1",
     "postcss-less": "^6.0.0",
     "prettier": "^2.6.2",
     "pretty-quick": "^3.1.3",
@@ -93,15 +93,15 @@
     "stylelint-order": "^5.0.0",
     "typescript": "4.6.3",
     "unplugin-vue-define-options": "^0.6.0",
-    "vite": "2.9.1",
-    "vite-plugin-eslint": "^1.3.0",
+    "vite": "2.9.4",
+    "vite-plugin-eslint": "^1.4.0",
     "vite-plugin-html": "^3.2.0",
     "vite-plugin-mock": "^2.9.6",
     "vite-plugin-purge-icons": "^0.8.1",
     "vite-plugin-style-import": "^1.4.1",
     "vite-plugin-svg-icons": "^2.0.1",
-    "vite-plugin-windicss": "^1.8.3",
-    "vue-tsc": "^0.34.5",
+    "vite-plugin-windicss": "^1.8.4",
+    "vue-tsc": "^0.34.6",
     "windicss": "^3.5.1",
     "windicss-analysis": "^0.3.5"
   },

File diff suppressed because it is too large
+ 4848 - 4280
pnpm-lock.yaml


+ 15 - 7
src/components/Editor/src/Editor.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
-import { onBeforeUnmount, computed, PropType, unref, nextTick, ref, watch } from 'vue'
-import { Editor, Toolbar, getEditor, removeEditor } from '@wangeditor/editor-for-vue'
+import { onBeforeUnmount, computed, PropType, unref, nextTick, ref, watch, shallowRef } from 'vue'
+import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
 import { IDomEditor, IEditorConfig, i18nChangeLanguage } from '@wangeditor/editor'
 import { propTypes } from '@/utils/propTypes'
 import { isNumber } from '@/utils/is'
@@ -23,6 +23,13 @@ const props = defineProps({
   defaultHtml: propTypes.string.def('')
 })
 
+// 编辑器实例,必须用 shallowRef
+const editorRef = shallowRef<IDomEditor>()
+
+const handleCreated = (editor: IDomEditor) => {
+  editorRef.value = editor
+}
+
 const emit = defineEmits(['change'])
 
 // 编辑器配置
@@ -70,17 +77,16 @@ const handleChange = (editor: IDomEditor) => {
 
 // 组件销毁时,及时销毁编辑器
 onBeforeUnmount(() => {
-  const editor = getEditor(props.editorId)
-  if (editor == null) return
+  const editor = unref(editorRef.value)
+  if (editor === null) return
 
   // 销毁,并移除 editor
-  editor.destroy()
-  removeEditor(props.editorId)
+  editor?.destroy()
 })
 
 const getEditorRef = async (): Promise<IDomEditor> => {
   await nextTick()
-  return getEditor(props.editorId) as IDomEditor
+  return unref(editorRef.value) as IDomEditor
 }
 
 defineExpose({
@@ -104,6 +110,7 @@ watch(
   <div v-if="show" class="border-1 border-solid border-[var(--tags-view-border-color)]">
     <!-- 工具栏 -->
     <Toolbar
+      :editor="editorRef"
       :editorId="editorId"
       class="border-bottom-1 border-solid border-[var(--tags-view-border-color)]"
     />
@@ -114,6 +121,7 @@ watch(
       :defaultHtml="defaultHtml"
       :style="editorStyle"
       @on-change="handleChange"
+      @onCreated="handleCreated"
     />
   </div>
 </template>

+ 3 - 0
src/components/Menu/src/Menu.vue

@@ -47,6 +47,8 @@ export default defineComponent({
 
     const collapse = computed(() => appStore.getCollapse)
 
+    const uniqueOpened = computed(() => appStore.getUniqueOpened)
+
     const activeMenu = computed(() => {
       const { meta, path } = unref(currentRoute)
       // if set path, the sidebar will highlight the path you set
@@ -87,6 +89,7 @@ export default defineComponent({
             collapse={
               unref(layout) === 'top' || unref(layout) === 'cutMenu' ? false : unref(collapse)
             }
+            uniqueOpened={unref(layout) === 'top' ? false : unref(uniqueOpened)}
             backgroundColor="var(--left-menu-bg-color)"
             textColor="var(--left-menu-text-color)"
             activeTextColor="var(--left-menu-text-active-color)"

+ 4 - 0
src/components/Setting/src/Setting.vue

@@ -128,8 +128,12 @@ const copyConfig = async () => {
       locale: ${appStore.getLocale},
       // 标签页
       tagsView: ${appStore.getTagsView},
+      // 标签页图标
+      getTagsViewIcon: ${appStore.getTagsViewIcon},
       // logo
       logo: ${appStore.getLogo},
+      // 菜单手风琴
+      uniqueOpened: ${appStore.getUniqueOpened},
       // 固定header
       fixedHeader: ${appStore.getFixedHeader},
       // 页脚

+ 24 - 0
src/components/Setting/src/components/InterfaceDisplay.vue

@@ -65,6 +65,13 @@ const tagsViewChange = (show: boolean) => {
   appStore.setTagsView(show)
 }
 
+// 标签页图标
+const tagsViewIcon = ref(appStore.getTagsViewIcon)
+
+const tagsViewIconChange = (show: boolean) => {
+  appStore.setTagsViewIcon(show)
+}
+
 // logo
 const logo = ref(appStore.getLogo)
 
@@ -72,6 +79,13 @@ const logoChange = (show: boolean) => {
   appStore.setLogo(show)
 }
 
+// 菜单手风琴
+const uniqueOpened = ref(appStore.getUniqueOpened)
+
+const uniqueOpenedChange = (uniqueOpened: boolean) => {
+  appStore.setUniqueOpened(uniqueOpened)
+}
+
 // 固定头部
 const fixedHeader = ref(appStore.getFixedHeader)
 
@@ -142,11 +156,21 @@ watch(
       <ElSwitch v-model="tagsView" @change="tagsViewChange" />
     </div>
 
+    <div class="flex justify-between items-center">
+      <span class="text-14px">{{ t('setting.tagsViewIcon') }}</span>
+      <ElSwitch v-model="tagsViewIcon" @change="tagsViewIconChange" />
+    </div>
+
     <div class="flex justify-between items-center">
       <span class="text-14px">{{ t('setting.logo') }}</span>
       <ElSwitch v-model="logo" @change="logoChange" />
     </div>
 
+    <div class="flex justify-between items-center">
+      <span class="text-14px">{{ t('setting.uniqueOpened') }}</span>
+      <ElSwitch v-model="uniqueOpened" @change="uniqueOpenedChange" />
+    </div>
+
     <div class="flex justify-between items-center">
       <span class="text-14px">{{ t('setting.fixedHeader') }}</span>
       <ElSwitch v-model="fixedHeader" @change="fixedHeaderChange" />

+ 17 - 0
src/components/TagsView/src/TagsView.vue

@@ -4,6 +4,7 @@ import { useRouter } from 'vue-router'
 import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
 import { usePermissionStore } from '@/store/modules/permission'
 import { useTagsViewStore } from '@/store/modules/tagsView'
+import { useAppStore } from '@/store/modules/app'
 import { useI18n } from '@/hooks/web/useI18n'
 import { filterAffixTags } from './helper'
 import { ContextMenu, ContextMenuExpose } from '@/components/ContextMenu'
@@ -30,6 +31,10 @@ const visitedViews = computed(() => tagsViewStore.getVisitedViews)
 
 const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
 
+const appStore = useAppStore()
+
+const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
+
 // 初始化tag
 const initTags = () => {
   affixTagArr.value = filterAffixTags(unref(routers))
@@ -341,6 +346,17 @@ watch(
                 @click="navigate"
                 class="h-full flex justify-center items-center whitespace-nowrap pl-15px"
               >
+                <Icon
+                  v-if="
+                    item?.matched &&
+                    item?.matched[1] &&
+                    item?.matched[1]?.meta?.icon &&
+                    tagsViewIcon
+                  "
+                  :icon="item?.matched[1]?.meta?.icon"
+                  :size="12"
+                  class="mr-5px"
+                />
                 {{ t(item?.meta?.title as string) }}
                 <Icon
                   :class="`${prefixCls}__item--close`"
@@ -434,6 +450,7 @@ watch(
 @prefix-cls: ~'@{namespace}-tags-view';
 
 .@{prefix-cls} {
+  background-color: #fff;
   :deep(.@{elNamespace}-scrollbar__view) {
     height: 100%;
   }

+ 4 - 0
src/config/app.ts

@@ -24,11 +24,13 @@ export interface AppState {
   breadcrumb: boolean
   breadcrumbIcon: boolean
   collapse: boolean
+  uniqueOpened: boolean
   hamburger: boolean
   screenfull: boolean
   size: boolean
   locale: boolean
   tagsView: boolean
+  tagsViewIcon: boolean
   logo: boolean
   fixedHeader: boolean
   greyMode: boolean
@@ -54,11 +56,13 @@ export const appModules: AppState = {
   breadcrumb: true, // 面包屑
   breadcrumbIcon: true, // 面包屑图标
   collapse: false, // 折叠菜单
+  uniqueOpened: false, // 是否只保持一个子菜单的展开
   hamburger: true, // 折叠图标
   screenfull: true, // 全屏图标
   size: true, // 尺寸图标
   locale: true, // 多语言图标
   tagsView: true, // 标签页
+  tagsViewIcon: true, // 是否显示标签图标
   logo: true, // logo
   fixedHeader: true, // 固定toolheader
   footer: true, // 显示页脚

+ 7 - 2
src/layout/Layout.vue

@@ -67,7 +67,12 @@ export default defineComponent({
 </script>
 
 <style lang="less" scoped>
-:deep(.@{elNamespace}-scrollbar__view) {
-  height: 100% !important;
+@prefix-cls: ~'@{namespace}-layout';
+
+.@{prefix-cls} {
+  background-color: var(--app-contnet-bg-color);
+  :deep(.@{elNamespace}-scrollbar__view) {
+    height: 100% !important;
+  }
 }
 </style>

+ 4 - 4
src/layout/components/useRenderLayout.tsx

@@ -92,7 +92,7 @@ export const useRenderLayout = () => {
               <ToolHeader class="border-bottom-1 border-solid border-[var(--top-tool-border-color)] bg-[var(--top-header-bg-color)]"></ToolHeader>
 
               {tagsView.value ? (
-                <TagsView class="border-bottom-1 border-solid border-[var(--tags-view-border-color)]"></TagsView>
+                <TagsView class="border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)]"></TagsView>
               ) : undefined}
             </div>
 
@@ -139,7 +139,7 @@ export const useRenderLayout = () => {
               {tagsView.value ? (
                 <TagsView
                   class={[
-                    'border-bottom-1 border-solid border-[var(--tags-view-border-color)]',
+                    'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)]',
                     {
                       '!fixed top-0 left-0 z-10': fixedHeader.value,
                       'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)] mt-[var(--logo-height)]':
@@ -181,7 +181,7 @@ export const useRenderLayout = () => {
             {tagsView.value ? (
               <TagsView
                 class={[
-                  'border-bottom-1 border-solid border-[var(--tags-view-border-color)]',
+                  'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)]',
                   {
                     '!fixed w-full top-[var(--top-tool-height)] left-0': fixedHeader.value
                   }
@@ -233,7 +233,7 @@ export const useRenderLayout = () => {
               {tagsView.value ? (
                 <TagsView
                   class={[
-                    'border-bottom-1 border-solid border-[var(--tags-view-border-color)]',
+                    'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)]',
                     {
                       '!fixed top-0 left-0 z-10': fixedHeader.value,
                       'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]':

+ 3 - 1
src/locales/en.ts

@@ -72,7 +72,9 @@ export default {
     clearAndReset: 'Clear cache and reset',
     copySuccess: 'Copy success',
     copyFailed: 'Copy failed',
-    footer: 'Footer'
+    footer: 'Footer',
+    uniqueOpened: 'Unique opened',
+    tagsViewIcon: 'Tags view icon'
   },
   size: {
     default: 'Default',

+ 3 - 1
src/locales/zh-CN.ts

@@ -72,7 +72,9 @@ export default {
     clearAndReset: '清除缓存并且重置',
     copySuccess: '拷贝成功',
     copyFailed: '拷贝失败',
-    footer: '页脚'
+    footer: '页脚',
+    uniqueOpened: '菜单手风琴',
+    tagsViewIcon: '标签页图标'
   },
   size: {
     default: '默认',

+ 12 - 0
src/store/modules/app.ts

@@ -24,6 +24,9 @@ export const useAppStore = defineStore({
     getCollapse(): boolean {
       return this.collapse
     },
+    getUniqueOpened(): boolean {
+      return this.uniqueOpened
+    },
     getHamburger(): boolean {
       return this.hamburger
     },
@@ -39,6 +42,9 @@ export const useAppStore = defineStore({
     getTagsView(): boolean {
       return this.tagsView
     },
+    getTagsViewIcon(): boolean {
+      return this.tagsViewIcon
+    },
     getLogo(): boolean {
       return this.logo
     },
@@ -89,6 +95,9 @@ export const useAppStore = defineStore({
     setCollapse(collapse: boolean) {
       this.collapse = collapse
     },
+    setUniqueOpened(uniqueOpened: boolean) {
+      this.uniqueOpened = uniqueOpened
+    },
     setHamburger(hamburger: boolean) {
       this.hamburger = hamburger
     },
@@ -104,6 +113,9 @@ export const useAppStore = defineStore({
     setTagsView(tagsView: boolean) {
       this.tagsView = tagsView
     },
+    setTagsViewIcon(tagsViewIcon: boolean) {
+      this.tagsViewIcon = tagsViewIcon
+    },
     setLogo(logo: boolean) {
       this.logo = logo
     },

Some files were not shown because too many files changed in this diff