Michael Wang vor 4 Jahren
Ursprung
Commit
b837fc9484

+ 100 - 0
src/components/QmDialog.vue

@@ -0,0 +1,100 @@
+<template>
+  <teleport to="body">
+    <div class="dialog-container" :style="positionStyle">
+      <header
+        ref="mouseHandler"
+        class="tw-flex tw-place-content-between"
+        @mousedown="handleMouseDown"
+      >
+        <div class="tw-text-2xl tw-cursor-move">{{ title }}</div>
+        <a-button shape="circle" @click="close">
+          <template #icon><CloseOutlined /></template>
+        </a-button>
+      </header>
+
+      <div class="tw-m-1">
+        <slot></slot>
+      </div>
+    </div>
+  </teleport>
+</template>
+
+<script lang="ts">
+import { store } from "@/features/mark/store";
+import { defineComponent, reactive, ref } from "vue";
+import { CloseOutlined } from "@ant-design/icons-vue";
+
+export default defineComponent({
+  components: { CloseOutlined },
+  props: {
+    title: { type: String, default: "" },
+    top: { type: String, default: "10%" },
+  },
+  setup({ top }) {
+    const close = () => {
+      store.setting.uiSetting["answer.paper.modal"] = false;
+    };
+
+    const positionStyle = reactive({
+      top: top,
+      left: "10%",
+    });
+
+    const mouseHandler = ref((null as unknown) as HTMLHeadElement);
+
+    const mousePosition = {
+      offsetX: 0,
+      offsetY: 0,
+    };
+
+    const handleMouseDown = (e: MouseEvent) => {
+      mouseHandler.value.addEventListener("mousemove", handleMouseMove);
+      mouseHandler.value.addEventListener("mouseup", handleMouseUp);
+      // console.log(e);
+      const { offsetX, offsetY } = e;
+      mousePosition.offsetX = offsetX;
+      mousePosition.offsetY = offsetY;
+    };
+    const handleMouseMove = (e: MouseEvent) => {
+      const { pageX, pageY, clientX, clientY } = e;
+      const windowWidth = window.innerWidth;
+      const windowHeight = window.innerHeight;
+      const newXRatio = (clientX - mousePosition.offsetX) / windowWidth;
+      const newYRatio = (clientY - mousePosition.offsetY) / windowHeight;
+      // console.log({
+      //   offsetX: mousePosition.offsetX,
+      //   pageX,
+      //   offsetY: mousePosition.offsetY,
+      //   pageY,
+      //   newYRatio,
+      //   newXRatio,
+      // });
+      positionStyle.top = newYRatio * 100 + "%";
+      positionStyle.left = newXRatio * 100 + "%";
+    };
+    const handleMouseUp = (e: MouseEvent) => {
+      mouseHandler.value.removeEventListener("mousemove", handleMouseMove);
+      mouseHandler.value.removeEventListener("mouseup", handleMouseUp);
+    };
+    return {
+      close,
+      positionStyle,
+      mouseHandler,
+      handleMouseDown,
+      handleMouseMove,
+      handleMouseUp,
+    };
+  },
+});
+</script>
+
+<style scoped>
+.dialog-container {
+  z-index: 9000;
+  position: absolute;
+  min-width: 100px;
+  background-color: white;
+  border: 1px solid grey;
+  border-radius: 5px;
+}
+</style>

+ 21 - 0
src/features/mark/AnswerModal.vue

@@ -0,0 +1,21 @@
+<template>
+  <qm-dialog
+    v-if="store.setting.uiSetting['answer.paper.modal']"
+    ref="dialog"
+    title="答案"
+  >
+    my answer
+  </qm-dialog>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from "vue";
+import { store } from "./store";
+
+export default defineComponent({
+  name: "AnswerModal",
+  setup() {
+    return { store };
+  },
+});
+</script>

+ 3 - 0
src/features/mark/Mark.vue

@@ -21,6 +21,7 @@
       />
     </div>
   </div>
+  <AnswerModal />
 </template>
 
 <script lang="ts">
@@ -50,6 +51,7 @@ import MarkBoardKeyBoard from "./MarkBoardKeyBoard.vue";
 import MarkBoardMouse from "./MarkBoardMouse.vue";
 import { isEmpty, isNumber } from "lodash";
 import { message } from "ant-design-vue";
+import AnswerModal from "./AnswerModal.vue";
 
 export default defineComponent({
   name: "Mark",
@@ -60,6 +62,7 @@ export default defineComponent({
     MarkBoardTrack,
     MarkBoardKeyBoard,
     MarkBoardMouse,
+    AnswerModal,
   },
   setup: () => {
     const { addInterval } = useTimers();

+ 8 - 0
src/features/mark/MarkHeader.vue

@@ -115,6 +115,14 @@
     <a-popover title="小助手" trigger="hover" class="tw-cursor-pointer">
       <template #content>
         <table class="assistant-table">
+          <tr>
+            <td>答案</td>
+            <td>
+              <a-switch
+                v-model:checked="store.setting.uiSetting['answer.paper.modal']"
+              />
+            </td>
+          </tr>
           <tr>
             <td>全卷</td>
             <td><a-switch v-model:checked="allPaperChecked" /></td>

+ 1 - 0
src/features/mark/store.ts

@@ -17,6 +17,7 @@ const obj = {
       "answer.paper.scale": 1,
       "score.board.collapse": false,
       "normal.mode": "keyboard",
+      "answer.paper.modal": false,
     },
     statusValue: "FORMAL",
     problemTypes: [],

+ 2 - 0
src/main.ts

@@ -7,6 +7,7 @@ import filters from "@/filters";
 import Antd from "ant-design-vue";
 import "ant-design-vue/dist/antd.css";
 import QmButton from "@/components/QmButton.vue";
+import QmDialog from "@/components/QmDialog.vue";
 
 // if(process.env.NODE_ENV)
 // console.log(import.meta.env.DEV);
@@ -16,6 +17,7 @@ app.use(Antd);
 app.config.globalProperties.$filters = filters;
 
 app.component("qm-button", QmButton);
+app.component("qm-dialog", QmDialog);
 
 if (import.meta.env.DEV) {
   initLogin().then(() => {

+ 1 - 0
src/styles/global.css

@@ -6,6 +6,7 @@ body {
   font-size: 14px;
   min-width: 1024px;
   min-height: 600px;
+  user-select: none;
 }
 
 .ant-message-custom-content span[role="img"] {

+ 1 - 0
src/types/index.ts

@@ -144,6 +144,7 @@ export interface UISetting {
   "score.board.collapse": boolean;
   "answer.paper.scale": number; // 0.2 gap
   "normal.mode": "keyboard" | "mouse";
+  "answer.paper.modal": boolean;
 }
 
 export interface MarkResult {