键盘快捷键设置录入

news2024/9/27 21:22:56

效果图:

代码:

import React, {useContext, useEffect, useRef} from 'react'
import {message} from "antd";
import lodash from "lodash";
import {StateContext} from '../../index.tsx'
import {useUpdateEffect} from "ahooks";
import './index.less'

const funcKeys = ['control','shift','alt']
const fCodes = ['f1','f2','f3','f4','f5','f6','f7','f8','f9','f10','f11','f12']
const aCodes = [
  'q','w','e','r','t','y','u','i','o','p',
  'a','s','d','f','g','h','j','k','l',
  'z','x','c','v','b','n','m'
].map((v:any) => 'key' + v)
let downCount = 0
let strArr: string[] = []

const placeholder = 'ctrl/shift/alt+a-z,F1-F12'

const Shortcut = () => {

  const {
    shortcut,
  } = useContext<any>(StateContext)

  const refSearch = useRef<any>(null)
  const refOrderLink = useRef<any>(null)
  const refCanteen = useRef<any>(null)
  const refOrderMark = useRef<any>(null)
  const refSubmit = useRef<any>(null)
  const refReset = useRef<any>(null)
  const refCreate = useRef<any>(null)

  const relationArr:any = [
    [refSearch, 'search'],
    [refOrderLink, 'orderLink'],
    [refCanteen, 'canteen'],
    [refOrderMark, 'orderMark'],
    [refSubmit, 'submit'],
    [refReset, 'reset'],
    [refCreate, 'create']
  ]

  useUpdateEffect(() => {
    relationArr.forEach((v:any) => {
      if ( shortcut[v[1]] ) {
        v[0].current.value = shortcut[v[1]]
      }
    })
  }, [shortcut]);

  const onKeyDown = (e: any) => {
    let {key, code} = e
    key = key.toLowerCase()
    code = code.toLowerCase()
    // 判定是否是有效值
    if (funcKeys.includes(key) || aCodes.includes(code) || fCodes.includes(code)) {
    } else {
      return
    }
    // 判定是否已经包含
    if (strArr.includes(key) || strArr.includes(code)) {
      return
    }
    // 如果是初次按下,需要重置str的值
    if (downCount === 0) {
      strArr = []
    }
    // 记录按键
    if (funcKeys.includes(key)) {
      strArr.push(key)
    }
    if (aCodes.includes(code)) {
      strArr.push(code)
    }
    if (fCodes.includes(code)) {
      strArr.push(code)
    }
    downCount++
    e.target.value = strArr.map(v => v.replace('key', '')).join('+')
  }

  const onKeyUp = (e: any) => {
    downCount--
    if (downCount <= 0) {
      downCount = 0
      strArr = []
    }
  }

  // 验证快捷键设置:1 不能重复,2 至少包含一个功能键 + 字母键 3 f1-f12不用包含功能键
  const checkValidateData = () => {
    const tmpArr = []
    for (let i=0; i<relationArr.length; i++) {
      const item = relationArr[i]
      if (item[0].current.value) {
        if (fCodes.includes(item[0].current.value)) {
        } else {
          const tArr2 =  item[0].current.value.split('+').sort()
          let hasFunc = false // 包含功能键
          let hasCode = false // 包含字母键
          tArr2.forEach((v2:any) => {
            if (funcKeys.includes(v2)) {
              hasFunc = true
            } else if (aCodes.includes('key' + v2)) {
              hasCode = true
            }
          })
          if (hasFunc && hasCode) {
            tmpArr.push(tArr2.toString())
          } else {
            item[0].current.value = ''
            message.warn(`快捷键规则:${placeholder}`)
            return false
          }
        }
      }
    }
    // 检查是否重复
    if (tmpArr.length !== lodash.uniq(tmpArr).length) {
      message.warn('快捷键重复')
      return false
    }
    return true
  }

  const onFocus = (e: any) => {
    const val = e.target.value
    // @ts-ignore
    val && window.electronAPI && window.electronAPI.changeShortcut({
      tp: 'delete',
      val
    })
  }

  const onBlur = () => {
    const rOk = checkValidateData()
    // if (!rOk) return;
    // 保存数据到store
    const tmpObj: any = {}
    relationArr.forEach((item: any) => {
      tmpObj[item[1]] = item[0].current.value
    })
    // @ts-ignore
    window.electronAPI && window.electronAPI.changeShortcut({
      tp: 'create',
      val: tmpObj
    })
  }

  return <div className={'page-config page-shortcut'}>
    <ul>
      <li>
        <span>搜索订单:</span>
        <input
          ref={refSearch}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
      <li>
        <span>订单号或选店链接:</span>
        <input
          ref={refOrderLink}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
      <li>
        <span>餐厅代码:</span>
        <input
          ref={refCanteen}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
      <li>
        <span>订单备注(可空):</span>
        <input
          ref={refOrderMark}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
      <li>
        <span>提交:</span>
        <input
          ref={refSubmit}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
      <li>
        <span>清空:</span>
        <input
          ref={refReset}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
      <li>
        <span>创建:</span>
        <input
          ref={refCreate}
          readOnly
          placeholder={placeholder}
          onKeyDown={onKeyDown}
          onKeyUp={onKeyUp}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      </li>
    </ul>
  </div>
}

Shortcut.displayName = 'Shortcut'
export default Shortcut

主要onKeyDown和onKeyUp方法的处理,见代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1919977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql快速精通(三)表关系

主打一个实用 一. 一对多&#xff08;多对一&#xff09;关系 例如班级和学生&#xff0c;这种类型我们一般建两个表,一方为主表&#xff0c;多方为从表 二. 多对多 例如课程与学生&#xff0c;这种类型我们一般需要建三张表&#xff0c;两张一方主表&#xff0c;与一张多方从表…

PyTorch人脸检测

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客 人脸检测解决的问题是确定一幅图上有没有人脸&#xff0c;而人脸识别解决的问题是这张脸是谁的。可以说人脸检测是人脸识别的前期工作。这里介绍Dlib库&#xff0c;它提供了Python接口&#xff0c;里面有人脸检测器&#x…

<数据集>穿越火线cf人物识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;3440张 标注数量(xml文件个数)&#xff1a;3440 标注数量(txt文件个数)&#xff1a;3440 标注类别数&#xff1a;1 标注类别名称&#xff1a;[person] 使用标注工具&#xff1a;labelImg 标注规则&#xff1a;对…

基于整体学习的大幅面超高分遥感影像桥梁目标检测(含数据集下载地址)

文章摘要 在遥感图像&#xff08;RSIs&#xff09;中进行桥梁检测在各种应用中起着至关重要的作用&#xff0c;但与其他对象检测相比&#xff0c;桥梁检测面临独特的挑战。在RSIs中&#xff0c;桥梁在空间尺度和纵横比方面表现出相当大的变化。因此&#xff0c;为了确保桥梁的…

[Godot3.3.3] - 过渡动画

过渡动画 ScreenTransitionAnimation 项目结构 添加场景&#xff0c;根节点为 CanvasLayer2D 并重命名为 ScreenTransition: 添加子节点 ColorRect 和 AnimationPlayer&#xff0c;在 ColorRect 中将颜色(Color)设置为黑色&#xff1a; 找到 Material&#xff0c;新建 Shader…

Scanner工具类

扫描控制台输入 1.nextLine nextLine() 方法会扫描输入流中的字符&#xff0c;直到遇到行末尾的换行符 \n&#xff0c;然后将该行的内容作为字符串返回&#xff0c;同时&#xff0c;nextLine() 会将 Scanner 对象的位置移动到下一行的开头&#xff0c;以便下一次读取数据时从下…

【机器学习】12.十大算法之一支持向量机(SVM - Support Vector Machine)算法原理讲解

【机器学习】12.十大算法之一支持向量机&#xff08;SVM - Support Vector Machine&#xff09;算法原理讲解 一摘要二个人简介三基本概念四支持向量与超平面4.1 超平面&#xff08;Hyperplane&#xff09;4.2 支持向量&#xff08;Support Vectors&#xff09;4.3 核技巧&…

数据结构实操代码题~考研

作者主页: 知孤云出岫 目录 数据结构实操代码题题目一&#xff1a;实现栈&#xff08;Stack&#xff09;题目二&#xff1a;实现队列&#xff08;Queue&#xff09;题目三&#xff1a;实现二叉搜索树&#xff08;BST&#xff09;题目四&#xff1a;实现链表&#xff08;Linked…

Gitlab CI/CD介绍

基本概念 GitLab CI/CD&#xff08;持续集成/持续部署&#xff09;流水线是GitLab平台提供的一项强大功能&#xff0c;旨在通过自动化构建、测试和部署过程&#xff0c;提高开发团队的效率和软件发布的质量。 CI&#xff08;Continuous Integration&#xff09;&#xff1a;持续…

【驱动篇】龙芯LS2K0300之spi设备驱动

实验介绍 GC9A01是一款小巧&#xff08;1.28寸&#xff09;、彩色&#xff08;分辨率为 240 * 240 RGB&#xff09;圆形TFT屏幕&#xff0c;它采用4线 SPI的控制方式&#xff0c;电源供电电压为3.3V&#xff0c;有7个控制引脚&#xff1b;本次实验将使用它来验证龙芯SOC的SPI通…

从汇编层看64位程序运行——程序中的栈(Stack)结构及其产生的历史原因

大纲 传统栈程序栈X86体系栈反向的原因参考资料 如果要讲程序在系统层的运行&#xff0c;一个绕不开的名词就是“栈”。所以深入理解“栈”是这个系列重要的基础。本文也将深入浅出&#xff0c;只讲明白程序运行中使用的栈是什么。 传统栈 有计算机基础的同学都知道栈的特点&…

开源浏览器引擎对比与适用场景:WebKit、Chrome、Gecko

WebKit与Chrome的Blink引擎对比 起源与关系&#xff1a; WebKit最初由苹果公司开发&#xff0c;用于Safari浏览器。后来&#xff0c;WebKit逐渐成为一个独立的开源项目&#xff0c;被多个浏览器厂商采用。Blink是Google基于WebKit项目分支出来的一个浏览器引擎&#xff0c;用于…

实现Android夜间模式主题:从入门到精通

实现Android夜间模式主题:从入门到精通 随着用户对夜间模式的需求越来越高,Android开发者需要掌握如何在应用中实现夜间模式。本文将详细介绍在Android中实现夜间模式的步骤,包括配置、实现、以及一些最佳实践,帮助开发者创建更具吸引力和用户友好的应用。 夜间模式的优势…

文献翻译与阅读《Integration Approaches for Heterogeneous Big Data: A Survey》

CYBERNETICS AND INFORMATION TECHNOLOGIES’24 论文原文下载地址&#xff1a;原文下载 目录 1 引言 2 大数据概述 3 大数据的异构性 4 讨论整合方法 4.1 大数据仓库&#xff08;BDW&#xff09; 4.2 大数据联盟&#xff08;BDF&#xff09; 5 DW 和 DF 方法的比较、分…

逻辑回归中的损失函数

目录 一、损失函数介绍&#xff1a;二、简化上述损失函数&#xff1a; 一、损失函数介绍&#xff1a; 与回归问题成本函数不同的是&#xff0c;逻辑回归模型&#xff08;解决分类问题&#xff09;的成本函数在获得损失J的时候不再用真实值y与预测值y^的差值计算损失&#xff0…

adminPage-vue3依赖FormPage说明文档,表单页快速开发,使用思路及范例(Ⅱ)formConfig基础配置项

adminPage-vue3依赖FormPage说明文档&#xff0c;表单页快速开发&#xff0c;使用思路及范例&#xff08;Ⅱ&#xff09;formConfig配置项 属性: formConfig&#xff08;表单项设置&#xff09;keylabelnoLabeldefaultValuebindchildSlottypeString类型数据&#xff08;除 time…

探索GitHub上的两个革命性开源项目

在数字世界中&#xff0c;总有一些项目能够以其创新性和实用性脱颖而出&#xff0c;吸引全球开发者的目光。今天&#xff0c;我们将深入探索GitHub上的两个令人惊叹的开源项目&#xff1a;Comic Translate和GPTPDF&#xff0c;它们不仅改变了我们处理信息的方式&#xff0c;还极…

为什么说https访问是网站的标配

在互联网时代&#xff0c;数据安全和隐私保护成为了不可忽视的重要议题。随着网络攻击、数据泄露等事件频发&#xff0c;用户对在线活动的安全性要求越来越高。HTTPS协议作为HTTP协议的加密版本&#xff0c;已经成为现代网站的标配&#xff0c;其重要性和必要性不言而喻。下面从…

【数据结构】初探数据结构面纱:栈和队列全面剖析

【数据结构】初探数据结构面纱&#xff1a;栈和队列全面剖析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;数据结构 文章目录 【数据结构】初探数据结构面纱&#xff1a;栈和队列全面剖析前言一.栈1.1栈的概念及结构1.2栈的结构选择1.3栈的…

Xilinx FPGA:vivado fpga与EEPROM的IIC通信,串口显示数据,含使用debug教程

一、实验要求 实现FPGA与EEPROM的通信&#xff0c;要求FPGA对EEPROM实现先“写”后“读”&#xff0c;读出的值给uart发送端并显示到电脑上&#xff0c;按下按键1让fpga对EEPROM写入数据&#xff1b;按下按键2让fpga读出对EEPROM写入过的数据。 二、信号流向图 三、程序设计 …