Procházet zdrojové kódy

更新升级
修复prettier格式化语句在语句前生成分号后,eslintrc检测报错误的问题

zhontai před 2 roky
rodič
revize
f11a4cfd4b

+ 2 - 0
.eslintrc.js

@@ -72,5 +72,7 @@ module.exports = {
     'no-case-declarations': 'off',
     'no-console': 'error',
     'no-redeclare': 'off',
+    //修复prettier格式化语句在语句前生成分号后,eslintrc检测报错误的问题
+    'no-extra-semi': 'off',
   },
 }

+ 23 - 66
package-lock.json

@@ -33,6 +33,7 @@
         "splitpanes": "^3.1.5",
         "vue": "^3.2.47",
         "vue-clipboard3": "^2.0.0",
+        "vue-demi": "^0.14.0",
         "vue-grid-layout": "^3.0.0-beta1",
         "vue-i18n": "^9.2.2",
         "vue-router": "^4.1.6"
@@ -1000,28 +1001,6 @@
         "vue-demi": "*"
       }
     },
-    "node_modules/@vueuse/core/node_modules/vue-demi": {
-      "version": "0.13.11",
-      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz",
-      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
-      "hasInstallScript": true,
-      "bin": {
-        "vue-demi-fix": "bin/vue-demi-fix.js",
-        "vue-demi-switch": "bin/vue-demi-switch.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.0.0-rc.1",
-        "vue": "^3.0.0-0 || ^2.6.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/@vueuse/metadata": {
       "version": "9.13.0",
       "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz",
@@ -1035,28 +1014,6 @@
         "vue-demi": "*"
       }
     },
-    "node_modules/@vueuse/shared/node_modules/vue-demi": {
-      "version": "0.13.11",
-      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz",
-      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
-      "hasInstallScript": true,
-      "bin": {
-        "vue-demi-fix": "bin/vue-demi-fix.js",
-        "vue-demi-switch": "bin/vue-demi-switch.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.0.0-rc.1",
-        "vue": "^3.0.0-0 || ^2.6.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/@wangeditor/basic-modules": {
       "version": "1.1.7",
       "resolved": "https://registry.npmmirror.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz",
@@ -3172,28 +3129,6 @@
         }
       }
     },
-    "node_modules/pinia/node_modules/vue-demi": {
-      "version": "0.13.11",
-      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz",
-      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
-      "hasInstallScript": true,
-      "bin": {
-        "vue-demi-fix": "bin/vue-demi-fix.js",
-        "vue-demi-switch": "bin/vue-demi-switch.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.0.0-rc.1",
-        "vue": "^3.0.0-0 || ^2.6.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/postcss": {
       "version": "8.4.21",
       "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz",
@@ -3991,6 +3926,28 @@
         "clipboard": "^2.0.6"
       }
     },
+    "node_modules/vue-demi": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.0.tgz",
+      "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/vue-eslint-parser": {
       "version": "9.1.1",
       "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",

+ 1 - 0
package.json

@@ -37,6 +37,7 @@
     "splitpanes": "^3.1.5",
     "vue": "^3.2.47",
     "vue-clipboard3": "^2.0.0",
+    "vue-demi": "^0.14.0",
     "vue-grid-layout": "^3.0.0-beta1",
     "vue-i18n": "^9.2.2",
     "vue-router": "^4.1.6"

+ 2 - 2
src/App.vue

@@ -22,8 +22,8 @@ import setIntroduction from '/@/utils/setIconfont'
 
 // 引入组件
 const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'))
-const Setings = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/setings.vue'))
-const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'))
+const Setings = defineAsyncComponent(() => import('/@/layout/navBars/topBar/setings.vue'))
+const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/topBar/closeFull.vue'))
 const Upgrade = defineAsyncComponent(() => import('/@/layout/upgrade/index.vue'))
 
 // 定义变量内容

+ 47 - 2
src/components/table/index.vue

@@ -22,7 +22,14 @@
       >
         <template v-slot="scope">
           <template v-if="item.type === 'image'">
-            <img :src="scope.row[item.key]" :width="item.width" :height="item.height" />
+            <el-image
+              :style="{ width: `${item.width}px`, height: `${item.height}px` }"
+              :src="scope.row[item.key]"
+              :zoom-rate="1.2"
+              :preview-src-list="[scope.row[item.key]]"
+              preview-teleported
+              fit="cover"
+            />
           </template>
           <template v-else>
             {{ scope.row[item.key] }}
@@ -56,6 +63,7 @@
       >
       </el-pagination>
       <div class="table-footer-tool">
+        <SvgIcon name="iconfont icon-dayin" :size="19" title="打印" @click="onPrintTable" />
         <SvgIcon name="iconfont icon-yunxiazai_o" :size="22" title="导出" @click="onImportTable" />
         <SvgIcon name="iconfont icon-shuaxin" :size="22" title="刷新" @click="onRefreshTable" />
         <el-popover
@@ -103,6 +111,7 @@
 <script setup lang="ts" name="netxTable">
 import { reactive, computed, nextTick, ref } from 'vue'
 import { ElMessage } from 'element-plus'
+import printJs from 'print-js'
 import table2excel from 'js-table2excel'
 import Sortable from 'sortablejs'
 import { storeToRefs } from 'pinia'
@@ -126,6 +135,11 @@ const props = defineProps({
     type: Object,
     default: () => {},
   },
+  // 打印标题
+  printName: {
+    type: String,
+    default: () => '',
+  },
 })
 
 // 定义子组件向父组件传值/事件
@@ -193,6 +207,37 @@ const pageReset = () => {
   state.page.pageSize = 10
   emit('pageChange', state.page)
 }
+// 打印
+const onPrintTable = () => {
+  // https://printjs.crabbly.com/#documentation
+  // 自定义打印
+  let tableTh = ''
+  let tableTrTd = ''
+  let tableTd: any = {}
+  // 表头
+  props.header.forEach((v) => {
+    tableTh += `<th class="table-th">${v.title}</th>`
+  })
+  // 表格内容
+  props.data.forEach((val, key) => {
+    if (!tableTd[key]) tableTd[key] = []
+    props.header.forEach((v) => {
+      if (v.type === 'text') {
+        tableTd[key].push(`<td class="table-th table-center">${val[v.key]}</td>`)
+      } else if (v.type === 'image') {
+        tableTd[key].push(`<td class="table-th table-center"><img src="${val[v.key]}" style="width:${v.width}px;height:${v.height}px;"/></td>`)
+      }
+    })
+    tableTrTd += `<tr>${tableTd[key].join('')}</tr>`
+  })
+  // 打印
+  printJs({
+    printable: `<div style=display:flex;flex-direction:column;text-align:center><h3>${props.printName}</h3></div><table border=1 cellspacing=0><tr>${tableTh}${tableTrTd}</table>`,
+    type: 'raw-html',
+    css: ['//at.alicdn.com/t/c/font_2298093_rnp72ifj3ba.css', '//unpkg.com/element-plus/dist/index.css'],
+    style: `@media print{.mb15{margin-bottom:15px;}.el-button--small i.iconfont{font-size: 12px !important;margin-right: 5px;}}; .table-th{word-break: break-all;white-space: pre-wrap;}.table-center{text-align: center;}`,
+  })
+}
 // 导出
 const onImportTable = () => {
   if (state.selectlist.length <= 0) return ElMessage.warning('请先选择要导出的数据')
@@ -211,7 +256,7 @@ const onSetTable = () => {
       animation: 150,
       onEnd: () => {
         const headerList: EmptyObjectType[] = []
-        sortable.toArray().forEach((val) => {
+        sortable.toArray().forEach((val: string) => {
           props.header.forEach((v) => {
             if (v.key === val) headerList.push({ ...v })
           })

+ 6 - 0
src/layout/component/aside.vue

@@ -154,6 +154,12 @@ watch(
       if (layoutAsideScrollbarRef.value) layoutAsideScrollbarRef.value.update()
     }
     if (layout === 'classic' && isClassicSplitMenu) return false
+  }
+)
+// 监听用户权限切换,用于演示 `权限管理 -> 前端控制 -> 页面权限` 权限切换不生效
+watch(
+  () => routesList.value,
+  () => {
     setFilterRoutes()
   }
 )

+ 2 - 2
src/layout/navBars/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="layout-navbars-container">
-    <BreadcrumbIndex />
+    <TopBarIndex />
     <TagsView v-if="setShowTagsView" />
   </div>
 </template>
@@ -11,7 +11,7 @@ import { storeToRefs } from 'pinia'
 import { useThemeConfig } from '/@/stores/themeConfig'
 
 // 引入组件
-const BreadcrumbIndex = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/index.vue'))
+const TopBarIndex = defineAsyncComponent(() => import('/@/layout/navBars/topBar/index.vue'))
 const TagsView = defineAsyncComponent(() => import('/@/layout/navBars/tagsView/tagsView.vue'))
 
 // 定义变量内容

+ 0 - 0
src/layout/navBars/breadcrumb/breadcrumb.vue → src/layout/navBars/topBar/breadcrumb.vue


+ 0 - 0
src/layout/navBars/breadcrumb/closeFull.vue → src/layout/navBars/topBar/closeFull.vue


+ 2 - 2
src/layout/navBars/breadcrumb/index.vue → src/layout/navBars/topBar/index.vue

@@ -16,8 +16,8 @@ import { useThemeConfig } from '/@/stores/themeConfig'
 import mittBus from '/@/utils/mitt'
 
 // 引入组件
-const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'))
-const User = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/user.vue'))
+const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/topBar/breadcrumb.vue'))
+const User = defineAsyncComponent(() => import('/@/layout/navBars/topBar/user.vue'))
 const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue'))
 const Horizontal = defineAsyncComponent(() => import('/@/layout/navMenu/horizontal.vue'))
 

+ 0 - 0
src/layout/navBars/breadcrumb/search.vue → src/layout/navBars/topBar/search.vue


+ 0 - 0
src/layout/navBars/breadcrumb/setings.vue → src/layout/navBars/topBar/setings.vue


+ 29 - 18
src/layout/navBars/breadcrumb/user.vue → src/layout/navBars/topBar/user.vue

@@ -32,20 +32,25 @@
     <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick">
       <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i>
     </div>
-    <div class="layout-navbars-breadcrumb-user-icon">
-      <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
-        <template #reference>
-          <el-badge :is-dot="true">
-            <el-icon :title="$t('message.user.title4')">
-              <ele-Bell />
-            </el-icon>
-          </el-badge>
-        </template>
-        <template #default>
-          <UserNews />
-        </template>
-      </el-popover>
+    <div class="layout-navbars-breadcrumb-user-icon" ref="userNewsBadgeRef" v-click-outside="onUserNewsClick">
+      <el-badge :is-dot="true">
+        <el-icon :title="$t('message.user.title4')">
+          <ele-Bell />
+        </el-icon>
+      </el-badge>
     </div>
+    <el-popover
+      ref="userNewsRef"
+      :virtual-ref="userNewsBadgeRef"
+      placement="bottom"
+      trigger="click"
+      transition="el-zoom-in-top"
+      virtual-triggering
+      :width="300"
+      :persistent="false"
+    >
+      <UserNews />
+    </el-popover>
     <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick">
       <i
         class="iconfont"
@@ -74,9 +79,9 @@
 </template>
 
 <script setup lang="ts" name="layoutBreadcrumbUser">
-import { defineAsyncComponent, ref, computed, reactive, onMounted } from 'vue'
+import { defineAsyncComponent, ref, unref, computed, reactive, onMounted } from 'vue'
 import { useRouter } from 'vue-router'
-import { ElMessageBox, ElMessage } from 'element-plus'
+import { ElMessageBox, ElMessage, ClickOutside as vClickOutside } from 'element-plus'
 import screenfull from 'screenfull'
 import { useI18n } from 'vue-i18n'
 import { storeToRefs } from 'pinia'
@@ -87,10 +92,12 @@ import mittBus from '/@/utils/mitt'
 import { Local } from '/@/utils/storage'
 
 // 引入组件
-const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/userNews.vue'))
-const Search = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/search.vue'))
+const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/topBar/userNews.vue'))
+const Search = defineAsyncComponent(() => import('/@/layout/navBars/topBar/search.vue'))
 
 // 定义变量内容
+const userNewsRef = ref()
+const userNewsBadgeRef = ref()
 const { locale, t } = useI18n()
 const router = useRouter()
 const storesUseUserInfo = useUserInfo()
@@ -98,7 +105,7 @@ const storesThemeConfig = useThemeConfig()
 const { userInfos } = storeToRefs(storesUseUserInfo)
 const { themeConfig } = storeToRefs(storesThemeConfig)
 const searchRef = ref()
-const state = reactive({
+const state = <any>reactive({
   isScreenfull: false,
   disabledI18n: 'zh-cn',
   disabledSize: 'large',
@@ -130,6 +137,10 @@ const onScreenfullClick = () => {
     else state.isScreenfull = false
   })
 }
+// 消息通知点击时
+const onUserNewsClick = () => {
+  unref(userNewsRef).popperRef?.delayHide?.()
+}
 // 布局配置 icon 点击时
 const onLayoutSetingClick = () => {
   mittBus.emit('openSetingsDrawer')

+ 0 - 0
src/layout/navBars/breadcrumb/userNews.vue → src/layout/navBars/topBar/userNews.vue


+ 1 - 1
src/router/backEnd.ts

@@ -58,7 +58,7 @@ export async function initBackEndControlRoutes() {
   // 添加动态路由
   await setAddRoute()
   // 设置路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
-  await setFilterMenuAndCacheTagsViewRoutes()
+  setFilterMenuAndCacheTagsViewRoutes()
 }
 
 /**

+ 1 - 1
src/router/frontEnd.ts

@@ -30,7 +30,7 @@ export async function initFrontEndControlRoutes() {
   // 添加动态路由
   await setAddRoute()
   // 设置递归过滤有权限的路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
-  await setFilterMenuAndCacheTagsViewRoutes()
+  setFilterMenuAndCacheTagsViewRoutes()
 }
 
 /**

+ 1 - 1
src/stores/themeConfig.ts

@@ -123,7 +123,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 
       /**
        * 布局切换
-       * 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue
+       * 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/topBar/setings.vue
        * 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
        */
       // 布局切换:可选值"<默认 defaults | 经典 classic | 横向 transverse | 分栏 columns>",默认 defaults

+ 1 - 8
src/stores/userInfo.ts

@@ -23,14 +23,7 @@ export const useUserInfo = defineStore('userInfo', {
   }),
   actions: {
     async setUserInfos() {
-      // if (Session.get('userInfo')) {
-      //   const userInfos: any = Session.get('userInfo')
-      //   merge(this.userInfos, userInfos)
-      // } else {
-      //   const userInfos: any = await this.getApiUserInfo().catch(() => {})
-      //   merge(this.userInfos, userInfos)
-      // }
-      const userInfos: any = await this.getApiUserInfo().catch(() => {})
+      const userInfos = <UserInfos>await this.getApiUserInfo().catch(() => {})
       merge(this.userInfos, userInfos)
     },
     setUserName(userName: string) {

+ 12 - 0
src/theme/element.scss

@@ -187,6 +187,18 @@
     color: var(--next-bg-topBarColor);
   }
 }
+// 菜单收起时,图标不居中问题
+.el-menu--collapse {
+  .el-menu-item .iconfont,
+  .el-sub-menu .iconfont,
+  .el-menu-item .fa,
+  .el-sub-menu .fa {
+    margin-right: 0 !important;
+  }
+  .el-sub-menu__title {
+    padding-right: 0 !important;
+  }
+}
 
 /* Tabs 标签页
 ------------------------------- */

+ 2 - 0
src/types/global.d.ts

@@ -27,6 +27,8 @@ declare module '*.vue' {
 /* eslint-disable */
 declare interface Window {
   nextLoading: boolean
+  BMAP_SATELLITE_MAP: any
+  BMap: any
 }
 
 // 声明路由当前项类型

+ 11 - 10
src/types/pinia.d.ts

@@ -3,16 +3,17 @@
  */
 
 // 用户信息
-declare interface UserInfosState<T = any> {
-  userInfos: {
-    token: string
-    authBtnList: string[]
-    photo: string
-    roles: string[]
-    time: number
-    userName: string
-    [key: string]: T
-  }
+declare interface UserInfos<T = any> {
+  token: string
+  authBtnList: string[]
+  photo: string
+  roles: string[]
+  time: number
+  userName: string
+  [key: string]: T
+}
+declare interface UserInfosState {
+  userInfos: UserInfos
 }
 
 // 路由缓存列表

+ 1 - 0
src/types/views.d.ts

@@ -325,6 +325,7 @@ declare type TableDemoState = {
     }
     search: TableSearchType[]
     param: EmptyObjectType
+    printName: string
   }
 }
 

+ 4 - 0
src/views/example/limits/frontEnd/page/index.vue

@@ -27,6 +27,7 @@ import { onMounted, ref } from 'vue'
 import Cookies from 'js-cookie'
 import { storeToRefs } from 'pinia'
 import { useUserInfo } from '/@/stores/userInfo'
+import { Session } from '/@/utils/storage'
 import { frontEndsResetRoute, setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/frontEnd'
 
 // 定义变量内容
@@ -40,6 +41,9 @@ const initUserAuth = () => {
 }
 // 用户权限改变时
 const onRadioChange = async () => {
+  // 清空之前缓存的 userInfo,防止不请求接口。
+  // stores/userInfo.ts
+  Session.remove('userInfo')
   // 模拟数据
   frontEndsResetRoute()
   Cookies.set('userName', userAuth.value)

+ 2 - 0
src/views/example/make/tableDemo/index.vue

@@ -71,6 +71,8 @@ const state = reactive<TableDemoState>({
       pageNum: 1,
       pageSize: 10,
     },
+    // 打印标题
+    printName: 'vueNextAdmin 表格打印演示',
   },
 })
 

+ 5 - 5
src/views/example/visualizing/demo1.vue

@@ -126,7 +126,7 @@ const initTime = () => {
 const convertData = (data: any) => {
   let res = []
   for (let i = 0; i < data.length; i++) {
-    let geoCoord = state.echartsMapData[data[i].name]
+    let geoCoord = (<any>state.echartsMapData)[data[i].name]
     if (geoCoord) {
       res.push({
         name: data[i].name,
@@ -250,16 +250,16 @@ const initEchartsMap = () => {
   // BMAP_SATELLITE_MAP:卫星地图 (没有坐标, 绿绿的一片的卫星地图)
   // BMAP_HYBRID_MAP:混合地图 (既有坐标,也是绿绿的一片的卫星地图)
   // eslint-disable-next-line no-undef
-  map.setMapType(BMAP_SATELLITE_MAP)
+  map.setMapType(window.BMAP_SATELLITE_MAP)
   // eslint-disable-next-line no-undef
-  let bdary = new BMap.Boundary()
+  let bdary = new window.BMap.Boundary()
   // 获取行政区域
   bdary.get('深圳', function (rs: any) {
     // 行政区域的点有多少个
     let count = rs.boundaries.length
     for (let i = 0; i < count; i++) {
       // eslint-disable-next-line no-undef
-      let ply = new BMap.Polygon(rs.boundaries[i], {
+      let ply = new window.BMap.Polygon(rs.boundaries[i], {
         // 设置多边形边线线粗
         strokeWeight: 4,
         // 设置多边形边线透明度0-1
@@ -280,7 +280,7 @@ const initEchartsMap = () => {
     // 初始化地图,设置中心点坐标和地图级别
     // new BMap.Point('深圳市', 11)
     // eslint-disable-next-line no-undef
-    map.centerAndZoom(new BMap.Point(114.064524, 22.549225), 11)
+    map.centerAndZoom(new window.BMap.Point(114.064524, 22.549225), 11)
   })
 }
 // 产业概况

+ 1 - 2
tsconfig.json

@@ -67,8 +67,7 @@
 
     /* Advanced Options */
     "skipLibCheck": true /* Skip type checking of declaration files. */,
-    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
-    "suppressImplicitAnyIndexErrors": true
+    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
   },
   "include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.tsx", "src/**/*.d.ts", "vite.config.ts"], // **Represents any directory, and * represents any file. Indicates that all files in the src directory will be compiled
   "exclude": ["node_modules", "dist"] // Indicates the file directory that does not need to be compiled

+ 4 - 6
vite.config.ts

@@ -30,9 +30,7 @@ const viteConfig = defineConfig(({ mode, command }: ConfigEnv) => {
     resolve: { alias },
     base: command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
     hmr: true,
-    optimizeDeps: {
-      include: ['element-plus/lib/locale/lang/zh-cn', 'element-plus/lib/locale/lang/en', 'element-plus/lib/locale/lang/zh-tw'],
-    },
+    optimizeDeps: { exclude: ['vue-demi'] },
     server: {
       host: '0.0.0.0',
       port: env.VITE_PORT,
@@ -47,17 +45,17 @@ const viteConfig = defineConfig(({ mode, command }: ConfigEnv) => {
       },
     },
     build: {
-      chunkSizeWarningLimit: 1500,
       outDir: 'dist',
+      chunkSizeWarningLimit: 1500,
       sourcemap: false,
       rollupOptions: {
         output: {
-          assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
           chunkFileNames: 'assets/js/[name]-[hash].js',
           entryFileNames: 'assets/js/[name]-[hash].js',
+          assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
           manualChunks(id) {
             if (id.includes('node_modules')) {
-              return id.toString().split('node_modules/')[1].split('/')[0].toString()
+              return id.toString().match(/\/node_modules\/(?!.pnpm)(?<moduleName>[^\/]*)\//)?.groups!.moduleName ?? 'vender'
             }
           },
         },