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

190 lines
6.3 KiB
JavaScript

import React, { Component } from "react";
import { Button } from "antd";
import { Controlled as CodeMirror } from "react-codemirror2";
import { keyboardBaseBtns } from "./constants";
import cs from "classnames";
import "./index.less";
import "codemirror/lib/codemirror.css";
import "codemirror/lib/codemirror.js";
//代码折叠
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/addon/lint/lint.css";
import "codemirror/addon/fold/foldcode.js";
import "codemirror/addon/fold/foldgutter.js";
import "codemirror/addon/fold/brace-fold.js";
import "codemirror/addon/hint/javascript-hint.js";
import "codemirror/addon/hint/show-hint.js";
import "codemirror/addon/lint/lint.js";
import "codemirror/addon/lint/json-lint.js";
import "codemirror/addon/lint/javascript-lint.js";
import "codemirror/addon/display/placeholder.js";
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/sql/sql.js";
// const sqlFormatter = require('sql-formatter');
class ExcelEditor extends Component {
constructor(props) {
super(props);
this.state = {
value: "",
widgets: []
};
this.editorRef = null;
}
replaceToWidget = (editor, data, value, inlineWidgetOpts) => {
editor.getAllMarks().forEach(m => m.clear());
let posInfos = _.flatMap(_.keys(inlineWidgetOpts), widgetName => {
let { regex, render } = inlineWidgetOpts[widgetName];
let res = [], newRe = new RegExp(regex, "g"), m;
do {
m = newRe.exec(value);
if (m) {
const mountToDom = document.createElement("span");
let text = m[0];
res.push({
widgetName,
text,
startAt: m.index,
endAt: m.index + text.length,
render: () => {
let x = `((...args) => args)${text.replace(new RegExp(`^${widgetName}`), "")}`;
let args = eval(x);
return render(...args);
},
mountToDom: mountToDom
});
}
} while (m);
return res;
});
posInfos.forEach(posInfo => {
let from = { line: 0, ch: posInfo.startAt };
let to = { line: 0, ch: posInfo.endAt };
editor.markText(from, to, {
replacedWith: posInfo.mountToDom,
clearWhenEmpty: false
});
});
this.setState({
widgets: posInfos
}, () => {
editor.refresh();
editor.focus();
});
};
/*
* Author: 黎永顺
* Description:格式化
* Params:
* Date: 2023/4/13
*/
autoFormatSelection = () => {
let editor = this.editorRef.editor;
if (this.props.type != "sql") {
const script_length = editor.getValue().length;
const startPos = { line: 0, ch: 0, sticky: null };
const endPos = editor.doc.posFromIndex(script_length);
// editor.setSelection(startPos, endPos);
// editor.autoFormatRange(startPos, endPos);
// editor.commentRange(false, startPos, endPos);
} else {
let splCont = "";
splCont = editor.getValue();
// editor.setValue(sqlFormatter.format(splCont));
}
};
render() {
const inlineWidgetOpts = {
useObject: {
regex: /useObject\("[^)]+"\)/,
render: (objId) => {
return (
<div
className="border iblock"
style={{ padding: "5px" }}
onClick={() => alert(objId)}
>{objId}</div>
);
}
}
};
return (
<React.Fragment>
<div className="excel-codeWrap">
<div className="excel-codeBox">
<CodeMirror
editorDidMount={editor => this.editorRef = editor}
value={this.state.value}
onBeforeChange={(editor, data, value) => {
this.setState({ value });
}}
onChange={(editor, data, value) => {
this.replaceToWidget(editor, data, value, inlineWidgetOpts);
}}
options={{
lineNumbers: false,
mode: { name: this.props.type === "sql" ? "text/x-sql" : "application/json" },
autofocus: false,
styleActiveLine: true,
lineWrapping: true,
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
lint: false,
indentUnit: 2,
cursorHeight: 0.85,
placeholder: ""
}}
/>
</div>
<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 === "space" ? "excel-codeBox-keyboard-space" : "excel-codeBox-keyboard-base")}
>{label}</Button>;
})
}
</div>
<div className="excel-codeBox-keyboard-operate-clear">
<Button title="←" size="small" className="excel-codeBox-keyboard-del"></Button>
<Button title="C" size="small" className="excel-codeBox-keyboard-clear">C</Button>
</div>
</div>
</div>
</div>
<div className="excel-codeAction">
<div className="excel-codeAction-item">
<div className="excel-codeAction-header">
<div className="excel-codeAction-header-title">变量</div>
</div>
<div className="excel-codeAction-content"></div>
</div>
<div className="excel-codeAction-item">
<div className="excel-codeAction-header">
<div className="excel-codeAction-header-title">函数</div>
</div>
<div className="excel-codeAction-content"></div>
</div>
<div className="excel-codeAction-item">
<div className="excel-codeAction-header">
<div className="excel-codeAction-header-title">提示</div>
</div>
<div className="excel-codeAction-content"></div>
</div>
</div>
</React.Fragment>
);
}
}
export default ExcelEditor;