salary-management-front/pc4mobx/hrmSalary/components/excelEditor/index.js

176 lines
6.6 KiB
JavaScript
Raw Normal View History

2023-04-13 10:00:24 +08:00
import React, { Component } from "react";
import { Button } from "antd";
2023-04-28 16:11:56 +08:00
import { WeaLocaleProvider } from "ecCom";
2023-04-13 13:26:43 +08:00
import { Controlled as CodeMirror } from "react-codemirror2";
2023-04-13 10:00:24 +08:00
import { keyboardBaseBtns } from "./constants";
2023-04-26 15:08:03 +08:00
import CodeAction from "./components/codeAction";
2023-04-13 10:00:24 +08:00
import cs from "classnames";
import "./index.less";
import "codemirror/lib/codemirror.css";
import "codemirror/lib/codemirror.js";
2023-04-28 16:11:56 +08:00
import "codemirror/mode/javascript/javascript.js";
require("./extendCodeMirror");
const getLabel = WeaLocaleProvider.getLabel;
2023-04-13 10:00:24 +08:00
class ExcelEditor extends Component {
constructor(props) {
super(props);
this.state = {
2023-04-28 16:11:56 +08:00
value: "",
2023-05-09 09:57:49 +08:00
isFormter: false,
isCustomFunctionClick: false
2023-04-13 10:00:24 +08:00
};
2023-04-13 13:26:43 +08:00
this.editorRef = null;
2023-04-27 14:52:03 +08:00
this.timer = null;
2023-04-13 10:00:24 +08:00
}
2023-04-28 11:30:05 +08:00
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.value !== this.props.value && nextProps.value) this.setState({ value: nextProps.value });
}
2023-04-27 14:52:03 +08:00
componentWillUnmount() {
if (this.timer) clearInterval(this.timer);
2023-05-09 09:57:49 +08:00
this.setState({ isCustomFunctionClick: false });
2023-04-27 14:52:03 +08:00
}
2023-04-26 15:08:03 +08:00
2023-04-28 16:11:56 +08:00
autoFormatSelection = () => {
const { isFormter } = this.state;
if (isFormter) {
const script_length = this.editorRef.getValue().length;
const startPos = { line: 0, ch: 0, sticky: null };
const endPos = this.editorRef.doc.posFromIndex(script_length);
this.editorRef.setSelection(startPos, endPos);
this.editorRef.autoFormatRange(startPos, endPos);
this.editorRef.commentRange(true, startPos, endPos);
} else {
this.editorRef.undo();
2023-05-29 16:49:45 +08:00
// this.editorRef.undo();
2023-04-28 16:11:56 +08:00
}
};
2023-04-13 16:42:57 +08:00
insertText = text => {
2023-04-26 15:08:03 +08:00
const cursor = this.editorRef.getCursor();
2023-04-13 16:42:57 +08:00
this.editorRef.replaceRange(text, cursor);
2023-04-28 10:51:06 +08:00
this.editorRef.refresh();
this.editorRef.focus();
2023-04-13 16:42:57 +08:00
};
2023-04-28 10:51:06 +08:00
replaceToWidget = (editor) => {
2023-04-13 13:26:43 +08:00
editor.getAllMarks().forEach(m => m.clear());
};
2023-04-26 15:08:03 +08:00
handleVariSelect = str => this.insertText(`{${str}}`);
handleFuncSelect = str => {
const cursor = this.editorRef.getCursor();
this.editorRef.replaceRange(`${str}()`, cursor);
2023-04-27 14:52:03 +08:00
this.timer = setTimeout(() => {
const { line, ch } = this.editorRef.getCursor();
this.editorRef.setCursor({ line, ch: ch - 1 });
2023-04-28 10:51:06 +08:00
this.editorRef.refresh();
this.editorRef.focus();
2023-04-27 14:52:03 +08:00
}, 100);
2023-04-26 15:08:03 +08:00
};
handleEditorRedo = () => {
const { ch, line } = this.editorRef.getCursor();
const delStr = this.editorRef.getRange({ line, ch: ch - 1 }, { line, ch });
const codeValue = this.editorRef.getValue();
if (delStr === "}") {
if (codeValue.slice(0, ch).lastIndexOf("{") === -1) {
this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch });
} else {
this.editorRef.replaceRange("", { line, ch: codeValue.slice(0, ch).lastIndexOf("{") }, { line, ch });
}
} else {
this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch });
}
2023-04-28 11:30:05 +08:00
this.editorRef.refresh();
this.editorRef.focus();
2023-04-26 15:08:03 +08:00
};
2023-04-27 09:34:19 +08:00
handleBackSpaceRedo = () => {
const { ch, line } = this.editorRef.getCursor();
const delStr = this.editorRef.getRange({ line, ch: ch - 1 }, { line, ch });
const codeValue = this.editorRef.getValue();
if (delStr === "}") {
if (codeValue.slice(0, ch).lastIndexOf("{") === -1) {
this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch });
} else {
2023-04-27 10:01:57 +08:00
this.editorRef.replaceRange("", { line, ch: codeValue.slice(0, ch).lastIndexOf("{") + 1 }, { line, ch });
2023-04-27 09:34:19 +08:00
}
}
2023-04-28 11:30:05 +08:00
this.editorRef.refresh();
this.editorRef.focus();
2023-04-27 09:34:19 +08:00
};
2023-04-13 10:00:24 +08:00
render() {
2023-05-09 09:57:49 +08:00
const { isFormter, isCustomFunctionClick } = this.state;
const { groupParams = {}, isCustomFunction, value, onChangeCustomFunction } = this.props;
2023-04-27 14:52:03 +08:00
const { referenceType } = groupParams;
2023-04-13 10:00:24 +08:00
return (
<React.Fragment>
<div className="excel-codeWrap">
<div className="excel-codeBox">
<CodeMirror
2023-04-13 13:26:43 +08:00
editorDidMount={editor => this.editorRef = editor}
2023-04-13 10:00:24 +08:00
value={this.state.value}
onBeforeChange={(editor, data, value) => {
2023-04-28 11:30:05 +08:00
this.setState({ value }, () => this.props.onChange(this.state.value));
2023-04-13 10:00:24 +08:00
}}
2023-04-13 13:26:43 +08:00
onChange={(editor, data, value) => {
2023-04-28 10:51:06 +08:00
this.replaceToWidget(editor, data, value);
2023-04-13 10:00:24 +08:00
}}
options={{
lineNumbers: false,
2023-04-28 16:11:56 +08:00
mode: "javascript",
2023-04-13 10:00:24 +08:00
autofocus: false,
styleActiveLine: true,
lineWrapping: true,
2023-04-28 16:11:56 +08:00
matchBrackets: true,
2023-04-13 10:00:24 +08:00
lint: false,
indentUnit: 2,
cursorHeight: 0.85,
2023-04-27 10:01:57 +08:00
placeholder: "",
showCursorWhenSelecting: true
2023-04-13 10:00:24 +08:00
}}
2023-04-27 09:34:19 +08:00
onKeyDown={(_, { keyCode }) => keyCode === 8 && this.handleBackSpaceRedo()}
2023-04-13 10:00:24 +08:00
/>
</div>
2023-04-27 14:52:03 +08:00
{
referenceType !== "sql" &&
<div className="excel-codeBox-keyboard">
<div className="excel-codeBox-keyboard-operate">
<div className="excel-codeBox-keyboard-operate-content">
{
_.map(keyboardBaseBtns, item => {
const { key, label } = item;
return <Button
key={key} title={label} size="small"
className={cs(key === " " ? "excel-codeBox-keyboard-space" : "excel-codeBox-keyboard-base")}
onClick={() => this.insertText(key)}
>{label}</Button>;
})
}
</div>
<div className="excel-codeBox-keyboard-operate-clear">
<Button title="←" size="small" className="excel-codeBox-keyboard-del"
onClick={this.handleEditorRedo}></Button>
<Button title="C" size="small" className="excel-codeBox-keyboard-clear"
2023-05-09 09:57:49 +08:00
onClick={() => this.setState({ value: "", isCustomFunctionClick: true })}>C</Button>
2023-04-27 14:52:03 +08:00
</div>
2023-04-13 10:00:24 +08:00
</div>
2023-04-28 16:11:56 +08:00
<Button type="ghost"
onClick={() => this.setState({ isFormter: !isFormter }, () => this.autoFormatSelection())}>
2023-08-09 10:35:49 +08:00
{!isFormter ? getLabel(543711, "格式美化") : getLabel(543712, "格式还原")}
2023-04-28 16:11:56 +08:00
</Button>
2023-04-13 10:00:24 +08:00
</div>
2023-04-27 14:52:03 +08:00
}
2023-04-13 10:00:24 +08:00
</div>
2023-04-26 15:08:03 +08:00
{/*公式参数列表*/}
2023-05-09 09:57:49 +08:00
<CodeAction groupParams={groupParams} isCustomFunction={isCustomFunction} onVariSelect={this.handleVariSelect}
onFuncSelect={this.handleFuncSelect} codeVal={value} isCustomFunctionClick={isCustomFunctionClick}
onChangeCustomFunction={onChangeCustomFunction}
/>
2023-04-13 10:00:24 +08:00
</React.Fragment>
);
}
}
export default ExcelEditor;