兰宝车间质量管理系统-前端
疯狂的狮子Li
2024-08-26 1606dbd76f64bb1dd2ea3e8876341528293c7ea5
!141 发布 vue 版本 5.2.2 与 cloud 版本 2.2.1
Merge pull request !141 from 疯狂的狮子Li/dev
已添加1个文件
已删除1个文件
已修改20个文件
412 ■■■■■ 文件已修改
.env.development 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.production 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/workflow/nodeConfig/index.ts 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Navbar.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/permission.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/tab.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/permission.ts 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/tagsView.ts 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sse.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/websocket.ts 168 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/oss/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/tenantPackage/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/authRole.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/workflow/leave/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development
@@ -28,5 +28,5 @@
# å®¢æˆ·ç«¯id
VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
# websocket å¼€å…³
VITE_APP_WEBSOCKET = true
# websocket å¼€å…³ é»˜è®¤ä½¿ç”¨sse推送
VITE_APP_WEBSOCKET = false
.env.production
@@ -31,5 +31,5 @@
# å®¢æˆ·ç«¯id
VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
# websocket å¼€å…³
VITE_APP_WEBSOCKET = true
# websocket å¼€å…³ é»˜è®¤ä½¿ç”¨sse推送
VITE_APP_WEBSOCKET = false
package.json
@@ -1,6 +1,6 @@
{
  "name": "ruoyi-vue-plus",
  "version": "5.2.1",
  "version": "5.2.2",
  "description": "RuoYi-Vue-Plus多租户管理系统",
  "author": "LionLi",
  "license": "MIT",
@@ -30,7 +30,7 @@
    "diagram-js": "12.3.0",
    "didi": "9.0.2",
    "echarts": "5.5.0",
    "element-plus": "2.7.5",
    "element-plus": "2.7.8",
    "file-saver": "2.0.5",
    "fuse.js": "7.0.0",
    "highlight.js": "11.9.0",
@@ -40,7 +40,7 @@
    "nprogress": "0.2.0",
    "pinia": "2.1.7",
    "screenfull": "6.0.2",
    "vue": "3.4.25",
    "vue": "3.4.34",
    "vue-cropper": "1.1.1",
    "vue-i18n": "9.10.2",
    "vue-router": "4.3.2",
@@ -81,7 +81,7 @@
    "unplugin-icons": "0.18.5",
    "unplugin-vue-components": "0.26.0",
    "unplugin-vue-setup-extend-plus": "1.0.1",
    "vite": "5.2.10",
    "vite": "5.2.12",
    "vite-plugin-compression": "0.5.1",
    "vite-plugin-svg-icons": "2.0.1",
    "vitest": "1.5.0",
src/api/login.ts
@@ -51,6 +51,10 @@
 * æ³¨é”€
 */
export function logout() {
  request({
    url: '/resource/sse/close',
    method: 'get'
  });
  return request({
    url: '/auth/logout',
    method: 'post'
src/api/workflow/nodeConfig/index.ts
ÎļþÒÑɾ³ý
src/layout/components/Navbar.vue
@@ -128,6 +128,7 @@
    dynamic.value = true;
    proxy?.$tab.closeAllPage();
    proxy?.$router.push('/');
    proxy?.$tab.refreshPage();
  }
};
@@ -136,6 +137,7 @@
  dynamic.value = false;
  proxy?.$tab.closeAllPage();
  proxy?.$router.push('/');
  proxy?.$tab.refreshPage();
};
/** ç§Ÿæˆ·åˆ—表 */
src/layout/index.vue
@@ -27,6 +27,7 @@
import useAppStore from '@/store/modules/app';
import useSettingsStore from '@/store/modules/settings';
import { initWebSocket } from '@/utils/websocket';
import { initSSE } from "@/utils/sse";
const settingsStore = useSettingsStore();
const theme = computed(() => settingsStore.theme);
@@ -71,6 +72,10 @@
  initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + '/resource/websocket');
});
onMounted(() => {
  initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse')
});
const handleClickOutside = () => {
  useAppStore().closeSideBar({ withoutAnimation: false });
};
src/permission.ts
@@ -40,6 +40,7 @@
              router.addRoute(route); // åŠ¨æ€æ·»åŠ å¯è®¿é—®è·¯ç”±è¡¨
            }
          });
          // @ts-ignore
          next({ path: to.path, replace: true, params: to.params, query: to.query, hash: to.hash, name: to.name as string }); // hack方法 ç¡®ä¿addRoutes已完成
        }
      } else {
src/plugins/tab.ts
@@ -1,5 +1,5 @@
import router from '@/router';
import { RouteLocationMatched, RouteLocationNormalized } from 'vue-router';
import {RouteLocationMatched, RouteLocationNormalized, RouteLocationRaw} from 'vue-router';
import useTagsViewStore from '@/store/modules/tagsView';
export default {
@@ -41,7 +41,7 @@
    });
  },
  // å…³é—­å½“前tab页签,打开新页签
  closeOpenPage(obj: RouteLocationNormalized): void {
  closeOpenPage(obj: RouteLocationRaw): void {
    useTagsViewStore().delView(router.currentRoute.value);
    if (obj !== undefined) {
      router.push(obj);
src/router/index.ts
@@ -159,7 +159,7 @@
        path: 'index/:tableId(\\d+)',
        component: () => import('@/views/tool/gen/editTable.vue'),
        name: 'GenEdit',
        meta: { title: '修改生成配置', activeMenu: '/tool/gen', icon: '' }
        meta: { title: '修改生成配置', activeMenu: '/tool/gen', icon: '', noCache: true }
      }
    ]
  },
src/store/modules/permission.ts
@@ -21,13 +21,13 @@
  const sidebarRouters = ref<RouteRecordRaw[]>([]);
  const getRoutes = (): RouteRecordRaw[] => {
    return routes.value;
    return routes.value as RouteRecordRaw[];
  };
  const getSidebarRoutes = (): RouteRecordRaw[] => {
    return sidebarRouters.value;
    return sidebarRouters.value as RouteRecordRaw[];
  };
  const getTopbarRoutes = (): RouteRecordRaw[] => {
    return topbarRouters.value;
    return topbarRouters.value as RouteRecordRaw[];
  };
  const setRoutes = (newRoutes: RouteRecordRaw[]): void => {
src/store/modules/tagsView.ts
@@ -6,10 +6,10 @@
  const iframeViews = ref<RouteLocationNormalized[]>([]);
  const getVisitedViews = (): RouteLocationNormalized[] => {
    return visitedViews.value;
    return visitedViews.value as RouteLocationNormalized[];
  };
  const getIframeViews = (): RouteLocationNormalized[] => {
    return iframeViews.value;
    return iframeViews.value as RouteLocationNormalized[];
  };
  const getCachedViews = (): string[] => {
    return cachedViews.value;
@@ -31,7 +31,7 @@
  const delIframeView = (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
    return new Promise((resolve) => {
      iframeViews.value = iframeViews.value.filter((item: RouteLocationNormalized) => item.path !== view.path);
      resolve([...iframeViews.value]);
      resolve([...iframeViews.value as RouteLocationNormalized[]]);
    });
  };
  const addVisitedView = (view: RouteLocationNormalized): void => {
@@ -54,7 +54,7 @@
        delCachedView(view);
      }
      resolve({
        visitedViews: [...visitedViews.value],
        visitedViews: [...visitedViews.value as RouteLocationNormalized[]],
        cachedViews: [...cachedViews.value]
      });
    });
@@ -68,7 +68,7 @@
          break;
        }
      }
      resolve([...visitedViews.value]);
      resolve([...visitedViews.value as RouteLocationNormalized[]]);
    });
  };
  const delCachedView = (view?: RouteLocationNormalized): Promise<string[]> => {
@@ -92,7 +92,7 @@
      delOthersVisitedViews(view);
      delOthersCachedViews(view);
      resolve({
        visitedViews: [...visitedViews.value],
        visitedViews: [...visitedViews.value as RouteLocationNormalized[]],
        cachedViews: [...cachedViews.value]
      });
    });
@@ -103,7 +103,7 @@
      visitedViews.value = visitedViews.value.filter((v: RouteLocationNormalized) => {
        return v.meta?.affix || v.path === view.path;
      });
      resolve([...visitedViews.value]);
      resolve([...visitedViews.value as RouteLocationNormalized[]]);
    });
  };
  const delOthersCachedViews = (view: RouteLocationNormalized): Promise<string[]> => {
@@ -124,7 +124,7 @@
      delAllVisitedViews();
      delAllCachedViews();
      resolve({
        visitedViews: [...visitedViews.value],
        visitedViews: [...visitedViews.value as RouteLocationNormalized[]],
        cachedViews: [...cachedViews.value]
      });
    });
@@ -132,7 +132,7 @@
  const delAllVisitedViews = (): Promise<RouteLocationNormalized[]> => {
    return new Promise((resolve) => {
      visitedViews.value = visitedViews.value.filter((tag: RouteLocationNormalized) => tag.meta?.affix);
      resolve([...visitedViews.value]);
      resolve([...visitedViews.value as RouteLocationNormalized[]]);
    });
  };
@@ -167,7 +167,7 @@
        }
        return false;
      });
      resolve([...visitedViews.value]);
      resolve([...visitedViews.value as RouteLocationNormalized[]]);
    });
  };
  const delLeftTags = (view: RouteLocationNormalized): Promise<RouteLocationNormalized[]> => {
@@ -186,7 +186,7 @@
        }
        return false;
      });
      resolve([...visitedViews.value]);
      resolve([...visitedViews.value as RouteLocationNormalized[]]);
    });
  };
src/utils/sse.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
import { getToken } from '@/utils/auth';
import { ElNotification } from 'element-plus';
import useNoticeStore from '@/store/modules/notice';
let message = '';
// åˆå§‹åŒ–
export const initSSE = (url: any) => {
  url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID
  const {
    data,
    error
  } = useEventSource(url, [], {
    autoReconnect: {
      retries: 10,
      delay: 3000,
      onFailed() {
        console.log('Failed to connect after 10 retries')
      },
    }
  });
  watch(error, () => {
    console.log('SSE connection error:', error.value)
    error.value = null;
  });
  watch(data, () => {
    if (!data.value) return;
    useNoticeStore().addNotice({
      message: data.value,
      read: false,
      time: new Date().toLocaleString()
    });
    ElNotification({
      title: '消息',
      message: data.value,
      type: 'success',
      duration: 3000
    });
    data.value = null;
  });
};
src/utils/websocket.ts
@@ -1,139 +1,51 @@
/**
 * @module initWebSocket åˆå§‹åŒ–
 * @module websocketonopen è¿žæŽ¥æˆåŠŸ
 * @module websocketonerror è¿žæŽ¥å¤±è´¥
 * @module websocketclose æ–­å¼€è¿žæŽ¥
 * @module resetHeart é‡ç½®å¿ƒè·³
 * @module sendSocketHeart å¿ƒè·³å‘送
 * @module reconnect é‡è¿ž
 * @module sendMsg å‘送数据
 * @module websocketonmessage æŽ¥æ”¶æ•°æ®
 * @module test æµ‹è¯•收到消息传递
 * @description socket é€šä¿¡
 * @param {any} url socket地址
 * @param {any} websocket websocket å®žä¾‹
 * @param {any} heartTime å¿ƒè·³å®šæ—¶å™¨å®žä¾‹
 * @param {number} socketHeart å¿ƒè·³æ¬¡æ•°
 * @param {number} HeartTimeOut å¿ƒè·³è¶…æ—¶æ—¶é—´
 * @param {number} socketError é”™è¯¯æ¬¡æ•°
 */
import { getToken } from '@/utils/auth';
import { ElNotification } from 'element-plus';
import useNoticeStore from '@/store/modules/notice';
let socketUrl: any = ''; // socket地址
let websocket: any = null; // websocket å®žä¾‹
let heartTime: any = null; // å¿ƒè·³å®šæ—¶å™¨å®žä¾‹
let socketHeart = 0 as number; // å¿ƒè·³æ¬¡æ•°
const HeartTimeOut = 10000; // å¿ƒè·³è¶…æ—¶æ—¶é—´ 10000 = 10s
let socketError = 0 as number; // é”™è¯¯æ¬¡æ•°
// åˆå§‹åŒ–socket
export const initWebSocket = (url: any) => {
  if (import.meta.env.VITE_APP_WEBSOCKET === 'false') {
    return;
  }
  socketUrl = url;
  // åˆå§‹åŒ– websocket
  websocket = new WebSocket(url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID);
  websocketonopen();
  websocketonmessage();
  websocketonerror();
  websocketclose();
  sendSocketHeart();
  return websocket;
};
// socket è¿žæŽ¥æˆåŠŸ
export const websocketonopen = () => {
  websocket.onopen = function () {
    console.log('连接 websocket æˆåŠŸ');
    resetHeart();
  };
};
// socket è¿žæŽ¥å¤±è´¥
export const websocketonerror = () => {
  websocket.onerror = function (e: any) {
    console.log('连接 websocket å¤±è´¥', e);
  };
};
// socket æ–­å¼€é“¾æŽ¥
export const websocketclose = () => {
  websocket.onclose = function (e: any) {
    console.log('断开连接', e);
  };
};
// socket é‡ç½®å¿ƒè·³
export const resetHeart = () => {
  socketHeart = 0;
  socketError = 0;
  clearInterval(heartTime);
  sendSocketHeart();
};
// socket心跳发送
export const sendSocketHeart = () => {
  heartTime = setInterval(() => {
    // å¦‚果连接正常则发送心跳
    if (websocket.readyState == 1) {
      // if (socketHeart <= 30) {
      websocket.send(
        JSON.stringify({
          type: 'ping'
        })
      );
      socketHeart = socketHeart + 1;
    } else {
      // é‡è¿ž
      reconnect();
  url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID
  useWebSocket(url, {
    autoReconnect: {
      // é‡è¿žæœ€å¤§æ¬¡æ•°
      retries: 3,
      // é‡è¿žé—´éš”
      delay: 1000,
      onFailed() {
        console.log('websocket重连失败');
      },
    },
    heartbeat: {
      message: JSON.stringify({type: 'ping'}),
      // å‘送心跳的间隔
      interval: 10000,
      // æŽ¥æ”¶åˆ°å¿ƒè·³response的超时时间
      pongTimeout: 2000,
    },
    onConnected() {
      console.log('websocket已经连接');
    },
    onDisconnected() {
      console.log('websocket已经断开');
    },
    onMessage: (_, e) => {
      if (e.data.indexOf('ping') > 0) {
        return;
      }
      useNoticeStore().addNotice({
        message: e.data,
        read: false,
        time: new Date().toLocaleString()
      });
      ElNotification({
        title: '消息',
        message: e.data,
        type: 'success',
        duration: 3000
      });
    }
  }, HeartTimeOut);
};
// socket重连
export const reconnect = () => {
  if (socketError <= 2) {
    clearInterval(heartTime);
    initWebSocket(socketUrl);
    socketError = socketError + 1;
    // eslint-disable-next-line prettier/prettier
    console.log('socket重连', socketError);
  } else {
    // eslint-disable-next-line prettier/prettier
    console.log('重试次数已用完');
    clearInterval(heartTime);
  }
};
// socket å‘送数据
export const sendMsg = (data: any) => {
  websocket.send(data);
};
// socket æŽ¥æ”¶æ•°æ®
export const websocketonmessage = () => {
  websocket.onmessage = function (e: any) {
    if (e.data.indexOf('heartbeat') > 0) {
      resetHeart();
    }
    if (e.data.indexOf('ping') > 0) {
      return;
    }
    useNoticeStore().addNotice({
      message: e.data,
      read: false,
      time: new Date().toLocaleString()
    });
    ElNotification({
      title: '消息',
      message: e.data,
      type: 'success',
      duration: 3000
    });
    return e.data;
  };
  });
};
src/views/index.vue
@@ -33,7 +33,7 @@
          * éƒ¨ç½²æ–¹å¼ Docker å®¹å™¨ç¼–排 ä¸€é”®éƒ¨ç½²ä¸šåŠ¡é›†ç¾¤<br />
          * å›½é™…化 SpringMessage Spring标准国际化方案<br />
        </p>
        <p><b>当前版本:</b> <span>v5.2.1</span></p>
        <p><b>当前版本:</b> <span>v5.2.2</span></p>
        <p>
          <el-tag type="danger">&yen;免费开源</el-tag>
        </p>
@@ -77,7 +77,7 @@
          * åˆ†å¸ƒå¼ç›‘控 Prometheus、Grafana å…¨æ–¹ä½æ€§èƒ½ç›‘控<br />
          * å…¶ä½™ä¸Ž Vue ç‰ˆæœ¬ä¸€è‡´<br />
        </p>
        <p><b>当前版本:</b> <span>v2.2.0</span></p>
        <p><b>当前版本:</b> <span>v2.2.1</span></p>
        <p>
          <el-tag type="danger">&yen;免费开源</el-tag>
        </p>
src/views/system/oss/index.vue
@@ -60,7 +60,7 @@
            >
          </el-col>
          <el-col :span="1.5">
            <el-button v-hasPermi="['system:oss:list']" type="info" plain icon="Operation" @click="handleOssConfig">配置管理</el-button>
            <el-button v-hasPermi="['system:ossConfig:list']" type="info" plain icon="Operation" @click="handleOssConfig">配置管理</el-button>
          </el-col>
          <right-toolbar v-model:showSearch="showSearch" @query-table="getList"></right-toolbar>
        </el-row>
src/views/system/role/index.vue
@@ -18,7 +18,7 @@
            <el-form-item label="创建时间" style="width: 308px">
              <el-date-picker
                v-model="dateRange"
                value-format="YYYY-MM-DD"
                value-format="YYYY-MM-DD HH:mm:ss"
                type="daterange"
                range-separator="-"
                start-placeholder="开始日期"
src/views/system/tenantPackage/index.vue
@@ -321,7 +321,7 @@
/** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
const handleExport = () => {
  proxy?.download(
    'system/tenantPackage/export',
    'system/package/export',
    {
      ...queryParams.value
    },
src/views/system/user/authRole.vue
@@ -80,8 +80,8 @@
/** å•击选中行数据 */
const clickRow = (row: RoleVO) => {
  // ele的方法有问题,selected应该为可选参数
  tableRef.value?.toggleRowSelection(row, false);
  row.flag = !row.flag
  tableRef.value?.toggleRowSelection(row, row.flag);
};
/** å¤šé€‰æ¡†é€‰ä¸­æ•°æ® */
const handleSelectionChange = (selection: RoleVO[]) => {
src/views/system/user/index.vue
@@ -39,11 +39,12 @@
                <el-form-item label="创建时间" style="width: 308px">
                  <el-date-picker
                    v-model="dateRange"
                    value-format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="daterange"
                    range-separator="-"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
                  ></el-date-picker>
                </el-form-item>
                <el-form-item>
src/views/workflow/leave/index.vue
@@ -176,7 +176,6 @@
/** æ–°å¢žæŒ‰é’®æ“ä½œ */
const handleAdd = () => {
  proxy.$tab.closePage(proxy.$route);
  proxy.$router.push(`/workflow/leaveEdit/index/add/add`);
  proxy.$router.push({
    path: `/workflow/leaveEdit/index`,
    query: {
vite.config.ts
@@ -75,61 +75,7 @@
        'diagram-js/lib/draw/BaseRenderer',
        'tiny-svg',
        'image-conversion',
        'element-plus/es/components/text/style/css',
        'element-plus/es/components/collapse-item/style/css',
        'element-plus/es/components/collapse/style/css',
        'element-plus/es/components/space/style/css',
        'element-plus/es/components/container/style/css',
        'element-plus/es/components/aside/style/css',
        'element-plus/es/components/main/style/css',
        'element-plus/es/components/header/style/css',
        'element-plus/es/components/button-group/style/css',
        'element-plus/es/components/radio-button/style/css',
        'element-plus/es/components/checkbox-group/style/css',
        'element-plus/es/components/form/style/css',
        'element-plus/es/components/form-item/style/css',
        'element-plus/es/components/button/style/css',
        'element-plus/es/components/input/style/css',
        'element-plus/es/components/input-number/style/css',
        'element-plus/es/components/switch/style/css',
        'element-plus/es/components/upload/style/css',
        'element-plus/es/components/menu/style/css',
        'element-plus/es/components/col/style/css',
        'element-plus/es/components/icon/style/css',
        'element-plus/es/components/row/style/css',
        'element-plus/es/components/tag/style/css',
        'element-plus/es/components/dialog/style/css',
        'element-plus/es/components/loading/style/css',
        'element-plus/es/components/radio/style/css',
        'element-plus/es/components/radio-group/style/css',
        'element-plus/es/components/popover/style/css',
        'element-plus/es/components/scrollbar/style/css',
        'element-plus/es/components/tooltip/style/css',
        'element-plus/es/components/dropdown/style/css',
        'element-plus/es/components/dropdown-menu/style/css',
        'element-plus/es/components/dropdown-item/style/css',
        'element-plus/es/components/sub-menu/style/css',
        'element-plus/es/components/menu-item/style/css',
        'element-plus/es/components/divider/style/css',
        'element-plus/es/components/card/style/css',
        'element-plus/es/components/link/style/css',
        'element-plus/es/components/breadcrumb/style/css',
        'element-plus/es/components/breadcrumb-item/style/css',
        'element-plus/es/components/table/style/css',
        'element-plus/es/components/tree-select/style/css',
        'element-plus/es/components/table-column/style/css',
        'element-plus/es/components/select/style/css',
        'element-plus/es/components/option/style/css',
        'element-plus/es/components/pagination/style/css',
        'element-plus/es/components/tree/style/css',
        'element-plus/es/components/alert/style/css',
        'element-plus/es/components/checkbox/style/css',
        'element-plus/es/components/date-picker/style/css',
        'element-plus/es/components/transfer/style/css',
        'element-plus/es/components/tabs/style/css',
        'element-plus/es/components/image/style/css',
        'element-plus/es/components/tab-pane/style/css'
        'element-plus/es/components/**/css'
      ]
    }
  };