键盘快捷键设置录入

效果图:

代码:

复制代码
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方法的处理,见代码

相关推荐
zhougl99626 分钟前
html处理Base文件流
linux·前端·html
花花鱼30 分钟前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_33 分钟前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo2 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)2 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之3 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端4 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡4 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木5 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!5 小时前
优选算法系列(5.位运算)
java·前端·c++·算法