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

511 lines
17 KiB
JavaScript
Raw Normal View History

import React from "react";
2023-04-27 14:52:03 +08:00
import { Button, Col, message, Modal, Row } from "antd";
import { WeaCheckbox, WeaDialog, WeaFormItem, WeaHelpfulTip, WeaInput, WeaSelect } from "ecCom";
import { inject, observer } from "mobx-react";
2023-01-04 11:19:22 +08:00
import { testFormual } from "../../apis/item";
2023-01-04 09:46:20 +08:00
import TestModal from "./testModal";
2023-04-27 14:52:03 +08:00
import ExcelEditor from "../../components/excelEditor";
2023-01-04 11:19:22 +08:00
import "./index.less";
2022-04-18 11:42:45 +08:00
@inject("salaryItemStore")
2022-04-18 11:42:45 +08:00
@observer
export default class FormalFormModal extends React.Component {
constructor(props) {
super(props);
this.state = {
2022-12-07 14:15:46 +08:00
validateType: "",
returnType: "",
value: "",
2023-05-18 16:42:45 +08:00
formula: "",
extendParam: {
2023-05-09 09:57:49 +08:00
isCustomFunction: "0",
sqlReturnKey: "",
openDecrypt: "0",
datasource: {
datasourceId: ""
2022-04-18 11:42:45 +08:00
}
},
returnValue: "",
2023-01-04 09:46:20 +08:00
formulaDatasourceList: [],
2023-01-04 11:19:22 +08:00
testVisible: false,
2023-04-27 14:52:03 +08:00
showTestVal: "",
groupParams: {}
};
this.group = {};
this.field = {};
this.parameters = [];
this.referenceType = "";
this.timer = null;
}
2022-04-18 15:33:19 +08:00
componentWillMount() {
2023-07-25 16:16:39 +08:00
const { salaryItemStore, formulaId, valueType } = this.props;
const { salaryAcctImportTemplateParam, setSearchFields, detailFormual } = salaryItemStore;
setSearchFields([]);
if (!!this.props.formulaId && this.props.formulaId != 0) {
detailFormual({
formulaId,
returnType: (valueType.toString() === "2" || valueType.toString() === "FORMULA") ? "formula" : "sql"
}).then(data => {
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) {
2022-05-05 09:13:38 +08:00
}
this.setState({
extendParam: {
2023-05-09 09:57:49 +08:00
isCustomFunction: extendParam.isCustomFunction || "1",
sqlReturnKey: extendParam.sqlReturnKey,
openDecrypt: extendParam.openDecrypt,
datasource: {
datasourceId: extendParam.datasource ? extendParam.datasource.datasourceId : ""
}
2022-05-05 09:13:38 +08:00
}
});
2022-04-20 15:28:40 +08:00
}
2023-04-27 14:52:03 +08:00
this.setState({
value: data.formula,
2023-05-18 16:42:45 +08:00
formula: data.formula,
2023-04-27 14:52:03 +08:00
returnType: data.returnType,
2023-04-28 10:51:06 +08:00
validateType: data.validateType
2023-04-27 14:52:03 +08:00
});
// salaryAcctImportTemplateParam(groupParams);
});
2023-04-27 14:52:03 +08:00
let groupParams = {};
if (this.props.valueType == "3") {
groupParams = { "referenceType": "sql" };
} else {
groupParams = this.props.backCalcType === "issuedItems" ? { "referenceType": "backCalc" } : {};
}
this.setState({ groupParams });
} else {
let groupParams = {};
if (this.props.valueType == "3") {
groupParams = { "referenceType": "sql" };
2022-12-13 16:10:48 +08:00
} else if (this.props.valueType === "FORMULA") {
groupParams = this.props.backCalcType === "issuedItems" ? { "referenceType": "backCalc" } : {};
this.referenceType = "formula";
2022-12-13 16:10:48 +08:00
this.setState({
value: this.props.formulaContent
});
}
2023-04-27 14:52:03 +08:00
this.setState({ groupParams });
// salaryAcctImportTemplateParam(groupParams);
2022-04-18 11:42:45 +08:00
}
}
2022-04-20 15:28:40 +08:00
componentDidMount() {
this.formulaDatasourceList();
}
componentWillUnmount() {
clearTimeout(this.timer);
}
2022-10-26 16:38:09 +08:00
triggerKeyDown = (e) => {
2022-10-26 17:55:16 +08:00
let propsTextarea = this.contentProps.refs.textareaNormal.refs.input.refs.input; // 获取dom节点实例
const { value } = this.state;
if (e.key === "Backspace" && value) {
2022-10-26 16:38:09 +08:00
const { end } = this.getPositionForTextArea(propsTextarea);
const str = value.substring(end - 1, end);
2022-10-26 16:38:09 +08:00
if (str === "}") {
e.preventDefault();
const index = value.lastIndexOf("{", end - 1);
const currentValue = value.substring(index, end);
2022-10-26 16:38:09 +08:00
this.setState({
value: value.replace(currentValue, "")
}, () => {
if (propsTextarea.setSelectionRange) {
this.timer = setTimeout(() => {
propsTextarea.setSelectionRange(index, index);
}, 0);
}
2022-10-26 16:38:09 +08:00
});
}
}
};
formulaDatasourceList = () => {
const { salaryItemStore } = this.props;
const { formulaDatasourceList } = salaryItemStore;
formulaDatasourceList().then(({ status, data }) => {
if (status) {
2022-04-18 11:42:45 +08:00
this.setState({
formulaDatasourceList: [{
key: "",
showname: ""
}, ..._.map(data, it => ({ key: it, showname: it }))]
});
}
});
};
// 多行文本编辑
2023-04-27 14:52:03 +08:00
handleChange = (value) => {
if (value && value.trim() == "") {
this.parameters = [];
2022-04-18 15:33:19 +08:00
}
2022-10-27 10:29:13 +08:00
this.setState({
2023-04-27 14:52:03 +08:00
value
2022-10-27 10:29:13 +08:00
});
2023-04-27 14:52:03 +08:00
};
2022-05-06 10:11:45 +08:00
// 获取光标位置
getPositionForTextArea(ctrl) {
let CaretPos = {
start: 0,
end: 0
};
if (ctrl.selectionStart) {// Firefox support
CaretPos.start = ctrl.selectionStart;
}
if (ctrl.selectionEnd) {
CaretPos.end = ctrl.selectionEnd;
2022-05-06 10:11:45 +08:00
}
return (CaretPos);
}
2022-05-06 10:11:45 +08:00
// 分组项被点击
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"
2022-05-05 09:13:38 +08:00
}
};
2022-04-18 15:33:19 +08:00
}
formualSearchField(item.key, params);
}
2022-04-18 15:33:19 +08:00
// 保存
2023-01-04 11:19:22 +08:00
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;
2022-04-18 15:33:19 +08:00
}
});
if (!flag) {
result.push(item);
}
});
this.parameters = result;
let params = {
2023-08-31 15:02:56 +08:00
name: this.props.name || "公式1",
description: "备注",
module: "salary",
useFor: "salaryitem",
2022-12-07 14:15:46 +08:00
returnType: this.props.dataType || this.state.returnType,
validateType: this.props.dataType || this.state.returnType,
extendParam: JSON.stringify(this.state.extendParam),
2023-04-27 14:52:03 +08:00
formula: this.state.value.replace(/[\r\n]/g, ""),
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();
});
2023-01-04 11:19:22 +08:00
};
2022-04-18 16:57:42 +08:00
/**
* 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;
2022-04-18 11:42:45 +08:00
}
};
2022-04-18 15:33:19 +08:00
// 字段点击回调
handleFieldClick(item) {
this.field = item;
let fieldName = "{" + this.group.value + "." + this.field.name + "}";
2022-05-06 12:25:32 +08:00
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); // 光标的位置
2023-01-04 11:39:00 +08:00
this.forceUpdate();
}
2022-04-18 15:33:19 +08:00
2023-01-04 11:19:22 +08:00
handleChangeTestValue = (record, value) => {
if (!record && !value) {
this.parameters = _.map(this.parameters, item => ({ ...item, content: null }));
this.setState({
showTestVal: "显示结果"
});
} else {
this.parameters = _.map(this.parameters, item => {
if (item.id === record.id) {
return {
...item,
content: value
};
}
return { ...item };
});
}
this.forceUpdate();
};
handleImplement = () => {
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 = {
2023-03-07 16:15:17 +08:00
// 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,
2023-01-04 11:19:22 +08:00
parameters: this.parameters,
2023-03-07 16:15:17 +08:00
id: this.props.formulaId
// referenceType: this.referenceType == "" ? this.props.valueType == "2" ? "formula" : this.props.valueType == "3" ? "sql" : "" : this.referenceType
2023-01-04 11:19:22 +08:00
};
testFormual(params).then(({ status, data, errormsg }) => {
if (status) {
message.success("测试结果已更新");
this.setState({
showTestVal: data
});
} else {
message.error(errormsg || "");
}
});
};
2023-05-09 09:57:49 +08:00
handleChangeCustomFunction = (isCustomFunction) => {
const { extendParam } = this.state;
this.setState({
extendParam: {
...extendParam,
isCustomFunction
}
});
};
2023-01-04 11:19:22 +08:00
render() {
const { salaryItemStore } = this.props;
const { searchGroup, searchFields } = salaryItemStore;
2023-05-18 16:42:45 +08:00
const { value, formula, formulaDatasourceList, extendParam, testVisible, showTestVal, groupParams } = this.state;
2023-01-03 10:36:13 +08:00
const title = <div className="formulaTitleWrapper">
<div>{`${(this.props.valueType == 2 || this.props.valueType === "FORMULA") ? "函数" : "SQL"}公式`}</div>
2023-01-04 09:46:20 +08:00
{
2023-05-26 15:51:05 +08:00
!_.isEmpty(value) && <Button type="primary" onClick={() => {
2023-01-06 09:35:34 +08:00
const isSaveBool = _.every(this.parameters, it => !!it.id);
2023-05-26 15:51:05 +08:00
if (value === formula) {
2023-01-06 09:35:34 +08:00
this.setState({ testVisible: true });
} else {
message.info("请先保存公式后再进行测试");
}
}}>测试</Button>
2023-01-04 09:46:20 +08:00
}
{/*公式测试*/}
2023-01-04 11:19:22 +08:00
<TestModal visible={testVisible} testParams={value} parameters={this.parameters}
showTestVal={showTestVal}
onChangeTestValue={this.handleChangeTestValue}
onImplement={this.handleImplement}
onCancel={() => this.setState({ testVisible: false }, () => this.handleChangeTestValue())}/>
2023-01-03 10:36:13 +08:00
</div>;
return (
<WeaDialog
2023-05-26 15:51:05 +08:00
title={title} hasScroll scalable className="formula-wrapper" initLoadCss
visible={this.props.visible} style={{ width: 1000 }}
buttons={[
2023-01-04 11:19:22 +08:00
<Button type="primary" onClick={this.handleSave}>保存</Button>
]}
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>
}
2023-05-09 09:57:49 +08:00
<ExcelEditor value={value} groupParams={groupParams} isCustomFunction={extendParam.isCustomFunction}
onChange={(value) => this.handleChange(value)}
onChangeCustomFunction={this.handleChangeCustomFunction}/>
2023-04-27 14:52:03 +08:00
{/*<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>
);
}
}