Преглед изворни кода

Merge branch 'iteration-20250110-last' into dev

lex-xin пре 5 месеци
родитељ
комит
7f43df1ad6

+ 1 - 57
dev-dist/sw.js

@@ -68,16 +68,7 @@ if (!self.define) {
     });
   };
 }
-<<<<<<< HEAD
-<<<<<<< HEAD
-define(['./workbox-5357ef54'], function (workbox) {
-  ('use strict');
-=======
-define(['./workbox-bb0550c6'], (function (workbox) { 'use strict';
->>>>>>> iteration-20240723
-=======
 define(['./workbox-88bf3160'], (function (workbox) { 'use strict';
->>>>>>> iteration-20240909
 
   self.skipWaiting();
   workbox.clientsClaim();
@@ -87,8 +78,6 @@ define(['./workbox-88bf3160'], (function (workbox) { 'use strict';
    * requests for URLs in the manifest.
    * See https://goo.gl/S9QRab
    */
-<<<<<<< HEAD
-<<<<<<< HEAD
   workbox.precacheAndRoute(
     [
       {
@@ -122,50 +111,5 @@ define(['./workbox-88bf3160'], (function (workbox) { 'use strict';
     new RegExp('|js'),
     workbox.strategies.networkOnly()
   );
-});
-=======
-=======
->>>>>>> iteration-20240909
-  workbox.precacheAndRoute([{
-    "url": "registerSW.js",
-    "revision": "3ca0b8505b4bec776b69afdba2768812"
-  }, {
-    "url": "index.html",
-<<<<<<< HEAD
-<<<<<<< HEAD
-<<<<<<< HEAD
-<<<<<<< HEAD
-<<<<<<< HEAD
-    "revision": "0.oe0btcmloh8"
-=======
-    "revision": "0.l07eibm7mu"
->>>>>>> iteration-20240909
-=======
-    "revision": "0.as64rvo1j3"
->>>>>>> iteration-20240924
-=======
-    "revision": "0.07uic5uubv8"
->>>>>>> iteration-20241007-tag
-=======
-    "revision": "0.4v8s4holqi"
->>>>>>> 2c7dbadb7e8c85b0a926f9a8f7e7d35b1c11084a
-=======
-    "revision": "0.do2tqkj2vn"
->>>>>>> iteration-20250110-last
-  }], {});
-  workbox.cleanupOutdatedCaches();
-  workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
-    allowlist: [/^\/$/]
-  }));
-  workbox.registerRoute(({
-    url
-  }) => url.origin === "https://dev.kt.colexiu.com", new workbox.NetworkFirst({
-    "cacheName": "api-cache",
-    plugins: []
-  }), 'GET');
+})
 
-}));
-<<<<<<< HEAD
->>>>>>> iteration-20240723
-=======
->>>>>>> iteration-20240909

+ 25 - 26
postcss.config.js

@@ -1,26 +1,25 @@
-module.exports = {
-  plugins: {
-    'postcss-px-to-viewport': {
-      unitToConvert: 'px', // 需要转换的单位,默认为"px"
-      viewportWidth: 1920,
-      viewportHeight: 1188, // 设计稿的视口宽度
-      unitPrecision: 8, // 单位转换后保留的精度
-      propList: ['*'], // 能转化为vw的属性列表
-      viewportUnit: 'vw', // 希望使用的视口单位
-      fontViewportUnit: 'rem', // 字体使用的视口单位
-      selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
-      minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
-      mediaQuery: true, // 媒体查询里的单位是否需要转换单位
-      replace: true, //  是否直接更换属性值,而不添加备用属性
-      exclude: [
-        /src\/components\/layout\/guide-section/,
-        /node_modules\/driver.js/
-      ], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
-      include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
-      landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
-      landscapeUnit: 'vw', // 横屏时使用的单位
-      landscapeWidth: 1920 // 横屏时使用的视口宽度
-    }
-  }
-};
-
+module.exports = {
+  plugins: {
+    'postcss-px-to-viewport': {
+      unitToConvert: 'px', // 需要转换的单位,默认为"px"
+      viewportWidth: 1920,
+      viewportHeight: 1188, // 设计稿的视口宽度
+      unitPrecision: 8, // 单位转换后保留的精度
+      propList: ['*'], // 能转化为vw的属性列表
+      viewportUnit: 'vw', // 希望使用的视口单位
+      fontViewportUnit: 'rem', // 字体使用的视口单位
+      selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
+      minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
+      mediaQuery: true, // 媒体查询里的单位是否需要转换单位
+      replace: true, //  是否直接更换属性值,而不添加备用属性
+      exclude: [
+        /src\/components\/layout\/guide-section/,
+        /node_modules\/driver.js/
+      ], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
+      include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
+      landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
+      landscapeUnit: 'vw', // 横屏时使用的单位
+      landscapeWidth: 1920 // 横屏时使用的视口宽度
+    }
+  }
+};

+ 1 - 1
public/version.json

@@ -1 +1 @@
-{"version":1736991615986}
+{"version":1736991615986}

+ 139 - 148
src/App.tsx

@@ -1,51 +1,40 @@
-import { computed, defineComponent, onMounted, ref, onUnmounted } from 'vue';
+import { computed, defineComponent, onMounted, onUnmounted } from 'vue';
 import { NConfigProvider, zhCN, dateZhCN, NModal } from 'naive-ui';
 import { AppProvider } from './components/Application';
-import { RouterView, useRouter } from 'vue-router';
+import { RouterView } from 'vue-router';
 import setting from './settings/designSetting';
 import { lighten } from './utils';
 import RouterError from './components/RouterError';
 import { useRegisterSW } from 'virtual:pwa-register/vue';
 import { useUserStore } from './store/modules/users';
-export function unregister() {
-  if ('serviceWorker' in navigator) {
-    // console.log('unregister - pwa');
-    // navigator.serviceWorker.ready.then(registration => {
-    //   registration.unregister();
-    // });
-    // navigator.serviceWorker
-    //   .getRegistrations()
-    //   .then(registrations => {
-    //     for (const registration of registrations) {
-    //       registration.unregister().then(boolean => {
-    //         if (boolean) {
-    //           console.log('Service Worker unregistered successfully');
-    //         } else {
-    //           console.log('Service Worker unregistration failed');
-    //         }
-    //       });
-    //     }
-    //   })
-    //   .catch(error => {
-    //     console.error('Error getting Service Worker registrations:', error);
-    //   });
-  } else {
-    console.log('Service Workers are not supported in this browser');
-  }
-}
+import UpdateTips from './update-tips';
 
 export default defineComponent({
   name: 'App',
   setup() {
-    const isIOSChrome = ref();
+    const upload = true;
+    const { needRefresh, offlineReady, updateServiceWorker } = useRegisterSW({
+      onRegistered(r: any) {
+        console.log(r, 'registered');
+
+        // r &&
+        //   setInterval(() => {
+        //     r.update();
+        //   }, 30000);
+      },
+      onNeedRefresh() {
+        console.log('新版本可用!');
+      },
+      onOfflineReady() {
+        console.log('离线功能就绪。');
+      }
+    });
+
+    // const isIOSChrome = ref();
+    // const showModalMask = ref(false);
     const getThemeOverrides = computed(() => {
       const appTheme = setting.appTheme;
       const lightenStr = lighten(setting.appTheme, 6);
-
-      //   errorColor: string;
-      // errorColorHover: string;
-      // errorColorPressed: string;
-      // errorColorSuppl: string;
       return {
         common: {
           primaryColor: appTheme,
@@ -61,109 +50,103 @@ export default defineComponent({
       };
     });
     // const showModal = ref(false);
-    const showModalMsg = ref('');
-    // 判断浏览器
-    // 是否是360
-    const check360 = () => {
-      const result = false;
-      for (const key in navigator.plugins) {
-        // np-mswmp.dll只在360浏览器下存在
-        if (navigator.plugins[key].filename == 'internal-nacl-plugin') {
-          return !result;
-        }
-      }
-      return result;
-    };
+    // const showModalMsg = ref('');
+    // // 判断浏览器
+    // // 是否是360
+    // const check360 = () => {
+    //   const result = false;
+    //   for (const key in navigator.plugins) {
+    //     // np-mswmp.dll只在360浏览器下存在
+    //     if (navigator.plugins[key].filename == 'internal-nacl-plugin') {
+    //       return !result;
+    //     }
+    //   }
+    //   return result;
+    // };
     //
 
-    const isChrome = () => {
-      const isChromium = window.chrome,
-        winNav = window.navigator,
-        vendorName = winNav.vendor,
-        isOpera = winNav.userAgent.indexOf('OPR') > -1,
-        isIEedge = winNav.userAgent.indexOf('Edge') > -1,
-        isIOSChrome = winNav.userAgent.match('CriOS'),
-        // QQ
-        isQQBriwser =
-          winNav.userAgent.indexOf('QQBrowser') > -1 ||
-          winNav.userAgent.indexOf('QQ') > -1,
-        // 搜狗
-        isSouggou =
-          winNav.userAgent.indexOf('se 2.x') > -1 ||
-          winNav.userAgent.indexOf('MetaSr') > -1,
-        // 360
-        is360 = check360() && winNav.userAgent.indexOf('Safari') > -1,
-        // 遨游
-        isMaxthon = winNav.userAgent.indexOf('Maxthon') > -1,
-        // 是否为2345浏览器
-        is2345Explorer = winNav.userAgent.includes('2345Explorer'),
-        // 世界之窗
-        isTheWorld = winNav.userAgent.indexOf('TheWorld') > -1,
-        // 猎豹
-        isLiebao = winNav.userAgent.indexOf('LBBROWSER') > -1;
-      // console.log(isQQBriwser, isSouggou, is360, isMaxthon, is2345Explorer, isTheWorld, isLiebao)
-      if (isIOSChrome) {
-        return true;
-      } else if (
-        isChromium !== null &&
-        typeof isChromium !== 'undefined' &&
-        vendorName === 'Google Inc.' &&
-        isOpera === false &&
-        isIEedge === false &&
-        isQQBriwser === false &&
-        isSouggou === false &&
-        is360 === false &&
-        isMaxthon === false &&
-        is2345Explorer === false &&
-        isTheWorld === false &&
-        isLiebao === false
-      ) {
-        return true;
-      } else {
-        return false;
-      }
-    };
+    // const isChrome = () => {
+    //   const isChromium = (window as any).chrome,
+    //     winNav = window.navigator,
+    //     vendorName = winNav.vendor,
+    //     isOpera = winNav.userAgent.indexOf('OPR') > -1,
+    //     isIEedge = winNav.userAgent.indexOf('Edge') > -1,
+    //     isIOSChrome = winNav.userAgent.match('CriOS'),
+    //     // QQ
+    //     isQQBriwser =
+    //       winNav.userAgent.indexOf('QQBrowser') > -1 ||
+    //       winNav.userAgent.indexOf('QQ') > -1,
+    //     // 搜狗
+    //     isSouggou =
+    //       winNav.userAgent.indexOf('se 2.x') > -1 ||
+    //       winNav.userAgent.indexOf('MetaSr') > -1,
+    //     // 360
+    //     is360 = check360() && winNav.userAgent.indexOf('Safari') > -1,
+    //     // 遨游
+    //     isMaxthon = winNav.userAgent.indexOf('Maxthon') > -1,
+    //     // 是否为2345浏览器
+    //     is2345Explorer = winNav.userAgent.includes('2345Explorer'),
+    //     // 世界之窗
+    //     isTheWorld = winNav.userAgent.indexOf('TheWorld') > -1,
+    //     // 猎豹
+    //     isLiebao = winNav.userAgent.indexOf('LBBROWSER') > -1;
+    //   // console.log(isQQBriwser, isSouggou, is360, isMaxthon, is2345Explorer, isTheWorld, isLiebao)
+    //   if (isIOSChrome) {
+    //     return true;
+    //   } else if (
+    //     isChromium !== null &&
+    //     typeof isChromium !== 'undefined' &&
+    //     vendorName === 'Google Inc.' &&
+    //     isOpera === false &&
+    //     isIEedge === false &&
+    //     isQQBriwser === false &&
+    //     isSouggou === false &&
+    //     is360 === false &&
+    //     isMaxthon === false &&
+    //     is2345Explorer === false &&
+    //     isTheWorld === false &&
+    //     isLiebao === false
+    //   ) {
+    //     return true;
+    //   } else {
+    //     return false;
+    //   }
+    // };
 
-    // 获取谷歌版本
-    const getChromeVersion = () => {
-      const arr = navigator.userAgent.split(' ');
-      let chromeVersion = '' as any;
-      for (let i = 0; i < arr.length; i++) {
-        if (/chrome/i.test(arr[i])) chromeVersion = arr[i];
-      }
-      if (chromeVersion) {
-        return Number(chromeVersion.split('/')[1].split('.')[0]);
-      } else {
-        return false;
-      }
-    };
+    // // 获取谷歌版本
+    // const getChromeVersion = () => {
+    //   const arr = navigator.userAgent.split(' ');
+    //   let chromeVersion = '' as any;
+    //   for (let i = 0; i < arr.length; i++) {
+    //     if (/chrome/i.test(arr[i])) chromeVersion = arr[i];
+    //   }
+    //   if (chromeVersion) {
+    //     return Number(chromeVersion.split('/')[1].split('.')[0]);
+    //   } else {
+    //     return false;
+    //   }
+    // };
 
-    const isChromeFlag = isChrome();
-    // console.log('isChromeFlag', isChromeFlag);
-    if (isChromeFlag) {
-      const chromeVersion = getChromeVersion();
-      if (!chromeVersion || (chromeVersion && chromeVersion < 100)) {
-        showModalMsg.value =
-          '您当前的chrome版本过低,为了保证您的用户体验请升级后使用';
-        // showModal.value = true;
-      }
-      // if (chromeVersion) {
-      //   return Number(chromeVersion.split('/')[1].split('.')[0]);
-      // } else {
-      //   return false;
-      // }
-    } else {
-      showModalMsg.value = '为了保证您的用户体验,请使用chrome打开,点击确定下载';
-      // showModal.value = true;
-      console.log('---');
-    }
-    const submitCallback = () => {
-      window.open('https://www.google.cn/intl/zh-CN/chrome/');
-    };
+    // const isChromeFlag = isChrome();
+    // // console.log('isChromeFlag', isChromeFlag);
+    // if (isChromeFlag) {
+    //   const chromeVersion = getChromeVersion();
+    //   if (!chromeVersion || (chromeVersion && chromeVersion < 100)) {
+    //     showModalMsg.value =
+    //       '您当前的chrome版本过低,为了保证您的用户体验请升级后使用';
+    //   }
+    // } else {
+    //   showModalMsg.value = '为了保证您的用户体验,请使用chrome打开,点击确定下载';
+    //   // showModal.value = true;
+    //   console.log('---');
+    // }
+    // const submitCallback = () => {
+    //   window.open('https://www.google.cn/intl/zh-CN/chrome/');
+    // };
     const handleOpen = (e: MessageEvent) => {
       if (e.data?.api === 'onLogin') {
         const userStore = useUserStore();
-        const router = useRouter();
+        // const router = useRouter();
         const documentDom: any = document;
         documentDom.exitFullscreen
           ? documentDom.exitFullscreen()
@@ -177,8 +160,21 @@ export default defineComponent({
       }
     };
 
+    // const resize = () => {
+    //   const params = {
+    //     width: document.body.clientWidth,
+    //     height: document.body.clientHeight
+    //   };
+    //   if (params.height >= params.width) {
+    //     showModalMask.value = true;
+    //   } else {
+    //     showModalMask.value = false;
+    //   }
+    // };
+
     onMounted(() => {
       window.addEventListener('message', handleOpen);
+      // window.addEventListener('resize', resize);
 
       // 禁用右键菜单
       document.addEventListener('contextmenu', function (event) {
@@ -196,20 +192,6 @@ export default defineComponent({
         }
       });
 
-      // const intervalMS = 60 * 60 * 1000;
-
-      // console.log(useRegisterSW, '1');
-      const updateServiceWorker = useRegisterSW({
-        onRegistered(r: any) {
-          console.log(r, 'registered');
-
-          r &&
-            setInterval(() => {
-              // console.log('registered interval:', r);
-              r.update();
-            }, 30000);
-        }
-      });
       // console.log('app - onounted - test interval');
 
       // if ('serviceWorker' in navigator) {
@@ -227,13 +209,12 @@ export default defineComponent({
       // }
     });
     onUnmounted(() => {
+      // window.removeEventListener('resize', resize);
       window.removeEventListener('message', handleOpen);
     });
 
-    // 卸载 pwa
-    unregister();
     return () => (
-      <>
+      <div>
         <NConfigProvider
           locale={zhCN}
           themeOverrides={getThemeOverrides.value}
@@ -245,6 +226,16 @@ export default defineComponent({
             <RouterError />
           </AppProvider>
         </NConfigProvider>
+        <NModal maskClosable={false} v-model:show={needRefresh.value}>
+          <UpdateTips onConfirm={() => updateServiceWorker(true)} />
+        </NModal>
+
+        <span style={{ display: 'none' }}>
+          {needRefresh.value ? '新内容可用,点击刷新页面' : '没有新内容'}
+        </span>
+        <span style={{ display: 'none' }}>
+          {offlineReady.value ? '应用已离线可用' : '没有离线'}
+        </span>
         {/* <NModal
           show={showModal.value}
           closeOnEsc={false}
@@ -255,7 +246,7 @@ export default defineComponent({
           content={showModalMsg.value}
           positive-text="确认"
           onPositiveClick={submitCallback}></NModal> */}
-      </>
+      </div>
     );
   }
 });

+ 2 - 2
src/components/layout/guide-section/index.tsx

@@ -286,8 +286,8 @@ export default defineComponent({
                       <TheSearch
                         round={false}
                         v-model:value={opInfo.searchValue}
-                        onSearch={async (val: any) => {
-                          await getTeacherManual(val);
+                        onSearch={async () => {
+                          await getTeacherManual();
                           if (windowInfo.windowType === 'LARGE') {
                             const id = opInfo.dataList[0]?.children[0]?.id;
                             id && getTeacherManualDetail(id);

BIN
src/screen-tips/images/tip-bg.png


BIN
src/screen-tips/images/tip-dang.png


+ 52 - 0
src/screen-tips/index.module.less

@@ -0,0 +1,52 @@
+.commonWork {
+    width: 560px;
+    background: #FFFFFF;
+    border-radius: 24px;
+    position: relative;
+    padding: 0 30px 35px;
+  
+    .downMoveBg {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 560px;
+      height: 121px;
+    }
+  
+    .dingPng {
+      width: 162px;
+      height: 98px;
+      position: absolute;
+      left: 50%;
+      margin-left: -81px;
+      top: -49px;
+      z-index: 100;
+    }
+  
+    h2 {
+      margin-top: 74px;
+      height: 33px;
+      font-size: max(24px, 18Px);
+      font-family: PingFangSC-Semibold, PingFang SC;
+      font-weight: 600;
+      color: #000000;
+      line-height: 33px;
+      text-align: center;
+      margin-bottom: 15px;
+    }
+  
+  
+    .header {
+      text-align: center;
+      padding: 25px 0 50px;
+      font-weight: 400;
+      font-size: max(18px, 14Px);
+      color: #777777;
+      line-height: max(30px, 18Px);
+
+      span {
+        color: #2784FF;
+      }
+    }
+  
+  }

+ 23 - 0
src/screen-tips/index.tsx

@@ -0,0 +1,23 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import commentBg from './images/tip-bg.png';
+import commentTop from './images/tip-dang.png';
+
+export default defineComponent({
+  name: 'screen-tips',
+  setup() {
+
+
+    return () => (
+      <div class={styles.commonWork}>
+        <img src={commentTop} class={styles.dingPng} alt="" />
+        <img src={commentBg} class={styles.downMoveBg} alt="" />
+        <h2>温馨提示</h2>
+        
+        <div class={styles.header}>
+          为了更好的上课体验,请切换到<span>横屏模式</span>
+        </div>
+      </div>
+    );
+  }
+});

BIN
src/update-tips/images/tip-bg.png


BIN
src/update-tips/images/tip-dang.png


+ 62 - 0
src/update-tips/index.module.less

@@ -0,0 +1,62 @@
+.commonWork {
+  width: 400px;
+  background: #ffffff;
+  border-radius: 18px;
+  position: relative;
+  padding: 0 30px 35px;
+
+  .downMoveBg {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 400px;
+    height: 104px;
+  }
+
+  .dingPng {
+    width: 159px;
+    height: 159px;
+    position: absolute;
+    left: 50%;
+    margin-left: -81px;
+    top: -57px;
+    z-index: 100;
+  }
+
+  h2 {
+    margin-top: 120px;
+    font-weight: 600;
+    font-size: 24px;
+    color: #131415;
+    line-height: 33px;
+    text-align: center;
+  }
+
+  .header {
+    text-align: center;
+    padding: 20px 0 30px;
+    font-size: 18px;
+    color: #777777;
+    line-height: 30px;
+
+    span {
+      color: #2784ff;
+    }
+  }
+
+  .btn {
+    cursor: pointer;
+    width: 256px;
+    border-radius: 50px;
+    text-align: center;
+    font-weight: 600;
+    font-size: 18px;
+    color: #ffffff;
+    line-height: 25px;
+    line-height: 47px;
+    margin: 0 auto;
+    --n-color: #40c8ff !important;
+    background: linear-gradient(305deg, #40c8ff 0%, #3192ff 100%);
+  }
+}
+

+ 24 - 0
src/update-tips/index.tsx

@@ -0,0 +1,24 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import commentBg from './images/tip-bg.png';
+import commentTop from './images/tip-dang.png';
+
+export default defineComponent({
+  name: 'screen-tips',
+  emits: ['confirm'],
+  setup(props, { emit }) {
+    return () => (
+      <div class={styles.commonWork}>
+        <img src={commentTop} class={styles.dingPng} alt="" />
+        <img src={commentBg} class={styles.downMoveBg} alt="" />
+        <h2>发现新版本</h2>
+
+        <div class={styles.header}>系统已更新版本,请刷新界面后继续使用</div>
+
+        <div class={styles.btn} onClick={() => emit('confirm')}>
+          立即刷新
+        </div>
+      </div>
+    );
+  }
+});