浏览代码

添加离线包功能

bill 8 月之前
父节点
当前提交
3eaf49df12
共有 9 个文件被更改,包括 155 次插入9 次删除
  1. 1 0
      .gitignore
  2. 14 0
      offline.html
  3. 1 0
      package.json
  4. 91 0
      src/api/offline.ts
  5. 3 0
      src/api/setup.ts
  6. 19 9
      src/model/app.vue
  7. 12 0
      src/utils/params.ts
  8. 2 0
      src/vite-env.d.ts
  9. 12 0
      vite.config.ts

+ 1 - 0
.gitignore

@@ -9,6 +9,7 @@ lerna-debug.log*
 
 node_modules
 dist
+public/__offline/*
 dist-ssr
 *.local
 

+ 14 - 0
offline.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>案件信息</title>
+    <script>window.offline = true</script>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.ts"></script>
+  </body>
+</html>

+ 1 - 0
package.json

@@ -6,6 +6,7 @@
   "scripts": {
     "dev": "vite",
     "build": "vite build",
+    "build-offline": " vite build ./ offline",
     "preview": "vite preview"
   },
   "dependencies": {

+ 91 - 0
src/api/offline.ts

@@ -0,0 +1,91 @@
+import { params as envParams } from "@/env";
+import { paramsToStr, strToParams } from "@/utils/params";
+import { AxiosInstance } from "axios";
+import Axios from 'axios'
+
+export const setOfflineAxios = (axios: AxiosInstance) => {
+  const data: {[key in string]: any} = {}
+  const prev = import.meta.env.DEV ? '__offline/' : ''
+  Axios.get(`./${prev}package/data.json`, {headers: { Accept: "application/json"}}).then(res => {
+    Object.assign(data, res.data)
+    ;(window as any).offlineData = data
+  })
+
+  // 流接口
+  const files = {
+    '/fusion-xj/caseExtractDetail/downDocx': './package/resource/caseExtractDetail.doc',
+    '/fusion-xj/caseInquest/downDocx': './package/resource/caseInquest.doc',
+  } as any
+
+
+  // 添加请求拦截器
+  axios.interceptors.request.use(
+    async function (config) {
+      const params = {...config.params}
+      if (envParams.caseId) {
+        params.caseId = envParams.caseId
+      }
+      let item = data[config.url!+ paramsToStr(params)] 
+      if (!item) {
+        delete params.caseId
+        item = data[config.url!+ paramsToStr(params)] 
+      }
+
+      if (item) {
+        throw {
+          isFakeResponse: true,
+            config,
+            response: {
+              data: item,
+              status: 200,
+              statusText: 'OK',
+              headers: {},
+              config: config,
+            }
+        }
+      } else if (files[config.url!]) {
+        const res = await Axios.get(files[config.url!], {responseType: 'blob'})
+        throw {
+          isFakeResponse: true,
+          response: {
+            data: res.data,
+            status: 200,
+            statusText: 'OK',
+            headers: {},
+            config: config,
+          },
+        }
+      } else {
+        console.error(config.url, '未在离线包中!')
+      }
+      return config
+    },
+    function (error) {
+      // 对请求错误做些什么
+      return Promise.reject(error);
+    }
+  );
+
+
+  // 添加响应拦截器
+  axios.interceptors.response.use(
+    function (response) {
+      if (!files[response.config.url!]) {
+        console.error(response.config.url + paramsToStr(response.config.params), '正在添加到离线包中!')
+        data[response.config.url+ paramsToStr(response.config.params)!] = response.data
+      }
+      // 对响应数据做点什么
+      return response;
+    },
+    err => {
+      if (err.isFakeResponse) {
+        return Promise.resolve(err.response);
+      }
+    }
+  );
+
+  (window as any).proxyData = () => {
+    console.log(data)
+    console.log(JSON.stringify(data))
+  };
+}

+ 3 - 0
src/api/setup.ts

@@ -1,5 +1,6 @@
 import Axios from 'axios'
 import { ResCode } from './constant'
+import { setOfflineAxios } from './offline'
 
 import type { AxiosResponse, AxiosRequestConfig } from 'axios'
 
@@ -148,6 +149,8 @@ export const axiosFactory = () => {
       return config
     }
   )
+  
+  offline && setOfflineAxios(axiosRaw)
 
   axiosRaw.interceptors.response.use(
     (response: AxiosResponse<ResData<any>>) => {

+ 19 - 9
src/model/app.vue

@@ -58,15 +58,25 @@ export const Model = defineComponent({
         return setUrl("");
       }
       const type = scene.value.type;
-      const urls = {
-        [SceneType.SWKK]: `/swkk/spg.html?m=${scene.value.num}`,
-        [SceneType.SWKJ]: `/swkk/spg.html?m=${scene.value.num}`,
-        [SceneType.SWSS]: `/swss/index.html?m=${scene.value.num}`,
-        [SceneType.SWSSMX]: `/swkk/spg.html?m=${scene.value.num}`,
-        [SceneType.SWMX]: `index.html?caseId=${params.caseId}&app=${params.app}&modelId=${scene.value.num}&share=1#sign-model`,
-        [SceneType.SWYDSS]: `/swss/index.html?m=${scene.value.num}`,
-        [SceneType.SWYDMX]: `/swkk/spg.html?m=${scene.value.num}`,
-      };
+      const urls = offline
+        ? {
+            [SceneType.SWKK]: `/swkk/${scene.value.num}/wwwroot/spg.html?m=${scene.value.num}&lang=zh`,
+            [SceneType.SWKJ]: `/swkk/${scene.value.num}/wwwroot/spg.html?m=${scene.value.num}&lang=zh`,
+            [SceneType.SWSS]: `/swss/${scene.value.num}/www/offline.html?m=${scene.value.num}&lang=zh`,
+            [SceneType.SWSSMX]: `/swkk/${scene.value.num}/wwwroot/spg.html?m=${scene.value.num}&lang=zh`,
+            [SceneType.SWMX]: `offline.html?caseId=${params.caseId}&app=${params.app}&modelId=${scene.value.num}&share=1#sign-model`,
+            [SceneType.SWYDSS]: `/swss/${scene.value.num}/www/offline.html?m=${scene.value.num}&lang=zh`,
+            [SceneType.SWYDMX]: `/swkk/${scene.value.num}/wwwroot/spg.html?m=${scene.value.num}&lang=zh`,
+          }
+        : {
+            [SceneType.SWKK]: `/swkk/spg.html?m=${scene.value.num}`,
+            [SceneType.SWKJ]: `/swkk/spg.html?m=${scene.value.num}`,
+            [SceneType.SWSS]: `/swss/index.html?m=${scene.value.num}`,
+            [SceneType.SWSSMX]: `/swkk/spg.html?m=${scene.value.num}`,
+            [SceneType.SWMX]: `index.html?caseId=${params.caseId}&app=${params.app}&modelId=${scene.value.num}&share=1#sign-model`,
+            [SceneType.SWYDSS]: `/swss/index.html?m=${scene.value.num}`,
+            [SceneType.SWYDMX]: `/swkk/spg.html?m=${scene.value.num}`,
+          };
       setUrl(urls[type]);
     });
 

+ 12 - 0
src/utils/params.ts

@@ -15,4 +15,16 @@ export const strToParams = (str: string) => {
   }
 
   return result
+}
+
+
+export const paramsToStr = (params: {[key in string]: string}) => {
+  
+  if (params && Object.keys(params).length > 0) {
+    const entitys = Object.entries(params)
+    entitys.sort((a, b) => a[0].localeCompare(b[0]))
+    return '?' + entitys.map(([k, v]) => `${k}=${v}`).join('&')
+  } else {
+    return ''
+  }
 }

+ 2 - 0
src/vite-env.d.ts

@@ -6,6 +6,8 @@ declare module '*.vue' {
   export default component
 }
 
+declare const offline: boolean
+
 type ToChangeAPI<T extends Record<string, any>> = {
   [key in keyof T as `change${Capitalize<key & string>}`]: (prop: T[key]) => void
 }

+ 12 - 0
vite.config.ts

@@ -42,8 +42,20 @@ const proxy = {
   }
 }
 
+let app = "index";
+if (process.argv.length > 3) {
+  app = process.argv[process.argv.length - 1].trim();
+}
+const input = {
+  [app]: resolve(__dirname, `${app}.html`),
+}
 // https://vitejs.dev/config/
 export default defineConfig({
+  build: {
+    rollupOptions:  {
+      input
+    },
+  },
   plugins: [vue(), mkcert() ],
   css: {
     preprocessorOptions: {