kindring 9 months ago
parent
commit
6030d27bb9

+ 60 - 0
package-lock.json

@@ -8,6 +8,7 @@
       "name": "fc-ele",
       "version": "0.0.0",
       "dependencies": {
+        "@headlessui/vue": "^1.7.22",
         "vuedraggable": "^4.1.0"
       },
       "devDependencies": {
@@ -1228,6 +1229,20 @@
       "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
       "dev": true
     },
+    "node_modules/@headlessui/vue": {
+      "version": "1.7.22",
+      "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.22.tgz",
+      "integrity": "sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==",
+      "dependencies": {
+        "@tanstack/vue-virtual": "^3.0.0-beta.60"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
     "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -1886,6 +1901,30 @@
         "node": ">=10"
       }
     },
+    "node_modules/@tanstack/virtual-core": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.1.tgz",
+      "integrity": "sha512-046+AUSiDru/V9pajE1du8WayvBKeCvJ2NmKPy/mR8/SbKKrqmSbj7LJBfXE+nSq4f5TBXvnCzu0kcYebI9WdQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      }
+    },
+    "node_modules/@tanstack/vue-virtual": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.5.1.tgz",
+      "integrity": "sha512-6mc4HtDPieDVKD6GqzHiJkdzuqRNdQZuoIbkwE6af939WV+w62YmSF69jN+BOqClqh/ObiW+X1VOQx1Pftrx1A==",
+      "dependencies": {
+        "@tanstack/virtual-core": "3.5.1"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      },
+      "peerDependencies": {
+        "vue": "^2.7.0 || ^3.0.0"
+      }
+    },
     "node_modules/@tootallnate/once": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -11014,6 +11053,14 @@
       "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
       "dev": true
     },
+    "@headlessui/vue": {
+      "version": "1.7.22",
+      "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.22.tgz",
+      "integrity": "sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==",
+      "requires": {
+        "@tanstack/vue-virtual": "^3.0.0-beta.60"
+      }
+    },
     "@isaacs/cliui": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -11518,6 +11565,19 @@
         "defer-to-connect": "^2.0.0"
       }
     },
+    "@tanstack/virtual-core": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.1.tgz",
+      "integrity": "sha512-046+AUSiDru/V9pajE1du8WayvBKeCvJ2NmKPy/mR8/SbKKrqmSbj7LJBfXE+nSq4f5TBXvnCzu0kcYebI9WdQ=="
+    },
+    "@tanstack/vue-virtual": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.5.1.tgz",
+      "integrity": "sha512-6mc4HtDPieDVKD6GqzHiJkdzuqRNdQZuoIbkwE6af939WV+w62YmSF69jN+BOqClqh/ObiW+X1VOQx1Pftrx1A==",
+      "requires": {
+        "@tanstack/virtual-core": "3.5.1"
+      }
+    },
     "@tootallnate/once": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
     "vue-tsc": "^1.8.5"
   },
   "dependencies": {
+    "@headlessui/vue": "^1.7.22",
     "vuedraggable": "^4.1.0"
   }
 }

+ 2 - 2
plugins/devPlugin.ts

@@ -31,8 +31,8 @@ export let devPlugin = () => {
             server.httpServer?.once("listening", () => {
                 let { spawn } = require("child_process");
                 let addressInfo = server.httpServer?.address() as any;
-                console.log(server);
-                console.log(addressInfo);
+                // console.log(server);
+                // console.log(addressInfo);
                 if (addressInfo.address == "0.0.0.0"){
                     addressInfo.address = "127.0.0.1"
                 }

+ 5 - 0
src/apis/ApiAction.ts

@@ -0,0 +1,5 @@
+export enum Magnet_Actions {
+  magnet_list = 'magnet_list',
+  magnet_batch_update = 'magnet_batch_update',
+  magnet_delete = 'magnet_delete',
+}

+ 58 - 2
src/apis/magnetControl.ts

@@ -1,3 +1,59 @@
-function getMagnetList(){
+import api from "./baseApi.ts"
+import {Magnet_Actions} from "./ApiAction.ts";
+import {ErrorCode, ResponseData} from "@/types/apiTypes.ts";
+import {Magnet, SavedMagnet} from "@/types/magnetType.ts";
+import {savedMagnets2Magnets} from "@/components/magnets/magnetInfo.ts";
 
-}
+function _magnet2savedMagnet(magnet: Magnet): SavedMagnet {
+   return {
+      id: magnet.id,
+      type: magnet.type,
+      size: magnet.size,
+      x: magnet.x,
+      y: magnet.y,
+   }
+}
+
+
+
+/**
+ * 获取磁贴信息
+ * @returns {Promise<ResponseData<SavedMagnet[]> | ResponseData<null>>}
+  */
+export async function fetchMagnetList(): Promise< ResponseData<Magnet[]> >
+{
+   let [_callId, promise] = api.sendQuery(Magnet_Actions.magnet_list, {});
+   let response = await promise;
+   if (response.code === ErrorCode.success) {
+      let arr = response.data as SavedMagnet[];
+      response.data = savedMagnets2Magnets(arr)
+      return response;
+   }
+   response.data = [];
+   return response;
+}
+
+/**
+ * 更新磁贴信息
+ * @param {Magnet[]} magnetList
+ */
+export async function changeMagnets(magnetList: Magnet[])
+{
+   let savedMagnets: SavedMagnet[] = magnetList.map(_magnet2savedMagnet);
+   let [_callId, promise] = api.sendQuery(Magnet_Actions.magnet_batch_update, {
+      magnetList: savedMagnets
+   });
+   return await promise;
+}
+
+/**
+ * 删除磁贴信息
+ * @param magnetId
+ */
+export async function deleteMagnet(magnetId: string)
+{
+   let [_callId, promise] = api.sendQuery(Magnet_Actions.magnet_delete, {
+      magnetId: magnetId
+   });
+   return await promise;
+}

+ 111 - 0
src/assets/base.css

@@ -191,3 +191,114 @@
 }
 
 
+
+.dialog{
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    top: 0;
+    left: 0;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+.dialog-mask::before{
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.4);
+}
+
+.dialog-content{
+    width: 80%;
+    height: 80%;
+    background-color: #fff;
+    border-radius: 5px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+    position: relative;
+    overflow: hidden;
+}
+
+.modal-content{
+    width: auto;
+    height: auto;
+    padding: 10px;
+    background-color: #fff;
+    border-radius: 5px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+    box-sizing: border-box;
+    position: relative;
+}
+
+
+.dialog-title{
+    width: 100%;
+    height: 30px;
+    display: flex;
+    justify-content: space-between;
+    box-sizing: border-box;
+    padding: 0 5px;
+    align-items: center;
+}
+
+.dialog-content .dialog-show{
+    width: 100%;
+    height: calc(100% - 30px);
+    overflow: auto;
+    box-sizing: border-box;
+    padding: 5px;
+}
+
+
+.site{
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+.site-content-left{
+    position: absolute;
+    width: 60%;
+    height: 100%;
+    background-color: #fff;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+}
+.site-content-bottom{
+    position: absolute;
+    width: 100%;
+    height: 80%;
+    background-color: #fff;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+    bottom: 0;
+    left: 0;
+}
+
+
+
+.close-btn{
+    width: 20px;
+    height: 20px;
+    border-radius: 50%;
+    cursor: pointer;
+    background-color: #e74c3c;
+    color: #fff;
+    display: flex;
+    padding: 0px;
+    font-size: 0.8rem;
+    justify-content: center;
+    align-items: center;
+    transition: all 0.3s;
+}
+.close-btn:hover, .close-btn:focus{
+    outline: none;
+    background-color: #c0392b;
+    color: #fff;
+    transform: rotate(180deg);
+}
+
+
+

+ 1 - 1
src/common/appConfig.ts

@@ -52,7 +52,7 @@ function _saveProjectConfig(config: AppConfig): boolean {
         // 判断目录是否存在
         if(!fs.existsSync(path.dirname(configPath))){
             logger.info("创建默认配置文件");
-            fs.mkdirSync(path.dirname(configPath));
+            fs.mkdirSync(path.dirname(configPath), {recursive: true});
         }
         fs.writeFileSync(configPath, JSON.stringify(config));
         return true;

+ 85 - 49
src/components/magnetView.vue

@@ -1,19 +1,16 @@
 <script setup lang="ts">
-import {reactive, ref, watch} from "vue";
+import {onBeforeMount, reactive, ref, watch} from "vue";
+import { Dialog, DialogPanel, DialogTitle, TransitionRoot  } from '@headlessui/vue'
 import TimeMagnet from "@/components/magnets/timeMagnet.vue";
 import vueDrag, {MoveInfo} from "@/components/public/vueDrag.vue";
-import {Magnet, MagnetEmit, MagnetSize} from "@/types/magnetType.ts";
-import {
-  comMaxWidth,
-  computeMagnetStyle,
-  computeStyle,
-  comXY,
-  initTimeMagnetInfo
-} from "@/components/magnets/magnetInfo.ts";
+import {Magnet, MagnetEmit} from "@/types/magnetType.ts";
+import {comMaxWidth, computeMagnetStyle, comXY, initTimeMagnetInfo} from "@/components/magnets/magnetInfo.ts";
 
 import {Calendar} from "@/util/time.ts";
 import {CollisionDirection, CollisionResult, detectCollisionDirection, Drag, Rect} from "@/util/domDrag.ts";
 import IconSvg from "@/components/public/icon/iconSvg.vue";
+import {fetchMagnetList} from "@/apis/magnetControl.ts";
+import {ErrorCode, ResponseData} from "@/types/apiTypes.ts";
 
 const timeMagnetInfo = initTimeMagnetInfo(TimeMagnet)
 
@@ -21,49 +18,27 @@ const typeComponent = {
   [timeMagnetInfo.type]: timeMagnetInfo.component
 }
 
-const magnetItemInfos: Magnet[] = [
-  {
-    id: `1`,
-    type: timeMagnetInfo.type,
-    x: 0,
-    y: 0,
-    width: timeMagnetInfo.sizes.medium?.width??0,
-    height: timeMagnetInfo.sizes.medium?.height??0,
-    size: MagnetSize.medium,
-    editMode: false,
-    selected: false,
-    changed: false,
-  },
-  {
-    id: `233`,
-    type: timeMagnetInfo.type,
-    x: 7,
-    y: 10,
-    width: timeMagnetInfo.sizes.small?.width??0,
-    height: timeMagnetInfo.sizes.small?.height??0,
-    size: MagnetSize.small,
-    editMode: false,
-    selected: false,
-    changed: false,
-  },
-  {
-    id: `2323`,
-    type: timeMagnetInfo.type,
-    x: 5,
-    y: 20,
-    width: timeMagnetInfo.sizes.small?.width??0,
-    height: timeMagnetInfo.sizes.small?.height??0,
-    size: MagnetSize.small,
-    editMode: false,
-    selected: false,
-    changed: false,
-  }
-];
 
-const magnetItems = reactive(magnetItemInfos)
+
+const magnetItems = reactive([]) as Magnet[]
 const magnetEl = ref();
 let maxWidth = 10;
 
+
+async function loadMagnetList() {
+  let response: ResponseData<Magnet[]> = await fetchMagnetList()
+  if (response.code !== ErrorCode.success) {
+    console.log(response.msg)
+    return;
+  }
+  let _MagnetItems = response.data;
+  magnetItems.splice(0, magnetItems.length, ..._MagnetItems)
+}
+
+onBeforeMount(() => {
+  loadMagnetList()
+})
+
 function daySelect(calendar: Calendar){
   console.log(`选择日期 ${calendar.year}年 ${calendar.month}月 ${calendar.day}日`)
 }
@@ -258,6 +233,21 @@ function deleteMagnet(magnet: Magnet) {
 }
 
 
+
+const isOpen = ref(false)
+function setIsOpen(value: boolean = false) {
+  isOpen.value = value
+  if (value)
+  {
+    setIsSite(false)
+  }
+}
+
+const isSite = ref(false)
+function setIsSite(value: boolean = false) {
+  isSite.value = value
+}
+
 </script>
 
 <template>
@@ -298,11 +288,57 @@ function deleteMagnet(magnet: Magnet) {
 
 <!--    编辑模式下的按钮控件 -->
     <div class="edit-control" v-if="editMode">
-      <div class="apple-btn mx-0.5">
+      <div class="apple-btn mx-0.5" @click="setIsOpen(true)">
         <icon-svg icon-name="add"></icon-svg>
       </div>
       <div class="apple-btn mx-0.5" @click="()=>{emit('editModeChange')}"> 完成</div>
     </div>
+
+
+    <TransitionRoot
+        :show="isOpen"
+        as="template"
+        enter="transition duration-300 ease-out"
+        enter-from="opacity-0"
+        enter-to="opacity-100"
+        leave="transition duration-200 ease-in"
+        leave-from="opacity-100"
+        leave-to="opacity-0"
+    >
+    <Dialog class="dialog" >
+      <DialogPanel class="dialog-content">
+        <DialogTitle class="dialog-title">
+          <span>新增磁贴</span>
+          <button class="close-btn" @click="setIsOpen(false)">
+            X
+          </button>
+        </DialogTitle>
+        <div class="dialog-show">
+<!--          磁贴组件选择列表-->
+          <TransitionRoot
+              class="site"
+              :show="isSite"
+              enter="transition ease-in-out duration-700 transform"
+              enterFrom="translate-y-full"
+              enterTo="translate-y-0"
+              leave="transition ease-in-out duration-700 transform"
+              leaveFrom="translate-y-0"
+              leaveTo="translate-y-full"
+          >
+            <div className="site-content-bottom">
+              测试
+              <button class="close-btn" @click="setIsSite(false)">
+                X
+              </button>
+            </div>
+          </TransitionRoot >
+          <button @click="setIsSite(true)">开启侧边栏</button>
+          <button @click="setIsOpen(false)">Cancel</button>
+        </div>
+
+      </DialogPanel>
+    </Dialog>
+  </TransitionRoot>
   </div>
 </template>
 

+ 43 - 2
src/components/magnets/magnetInfo.ts

@@ -1,7 +1,8 @@
 
 // import {App} from "vue";
 
-import {Magnet, MagnetInfo, MagnetSize} from "@/types/magnetType.ts";
+import {Magnet, MagnetInfo, MagnetSize, SavedMagnet} from "@/types/magnetType.ts";
+
 
 
 const cellWidth = 50;
@@ -28,14 +29,53 @@ export const timeMagnetInfo: MagnetInfo =
     component: null
 }
 
+const magnetInfos: MagnetInfo[] =
+[
+    timeMagnetInfo
+]
 
-
+/**
+ * 初始化时间磁贴组件
+ * @param component
+ */
 export function initTimeMagnetInfo(component: any): MagnetInfo{
     timeMagnetInfo.component = component
     return timeMagnetInfo
 }
 
+function _findMagnetInfo(type: string): MagnetInfo
+{
+    let _magnetInfo = magnetInfos.find(magnetInfo => magnetInfo.type === type)
+    if (!_magnetInfo) {
+        throw new Error(`magnetInfo not found: ${type}`)
+    }
+    return _magnetInfo
+}
+function  _savedMagnet2Magnet(savedMagnet: SavedMagnet) : Magnet
+{
+    let magnetInfo = _findMagnetInfo(savedMagnet.type)
+    let size = magnetInfo.sizes[savedMagnet.size] || magnetInfo.sizes[magnetInfo.defaultSize]
+    if (!size) {
+        throw new Error(`magnetInfo size not found: ${savedMagnet.type} ${savedMagnet.size} magnet must have size`)
+    }
+    return {
+        id: savedMagnet.id,
+        type: savedMagnet.type,
+        size: savedMagnet.size,
+        x: savedMagnet.x,
+        y: savedMagnet.y,
+        width: size.width,
+        height: size.height,
+        event: magnetInfo.event,
+        selected: false,
+        changed: false,
+    }
+}
 
+export function savedMagnets2Magnets(savedMagnets: SavedMagnet[]): Magnet[]{
+    let arr = savedMagnets.map(savedMagnet => _savedMagnet2Magnet(savedMagnet))
+    return arr
+}
 
 export function computeMagnetStyle(magnet: Magnet) {
     // console.log(magnet)
@@ -46,6 +86,7 @@ export function computeMagnetStyle(magnet: Magnet) {
 
 
 
+
 export function computeStyle(w: number, h: number, x: number, y: number, sub: boolean = false) {
     let _w = cellWidth * w + (cellMargin * w - cellMargin);
     let _h = cellWidth * h + (cellMargin * h  - cellMargin);

+ 35 - 6
src/components/window/macWindow.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import {ComponentInternalInstance, getCurrentInstance, Ref, ref, UnwrapRef} from "vue";
+import {ComponentInternalInstance, getCurrentInstance, onBeforeMount, onMounted, Ref, ref, UnwrapRef} from "vue";
 import { IpcAction, windowAction} from "../../tools/IpcCmd.ts";
 
 import "@/assets/base.css"
@@ -27,13 +27,41 @@ const switchFullHandle = () => {
 const btnClickHandel = (action: IpcAction) => {
   proxy?.$winHandle(action)
 }
+
+const mainWindow = ref<HTMLDivElement >()
+const dragBar = ref<HTMLDivElement >()
+onMounted(()=>{
+  const el = mainWindow.value as HTMLElement
+  const drag = dragBar.value as HTMLElement
+  if(!el || !drag){
+    console.log("窗口dom未找到")
+    return
+  }
+  el.addEventListener('mouseenter', () => {
+    console.log("鼠标进入窗口")
+    proxy?.$winHandle(windowAction.disableIgnoreMouse);
+  });
+  el.addEventListener('mouseleave', (evt: MouseEvent) => {
+    // 判断触发的dom
+    // tips 判断鼠标是否真的移出了指定的dom窗口, 在内部有元素设置了drag属性的情况下, 鼠标会被视作离开窗口
+    // 1. 获取元素的区域位置,
+    let { left, top, width, height } = el.getBoundingClientRect();
+
+    if (evt.pageX < left || evt.pageX > left + width || evt.pageY < top || evt.pageY > top + height) {
+      console.log("鼠标离开窗口")
+      proxy?.$winHandle(windowAction.enableIgnoreMouse);
+    }
+  });
+
+})
+
 </script>
 
 <template>
-  <div :class="[isFull? 'max_window': 'min_window']">
+  <div :class="[isFull? 'max_window': 'min_window']" ref="mainWindow">
     <div class="window">
       <div class="top-bar">
-        <div class="drag top-title" >
+        <div class="drag top-title" ref="dragBar">
           <slot name="top">
             <icon-svg  :icon-name="icon"/>
             <span class="ml-1.5 ">{{title}}</span>
@@ -67,10 +95,11 @@ const btnClickHandel = (action: IpcAction) => {
 <style>
 
 .min_window{
-  width: calc( 100% - 10px);
-  height:  calc( 100% - 10px);
-  margin: 5px;
+  width: calc( 100% - 30px);
+  height:  calc( 100% - 30px);
+  margin: 15px;
   box-sizing: border-box;
+  border: 1px solid transparent;
 }
 .max_window{
   width: 100%;

+ 35 - 0
src/main/tools/doWindowAction.ts

@@ -258,6 +258,41 @@ export function showWin(sign: string){
     });
 }
 
+export function disableIgnoreMouse(sign: string)
+{
+    return new Promise((resolve,reject)=>{
+        let winObj = AppControl.findWin(sign);
+        if(!winObj || !winObj.win) return reject(Error(`[取消鼠标穿透] 窗口${sign}不存在`));
+        try {
+            winObj.win.setIgnoreMouseEvents(false);
+            logger.debug('取消鼠标穿透:' + winObj.title);
+            resolve(true);
+        }
+        catch (err) {
+            logger.debug('取消鼠标穿透失败');
+            let error = err as Error;
+            logger.error(error.message);
+            reject(err);
+            // logger.info()
+        }
+    });
+}
+export function enableIgnoreMouse(sign: string)
+{
+    return new Promise((resolve,reject)=>{
+        let winObj = AppControl.findWin(sign);
+        if(!winObj || !winObj.win) return reject(Error(`[鼠标穿透] 窗口${sign}不存在`));
+        try {
+            winObj.win.setIgnoreMouseEvents(true,  { forward: true });
+            logger.debug('鼠标穿透:' + winObj.title);
+            resolve(true);
+        }
+        catch (err) {
+            logger.debug('鼠标穿透失败');
+        }
+    })
+}
+
 
 
 export function centerWin(sign: string){

+ 3 - 1
src/main/tools/hookInit.ts

@@ -2,7 +2,7 @@ import {IpcAction, actionMap} from "../../tools/IpcCmd.ts";
 import hook, {HookFn} from "../../util/hook.ts";
 import {
     closeWin,
-    connectedWin,
+    connectedWin, disableIgnoreMouse, enableIgnoreMouse,
     hideWin,
     maxWin,
     minWin,
@@ -49,4 +49,6 @@ export function initHook(){
     hookBind(actionMap.hide, hideWin);
     hookBind(actionMap.show, showWin);
     hookBind(actionMap.exitApp, appControl.exit);
+    hookBind(actionMap.enableIgnoreMouse, enableIgnoreMouse);
+    hookBind(actionMap.disableIgnoreMouse, disableIgnoreMouse);
 }

+ 2 - 0
src/main/tools/ipcInit.ts

@@ -46,5 +46,7 @@ export function initIpc() {
     bindAction(windowAction.restore);
     bindAction(windowAction.openSetting);
     bindAction(actionMap.exitApp);
+    bindAction(windowAction.enableIgnoreMouse);
+    bindAction(windowAction.disableIgnoreMouse);
 }
 

+ 1 - 0
src/style.css

@@ -1,3 +1,4 @@
+/* no use tailwind default css*/
 @tailwind base;
 @tailwind components;
 @tailwind utilities;

+ 15 - 1
src/tools/IpcCmd.ts

@@ -90,6 +90,18 @@ export const actionMap: { [key: string]: IpcAction } = {
         icon: 'api',
         code: 'apiControl',
         resCode: 'apiControl_replay'
+    },
+    enableIgnoreMouse: {
+        title: '开启鼠标穿透',
+        icon: 'mouse',
+        code: 'enableIgnoreMouse',
+        resCode: 'enableIgnoreMouse_replay'
+    },
+    disableIgnoreMouse: {
+        title: '关闭鼠标穿透',
+        icon: 'mouse',
+        code: 'disableIgnoreMouse',
+        resCode: 'disableIgnoreMouse_replay'
     }
 }
 
@@ -106,5 +118,7 @@ export const windowAction: { [key: string]: IpcAction } = {
     openSetting: actionMap.openSetting,
     exitApp: actionMap.exitApp,
     bindSignId: actionMap.bindSignId,
-    questionUser: actionMap.questionUser
+    questionUser: actionMap.questionUser,
+    enableIgnoreMouse: actionMap.enableIgnoreMouse,
+    disableIgnoreMouse: actionMap.disableIgnoreMouse,
 };

+ 3 - 3
src/types/apiTypes.ts

@@ -33,7 +33,7 @@ export interface RequestData
     timeout: number;
 }
 
-export interface ResponseData
+export interface ResponseData<T>
 {
     type: ApiType.res;
     callId: string;
@@ -44,7 +44,7 @@ export interface ResponseData
     // 错误信息
     msg: string;
     // 返回的数据
-    data: any;
+    data: T;
 }
 
 export interface NotifyData
@@ -68,4 +68,4 @@ export enum magnet_Actions {
     magnet_batch_update = 'magnet_batch_update',
     // 删除磁力链接
     magnet_delete = 'magnet_delete',
-}
+}

+ 16 - 3
src/types/magnetType.ts

@@ -16,7 +16,7 @@ export enum MagnetSize {
 }
 
 /**
- * 磁贴类型
+ * 磁贴类型, 前端应用的磁贴类型
  */
 export interface Magnet {
     // 磁贴id, 用于存储再数据库中
@@ -29,17 +29,30 @@ export interface Magnet {
     height: number,
     // 磁贴内容, 确定磁贴中的具体内容
     type: string,
+    // event 触发事件的key
+    event: string,
     // 磁贴大小, 用于确定磁贴的样式
     size: MagnetSize,
-    // 编辑模式, 用于判断是否可以拖动
-    editMode: boolean,
     // 磁贴是否被选中, 用于判断是否可以拖动
     selected: boolean,
     // 磁贴是否被改变, 用于判断是否需要保存
     changed: boolean,
+}
 
+/**
+ * 存储磁贴信息
+ */
+export interface SavedMagnet
+{
+    id: string,
+    x: number,
+    y: number,
+    type: string,
+    size: MagnetSize,
 }
 
+
+
 interface size {
     width: number,
     height: number,

+ 3 - 3
src/util/domDrag.ts

@@ -231,7 +231,7 @@ export class Drag{
 
         this.moveStart && this.moveStart(mouseInfo, this.thisInfo);
         setTimeout(()=>{
-            document.addEventListener('mousemove', this.mouseMove);
+            document.addEventListener('pointermove', this.mouseMove);
         }, 100)
         document.addEventListener('mouseup', this.mouseUp);
 
@@ -247,14 +247,14 @@ export class Drag{
             y: y
         }
         // 解除事件绑定
-        document.removeEventListener('mousemove', this.mouseMove);
+        document.removeEventListener('pointermove', this.mouseMove);
         document.removeEventListener('mouseup', this.mouseUp);
         this.moveEnd && this.moveEnd(mouseInfo , this.thisInfo);
     }
     mouseMove = (e: MouseEvent) => {
         if (!this.isMove){
             // 已经被取消
-            document.removeEventListener('mousemove', this.mouseMove);
+            document.removeEventListener('pointermove', this.mouseMove);
             return
         }
         // 获取鼠标位置

+ 4 - 0
tailwind.config.js

@@ -8,4 +8,8 @@ export default {
     extend: {},
   },
   plugins: [],
+  // not use tailwind default css
+  corePlugins: {
+    preflight: false,
+  }
 }

+ 20 - 1
yarn.lock

@@ -382,6 +382,13 @@
   resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz"
   integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
 
+"@headlessui/vue@^1.7.22":
+  version "1.7.22"
+  resolved "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.22.tgz"
+  integrity sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==
+  dependencies:
+    "@tanstack/vue-virtual" "^3.0.0-beta.60"
+
 "@isaacs/cliui@^8.0.2":
   version "8.0.2"
   resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz"
@@ -731,6 +738,18 @@
   dependencies:
     defer-to-connect "^2.0.0"
 
+"@tanstack/virtual-core@3.5.1":
+  version "3.5.1"
+  resolved "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.1.tgz"
+  integrity sha512-046+AUSiDru/V9pajE1du8WayvBKeCvJ2NmKPy/mR8/SbKKrqmSbj7LJBfXE+nSq4f5TBXvnCzu0kcYebI9WdQ==
+
+"@tanstack/vue-virtual@^3.0.0-beta.60":
+  version "3.5.1"
+  resolved "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.5.1.tgz"
+  integrity sha512-6mc4HtDPieDVKD6GqzHiJkdzuqRNdQZuoIbkwE6af939WV+w62YmSF69jN+BOqClqh/ObiW+X1VOQx1Pftrx1A==
+  dependencies:
+    "@tanstack/virtual-core" "3.5.1"
+
 "@tootallnate/once@2":
   version "2.0.0"
   resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz"
@@ -5447,7 +5466,7 @@ vue-tsc@^1.8.5:
     "@vue/typescript" "1.8.8"
     semver "^7.3.8"
 
-vue@^3.0.1, vue@^3.2.25, vue@^3.3.4, vue@3.3.4:
+"vue@^2.7.0 || ^3.0.0", vue@^3.0.1, vue@^3.2.0, vue@^3.2.25, vue@^3.3.4, vue@3.3.4:
   version "3.3.4"
   resolved "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz"
   integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==