salary-management-front/pc4mobx/hrmSalary/pages/salaryItem/formalFormModal.js

410 lines
13 KiB
JavaScript

import React from "react";
import { Button, Col, Icon, Modal, Row } from "antd";
import { WeaCheckbox, WeaDialog, WeaFormItem, WeaHelpfulTip, WeaInput, WeaSelect, WeaTextarea } from "ecCom";
import { inject, observer } from "mobx-react";
import "./index.less";
@inject("salaryItemStore")
@observer
export default class FormalFormModal extends React.Component {
constructor(props) {
super(props);
this.state = {
validateType: "",
returnType: "",
value: "",
extendParam: {
sqlReturnKey: "",
openDecrypt: "0",
datasource: {
datasourceId: ""
}
},
returnValue: "",
formulaDatasourceList: []
};
this.group = {};
this.field = {};
this.parameters = [];
this.referenceType = "";
this.timer = null;
}
componentWillMount() {
const { salaryItemStore } = this.props;
const { salaryAcctImportTemplateParam, setSearchFields, detailFormual } = salaryItemStore;
setSearchFields([]);
if (this.props.formulaId) {
detailFormual(this.props.formulaId).then(data => {
this.setState({
value: data.formula,
returnType: data.returnType,
validateType: data.validateType
});
this.parameters = data.parameters;
this.referenceType = data.referenceType;
this.extendParam = data.extendParam;
if (this.extendParam && this.extendParam.length > 0) {
let extendParam = {};
try {
extendParam = JSON.parse(this.extendParam);
} catch (ex) {
}
this.setState({
extendParam: {
sqlReturnKey: extendParam.sqlReturnKey,
openDecrypt: extendParam.openDecrypt,
datasource: {
datasourceId: extendParam.datasource ? extendParam.datasource.datasourceId : ""
}
}
});
}
let groupParams = {};
if (this.referenceType == "sql") {
groupParams = { "referenceType": "sql" };
}else{
groupParams = this.props.backCalcType === "issuedItems" ? { "referenceType": "backCalc" } : {};
}
salaryAcctImportTemplateParam(groupParams);
});
} else {
let groupParams = {};
if (this.props.valueType == "3") {
groupParams = { "referenceType": "sql" };
} else if (this.props.valueType === "FORMULA") {
groupParams = this.props.backCalcType === "issuedItems" ? { "referenceType": "backCalc" } : {};
this.referenceType = "formula";
this.setState({
value: this.props.formulaContent
});
}
salaryAcctImportTemplateParam(groupParams);
}
}
componentDidMount() {
this.formulaDatasourceList();
}
componentWillUnmount() {
clearTimeout(this.timer);
}
triggerKeyDown = (e) => {
let propsTextarea = this.contentProps.refs.textareaNormal.refs.input.refs.input; // 获取dom节点实例
const { value } = this.state;
if (e.key === "Backspace" && value) {
const { end } = this.getPositionForTextArea(propsTextarea);
const str = value.substring(end - 1, end);
if (str === "}") {
e.preventDefault();
const index = value.lastIndexOf("{", end - 1);
const currentValue = value.substring(index, end);
this.setState({
value: value.replace(currentValue, "")
}, () => {
if (propsTextarea.setSelectionRange) {
this.timer = setTimeout(() => {
propsTextarea.setSelectionRange(index, index);
}, 0);
}
});
}
}
};
formulaDatasourceList = () => {
const { salaryItemStore } = this.props;
const { formulaDatasourceList } = salaryItemStore;
formulaDatasourceList().then(({ status, data }) => {
if (status) {
this.setState({
formulaDatasourceList: [{
key: "",
showname: ""
}, ..._.map(data, it => ({ key: it, showname: it }))]
});
}
});
};
// 多行文本编辑
handleChange(value) {
if (value && value.trim() == "") {
this.parameters = [];
}
this.setState({
value
});
}
// 获取光标位置
getPositionForTextArea(ctrl) {
let CaretPos = {
start: 0,
end: 0
};
if (ctrl.selectionStart) {// Firefox support
CaretPos.start = ctrl.selectionStart;
}
if (ctrl.selectionEnd) {
CaretPos.end = ctrl.selectionEnd;
}
return (CaretPos);
}
// 分组项被点击
handleItemClick(item) {
const { salaryItemStore } = this.props;
const { formualSearchField } = salaryItemStore;
this.group = item;
let params = {};
if (this.props.valueType == "3" || this.referenceType == "sql") {
params = {
extendParam: {
"referenceType": "sql"
}
};
}
formualSearchField(item.key, params);
}
// 保存
handleSave() {
const { salaryItemStore } = this.props;
const { saveFormual } = salaryItemStore;
this.parameters = this.parameters.filter(item => this.state.value.indexOf(item.name) > -1);
// 去重
let result = [];
this.parameters.map(item => {
let flag = false;
result.map(i => {
if (item.fieldId == i.fieldId) {
flag = true;
}
});
if (!flag) {
result.push(item);
}
});
this.parameters = result;
let params = {
name: "公式1",
description: "备注",
module: "salary",
useFor: "salaryitem",
returnType: this.props.dataType || this.state.returnType,
validateType: this.props.dataType || this.state.returnType,
extendParam: JSON.stringify(this.state.extendParam),
formula: this.state.value,
parameters: this.parameters,
referenceType: this.referenceType == "" ? this.props.valueType == "2" ? "formula" : this.props.valueType == "3" ? "sql" : "" : this.referenceType
};
saveFormual(params).then(data => {
this.props.onSaveFormal(data);
this.props.onCancel();
});
}
/**
* name: 获取文本框光标位置
* param {*} obj
* param {*} str
* return {*}
*/
insertText = (obj, str) => {
if (document.selection) {
let sel = document.selection.createRange();
sel.text = str;
} else if (typeof obj.selectionStart === "number" && typeof obj.selectionEnd === "number") {
let startPos = obj.selectionStart,
endPos = obj.selectionEnd,
cursorPos = startPos,
tmpStr = obj.value;
obj.value = tmpStr.substring(0, startPos) + str + tmpStr.substring(endPos, tmpStr.length);
cursorPos += str.length;
obj.selectionStart = obj.selectionEnd = cursorPos;
obj.focus();
this.setState({ value: obj.value });
} else {
obj.value += str;
}
};
// 字段点击回调
handleFieldClick(item) {
this.field = item;
let fieldName = "{" + this.group.value + "." + this.field.name + "}";
let parameterItem = {
name: item.name,
fieldId: item.fieldId,
fieldName: fieldName,
fieldType: item.fieldType,
source: item.source,
orderIndex: this.parameters.length
};
this.parameters.push(parameterItem);
let propsTextarea = this.contentProps.refs.textareaNormal.refs.input.refs.input; // 获取dom节点实例
let position = this.insertText(propsTextarea, fieldName); // 光标的位置
}
render() {
const { salaryItemStore } = this.props;
const { searchGroup, searchFields } = salaryItemStore;
const { value, formulaDatasourceList, extendParam } = this.state;
return (
<WeaDialog
title={`${(this.props.valueType == 2 || this.props.valueType === "FORMULA") ? "函数" : "SQL"}公式`}
visible={this.props.visible}
style={{ width: 800 }}
buttons={[
<Button type="primary" onClick={() => {
this.handleSave();
}}>保存</Button>
]}
className="formula-wrapper"
initLoadCss
onCancel={() => {
this.props.onCancel();
}}>
{
(this.props.valueType == "3" || this.referenceType == "sql") &&
<Row gutter={20} style={{ marginBottom: 10 }}>
<Col span={12}>
<WeaFormItem
label="返回字段"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaInput style={{ width: "100%" }} value={extendParam.sqlReturnKey} onChange={(sqlReturnKey) => {
this.setState({ extendParam: { ...extendParam, sqlReturnKey } });
}}/>
</WeaFormItem>
</Col>
<Col span={12} className="dataList-wrapper">
<WeaFormItem
label="外部数据源"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaSelect
options={formulaDatasourceList}
value={extendParam.datasource.datasourceId}
onChange={(datasourceId) => {
if (datasourceId) {
Modal.confirm({
title: "信息确认",
content: "外部数据源指第三方数据库,连接第三方数据库会影响核算效率。",
onOk: () => {
this.setState({ extendParam: { ...extendParam, datasource: { datasourceId } } });
},
onCancel: () => {
this.setState({ extendParam: { ...extendParam, datasource: { datasourceId: "" } } });
}
});
} else {
this.setState({ extendParam: { ...extendParam, datasource: { datasourceId: "" } } });
}
}}
/>
<WeaHelpfulTip
width={196}
title="不设置,默认使用系统数据源。"
isCenter={true}
/>
</WeaFormItem>
</Col>
<Col span={12}>
<WeaFormItem
label="开启解密"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<WeaCheckbox
style={{ marginRight: 8 }}
display="switch"
value={extendParam.openDecrypt}
onChange={(openDecrypt) => {
this.setState({ extendParam: { ...extendParam, openDecrypt } });
}}
/>
<WeaHelpfulTip
width={196}
title="若需要获取薪酬加密数据,需开启解密。"
isCenter={true}
/>
</WeaFormItem>
</Col>
</Row>
}
<div>
<WeaTextarea
ref={(input) => this.contentProps = input}
minRows={8}
maxRows={8}
value={value}
onChange={(value) => this.handleChange(value)}
noResize={true}
style={{ fontSize: "14px", lineHeight: 1.2 }}
onKeyDown={this.triggerKeyDown}
/>
</div>
<div style={{ display: "flex", height: "300px", marginTop: "10px" }}>
<div style={{
flex: 1,
height: "300px",
overflowY: "scroll",
padding: "10px",
border: "1px solid rgb(217, 217, 217)",
marginRight: "10px"
}}>
<div>
<div style={{ marginBottom: "10px", fontSize: "14px" }}>变量</div>
<div>
{
searchGroup && searchGroup.map(item => {
return <div style={{ height: "25px", lineHeight: "25px", cursor: "pointer", overflow: "hidden" }}
key={item.key} onClick={() => {
this.handleItemClick(item);
}}>
{item.value}
<Icon type="right" style={{ float: "right", marginLeft: "10px", color: "#eee", marginTop: "9px" }}/>
<span style={{ color: "#999", float: "right" }}>{item.value} 的字段</span>
</div>;
})
}
</div>
</div>
</div>
<div style={{
flex: 1,
height: "300px",
overflowY: "scroll",
border: "1px solid rgb(217, 217, 217)",
padding: "10px"
}}>
{
searchFields && searchFields.map(item => {
return (
<div style={{ height: "25px", lineHeight: "25px", cursor: "pointer" }} key={item.fieldId}
onClick={() => {
this.handleFieldClick(item);
}}>
{item.name}
</div>
);
})
}
</div>
</div>
</WeaDialog>
);
}
}