Browse Source

Merge branch 'master' of http://39.97.59.228:8013/hrx/mky-vent-base

wangkeyi 1 week ago
parent
commit
2620ad9ba1

+ 11 - 0
src/api/vent/index.ts

@@ -5,6 +5,13 @@ import { loginCipher } from '/@/settings/encryptionSetting';
 enum Api {
   DEVICE_CONTROL = '/safety/ventanalyMonitorData/devicecontrol', // 开关控制
   SPRAY_CONTROL = '/ventanaly-device/safety/ventanalyMonitorData/batchDevicecontrol', // 皮带三级防灭火批量控制
+  LATEST_APP = '/ventanaly-device/safety/app/last',
+}
+
+export interface LatestAppDownload {
+  filename: string;
+  downloadUrl: string;
+  lastModified: string;
 }
 
 // Get personal center-basic settings
@@ -33,3 +40,7 @@ export const sprayControlApi = (data) => {
     return defHttp.put({ url: Api.SPRAY_CONTROL, data });
   }
 };
+
+export const getLatestAppDownload = () => {
+  return defHttp.get<LatestAppDownload>({ url: Api.LATEST_APP });
+};

+ 266 - 235
src/layouts/default/header/components/user-dropdown/index.vue

@@ -25,6 +25,7 @@
             :text="t('layout.header.tooltipLock')"
             icon="ion:lock-closed-outline"
         />-->
+        <MenuItem key="download" :text="t('layout.header.dropdownItemApp')" icon="ion:download-outline" />
         <MenuItem key="homeStyle" :text="t('layout.header.dropdownItemHomeStyle')" icon="ion:home-outline" />
         <MenuItem key="about" :text="t('layout.header.dropdownItemAbout')" icon="ion:information-outline" />
         <MenuItem key="logout" :text="t('layout.header.dropdownItemLoginOut')" icon="ion:power-outline" />
@@ -38,274 +39,304 @@
   <UpdatePassword v-if="passwordVisible" ref="updatePasswordRef" />
 </template>
 <script lang="ts">
-  // components
-  import { Dropdown, Menu, message } from 'ant-design-vue';
+// components
+import { Dropdown, Menu, message } from 'ant-design-vue';
 
-  import { defineComponent, computed, ref } from 'vue';
+import { defineComponent, computed, ref } from 'vue';
 
-  import { SITE_URL } from '/@/settings/siteSetting';
+import { SITE_URL } from '/@/settings/siteSetting';
 
-  import { useUserStore } from '/@/store/modules/user';
-  import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { useDesign } from '/@/hooks/web/useDesign';
-  import { useModal } from '/@/components/Modal';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { useGo } from '/@/hooks/web/usePage';
-  import headerImg from '/@/assets/images/header.jpg';
-  import { propTypes } from '/@/utils/propTypes';
-  import { openWindow } from '/@/utils';
-  import { useGlobSetting } from '/@/hooks/setting';
-  import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
+import { useUserStore } from '/@/store/modules/user';
+import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
+import { useI18n } from '/@/hooks/web/useI18n';
+import { useDesign } from '/@/hooks/web/useDesign';
+import { useModal } from '/@/components/Modal';
+import { useMessage } from '/@/hooks/web/useMessage';
+import { useGo } from '/@/hooks/web/usePage';
+import headerImg from '/@/assets/images/header.jpg';
+import { propTypes } from '/@/utils/propTypes';
+import { openWindow } from '/@/utils';
+import { useGlobSetting } from '/@/hooks/setting';
+import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
 
-  import { refreshCache, queryAllDictItems, refreshRedis } from '/@/views/system/dict/dict.api';
-  import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
-  import { removeAuthCache, setAuthCache } from '/@/utils/auth/index';
-  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
-  import { getRefPromise } from '/@/utils/index';
-  import { get } from 'lodash-es';
+import { refreshCache, queryAllDictItems, refreshRedis } from '/@/views/system/dict/dict.api';
+import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
+import { removeAuthCache, setAuthCache } from '/@/utils/auth/index';
+import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
+import { getRefPromise } from '/@/utils/index';
+import { get } from 'lodash-es';
+import { getLatestAppDownload } from '/@/api/vent';
 
-  type MenuEvent = 'logout' | 'doc' | 'lock' | 'cache' | 'depart' | 'modalCache' | 'switchTheme' | 'info' | 'homeStyle';
-  const { createMessage } = useMessage();
-  export default defineComponent({
-    name: 'UserDropdown',
-    components: {
-      Dropdown,
-      Menu,
-      MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
-      MenuDivider: Menu.Divider,
-      LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
-      DepartSelect: createAsyncComponent(() => import('./DepartSelect.vue')),
-      ThemeSelect: createAsyncComponent(() => import('./ThemeSelect.vue')),
-      HomeStyleSelect: createAsyncComponent(() => import('./HomeStyleSelect.vue')),
-      UpdatePassword: createAsyncComponent(() => import('./UpdatePassword.vue')),
-    },
-    props: {
-      theme: propTypes.oneOf(['dark', 'light']),
-    },
-    setup() {
-      const { sysOrgCode } = useGlobSetting();
-      const { prefixCls } = useDesign('header-user-dropdown');
-      const { t } = useI18n();
-      const { getShowDoc, getUseLockPage } = useHeaderSetting();
-      const userStore = useUserStore();
-      const go = useGo();
-      const passwordVisible = ref(false);
-      const lockActionVisible = ref(false);
-      const lockActionRef = ref(null);
+type MenuEvent = 'logout' | 'doc' | 'lock' | 'cache' | 'depart' | 'modalCache' | 'switchTheme' | 'info' | 'homeStyle' | 'download';
+const { createMessage, createConfirmSync } = useMessage();
+export default defineComponent({
+  name: 'UserDropdown',
+  components: {
+    Dropdown,
+    Menu,
+    MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
+    MenuDivider: Menu.Divider,
+    LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
+    DepartSelect: createAsyncComponent(() => import('./DepartSelect.vue')),
+    ThemeSelect: createAsyncComponent(() => import('./ThemeSelect.vue')),
+    HomeStyleSelect: createAsyncComponent(() => import('./HomeStyleSelect.vue')),
+    UpdatePassword: createAsyncComponent(() => import('./UpdatePassword.vue')),
+  },
+  props: {
+    theme: propTypes.oneOf(['dark', 'light']),
+  },
+  setup() {
+    const { sysOrgCode, domainUrl } = useGlobSetting();
+    const { prefixCls } = useDesign('header-user-dropdown');
+    const { t } = useI18n();
+    const { getShowDoc, getUseLockPage } = useHeaderSetting();
+    const userStore = useUserStore();
+    const go = useGo();
+    const passwordVisible = ref(false);
+    const lockActionVisible = ref(false);
+    const lockActionRef = ref(null);
 
-      const getUserInfo = computed(() => {
-        const { realname = '', avatar, desc } = userStore.getUserInfo || {};
-        return { realname, avatar: avatar || headerImg, desc };
-      });
-
-      const getAvatarUrl = computed(() => {
-        let { avatar } = getUserInfo.value;
-        if (avatar == headerImg) {
-          return avatar;
-        } else {
-          return getFileAccessHttpUrl(avatar);
-        }
-      });
+    const getUserInfo = computed(() => {
+      const { realname = '', avatar, desc } = userStore.getUserInfo || {};
+      return { realname, avatar: avatar || headerImg, desc };
+    });
 
-      const [register, { openModal }] = useModal();
-      /**
-       * 多部门弹窗逻辑
-       */
-      const loginSelectRef = ref();
-      // update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
-      async function handleLock() {
-        await getRefPromise(lockActionRef);
-        openModal(true);
-      }
-      // update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
-      //  login out
-      function handleLoginOut() {
-        userStore.confirmLoginOut();
+    const getAvatarUrl = computed(() => {
+      let { avatar } = getUserInfo.value;
+      if (avatar == headerImg) {
+        return avatar;
+      } else {
+        return getFileAccessHttpUrl(avatar);
       }
+    });
 
-      // open doc
-      function openDoc() {
-        openWindow(SITE_URL);
-      }
+    const [register, { openModal }] = useModal();
+    /**
+     * 多部门弹窗逻辑
+     */
+    const loginSelectRef = ref();
+    // update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
+    async function handleLock() {
+      await getRefPromise(lockActionRef);
+      openModal(true);
+    }
+    // update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
+    //  login out
+    function handleLoginOut() {
+      userStore.confirmLoginOut();
+    }
 
-      // 清除缓存
-      async function clearCache() {
-        const result = await refreshCache();
-        const refreshRedisResult = await refreshRedis();
-        if (result.success && refreshRedisResult) {
-          const res = await queryAllDictItems();
-          removeAuthCache(DB_DICT_DATA_KEY);
-          setAuthCache(DB_DICT_DATA_KEY, res.result);
-          createMessage.success('刷新缓存完成!');
-        } else {
-          createMessage.error('刷新缓存失败!');
-        }
-      }
+    // open doc
+    function openDoc() {
+      openWindow(SITE_URL);
+    }
 
-      function clearModalCache() {
-        return new Promise((resolve) => {
-          if (window['CustomDB']) {
-            // 清除指定表的所有数据
-            window['CustomDB'].modal
-              .clear()
-              .then(() => {
-                console.log('表数据已成功清除!');
-                resolve(null);
-                window.location.reload();
-              })
-              .catch((error) => {
-                console.error('清除数据时发生错误:', error);
-                resolve(null);
-                window.location.reload();
-              });
-          }
-        });
+    async function downloadApp() {
+      const confirmed = await createConfirmSync({
+        title: '应用下载',
+        content: '是否下载?',
+      });
+      if (!confirmed) {
+        return;
       }
 
-      // 切换部门
-      function updateCurrentDepart() {
-        loginSelectRef.value.show();
+      const app = await getLatestAppDownload();
+      if (!app?.filename || !app?.downloadUrl) {
+        createMessage.warning('未获取到应用下载路径');
+        return;
       }
-      // 修改密码
-      const updatePasswordRef = ref();
-      // update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
-      async function updatePassword() {
-        passwordVisible.value = true;
-        await getRefPromise(updatePasswordRef);
-        updatePasswordRef.value.show(userStore.getUserInfo.username);
+
+      const downloadUrl = /^https?:\/\//i.test(app.downloadUrl) ? app.downloadUrl : `${domainUrl}${app.downloadUrl}`;
+      const link = document.createElement('a');
+      link.href = downloadUrl;
+      link.download = app.filename;
+      link.style.display = 'none';
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+      createMessage.success('应用下载已开始,请在浏览器下载列表中查看');
+    }
+
+    // 清除缓存
+    async function clearCache() {
+      const result = await refreshCache();
+      const refreshRedisResult = await refreshRedis();
+      if (result.success && refreshRedisResult) {
+        const res = await queryAllDictItems();
+        removeAuthCache(DB_DICT_DATA_KEY);
+        setAuthCache(DB_DICT_DATA_KEY, res.result);
+        createMessage.success('刷新缓存完成!');
+      } else {
+        createMessage.error('刷新缓存失败!');
       }
-      // update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
-      function handleMenuClick(e: { key: MenuEvent }) {
-        switch (e.key) {
-          case 'homeStyle':
-            updateHomeStyle();
-            break;
-          case 'about':
-            message.info(`当前版本:${get(window, '__LAST_PRODUCTION_TAG__.version', '开发模式')}`);
-            break;
-          case 'logout':
-            handleLoginOut();
-            break;
-          case 'doc':
-            openDoc();
-            break;
-          case 'lock':
-            handleLock();
-            break;
-          case 'cache':
-            clearCache();
-            break;
-          case 'modalCache':
-            clearModalCache();
-            break;
-          case 'depart':
-            updateCurrentDepart();
-            break;
-          case 'switchTheme':
-            updateTheme();
-            break;
-          case 'password':
-            updatePassword();
-            break;
-          case 'account':
-            //update-begin---author:wangshuai ---date:20221125  for:进入用户设置页面------------
-            go(`/system/usersetting`);
-            //update-end---author:wangshuai ---date:20221125  for:进入用户设置页面--------------
-            break;
+    }
+
+    function clearModalCache() {
+      return new Promise((resolve) => {
+        if (window['CustomDB']) {
+          // 清除指定表的所有数据
+          window['CustomDB'].modal
+            .clear()
+            .then(() => {
+              console.log('表数据已成功清除!');
+              resolve(null);
+              window.location.reload();
+            })
+            .catch((error) => {
+              console.error('清除数据时发生错误:', error);
+              resolve(null);
+              window.location.reload();
+            });
         }
-      }
+      });
+    }
 
-      /**
-       * 切换主题弹窗
-       */
-      const themeSelectRef = ref();
-      function updateTheme() {
-        themeSelectRef.value.show();
+    // 切换部门
+    function updateCurrentDepart() {
+      loginSelectRef.value.show();
+    }
+    // 修改密码
+    const updatePasswordRef = ref();
+    // update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
+    async function updatePassword() {
+      passwordVisible.value = true;
+      await getRefPromise(updatePasswordRef);
+      updatePasswordRef.value.show(userStore.getUserInfo.username);
+    }
+    // update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
+    function handleMenuClick(e: { key: MenuEvent }) {
+      switch (e.key) {
+        case 'homeStyle':
+          updateHomeStyle();
+          break;
+        case 'about':
+          message.info(`当前版本:${get(window, '__LAST_PRODUCTION_TAG__.version', '开发模式')}`);
+          break;
+        case 'logout':
+          handleLoginOut();
+          break;
+        case 'doc':
+          openDoc();
+          break;
+        case 'lock':
+          handleLock();
+          break;
+        case 'cache':
+          clearCache();
+          break;
+        case 'modalCache':
+          clearModalCache();
+          break;
+        case 'depart':
+          updateCurrentDepart();
+          break;
+        case 'switchTheme':
+          updateTheme();
+          break;
+        case 'password':
+          updatePassword();
+          break;
+        case 'download':
+          downloadApp();
+          break;
+        case 'account':
+          //update-begin---author:wangshuai ---date:20221125  for:进入用户设置页面------------
+          go(`/system/usersetting`);
+          //update-end---author:wangshuai ---date:20221125  for:进入用户设置页面--------------
+          break;
       }
+    }
 
-      // 首页风格弹窗
-      const homeStyleSelectRef = ref();
-      function updateHomeStyle() {
-        homeStyleSelectRef.value.show();
-      }
+    /**
+     * 切换主题弹窗
+     */
+    const themeSelectRef = ref();
+    function updateTheme() {
+      themeSelectRef.value.show();
+    }
+
+    // 首页风格弹窗
+    const homeStyleSelectRef = ref();
+    function updateHomeStyle() {
+      homeStyleSelectRef.value.show();
+    }
 
-      return {
-        prefixCls,
-        t,
-        getUserInfo,
-        getAvatarUrl,
-        handleMenuClick,
-        getShowDoc,
-        register,
-        getUseLockPage,
-        loginSelectRef,
-        themeSelectRef,
-        homeStyleSelectRef,
-        updateHomeStyle,
-        updatePasswordRef,
-        passwordVisible,
-        lockActionVisible,
-        sysOrgCode,
-      };
-    },
-  });
+    return {
+      prefixCls,
+      t,
+      getUserInfo,
+      getAvatarUrl,
+      handleMenuClick,
+      getShowDoc,
+      register,
+      getUseLockPage,
+      loginSelectRef,
+      themeSelectRef,
+      homeStyleSelectRef,
+      updateHomeStyle,
+      updatePasswordRef,
+      passwordVisible,
+      lockActionVisible,
+      sysOrgCode,
+    };
+  },
+});
 </script>
 <style lang="less">
-  @prefix-cls: ~'@{namespace}-header-user-dropdown';
-  @ventSpace: zxm;
+@prefix-cls: ~'@{namespace}-header-user-dropdown';
+@ventSpace: zxm;
 
-  .@{prefix-cls} {
-    //height: @header-height;
-    height: 48px;
-    padding: 0 0 0 10px;
-    padding-right: 10px;
-    // overflow: hidden;
-    font-size: 12px;
-    cursor: pointer;
-    align-items: center;
-    color: @text-color-base;
+.@{prefix-cls} {
+  //height: @header-height;
+  height: 48px;
+  padding: 0 0 0 10px;
+  padding-right: 10px;
+  // overflow: hidden;
+  font-size: 12px;
+  cursor: pointer;
+  align-items: center;
+  color: @text-color-base;
 
-    img {
-      width: 24px;
-      height: 24px;
-      margin-right: 12px;
-    }
+  img {
+    width: 24px;
+    height: 24px;
+    margin-right: 12px;
+  }
 
-    &__header {
-      border-radius: 50%;
-    }
+  &__header {
+    border-radius: 50%;
+  }
 
-    &__name {
-      font-size: 14px;
-    }
+  &__name {
+    font-size: 14px;
+  }
 
-    &--dark {
-      &:hover {
-        background-color: @header-dark-bg-hover-color;
-      }
+  &--dark {
+    &:hover {
+      background-color: @header-dark-bg-hover-color;
     }
+  }
 
-    &--light {
-      &:hover {
-        //background-color: @header-light-bg-hover-color;
-      }
+  &--light {
+    &:hover {
+      //background-color: @header-light-bg-hover-color;
+    }
 
-      .@{prefix-cls}__name {
-        //color: @text-color-base;
-        color: @white;
-      }
+    .@{prefix-cls}__name {
+      //color: @text-color-base;
+      color: @white;
+    }
 
-      .@{prefix-cls}__desc {
-        //color: @header-light-desc-color;
-        color: @white;
-      }
+    .@{prefix-cls}__desc {
+      //color: @header-light-desc-color;
+      color: @white;
     }
+  }
 
-    &-dropdown-overlay {
-      .@{ventSpace}-dropdown-menu-item {
-        min-width: 160px;
-      }
+  &-dropdown-overlay {
+    .@{ventSpace}-dropdown-menu-item {
+      min-width: 160px;
     }
   }
+}
 </style>

+ 1 - 0
src/locales/lang/zh-CN/layout.ts

@@ -1,6 +1,7 @@
 export default {
   footer: { onlinePreview: 'JEECG首页', onlineDocument: '在线文档' },
   header: {
+    dropdownItemApp: '下载APP',
     // user dropdown
     // dropdownItemDoc: '官网',
     dropdownItemAbout: '关于',