Browse Source

移除不需要插件,简化utils
Signed-off-by: Caner <5658514@qq.com>

Caner 3 years ago
parent
commit
614d40593b

+ 1 - 4
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "vite-project",
+  "name": "vite-vue3-ts-template",
   "private": true,
   "version": "0.0.0",
   "type": "module",
@@ -9,9 +9,6 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "@wangeditor/editor": "^5.1.18",
-    "@wangeditor/editor-for-vue": "^5.1.12",
-    "axios": "^1.1.3",
     "js-md5": "^0.7.3",
     "naive-ui": "^2.33.5",
     "pinia": "^2.0.18",

+ 0 - 184
src/components/editeDemo.vue

@@ -1,184 +0,0 @@
-<template>
-  <div class="EditorTop">
-    <Toolbar
-      :editor="editorRef"
-      :default-config="config.toolbarConfig"
-    />
-  </div>
-  <div class="EditorContent">
-    <div
-      v-for="s in arrBr"
-      :key="s"
-      class="brs"
-      :style="`top:${s*1228+30}px`"
-    >
-      PDF分割线
-    </div>
-
-    <div class="resetStyle">
-      <Editor
-        id="exportPDF"
-        v-model="valueHtml"
-        :default-config="config.editorConfig"
-        @onCreated="handleCreated"
-        @onChange="changes"
-      />
-    </div>
-  </div>
-</template>
-
-<script setup lang='ts'>
-import { onBeforeUnmount, ref, shallowRef } from 'vue'
-import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
-import '@wangeditor/editor/dist/css/style.css'
-
-// 编辑器实例,必须用 shallowRef,重要!
-const editorRef = shallowRef()
-
-// 配置模式及上传图片地址
-const config = {
-  toolbarConfig: {
-    toolbarKeys: [
-      'headerSelect',
-      'bold', 'underline', 'italic',
-      'clearStyle', 'color', 'bgColor',
-      'fontSize', 'fontFamily', 'justifyLeft',
-      'justifyRight', 'justifyCenter', 'justifyJustify',
-      'uploadImage', 'insertLink', 'insertTable',
-      'SaveBtn'
-    ]
-  },
-  editorConfig: {
-    placeholder: '请输入内容...',
-    MENU_CONF: {
-      uploadImage: {
-        server: '/api/upload',
-        withCredentials: true, // 跨域是否传递 cookie
-        // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
-        meta: {
-          token: 'xxx'
-        },
-        allowedFileTypes: [ 'image/*' ],
-        maxFileSize: 50 * 1024 * 1024, // 最大50M
-        base64LimitSize: 20 * 1024 * 1024 // 小于20M就插入 base64 格式
-      }
-    }
-  }
-}
-
-// 内容 HTML
-const value = (
-  `
-  <p style="text-indent: 42pt; text-align: left;"><span style="font-size: 19px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-size: 19px; font-family: 黑体;"> &nbsp;合同编号</span><span style="font-size: 19px; font-family: 黑体;"><u>xxx</u></span></p>
-  <p style="text-indent: 42pt; text-align: left;"><span style="font-size: 19px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-size: 19px; font-family: 黑体;"> &nbsp;报告编号</span><span style="font-size: 19px; font-family: 黑体;"><u>xxx</u></span></p>
-  <p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p>
-  <p style="text-indent: 42pt;"><br></p><p style="text-align: center;"><span style="font-size: 22px;">XXX高速公路</span></p>
-  <p style="text-align: center;"><span style="font-size: 22px;">XXX隧道进(出)口</span></p><p style="text-align: center;"><br></p>
-  <h4 style="text-align: center;"><span style="font-size: 48px;">监控量测周/旬/月报</span></h4>
-  <p style="text-align: center;"><strong> </strong></p><p style="text-align: center;"><br></p>
-  <p style="text-align: center;"><br></p><p style="text-align: center;"><span style="font-size: 19px; font-family: 黑体;"><strong>(2022.xx.xx~2022.xx.xx)</strong></span></p>
-  <p style="text-align: center;"><span style="font-size: 22px;"><strong> </strong></span></p>
-  <p style="text-align: center;"><br></p><p style="text-align: center;"><br></p>
-  <p style="text-align: center;"><br></p><p style="text-align: center;"><br></p>
-  <p style="text-align: center;"><br></p><p style="text-align: center;"><span style="color: rgb(0, 0, 0); font-size: 22px;">xxx单位</span></p>
-  <p style="text-align: center;"><span style="color: rgb(0, 0, 0); font-size: 22px;">二零二二</span><span style="font-size: 22px;">年xx月xx</span><span style="color: rgb(0, 0, 0); font-size: 22px;">日</span></p>
-  <p style="text-align: center;"><br></p>
-  <p style="text-align: center;"><br></p>
-  <p style="text-align: center;"><br></p>
-  `
-).replace(/[\r\n]/g, '')
-const valueHtml = ref(value)
-
-// A4 默认1228高度
-const A4Height = 1228
-// 分割线
-const arrBr = ref(0)
-
-// 编辑器回调函数
-const handleCreated = (editor: any) => {
-  editorRef.value = editor // 记录 editor 实例,重要!
-}
-
-// 根据A4高度标识分割线条数
-const changes = (editor:any) => {
-  const dom = editor.getEditableContainer() || null
-  if (dom) {
-    const num = Math.floor(dom.offsetHeight / A4Height)
-    if (num !== arrBr.value) {
-      arrBr.value = num
-    }
-  }
-}
-
-// // 获取编辑后的数据
-// setTimeout(() => {
-//   console.log('output->test', editorRef.value.getAllMenuKeys(), editorRef.value.getHtml())
-// }, 3000)
-
-// 组件销毁时,也及时销毁编辑器,重要!
-onBeforeUnmount(() => {
-  const editor = editorRef.value
-  if (editor == null) return
-  editor.destroy()
-})
-
-</script>
-
-<style lang="less" scoped>
-
-  .EditorTop{
-    background: white;
-    &>div{
-      border-bottom: 1px solid #ccc;
-      text-align: center;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-  }
-  .EditorContent{
-    height:9.9rem;
-    background-color: rgb(245, 245, 245);
-    overflow-y: scroll;
-    position: relative;
-    .resetStyle{
-      width: 850px;
-      min-height: 7rem;
-      margin: 30px auto;
-      background-color: #fff;
-      padding: 20px 50px 50px 50px;
-      border: 1px solid #e8e8e8;
-      box-shadow: 0 2px 10px rgb(0 0 0 / 12%);
-      position: relative;
-      z-index: 0;
-      :deep(.w-e-text-container){
-        min-height: 6rem;
-        .w-e-scroll{
-          min-height: 6rem;
-        }
-      }
-    }
-
-    &::-webkit-scrollbar{
-        display: block;
-        width: 15px !important;//对垂直方向滚动条
-    }
-    //滚动的滑块
-    &::-webkit-scrollbar-thumb{
-      border-radius:3px !important;
-      background-color: #ccc !important;//滚动条的颜色
-    }
-    //内层滚动槽
-    &::-webkit-scrollbar-track-piece{
-      background-color: rgb(245, 245, 245) !important;
-    }
-    .brs{
-      width: 100%;
-      position: absolute;
-      border-bottom: dashed 2px #ccc;
-      color: #ccc;
-      text-align: right;
-    }
-  }
-
-</style>

+ 12 - 1
src/pages/index/views/home/index.vue

@@ -1,6 +1,17 @@
+<script setup lang="ts">
+import { post } from '@/utils/request'
+
+function change() {
+  console.log(123)
+  post('/sys/login', { userAccount: 1, userPwd: 'c4ca4238a0b923820dcc509a6f75849b' })
+}
+</script>
 <template>
   <div>
-    <n-button type="primary">
+    <n-button
+      type="primary"
+      @click="change"
+    >
       我不是全局组件
     </n-button>
   </div>

+ 0 - 52
src/utils/axios.ts

@@ -1,52 +0,0 @@
-import axios from 'axios'
-import { getActivePinia } from "pinia";
-import userData from '@/utils/userdata'
-const userinfo = userData.getUserData() || ''
-
-// 全局loading
-const resetLoaing = (type: boolean) => {
-  const store = getActivePinia()
-  if (!store) return
-  const obj = store.state.value
-  for (const key in obj) {
-    const el = obj[key]
-    if ('loading' in el) {
-      el.loading = type
-      break
-    }
-  }
-
-}
-
-// http request 拦截=>增加是否显示loading
-axios.interceptors.request.use(
-  (config: any) => {
-    if (!config.url.includes('https://')) {
-      config.baseURL = import.meta.env.VITE_SERVER_URL
-      const headers = config.headers || {}
-      headers['Authorization'] = 'Bearer ' + userinfo.token
-    }
-    const showLoading = config.showLoading || false
-    if (showLoading) resetLoaing(true)
-    return config
-  },
-  (err) => { throw err }
-)
-
-// http response 拦截
-axios.interceptors.response.use(
-  (response) => {
-    const data = response.data
-    if (data.code !== 200) {
-      if (data.code === 401) {
-        // token 错误
-        userData.clear()
-        window.location.href = '/login.html'
-      }
-    }
-    resetLoaing(false)
-    return data
-  },
-  (error) => { throw error }
-)
-export default axios

+ 0 - 140
src/utils/exp-to-file.ts

@@ -1,140 +0,0 @@
-import * as XLSX from 'xlsx'
-
-/**
-   * 解析后的浮点数转时间戳
-   * @param num 时间浮点
-   */
-const number2times = (num: number) => {
-    const utc_value = (num - 25569) * 86400
-    const date_info = new Date(utc_value * 1000).getTime()
-    const newtime = (date_info - 8 * 3600 * 1000)
-    return newtime
-}
-
-/**
- * 自动下载
- * @param url 保存地址|blob
- * @param saveName 文件名
- */
-const openDownloadDialog = (url: string | Blob | object, saveName: string) => {
-    if (typeof url === 'object' && url instanceof Blob) {
-        url = URL.createObjectURL(url) // 创建blob地址
-    }
-    const aLink = document.createElement('a')
-    aLink.href = url as any
-    aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
-    let event
-    if (window.MouseEvent) event = new MouseEvent('click')
-    else {
-        event = document.createEvent('MouseEvents')
-        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
-    }
-    aLink.dispatchEvent(event)
-}
-
-/**
- * 解析excel表格
- * @param file 文件
- * @returns 
- */
-export const exp2json = async (file: File) => {
-    return await new Promise((resolve, reject) => {
-        try {
-            const reader = new FileReader()
-            reader.onload = (e) => {
-                const wb = XLSX.read(e.target?.result, {
-                    type: 'binary'
-                }) // 读取完成的数据
-                // 转成json header解析第一行标题
-                const data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 })
-                resolve(data)
-            }
-            reader.readAsBinaryString(file)
-        } catch (error) {
-            console.log('解析错误')
-            reject(error)
-        }
-    })
-}
-
-/**
- * 导出excel表格
- * @param arr 数据是数组包含的对象
- * @param fileName 名字
- */
-export const exp2excel = (arr: object[], fileName:string,cellMerges?:Array<any>) => {
-    const sheet = XLSX.utils.json_to_sheet(arr);
-    // excel宽高设置
-    sheet["!cols"] = arr.map(() => {
-        return { wch: 30 }
-    })
-    if(cellMerges){
-        sheet['!merges'] = cellMerges; // <====合并单元格
-    }
-    // 转blob
-    const sheet2blob = (sheet: any, sheetName='sheet1') => {
-        const workbook = {
-            SheetNames: [sheetName],
-            Sheets: {} as any
-        };
-        workbook.Sheets[sheetName] = sheet;
-        // 生成excel的配置项
-        const wopts = {
-            bookType: 'xlsx', // 要生成的文件类型
-            bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
-            type: 'binary'
-        } as any
-        const wbout = XLSX.write(workbook, wopts);
-        // 字符串转ArrayBuffer
-        const s2ab = (s: string) => {
-            let buf = new ArrayBuffer(s.length);
-            let view = new Uint8Array(buf);
-            for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
-            return buf;
-        }
-        const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
-
-        return blob;
-    }
-    openDownloadDialog(sheet2blob(sheet), fileName + '.xlsx')
-}
-
-/**
- * dom导出excel
- * @param domID domID
- * @param fileName 文件名
- */
-export const dom2excel = (domID: string, fileName: string) => {
-    const dom = document.getElementsByTagName(domID)
-    if (!dom) return
-    const wb = XLSX.utils.table_to_book(dom[0])
-    const baty = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
-    // 字符串转ArrayBuffer
-    const s2ab = (s: any) => {
-        const buf = new ArrayBuffer(s.length)
-        const view = new Uint8Array(buf)
-        for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
-        return buf
-    }
-    const blob = new Blob([s2ab(baty)], { type: 'application/octet-stream' })
-    openDownloadDialog(blob, fileName + '.xlsx')
-}
-/**
- * 数组按指定key值分组
- * @param {*} array 
- * @param {*} id 
- * @returns 
- */
- export function groupBy(array:Array<any>, id:string) {
-    let groups = {} as any;
-    array.forEach((o) => {
-        let group = JSON.stringify(o[id]);
-        if (typeof o[id] === 'string') {
-            group = o[id]
-        }
-        groups[group] = groups[group] || [];
-        groups[group].push(o);
-    });
-    // return Object.values(groups);
-    return groups;
-}

+ 105 - 45
src/utils/html-tp-File.ts → src/utils/export-file.ts

@@ -1,23 +1,114 @@
+import * as XLSX from 'xlsx'
 import html2canvas from "html2canvas";
 import JSPDF from "jspdf";
-import { getActivePinia } from "pinia";
 
 /**
- * loading
- * @param type 是否显示
+ * 自动下载
+ * @param url 保存地址|blob
+ * @param saveName 文件名
  */
-const resetLoaing = (type: boolean) => {
-    const store = getActivePinia()
-    if (!store) return
-    const obj = store.state.value
-    for (const key in obj) {
-        const el = obj[key]
-        if ('loading' in el) {
-            el.loading = type
-            break
+const download = (url: string | Blob | object, saveName: string) => {
+    if (typeof url === 'object' && url instanceof Blob) {
+        url = URL.createObjectURL(url) // 创建blob地址
+    }
+    const aLink = document.createElement('a')
+    aLink.href = url as Any
+    aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
+    let event
+    if (window.MouseEvent) event = new MouseEvent('click')
+    else {
+        event = document.createEvent('MouseEvents')
+        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
+    }
+    aLink.dispatchEvent(event)
+}
+
+/**
+ * 解析excel表格
+ * @param file 文件
+ * @returns 
+ */
+export const exp2json = async (file: File) => {
+    return await new Promise((resolve, reject) => {
+        try {
+            const reader = new FileReader()
+            reader.onload = (e) => {
+                const wb = XLSX.read(e.target?.result, {
+                    type: 'binary'
+                }) // 读取完成的数据
+                // 转成json header解析第一行标题
+                const data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 })
+                resolve(data)
+            }
+            reader.readAsBinaryString(file)
+        } catch (error) {
+            console.log('解析错误')
+            reject(error)
+        }
+    })
+}
+
+/**
+ * 导出excel表格
+ * @param arr 数据是数组包含的对象
+ * @param fileName 名字
+ */
+export const exp2excel = (arr: object[], fileName: string, cellMerges?: Array<any>) => {
+    const sheet = XLSX.utils.json_to_sheet(arr);
+    // excel宽高设置
+    sheet["!cols"] = arr.map(() => {
+        return { wch: 30 }
+    })
+    if (cellMerges) {
+        sheet['!merges'] = cellMerges; // <====合并单元格
+    }
+    // 转blob
+    const sheet2blob = (sheet: Any, sheetName = 'sheet1') => {
+        const workbook = {
+            SheetNames: [sheetName],
+            Sheets: {} as Any
+        };
+        workbook.Sheets[sheetName] = sheet;
+        // 生成excel的配置项
+        const wopts = {
+            bookType: 'xlsx', // 要生成的文件类型
+            bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
+            type: 'binary'
+        } as Any
+        const wbout = XLSX.write(workbook, wopts);
+        // 字符串转ArrayBuffer
+        const s2ab = (s: string) => {
+            let buf = new ArrayBuffer(s.length);
+            let view = new Uint8Array(buf);
+            for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
+            return buf;
         }
+        const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
+
+        return blob;
     }
+    download(sheet2blob(sheet), fileName + '.xlsx')
+}
 
+/**
+ * dom导出excel
+ * @param domID domID
+ * @param fileName 文件名
+ */
+export const dom2excel = (domID: string, fileName: string) => {
+    const dom = document.getElementsByTagName(domID)
+    if (!dom) return
+    const wb = XLSX.utils.table_to_book(dom[0])
+    const baty = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
+    // 字符串转ArrayBuffer
+    const s2ab = (s: Any) => {
+        const buf = new ArrayBuffer(s.length)
+        const view = new Uint8Array(buf)
+        for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
+        return buf
+    }
+    const blob = new Blob([s2ab(baty)], { type: 'application/octet-stream' })
+    download(blob, fileName + '.xlsx')
 }
 
 /**
@@ -32,7 +123,6 @@ const resetLoaing = (type: boolean) => {
 export const exp2pdf = async (domID: string, fileName: string, type = 'A4', wMultiple = null, hMultiple = null) => {
     const dom = document.getElementById(domID)
     if (!dom) return
-    resetLoaing(true)
     const domHeight = dom.offsetHeight // 获取DOM高度
     const domWidth = dom.offsetWidth // 获取DOM宽度
     const canvas = await html2canvas(dom, {
@@ -70,7 +160,6 @@ export const exp2pdf = async (domID: string, fileName: string, type = 'A4', wMul
         pdf.addImage(canvas.toDataURL("image/jpeg", 1.0), "JPEG", 10, 10, domWidth, domHeight)
         pdf.save(fileName)
     }
-    resetLoaing(false)
 }
 
 /**
@@ -80,7 +169,6 @@ export const exp2pdf = async (domID: string, fileName: string, type = 'A4', wMul
  * @param bkcolor 背景色
  */
 export const exp2png = async (domID: string, fileName: string, bkcolor: string) => {
-    resetLoaing(true)
     window.scroll(0, 0) // 首先先顶部
     const design = document.getElementById(domID) as HTMLElement
     if (!design) return
@@ -95,34 +183,7 @@ export const exp2png = async (domID: string, fileName: string, bkcolor: string)
         height: imgHeight,
         imageTimeout: 5000 // 设置图片的超时,设置0为禁用
     })
-    const download = (url: string, fileName: string) => {
-        let aLink = document.createElement('a')
-        aLink.href = url
-        aLink.download = fileName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
-        let event
-        if (window.MouseEvent) event = new MouseEvent('click')
-        else {
-            event = document.createEvent('MouseEvents')
-            event.initMouseEvent(
-                'click',
-                true,
-                false,
-                window,
-                0,
-                0,
-                0,
-                0,
-                0,
-                false,
-                false,
-                false,
-                false,
-                0,
-                null
-            )
-        }
-        aLink.dispatchEvent(event)
-    }
+
     // 两种下载方式url + blob
     let imgURL = canvas.toDataURL('image/png') as any
     if (typeof imgURL === 'object' && imgURL instanceof Blob) {
@@ -133,7 +194,7 @@ export const exp2png = async (domID: string, fileName: string, bkcolor: string)
         let htmlrq = new XMLHttpRequest() as any
         htmlrq.open('GET', imgURL, true)
         htmlrq.responseType = 'blob'
-        htmlrq.onload =  (e: { target: { status: number; response: Blob | MediaSource; } })=> {
+        htmlrq.onload = (e: { target: { status: number; response: Blob | MediaSource; } }) => {
             if (e.target.status === 200) {
                 imgURL = URL.createObjectURL(e.target.response) // 创建blob地址
                 download(imgURL, fileName)
@@ -143,5 +204,4 @@ export const exp2png = async (domID: string, fileName: string, bkcolor: string)
         }
         htmlrq.send()
     }
-    resetLoaing(true)
 }

+ 13 - 2
src/utils/js-fn.ts

@@ -115,8 +115,8 @@ export const uniqueArr = <T = Any>(arr: T[], key: keyof T) => {
  * @param {*} id 
  * @returns 
  */
-export const groupBy = (array: Array<any>, id: string) => {
-  let groups = {} as any;
+export const groupBy = (array: Array<Any>, id: string) => {
+  let groups = {} as Any;
   array.forEach((o) => {
     let group = JSON.stringify(o[id]);
     if (typeof o[id] === 'string') {
@@ -127,4 +127,15 @@ export const groupBy = (array: Array<any>, id: string) => {
   });
   // return Object.values(groups);
   return groups;
+}
+
+/**
+  * 解析后的浮点数转时间戳
+  * @param num 时间浮点
+  */
+export const number2times = (num: number) => {
+  const utc_value = (num - 25569) * 86400
+  const date_info = new Date(utc_value * 1000).getTime()
+  const newtime = (date_info - 8 * 3600 * 1000)
+  return newtime
 }

+ 0 - 37
src/utils/register-menu.ts

@@ -1,37 +0,0 @@
-import { Boot } from '@wangeditor/editor'
-import { exp2pdf } from '@/utils/html2File'
-console.warn('此插件注册富文本自定义按钮')
-// 注册一个保存按钮
-class SaveBtn {
-    title: string
-    iconSvg: string
-    tag: string
-
-    constructor() {
-        this.title = '导出PDF'
-        this.iconSvg = '<svg viewBox="0 0 1024 1024" style="width:22px;height:22px;" version="1.1" xmlns="http://www.w3.org/2000/svg" ><path d="M773.696 134.812444l-509.155556 0c-69.76 0-126.520889 56.760889-126.520889 126.542222l0 501.326222c0 69.781333 56.760889 126.499556 126.520889 126.499556l509.141333 0c69.781333 0 126.520889-56.718222 126.520889-126.499556L900.202667 261.361778C900.202667 191.573333 843.441778 134.833778 773.696 134.812444zM324.437333 184.213333l389.347556 0 0 279.608889L324.437333 463.822222 324.437333 184.213333zM850.872889 762.680889c0 42.552889-34.616889 77.191111-77.169778 77.191111l-509.155556 0c-42.552889 0-77.169778-34.638222-77.169778-77.191111L187.377778 261.383111c0-42.574222 34.616889-77.169778 77.169778-77.169778l0-0.021333 10.567111 0 0 329.009778 488.007111 0 0.021333 0L763.143111 184.184889l10.567111 0c42.56 0 77.169778 34.595556 77.169778 77.169778L850.88 762.680889zM591.772444 256.832l49.329778 0 0 164.522667-49.329778 0 0-164.522667ZM591.772444 256.832"></path></svg>'
-        this.tag = 'button'
-    }
-
-    getValue() {
-        return ''
-    }
-
-    isActive() {
-        return false
-    }
-
-    isDisabled() {
-        return false
-    }
-
-    exec() {
-        exp2pdf('exportPDF', '监控量测报告' + new Date().toLocaleDateString())
-    }
-}
-Boot.registerMenu({
-    key: 'SaveBtn',
-    factory() {
-        return new SaveBtn() as any
-    }
-})

+ 127 - 0
src/utils/request.ts

@@ -0,0 +1,127 @@
+/** api接口返回值类型 */
+declare type NetResult = {
+  success: boolean,
+  data: Any,
+  msg: string,
+  code: number
+}
+
+
+/**
+ * post方法请求接口
+ * @param url 接口地址
+ * @param params 接口参数
+ */
+export function POST(url: string, params: Any = {}, timeout = 6000): Promise<NetResult> {
+  return new Promise((resolve) => {
+    const controller = new AbortController()
+    const { signal } = controller
+    setTimeout(() => {
+      controller.abort()
+    }, timeout)
+    fetch('/api' + url, {
+      signal,
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: 'Bearer '
+      },
+      body: JSON.stringify(params)
+    }).then((res: Any) => resolve(res)).catch((err: Any) => resolve(err))
+  })
+}
+
+/**
+ * upload上传文件接口
+ * @param url 接口地址
+ * @param params 接口参数
+ */
+export function UPLOAD(url: string, params: Any, timeout = 6000): Promise<NetResult> {
+  return new Promise((resolve) => {
+    const controller = new AbortController()
+    const { signal } = controller
+    setTimeout(() => {
+      controller.abort()
+    }, timeout)
+
+    fetch('/api' + url, {
+      signal,
+      method: 'POST',
+      headers: { Authorization: 'Bearer ' },
+      body: params
+    }).then((res: Any) => resolve(res)).catch((err: Any) => resolve(err))
+
+  })
+}
+
+/**
+ * get请求api接口
+ * @param url 接口地址
+ */
+export function GET(url: string, timeout = 6000): Promise<NetResult> {
+  return new Promise((resolve) => {
+    const controller = new AbortController()
+    const { signal } = controller
+    setTimeout(() => {
+      controller.abort()
+    }, timeout)
+    fetch('/api' + url, {
+      signal,
+      method: 'get',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: 'Bearer ' 
+      }
+    }).then((res: Any) => resolve(res)).catch((err: Any) => resolve(err))
+
+  })
+}
+
+/**
+ * del请求api接口
+ * @param url 接口地址
+ */
+export function DEL(url: string, timeout = 6000): Promise<NetResult> {
+  return new Promise((resolve) => {
+    const controller = new AbortController()
+    const { signal } = controller
+    setTimeout(() => {
+      controller.abort()
+    }, timeout)
+    fetch('/api' + url, {
+      signal,
+      method: 'DELETE',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: 'Bearer '
+      }
+    }).then((res: Any) => resolve(res)).catch((err: Any) => resolve(err))
+
+  })
+}
+
+/**
+ * post方法请求接口
+ * @param url 接口地址
+ * @param params 接口参数
+ */
+export function PUT(url: string, params: Any = {}, timeout = 6000): Promise<NetResult> {
+  return new Promise((resolve) => {
+    const controller = new AbortController()
+    const { signal } = controller
+    setTimeout(() => {
+      controller.abort()
+    }, timeout)
+    fetch('/api' + url, {
+      signal,
+      method: 'put',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: 'Bearer '
+      },
+      body: JSON.stringify(params)
+    }).then((res: Any) => resolve(res)).catch((err: Any) => resolve(err))
+
+  })
+}
+

+ 0 - 173
src/utils/srs-wertc-player.ts

@@ -1,173 +0,0 @@
-/**
- * srs webrtc palyer
- * auth Caner
- */
-class WebRtcPlayer {
-    private Peer: RTCPeerConnection | null
-    private TIMER: number | null
-    constructor(option: { HOST: string; TOKEN: string; UUID: string; PROFILE: number; PORT: number; DOM: HTMLVideoElement }) {
-        this.TIMER = null
-        this.Peer = null
-        this.initWebRtc(option.HOST, option.PORT, option.TOKEN, option.UUID, option.PROFILE, option.DOM).then(res => {
-            this.Peer = res
-        }).catch(() => {
-            this.Peer = null
-        })
-    }
-
-    /**
-     * 同步睡眠
-     * @param ms 毫秒
-     * @returns
-     */
-    private sleep(ms: number) { return new Promise((resolve) => { setTimeout(resolve, ms) }) }
-
-    /**
-     * 初始化webrtc
-     * @param HOST 媒体服务器地址
-     * @param TOKEN 用户token
-     * @param UUID 摄像头uuid
-     * @param PROFILE 码流
-     * @param DOM video节点
-     * @returns 
-     */
-    private async initWebRtc(HOST: string, PORT: number, TOKEN: string, UUID: string, PROFILE: number, DOM: HTMLVideoElement): Promise<RTCPeerConnection | null> {
-        try {
-            const Peer = new RTCPeerConnection()
-            Peer.addTransceiver('video', { direction: 'recvonly' })
-            const offer = await Peer.createOffer()
-            await Peer.setLocalDescription(offer)
-
-            // 监听视频=播放
-            Peer.ontrack = (event: RTCTrackEvent) => {
-                if (DOM) {
-                    const { streams } = event
-                    DOM.srcObject = streams![0]
-                    console.log('track', event)
-                }
-            }
-
-            Peer.oniceconnectionstatechange = () => {
-                const state = Peer.iceConnectionState
-                console.log('ICE状态', state)
-            }
-
-            Peer.onicegatheringstatechange = () => {
-                console.log('GatheringState: ', Peer.iceGatheringState)
-            }
-
-            Peer.onconnectionstatechange = () => {
-                const state = Peer.connectionState
-                console.log('连接状态', state)
-            }
-
-            // SDP SRS params
-            const params = {
-                api: `http://${HOST}:${PORT}/rtc/v1/play/?token=${TOKEN}&uuid=${UUID}&stream=${UUID + PROFILE}&profile=${PROFILE}`,
-                clientip: null,
-                sdp: offer.sdp,
-                streamurl: `webrtc://${HOST}/live/${UUID + PROFILE}?token=${TOKEN}&uuid=${UUID}&stream=${UUID + PROFILE}&profile=${PROFILE}`,
-                tid: Number(Math.floor(new Date().getTime() * Math.random() * 100)).toString(16).slice(0, 7)
-            }
-            console.log('params', params)
-
-            // 发送offer
-            const res = await window.fetch(params.api, {
-                method: 'POST',
-                headers: { 'Content-Type': 'application/json' },
-                body: JSON.stringify(params)
-            })
-
-            // 接收 answer
-            const { sdp } = await res.json()
-            if (sdp) await Peer.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp }))
-
-            return Peer
-        } catch (error) {
-            console.warn('webRtcInit:', error);
-            return null
-        }
-    }
-
-    /**
-     * 云台控制
-     * @param URL 
-     * @param UUID 
-     * @param TOKEN 
-     * @param command 指令:数字键盘1-9去掉5,10:焦距放大,11:焦距缩小 12:亮度,13:色彩饱和度,14:对比度,15:清晰度
-     * @param number [云台速度|焦距参数|色彩饱和度]等值  亮度值 0-100
-     * @returns 
-     */
-    public contrl(URL: string, UUID: string, TOKEN: string, command: number, number: number) {
-        if (!UUID) return
-        if (this.TIMER !== null) clearTimeout(this.TIMER)
-        this.TIMER = setTimeout(() => {
-            window.fetch(URL, {
-                method: 'POST',
-                headers: { 'Content-Type': 'application/json' },
-                body: JSON.stringify({
-                    code: 'cloudcontrol.control',
-                    token: TOKEN,
-                    body: {
-                        uuid: UUID,
-                        command,
-                        number
-                    }
-                })
-            })
-        }, 500) as unknown as number
-    }
-
-    /**
-     * 视频截图
-     * @param option 
-     * @returns base64
-     */
-    public capPhoto(DOM: HTMLVideoElement) {
-        const canvas = document.createElement('canvas')
-        canvas.width = DOM.offsetWidth
-        canvas.height = DOM.offsetHeight
-        const context = canvas.getContext('2d')
-        context?.drawImage(DOM, 0, 0, DOM.offsetWidth, DOM.offsetHeight)
-        const base64 = canvas.toDataURL('image/jpg')
-        return base64
-    }
-
-    /**
-     * 视频录像
-     * @param DOM 
-     * @param TIME ms
-     * @returns 
-     */
-    public async capVideo(DOM: HTMLVideoElement, TIME: number) {
-        const recordedBlobs = [] as any
-        const MediaStream = DOM['srcObject'] as MediaStream
-        const mediaRecorder = new MediaRecorder(MediaStream, { mimeType: 'video/webm;codecs=h264' })
-        mediaRecorder.ondataavailable = (event: { data: { size: number } }) => {
-            if (event.data && event.data.size > 0) {
-                recordedBlobs.push(event.data);
-            }
-        }
-        mediaRecorder.start()
-        await this.sleep(TIME || 1000 * 3)
-        mediaRecorder.stop()
-        return await new Promise((resolve, reject) => {
-            mediaRecorder.onstop = () => {
-                const blob = new Blob(recordedBlobs, { type: 'video/mp4' });
-                resolve(blob)
-            }
-            mediaRecorder.onerror = reject
-        })
-    }
-
-    /**
-     * 关闭webrtc
-     */
-    public async close() {
-        if (this.Peer) this.Peer.close()
-        if (this.TIMER) clearTimeout(this.TIMER)
-    }
-
-}
-
-export default WebRtcPlayer

+ 0 - 70
src/utils/user-data.ts

@@ -1,70 +0,0 @@
-import MD5 from 'js-md5'
-interface userDATA {
-  lastLogin: number,
-  loginInfo: {
-    token: string
-  },
-}
-/**
- * 用户加密操作
- */
-class Userservice {
-  constructor() {
-    this.setTime()
-   }
-  /**
-   * 加密
-   * @param {string} txt 密码
-   */
-  encryPassword(txt: string) {
-    const password = MD5(txt)
-    return password
-  }
-  /**
-   * 存储
-   * @param {userDATA} params 参数
-   */
-  saveUserData(params: userDATA) {
-    const lastLogin = Date.now()
-    const uses = {
-      ...params,
-      lastLogin,
-      token: params.loginInfo.token || ''
-    }
-    const USERS = JSON.stringify(uses)
-    localStorage.setItem('userDATA', USERS)
-    return uses
-  }
-  /**
-   * 获取
-   */
-  getUserData() {
-    return JSON.parse(localStorage.getItem('userDATA') as string) || null
-  }
-  /**
-   * 时间限制24小时
-   */
-  async setTime() {
-    const nowtime = Date.now()
-    const data = this.getUserData()
-    if (data && data.lastLogin) {
-      if ((nowtime - data.lastLogin) > (1000 * 60 * 60 * 24)) {
-        localStorage.clear()
-        return false
-      } else {
-        return true
-      }
-    } else {
-      localStorage.clear()
-      return false
-    }
-  }
-
-  /** 
-   * 清楚数据
-   */
-  clear() {
-    localStorage.clear()
-  }
-}
-export default new Userservice()

File diff suppressed because it is too large
+ 0 - 13
src/utils/weather.ts


+ 9 - 1
src/vite-env.d.ts

@@ -1,9 +1,17 @@
 /// <reference types="vite/client" />
 
+/** 代指任意类型 请不要随意使用 */
+// eslint-disable-next-line no-unused-vars
+declare type Any = any
+
 declare module '*.vue' {
   import type { DefineComponent } from 'vue'
   const component: DefineComponent<{}, {}, any>
   export default component
 }
 
-declare module 'js-md5'
+declare module 'js-md5'
+declare module 'xlsx'
+declare module 'html2canvas'
+declare module 'jspdf'
+declare module '@/utils/*'

+ 1 - 0
vite.config.ts

@@ -1,3 +1,4 @@
+/* eslint-disable import/no-extraneous-dependencies */
 import { defineConfig, loadEnv } from 'vite'
 import vue from '@vitejs/plugin-vue'
 import eslint from 'vite-plugin-eslint'

Some files were not shown because too many files changed in this diff