效果图:
代码:
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方法的处理,见代码