From 4e201651d4a5ca76b66faba9e00f5ee2f9ae484f Mon Sep 17 00:00:00 2001
From: YM <479443481@qq.com>
Date: 星期三, 20 十一月 2024 15:27:54 +0800
Subject: [PATCH] 1

---
 src/assets/images/graffiti/rubber.png            |    0 
 src/assets/main.css                              |    4 
 src/assets/images/graffiti/save.png              |    0 
 src/assets/images/graffiti/scrub.png             |    0 
 src/main.ts                                      |    8 
 vite.config.ts                                   |   12 
 src/assets/js/middleGround/api/app.js            |   27 +
 src/components/graffiti/components/toolBtns.vue  |  106 +++++++++
 src/views/readerPages/webHome.vue                |   17 +
 src/assets/images/graffiti/revoke.png            |    0 
 src/components/graffiti/index.vue                |  243 ++++++++++++++++++++++
 index.html                                       |   27 +-
 package.json                                     |    8 
 src/components/graffiti/components/brushSize.vue |  113 ++++++++++
 src/views/components/formula.vue                 |   58 +++++
 src/assets/images/graffiti/brush.png             |    0 
 16 files changed, 597 insertions(+), 26 deletions(-)

diff --git a/index.html b/index.html
index a9a6a0f..465a048 100644
--- a/index.html
+++ b/index.html
@@ -1,14 +1,17 @@
 <!DOCTYPE html>
 <html lang="zh-cn">
-  <head>
-    <meta charset="UTF-8">
-    <link rel="icon" href="/favicon.ico">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline';"> -->
-    <title>鏁板瓧鏁欐潗闃呰鍣�</title>
-  </head>
-  <body>
-    <div id="parentApp"></div>
-    <script type="module" src="/src/main.ts"></script>
-  </body>
-</html>
+
+<head>
+  <meta charset="UTF-8">
+  <link rel="icon" href="/favicon.ico">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline';"> -->
+  <title>鏁板瓧鏁欐潗闃呰鍣�</title>
+</head>
+
+<body>
+  <div id="parentApp"></div>
+  <script type="module" src="/src/main.ts"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/package.json b/package.json
index 9f95fbc..1c1586a 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
+    "@vitejs/plugin-vue-jsx": "^4.0.0",
     "@vue-office/docx": "^1.6.1",
     "axios": "^1.6.2",
     "cross-env": "^7.0.3",
@@ -28,21 +29,24 @@
     "element-plus": "^2.4.3",
     "fabric": "^5.3.0",
     "js-web-screen-shot": "^1.9.9-rc.18",
+    "katex": "^0.16.11",
     "less": "^4.2.0",
     "less-loader": "^11.1.3",
+    "mathlive": "^0.101.0",
     "moment": "^2.30.1",
     "node-xlsx": "^0.23.0",
     "pinia": "^2.1.7",
     "qiankun": "^2.10.16",
     "spark-md5": "^3.0.2",
     "style-resources-loader": "^1.5.0",
+    "vatex": "^0.1.0",
+    "viewerjs": "^1.11.6",
     "vite-plugin-electron": "^0.15.5",
     "vue": "^3.3.10",
     "vue-cli-plugin-style-resources-loader": "^0.1.5",
     "vue-clipboard3": "^2.0.0",
     "vue-demi": "^0.14.7",
-    "vue-router": "^4.2.5",
-    "viewerjs": "^1.11.6"
+    "vue-router": "^4.2.5"
   },
   "devDependencies": {
     "@rushstack/eslint-patch": "^1.3.3",
diff --git a/src/assets/images/graffiti/brush.png b/src/assets/images/graffiti/brush.png
new file mode 100644
index 0000000..5f23599
--- /dev/null
+++ b/src/assets/images/graffiti/brush.png
Binary files differ
diff --git a/src/assets/images/graffiti/revoke.png b/src/assets/images/graffiti/revoke.png
new file mode 100644
index 0000000..97c4e20
--- /dev/null
+++ b/src/assets/images/graffiti/revoke.png
Binary files differ
diff --git a/src/assets/images/graffiti/rubber.png b/src/assets/images/graffiti/rubber.png
new file mode 100644
index 0000000..bf9955c
--- /dev/null
+++ b/src/assets/images/graffiti/rubber.png
Binary files differ
diff --git a/src/assets/images/graffiti/save.png b/src/assets/images/graffiti/save.png
new file mode 100644
index 0000000..f7b2421
--- /dev/null
+++ b/src/assets/images/graffiti/save.png
Binary files differ
diff --git a/src/assets/images/graffiti/scrub.png b/src/assets/images/graffiti/scrub.png
new file mode 100644
index 0000000..2ef004c
--- /dev/null
+++ b/src/assets/images/graffiti/scrub.png
Binary files differ
diff --git a/src/assets/js/middleGround/api/app.js b/src/assets/js/middleGround/api/app.js
index f7edc50..cf11cec 100644
--- a/src/assets/js/middleGround/api/app.js
+++ b/src/assets/js/middleGround/api/app.js
@@ -1,22 +1,29 @@
-import request from "@/plugin/axios/index.ts";
+import request from '@/plugin/axios/index.ts'
 const appApi = {
   // 鑾峰彇鐢ㄦ埛娑堟伅鍒楄〃
   getAppMessageList(data) {
     return request({
-      url: "/app/api/ApiGetAppMessageList",
-      method: "post",
+      url: '/app/api/ApiGetAppMessageList',
+      method: 'post',
       data
-    });
+    })
   },
   // 鑾峰彇鐢ㄦ埛娑堟伅璇︽儏
   getMessage(data) {
     return request({
-      url: "/app/api/ApiGetMessage",
-      method: "post",
+      url: '/app/api/ApiGetMessage',
+      method: 'post',
       data
-    });
+    })
   },
+  // ai璇嗗埆鍥剧墖涓殑鍏紡
+  getLatexFormulaFromImage(data) {
+    return request({
+      url: '/ai/api/GetLatexFormulaFromImage',
+      method: 'post',
+      data
+    })
+  }
+}
 
-};
-
-export default appApi;
+export default appApi
diff --git a/src/assets/main.css b/src/assets/main.css
index 659e1b2..422cb91 100644
--- a/src/assets/main.css
+++ b/src/assets/main.css
@@ -311,3 +311,7 @@
 .icon-tabler-arrow-bar-to-left,.icon-tabler-arrow-bar-to-right{
   color:#707070 !important;
 }
+
+body {
+  --keyboard-zindex: 999999;
+}
\ No newline at end of file
diff --git a/src/components/graffiti/components/brushSize.vue b/src/components/graffiti/components/brushSize.vue
new file mode 100644
index 0000000..ec5043a
--- /dev/null
+++ b/src/components/graffiti/components/brushSize.vue
@@ -0,0 +1,113 @@
+<template>
+  <div class="brushSize">
+    <!-- 涓轰簡涓嶅湪瀛愮粍浠朵腑鍙樻洿鍊硷紝涓嶇敤v-model -->
+     <div class="wrap-range">
+      <input
+      type="range"
+      :value="brushSize"
+      min="1"
+      max="30"
+      title="璋冩暣绗斿埛绮楃粏"
+      class="input-brush"
+      @change="(event) => $emit('change-size', +event.target.value)"
+    />
+     </div>
+
+    <!-- <el-color-picker v-model="checkColor" @change="onChangeColor"></el-color-picker> -->
+     <div>
+       <input type="color" v-model="checkColor" @input="onChangeColor">
+     </div>
+    
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    size: {
+      type: Number,
+      default: 5,
+    },
+  },
+  computed:{
+    brushSize() {
+      return this.size
+    }
+  },
+  data() {
+    return  {
+      checkColor:"#000000"
+    }
+  },
+  methods:{
+    onChangeColor(e) {
+      this.$emit("change-color", e.srcElement.value);
+    },
+  }
+};
+
+// const brushSize = computed(() => props.size);
+</script>
+<style lang="less" scoped>
+.brushSize {
+  display: flex;
+}
+.wrap-range {
+  display: flex;
+  align-items: center;
+  margin-right: 10px;
+  .el-color-picker {
+    margin-left: 20px;
+  }
+}
+.wrap-range input {
+  width: 150px;
+  height: 20px;
+  margin: 0;
+  transform-origin: 75px 75px;
+  border-radius: 15px;
+  -webkit-appearance: none;
+  appearance: none;
+  outline: none;
+  position: relative;
+}
+
+.wrap-range input::after {
+  display: block;
+  content: "";
+  width: 0;
+  height: 0;
+  border: 5px solid transparent;
+  border-right: 150px solid #00ccff;
+  border-left-width: 0;
+  position: absolute;
+  left: 0;
+  top: 5px;
+  border-radius: 15px;
+  z-index: 0;
+}
+
+.wrap-range input[type="range"]::-webkit-slider-thumb,
+.wrap-range input[type="range"]::-moz-range-thumb {
+  -webkit-appearance: none;
+}
+
+.wrap-range input[type="range"]::-webkit-slider-runnable-track,
+.wrap-range input[type="range"]::-moz-range-track {
+  height: 10px;
+  border-radius: 10px;
+  box-shadow: none;
+}
+
+.wrap-range input[type="range"]::-webkit-slider-thumb {
+  -webkit-appearance: none;
+  height: 20px;
+  width: 20px;
+  margin-top: -1px;
+  background: #ffffff;
+  border-radius: 50%;
+  box-shadow: 0 0 8px #00ccff;
+  position: relative;
+  z-index: 999;
+}
+</style>
diff --git a/src/components/graffiti/components/toolBtns.vue b/src/components/graffiti/components/toolBtns.vue
new file mode 100644
index 0000000..9f608cd
--- /dev/null
+++ b/src/components/graffiti/components/toolBtns.vue
@@ -0,0 +1,106 @@
+<template>
+  <div class="tools">
+    <button v-for="(item, index) of toolList" :key="index" :class="{ active: toolSelected === item.name }"
+      :title="item.title" @click="onChangeTool(item.name, index)"
+      :style="{ boxShadow: index == num ? '0 0 15px #00ccff' : '' }">
+      <img :src="item.icon" alt="" class="giaffiti-btn" :style="{ width: index == 0 ? '18px' : '' }" />
+    </button>
+  </div>
+</template>
+
+<script>
+  import brush from '@/assets/images/graffiti/brush.png'
+  import rubber from '@/assets/images/graffiti/rubber.png'
+  import scrub from '@/assets/images/graffiti/scrub.png'
+  import revoke from '@/assets/images/graffiti/revoke.png'
+  import save from '@/assets/images/graffiti/save.png'
+  export default {
+    props: {
+      tool: {
+        type: String,
+        default: "brush",
+      },
+    },
+    computed: {
+      toolSelected() {
+        return this.tool;
+      },
+    },
+    data() {
+      return {
+        toolList: [
+          {
+            name: "brush",
+            title: "鐢荤瑪",
+            icon: brush,
+          },
+          {
+            name: "eraser",
+            title: "姗$毊鎿�",
+            icon: rubber,
+          },
+          {
+            name: "clear",
+            title: "娓呯┖",
+            icon: scrub,
+          },
+          {
+            name: "undo",
+            title: "鎾ら攢",
+            icon: revoke,
+          },
+          {
+            name: "save",
+            title: "淇濆瓨",
+            icon: save,
+          },
+        ],
+        num: 0,
+      };
+    },
+    methods: {
+      onChangeTool(tool, index) {
+        if (index == 0 || index == 1) this.num = index;
+        this.$emit("change-tool", tool);
+      },
+    },
+  };
+</script>
+
+<style scoped>
+  .tools {
+    display: flex;
+    align-items: center;
+  }
+
+  .tools button {
+    /* border-radius: 50%; */
+    width: 32px;
+    height: 32px;
+    background-color: rgba(255, 255, 255, 0.7);
+    border: 1px solid #eee;
+    outline: none;
+    cursor: pointer;
+    box-sizing: border-box;
+    margin: 0 8px;
+    padding: 0;
+    text-align: center;
+    color: #ccc;
+    box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
+    transition: 0.3s;
+  }
+
+  .tools button.active,
+  .tools button:active {
+    /* box-shadow: 0 0 15px #00CCFF; */
+    color: #00ccff;
+  }
+
+  .tools button i {
+    font-size: 20px;
+  }
+
+  .giaffiti-btn {
+    width: 24px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/components/graffiti/index.vue b/src/components/graffiti/index.vue
new file mode 100644
index 0000000..4c8034a
--- /dev/null
+++ b/src/components/graffiti/index.vue
@@ -0,0 +1,243 @@
+<!-- 娑傝壊杩炵嚎棰樻帶浠� -->
+<template>
+  <div class="page">
+    <div class="main">
+      <div id="canvas_panel">
+        <canvas id="canvas" :style="{
+            backgroundSize: 'cover',
+            backgroundPosition: 'center',
+          }">褰撳墠娴忚鍣ㄤ笉鏀寔canvas銆�</canvas>
+      </div>
+    </div>
+    <div class="footer">
+      <BrushSize :size="brushSize" @change-size="onChangeSize" @change-color="onChangeColor" />
+      <ToolBtns :tool="brushTool" @change-tool="onChangeTool" />
+    </div>
+  </div>
+</template>
+
+<script>
+  import BrushSize from "./components/brushSize.vue";
+  import ToolBtns from "./components/toolBtns.vue";
+  export default {
+    name: "graffiti",
+    components: { BrushSize, ToolBtns },
+    props: {
+      save: {
+        type: Function,
+      },
+    },
+    data() {
+      return {
+        canvas: null,
+        context: null,
+        painting: false, // 璁板綍鐘舵�侊紝榧犳爣鏄惁鍦ㄦ寜涓嬬姸鎬�
+        historyData: [], // 瀛樺偍鍘嗗彶鏁版嵁锛岀敤浜庢挙閿�
+        brushSize: 2, // 绗斿埛澶у皬
+        brushColor: "#000000", // 绗斿埛棰滆壊
+        brushTool: "brush",
+        canvasOffset: {
+          left: 0,
+          top: 0,
+        },
+      };
+    },
+    mounted() {
+      this.canvas = (this.container ? this.container : document).getElementById(
+        "canvas"
+      );
+      if (this.canvas.getContext) {
+        this.context = this.canvas.getContext("2d", { willReadFrequently: true });
+        // window.addEventListener('resize', updateCanvasPosition);
+        (this.container ? this.container : document).addEventListener(
+          "scroll",
+          this.updateCanvasOffset,
+          true
+        ); // 娣诲姞婊氬姩鏉℃粴鍔ㄤ簨浠剁洃鍚櫒
+        this.getCanvasOffset();
+        this.context.lineGap = "round";
+        this.context.lineJoin = "round";
+        this.canvas.addEventListener("mousedown", this.downCallback);
+        this.canvas.addEventListener("mousemove", this.moveCallback);
+        this.canvas.addEventListener("mouseup", this.closePaint);
+        this.canvas.addEventListener("mouseleave", this.closePaint);
+        setTimeout(() => {
+          this.initCanvas();
+        }, 300);
+      }
+      this.toolClear();
+    },
+    methods: {
+      // 鍒濆鍖� 鐢诲竷锛岃缃ぇ灏忚儗鏅壊
+      initCanvas() {
+        const that = this;
+        const resetCanvas = () => {
+          const elPanel = (
+            this.container ? this.container : document
+          ).getElementById("canvas_panel");
+          console.log("clientWidth"+elPanel.clientWidth);
+          console.log("clientWidth"+elPanel.clientHeight);
+          try {
+            that.canvas.width = elPanel.clientWidth;
+            that.canvas.height = elPanel.clientHeight;
+          } catch (error) { }
+
+          that.context = that.canvas.getContext("2d", {
+            willReadFrequently: true,
+          }); // 娣诲姞杩欎竴琛�
+          that.context.fillStyle = "white";
+          that.context.fillRect(0, 0, that.canvas.width, that.canvas.height);
+          that.context.fillStyle = "black";
+          that.getCanvasOffset(); // 鏇存柊鐢诲竷浣嶇疆
+        };
+        resetCanvas();
+        // 鐩戝惉绐楀彛澶у皬 锛岀獥鍙f敼鍙橀噸鏂版覆鏌撶敾甯�
+        window.addEventListener("resize", resetCanvas);
+      },
+
+      // 鑾峰彇canvas鐨勫亸绉诲��
+      getCanvasOffset() {
+        const rect = this.canvas.getBoundingClientRect();
+        this.canvasOffset.left = rect.left * (this.canvas.width / rect.width); // 鍏煎缂╂斁鍦烘櫙
+        this.canvasOffset.top = rect.top * (this.canvas.height / rect.height);
+      },
+
+      // 璁$畻褰撳墠榧犳爣鐩稿浜巆anvas鐨勫潗鏍�
+      calcRelativeCoordinate(x, y) {
+        return {
+          x: x - this.canvasOffset.left,
+          y: y - this.canvasOffset.top,
+        };
+      },
+      // 榧犳爣鎶捣鏂规硶
+      downCallback(event) {
+        // 鍏堜繚瀛樹箣鍓嶇殑鏁版嵁锛岀敤浜庢挙閿�鏃舵仮澶嶏紙缁樺埗鍓嶄繚瀛橈紝涓嶆槸缁樺埗鍚庡啀淇濆瓨锛�
+        const data = this.context.getImageData(
+          0,
+          0,
+          this.canvas.width,
+          this.canvas.height
+        );
+        this.saveData(data);
+        const { clientX, clientY } = event;
+        const { x, y } = this.calcRelativeCoordinate(clientX, clientY);
+        this.context.beginPath();
+        this.context.moveTo(x, y);
+        this.context.lineWidth = this.brushSize;
+        this.context.strokeStyle =
+          this.brushTool === "eraser" ? "#FFFFFF" : this.brushColor;
+        this.painting = true;
+      },
+      // 榧犳爣绉诲姩鏂规硶(璁$畻鍧愭爣骞舵覆鏌撹建杩�)
+      moveCallback(event) {
+        if (!this.painting) {
+          return;
+        }
+        const { clientX, clientY } = event;
+        const { x, y } = this.calcRelativeCoordinate(clientX, clientY);
+        this.context.lineTo(x, y);
+        this.context.stroke();
+      },
+      closePaint() {
+        this.painting = false;
+      },
+      // 閲嶆柊璁$畻鐢诲竷鐨勫亸绉诲��
+      updateCanvasOffset() {
+        this.getCanvasOffset();
+      },
+      // 鏀瑰彉绗斿埛澶у皬
+      onChangeSize(size) {
+        this.brushSize = size;
+      },
+      // 鏀瑰彉绗斿埛棰滆壊
+      onChangeColor(color) {
+        this.brushColor = color;
+      },
+      // 淇濆瓨锛屾竻绌虹瓑鎸夐挳
+      onChangeTool(tool) {
+        this.brushTool = tool;
+        switch (tool) {
+          case "clear":
+            this.toolClear();
+            break;
+          case "undo":
+            this.toolUndo();
+            break;
+          case "save":
+            this.toolSave();
+            break;
+        }
+      },
+      // 娓呯┖canvas鎵�鏈夊唴瀹�(鑳屾櫙鍥鹃櫎澶�)
+      toolClear() {
+        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+        this.resetToolActive();
+      },
+      // 淇濆瓨鐢诲竷鑳屾櫙鍜屽垝绾垮埌鏈湴鏂规硶
+      toolSave() {
+        var imgData = this.canvas.toDataURL('image/jpeg');
+        console.log(imgData);
+        if (this.save) {
+          this.save(imgData);
+        }
+      },
+      // 杩斿洖涓婁竴姝ユ柟娉�(鎾ら攢)
+      toolUndo() {
+        if (this.historyData.length <= 0) {
+          this.resetToolActive();
+          return;
+        }
+        // 灏嗙敾鐨勪笂涓�姝ユ暟鎹啓鍏anvas 閲嶆柊娓叉煋
+        const lastIndex = this.historyData.length - 1;
+        this.context.putImageData(this.historyData[lastIndex], 0, 0);
+        this.historyData.pop();
+        this.resetToolActive();
+      },
+      // 瀛樺偍鏁版嵁
+      saveData(data) {
+        this.historyData.length >= 50 && this.historyData.shift(); // 璁剧疆鍌ㄥ瓨涓婇檺涓�50姝�
+        this.historyData.push(data);
+      },
+      // 娓呴櫎銆佹挙閿�銆佷繚瀛樼姸鎬佷笉闇�瑕佷繚鎸侊紝鎿嶄綔瀹屽悗鎭㈠绗斿埛鐘舵��
+      resetToolActive() {
+        setTimeout(() => {
+          this.brushTool = "brush";
+        }, 1000);
+      },
+    },
+  };
+</script>
+
+<style scoped>
+  .page {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+    height: 100%;
+  }
+
+  .main {
+    flex: 1;
+  }
+
+  .footer {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    height: 88px;
+  }
+
+  #canvas_panel {
+    width: 100%;
+    height: 100%;
+    margin-bottom: 12px;
+    /* 娑堥櫎绌烘牸褰卞搷 */
+    font-size: 0;
+    background-color: #fff;
+    border-bottom: 1px solid #ccc;
+  }
+  
+  #canvas {
+    cursor: crosshair;
+  }
+</style>
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
index de5d30d..43ec77a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -12,6 +12,12 @@
 import './child.ts'
 import { loginCtx } from '@/assets/js/config.ts'
 
+// 鍏紡杈撳叆
+import { MathfieldElement } from "mathlive"
+// 鍏紡瑙f瀽
+import VueLatex from 'vatex'
+
+
 const handleGetToken = () => {
   return localStorage.getItem('token')
 }
@@ -77,8 +83,10 @@
 
 const app = createApp(App)
 
+
 app.provide('toolClass', toolClass)
 app.provide('MG', MG)
+app.use(VueLatex)
 app.use(router)
 app.use(ElementPlus)
 app.use(pinia)
diff --git a/src/views/components/formula.vue b/src/views/components/formula.vue
new file mode 100644
index 0000000..9e3b39f
--- /dev/null
+++ b/src/views/components/formula.vue
@@ -0,0 +1,58 @@
+<template>
+  <div>
+    <h2>鎵嬪啓璇嗗埆</h2>
+    <div class="box" style="width: 100%;height: 400px;">
+      <graffiti :save="save" />
+    </div>
+    <div>
+      <p>璇嗗埆缁撴灉锛�</p>
+
+      <div id="showData">
+        <vue-latex :expression="content" display-mode />
+      </div>
+    </div>
+    <h2>鍏紡杈撳叆</h2>
+    <math-field class="mathField" @input="handleInput" :menuItems="[]"></math-field>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { ref, nextTick, reactive, watch, onMounted, onBeforeMount, onBeforeUnmount, inject } from 'vue'
+  import { MathfieldElement } from "mathlive"
+  import graffiti from '@/components/graffiti/index.vue'
+  const commonsVariable: any = inject('commonsVariable')
+  const MG: any = inject('MG')
+  const handleInput = (...data) => {
+    console.log(data);
+  }
+
+  const content = ref('')
+  const save = (data) => {
+    console.log(data.split(",")[1]);
+    MG.app
+      .getLatexFormulaFromImage({
+        base64Jpg: data.split(",")[1]
+      })
+      .then((res: any) => {
+        content.value = res;
+        nextTick(() => {
+          
+        })
+      })
+  }
+
+</script>
+
+<style lang="less">
+  .mathField {
+    width: 500px;
+    margin-top: 10px;
+  }
+
+  #showData {
+    border: 1px solid #ccc;
+    padding: 20px;
+    margin-top: 10px;
+    margin-bottom: 50px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/readerPages/webHome.vue b/src/views/readerPages/webHome.vue
index e4f1f31..3ba1680 100644
--- a/src/views/readerPages/webHome.vue
+++ b/src/views/readerPages/webHome.vue
@@ -8,6 +8,7 @@
         <div class="userName" v-if="userInfo.name">{{ userInfo.name }}</div>
         <div v-if="token"><div class="layout hover" @click="layoutBtn">閫�鍑�</div></div>
         <div v-else><div class="layout hover" @click="goLogin">鐧诲綍</div></div>
+        <div @click="openFormulaDialog">鍏紡</div>
       </div>
     </div>
     <div class="contentBox">
@@ -1238,6 +1239,16 @@
       <wrongQuestion />
     </div>
   </el-dialog>
+  <el-dialog
+    title="鍏紡缂栬緫"
+    align-center
+    v-model="formulaDialog"
+    class="myDialogs"
+  >
+    <div class="wendabox">
+      <formula />
+    </div>
+  </el-dialog>
   <!-- 绛旈鍣� -->
   <examination
     ref="examinationRef"
@@ -1271,6 +1282,7 @@
 import moment from 'moment'
 import dictionary from '@/views/components/dictionary.vue'
 import newWord from '@/views/components/newWord.vue'
+import formula from '@/views/components/formula.vue'
 import wrongQuestion from '@/views/components/wrongQuestion.vue'
 import voiceReader from '@/views/components/voiceReader.vue'
 import { ElMessage, ElMessageBox, valueEquals } from 'element-plus'
@@ -4028,6 +4040,11 @@
     })
   }
 }
+
+const formulaDialog = ref(false)
+const openFormulaDialog = () => {
+  formulaDialog.value = true
+}
 </script>
 
 <style lang="less">
diff --git a/vite.config.ts b/vite.config.ts
index 2f5b6f7..ecb6c57 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -2,13 +2,21 @@
 
 import { defineConfig } from 'vite'
 import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx';
 import electron from 'vite-plugin-electron'
 
 // https://vitejs.dev/config/
 export default defineConfig({
   base:"./",
   plugins: [
-    vue(),
+    vueJsx(),
+    vue({
+      template: {
+        compilerOptions: {
+          isCustomElement: (tag) => tag.includes('math-field')
+        }
+      }
+    }),
     // electron({
     //   // 閰嶇疆 Electron 鍏ュ彛鏂囦欢
     //   entry: 'electron-commonJS/main.js'
@@ -39,5 +47,5 @@
         additionalData: '@import "./src/assets/style/global.less";'
       }
     }
-  }
+  },
 })

--
Gitblit v1.9.1