薪资项目管理页面添加sql项的数据源选项

This commit is contained in:
liyongshun 2022-08-03 17:54:47 +08:00
parent f8f485c6a7
commit ae3af8e59e
11 changed files with 850 additions and 757 deletions

View File

@ -12,7 +12,7 @@ export const getItemList = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
};
@ -22,6 +22,11 @@ export const getSaCondition = params => {
return WeaTools.callApi('/api/bs/hrmsalary/salaryitem/getSearchCondition', 'GET', params);
};
//数据源列表字典项
export const formulaDatasourceList = params => {
return WeaTools.callApi('/api/bs/hrmsalary/formula/datasource/list', 'GET', params);
};
//薪资项目-系统薪资项目列表
export const getSysItemList = params => {
return fetch('/api/bs/hrmsalary/salaryitem/sysList', {
@ -29,7 +34,7 @@ export const getSysItemList = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
};
@ -46,7 +51,7 @@ export const deleteItem = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -58,7 +63,7 @@ export const deleteItemList = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -70,7 +75,7 @@ export const saveItem = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -92,7 +97,7 @@ export const saveSysItem = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -110,7 +115,7 @@ export const formualSearchGroup = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -122,7 +127,7 @@ export const formualSearchField = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -135,7 +140,7 @@ export const saveFormual = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}
@ -156,7 +161,7 @@ export const listCanDelete = params => {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
},
body: JSON.stringify(params)
}).then(res => res.json())
}

View File

@ -1,8 +1,12 @@
import React from "react";
import { WeaTable } from "ecCom";
import React, { PureComponent } from "react";
import CustomTable from "../../components/customTable";
export default class CustomPaginationTable extends React.Component {
class CustomPaginationTable extends PureComponent {
shouldComponentUpdate(nextProps, nextState, nextContext) {
if (nextProps.columnIndex && this.props.columnIndex !== nextProps.columnIndex) return false;
return true;
}
render() {
return (
<CustomTable
@ -20,10 +24,12 @@ export default class CustomPaginationTable extends React.Component {
pageSize: this.props.pageSize,
onShowSizeChange: (current, pageSize) => {
this.props.onShowSizeChange &&
this.props.onShowSizeChange(current, pageSize);
this.props.onShowSizeChange(current, pageSize);
}
}}
/>
);
}
}
export default CustomPaginationTable;

View File

@ -1,12 +1,12 @@
import React from 'react';
import { WeaSteps, WeaDatePicker, WeaInput, WeaSelect } from 'ecCom';
import { Upload, Icon, Modal, Row, Col, Button, message } from "antd";
import { inject, observer } from 'mobx-react';
import { toJS } from 'mobx';
import React from "react";
import { WeaSteps } from "ecCom";
import { message, Modal, Upload } from "antd";
import { inject, observer } from "mobx-react";
import { toJS } from "mobx";
import ModalStep1 from './modalStep1'
import ModalStep2 from './modalStep2'
import ModalStep3 from './modalStep3'
import ModalStep1 from "./modalStep1";
import ModalStep2 from "./modalStep2";
import ModalStep3 from "./modalStep3";
const Dragger = Upload.Dragger;
@ -15,127 +15,127 @@ const Step = WeaSteps.Step;
@inject("taxAgentStore")
@observer
export default class ImportModal extends React.Component {
constructor(props) {
super(props)
this.state = {
fileId: ""
constructor(props) {
super(props);
this.state = {
fileId: ""
};
this.props.init && this.props.init();
}
componentWillMount() { // 初始化渲染页面
// const { taxAgentStore: {fetchTaxAgentOption} } = this.props;
// fetchTaxAgentOption();
}
nextStep() {
const { step } = this.props;
this.props.setStep(step + 1);
}
preStep() {
const { step } = this.props;
this.props.setStep(step - 1);
}
validateDate() {
const { params } = this.props;
let flag = true;
try {
params && Object.keys(params).forEach((key) => {
if (!params[key] || params[key] == "") {
message.warning("请完善导入选项");
throw new Error("请完善导入选项");
}
});
} catch (e) {
flag = false;
}
return flag;
}
handleStep1Next() {
if (!this.validateDate()) {
return;
}
if (this.state.fileId) {
this.props.setStep(1);
} else {
message.warning("请上传文件");
}
}
handlePreviewDate() {
const { fileId } = this.state;
const { params } = this.props;
this.props.previewImport({
...params,
imageId: fileId
});
}
hanleImportData() {
const { fileId } = this.state;
const { params } = this.props;
this.props.importFile({
...params,
imageId: fileId
});
}
render() {
const { step, slideDataSource, isInit } = this.props;
return (
<Modal title="数据导入" visible={this.props.visiable}
onCancel={this.props.onCancel}
width={850} className="cumDeductModal"
footer={null}
>
<div className="stepWrapper">
<WeaSteps current={step}>
<Step description="上传Excel"/>
<Step description="数据预览"/>
<Step description="导入数据"/>
</WeaSteps>
</div>
{
this.props.step == 0 && (<ModalStep1
isInit={isInit}
templateLink={this.props.templateLink}
headerSetCompoent={this.props.headerSetCompoent}
formComponent={this.props.renderFormComponent && this.props.renderFormComponent()}
onFileIdChange={(fileId) => {
this.setState({ fileId });
}}
onStep1Next={() => {
this.handleStep1Next();
}}/>)
}
{
this.props.step == 1 && (<ModalStep2
onPreviewDate={() => this.handlePreviewDate()}
dataSource={slideDataSource}
columns={this.props.columns}
onStep2Next={() => {
this.nextStep();
this.hanleImportData();
}} onStep2Pre={() => {
this.preStep();
}}/>)
}
{
this.props.step == 2 && (<ModalStep3
// onImportData={() => this.hanleImportData()}
importResult={toJS(this.props.importResult)}
onFinish={() => {
this.props.onFinish();
}}/>)
}
this.props.init && this.props.init()
}
componentWillMount() { // 初始化渲染页面
// const { taxAgentStore: {fetchTaxAgentOption} } = this.props;
// fetchTaxAgentOption();
}
nextStep() {
const { step } = this.props;
this.props.setStep(step + 1)
}
preStep() {
const { step } = this.props;
this.props.setStep(step - 1);
}
validateDate() {
const { params } = this.props;
let flag = true
try {
params && Object.keys(params).forEach((key) => {
if(!params[key] || params[key] == "") {
message.warning("请完善导入选项");
throw new Error("请完善导入选项")
}
})
} catch(e) {
flag = false
}
return flag;
}
handleStep1Next() {
if(!this.validateDate()) {
return
}
if(this.state.fileId) {
this.props.setStep(1)
} else {
message.warning("请上传文件")
}
}
handlePreviewDate() {
const { fileId } = this.state;
const { params } = this.props;
this.props.previewImport({
...params,
imageId: fileId
})
}
hanleImportData() {
const { fileId } = this.state;
const { params } = this.props;
this.props.importFile({
...params,
imageId: fileId,
})
}
render() {
const { step, slideDataSource, isInit } = this.props;
return (
<Modal title="数据导入" visible={this.props.visiable}
onCancel={this.props.onCancel}
width={850} className="cumDeductModal"
footer={null}
>
<div className="stepWrapper">
<WeaSteps current={step}>
<Step description="上传Excel" />
<Step description="数据预览" />
<Step description="导入数据" />
</WeaSteps>
</div>
{
this.props.step == 0 && (<ModalStep1
isInit={ isInit }
templateLink={this.props.templateLink}
headerSetCompoent={this.props.headerSetCompoent}
formComponent={this.props.renderFormComponent && this.props.renderFormComponent()}
onFileIdChange={(fileId) => {
this.setState({fileId})
}}
onStep1Next={() => {
this.handleStep1Next();
}}/>)
}
{
this.props.step == 1 && (<ModalStep2
onPreviewDate={() => this.handlePreviewDate()}
dataSource={slideDataSource}
columns={this.props.columns}
onStep2Next={() => {
this.nextStep();
this.hanleImportData()
}} onStep2Pre={() => {
this.preStep()
}}/>)
}
{
this.props.step == 2 && (<ModalStep3
// onImportData={() => this.hanleImportData()}
importResult={toJS(this.props.importResult)}
onFinish={() => {
this.props.onFinish()
}}/>)
}
</Modal>
)
}
</Modal>
);
}
}

View File

@ -1,158 +1,157 @@
import React from 'react'
import { WeaSteps, WeaDatePicker, WeaInput, WeaSelect, message, WeaCheckbox } from 'ecCom';
import { inject, observer } from 'mobx-react';
import { Upload, Icon, Row, Col, Button } from "antd";
import uploadImg from './upload.svg'
import React from "react";
import { WeaCheckbox } from "ecCom";
import { inject, observer } from "mobx-react";
import { Button, Icon, Upload } from "antd";
const Dragger = Upload.Dragger;
@inject("taxAgentStore")
@observer
export default class ModalStep1 extends React.Component {
constructor(props) {
super(props)
this.state = {
datetime: "",
taxAgentId: "",
hasData: "0",
fileList: []
}
}
constructor(props) {
super(props);
this.state = {
datetime: "",
taxAgentId: "",
hasData: "0",
fileList: []
};
}
componentWillMount() { // 初始化渲染页面
// const { taxAgentStore: {fetchTaxAgentOption} } = this.props;
// fetchTaxAgentOption();
}
componentWillMount() { // 初始化渲染页面
// const { taxAgentStore: {fetchTaxAgentOption} } = this.props;
// fetchTaxAgentOption();
}
handleChange(info) {
let fileList = info.fileList;
handleChange(info) {
let fileList = info.fileList;
// 1. 上传列表数量的限制
// 只显示最近上传的一个,旧的会被新的顶掉
fileList = fileList.slice(-1);
// 2. 读取远程路径并显示链接
fileList = fileList.map((file) => {
if (file.response) {
// 组件会将 file.url 作为链接进行展示
file.url = file.response.url;
}
return file;
});
// 3. 按照服务器返回信息筛选成功上传的文件
fileList = fileList.filter((file) => {
if (file.response) {
return file.response.status === 1;
}
return true;
});
if(fileList && fileList.length > 0 && fileList[0].response && fileList[0].response.status === 1) {
this.props.onFileIdChange(fileList[0].response.data.fileid)
}
this.setState({ fileList });
// 1. 上传列表数量的限制
// 只显示最近上传的一个,旧的会被新的顶掉
fileList = fileList.slice(-1);
// 2. 读取远程路径并显示链接
fileList = fileList.map((file) => {
if (file.response) {
// 组件会将 file.url 作为链接进行展示
file.url = file.response.url;
}
return file;
});
render() {
const { datetime, taxAgentId, hasData } = this.state
const { taxAgentStore: {taxAgentOption}, isInit } = this.props;
let downloadExtra= '';
if(isInit){
downloadExtra= hasData === '1' ? `&hasData=true` : `&hasData=false`;
}
const dragger = {
accept: ".xlsx",
name: 'file',
multiple: false,
action: "/api/doc/upload/uploadFile", //上传地址
onChange: (info) => {
this.handleChange(info)
},
};
return (
<div style={{ height: "550px", display: "flex", flexFlow: "column"}}>
<div style={{ flex: "1", overflow: "scroll" }}>
{
this.props.formComponent && <div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
导入选项
</div>
<div className="formWrapper" style={{ border: "1px solid #eee", borderRadiu: "5px", padding: "10px" }}>
{this.props.formComponent}
</div>
</div>
}
// 3. 按照服务器返回信息筛选成功上传的文件
fileList = fileList.filter((file) => {
if (file.response) {
return file.response.status === 1;
}
return true;
});
<div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
导入Excel
</div>
<div>
<Dragger {...dragger} fileList={this.state.fileList}>
<div style={{ padding: '25px 0' }}>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<p className="ant-upload-text">点击或将文件拖拽到此区域上传</p>
<p className="ant-upload-hint">支持单个或批量上传严禁上传公司内部资料及其他违禁文件</p>
</div>
</Dragger>
</div>
</div>
<div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
操作步骤
</div>
<div style={{ lineHeight: "30px" }}>
<p>1. 第一步请选择导出的Excel文件或
{
(typeof this.props.templateLink) == "string" ?
<a href={`${this.props.templateLink}${downloadExtra}`}>点击这里下载模板</a>
:
<a onClick={() => {
this.props.templateLink(hasData === '1' ? `true` : `false`)
}}>点击这里下载模板</a>
}
{this.props.headerSetCompoent && this.props.headerSetCompoent };
{
this.props.isInit &&
<WeaCheckbox
value={hasData}
content="导出现有数据"
helpfulTip="提示:建议先导出现有最新数据,修改后再导入"
style={{ marginLeft: 10 }}
onChange={(hasData)=> this.setState({hasData})}
/>
}
</p>
<p>2. 第二步请一定要确定Excel文档中的格式是模板中的格式没有被修改掉</p>
<p>3. 第三步选择填写好的Excel文档点击下一步按钮进行数据预览</p>
<p>4. 第四步如果以上步骤和Excel文档正确的话数据会被正确导入导入成功会有提示如果有问题则会提示Excel文档的错误之处</p>
</div>
</div>
<div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
Excel文件说明
</div>
<div style={{ lineHeight: "30px" }}>
1. 后缀名为xls或者xlsx<br />
2. 数据请勿放在合并的单元格中<br />
</div>
</div>
</div>
<div className="footerBtnWrapper" style={{ overflow: "hidden", height: "30px" }}>
<Button type="primary" style={{ float: "right" }} onClick={this.props.onStep1Next}>下一步</Button>
</div>
</div>
)
if (fileList && fileList.length > 0 && fileList[0].response && fileList[0].response.status === 1) {
this.props.onFileIdChange(fileList[0].response.data.fileid);
}
this.setState({ fileList });
}
render() {
const { datetime, taxAgentId, hasData } = this.state;
const { taxAgentStore: { taxAgentOption }, isInit } = this.props;
let downloadExtra = "";
if (isInit) {
downloadExtra = hasData === "1" ? `&hasData=true` : `&hasData=false`;
}
const dragger = {
accept: ".xlsx",
name: "file",
multiple: false,
action: "/api/doc/upload/uploadFile", //上传地址
onChange: (info) => {
this.handleChange(info);
}
};
return (
<div style={{ height: "550px", display: "flex", flexFlow: "column" }}>
<div style={{ flex: "1", overflow: "scroll" }}>
{
this.props.formComponent && <div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
导入选项
</div>
<div className="formWrapper" style={{ border: "1px solid #eee", borderRadiu: "5px", padding: "10px" }}>
{this.props.formComponent}
</div>
</div>
}
<div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
导入Excel
</div>
<div>
<Dragger {...dragger} fileList={this.state.fileList}>
<div style={{ padding: "25px 0" }}>
<p className="ant-upload-drag-icon">
<Icon type="inbox"/>
</p>
<p className="ant-upload-text">点击或将文件拖拽到此区域上传</p>
<p className="ant-upload-hint">支持单个或批量上传严禁上传公司内部资料及其他违禁文件</p>
</div>
</Dragger>
</div>
</div>
<div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
操作步骤
</div>
<div style={{ lineHeight: "30px" }}>
<p>1. 第一步请选择导出的Excel文件或
{
(typeof this.props.templateLink) == "string" ?
<a href={`${this.props.templateLink}${downloadExtra}`}>点击这里下载模板</a>
:
<a onClick={() => {
this.props.templateLink(hasData === "1" ? `true` : `false`);
}}>点击这里下载模板</a>
}
{this.props.headerSetCompoent && this.props.headerSetCompoent};
{
this.props.isInit &&
<WeaCheckbox
value={hasData}
content="导出现有数据"
helpfulTip="提示:建议先导出现有最新数据,修改后再导入"
style={{ marginLeft: 10 }}
onChange={(hasData) => this.setState({ hasData })}
/>
}
</p>
<p>2. 第二步请一定要确定Excel文档中的格式是模板中的格式没有被修改掉</p>
<p>3. 第三步选择填写好的Excel文档点击下一步按钮进行数据预览</p>
<p>4. 第四步如果以上步骤和Excel文档正确的话数据会被正确导入导入成功会有提示如果有问题则会提示Excel文档的错误之处</p>
</div>
</div>
<div className="stepInformItem">
<div className="stepInformTitle" style={{ margin: "10px 0 10px 0" }}>
Excel文件说明
</div>
<div style={{ lineHeight: "30px" }}>
1. 后缀名为xls或者xlsx<br/>
2. 数据请勿放在合并的单元格中<br/>
</div>
</div>
</div>
<div className="footerBtnWrapper" style={{ overflow: "hidden", height: "30px" }}>
<Button type="primary" style={{ float: "right" }} onClick={this.props.onStep1Next}>下一步</Button>
</div>
</div>
);
}
}

View File

@ -1,164 +1,180 @@
import React from 'react'
import ImportModal from '../../../../components/importModal'
import { Button } from 'antd'
import { inject, observer } from 'mobx-react';
import SelectFieldModal from './selectFieldModal';
import React from "react";
import ImportModal from "../../../../components/importModal";
import { Button, message } from "antd";
import { inject, observer } from "mobx-react";
import SelectFieldModal from "./selectFieldModal";
@inject('calculateStore')
@inject("calculateStore")
@observer
export default class AcctResultImportModal extends React.Component {
constructor(props) {
super(props)
this.state = {
modalParam: {
salaryAcctRecordId: "",
salaryItemIds: ""
},
step: 0,
selectFieldVisible: false
constructor(props) {
super(props);
this.state = {
modalParam: {
salaryAcctRecordId: "",
salaryItemIds: ""
},
step: 0,
selectFieldVisible: false
};
}
componentWillMount() {
const { id } = this.props;
let modalParam = { ...this.state.modalParam };
modalParam.salaryAcctRecordId = id;
this.setState({
modalParam
});
}
// 获取模板
handleAccResultTemplateLink() {
const { calculateStore: { getImportTemplate } } = this.props;
if (_.isEmpty(this.state.modalParam.salaryItemIds)) {
message.warning("请选择表单字段");
return;
}
getImportTemplate(this.state.modalParam.salaryItemIds, this.state.modalParam.salaryAcctRecordId);
}
// 设置步骤
setStep(step) {
this.setState({ step });
}
// 完成
handleFinish() {
this.setState({ step: 0 });
this.props.onCancel();
const { calculateStore: { acctResultList } } = this.props;
acctResultList(this.props.id);
}
// 关闭
handleCancel() {
this.setState({
modalVisiable: false,
step: 0
});
}
// 渲染第一步表单
renderFormComponent() {
return <Button onClick={() => {
this.handleSelectedField();
}}>请选择表单字段</Button>;
}
// 选择表单字段
handleSelectedField() {
this.setState({
selectFieldVisible: true
});
}
// 添加表头字段
handleAdd(fieldDate) {
let salaryItemIdsList = [];
fieldDate.formulaItems.map(item => {
if (item.checked) {
salaryItemIdsList.push(item.salaryItemId);
}
});
fieldDate.inputItems.map(item => {
if (item.checked) {
salaryItemIdsList.push(item.salaryItemId);
}
});
let salaryItemIds = "";
if (salaryItemIdsList.length > 0) {
salaryItemIds = salaryItemIdsList.join(",");
}
let modalParam = { ...this.state.modalParam };
modalParam.salaryItemIds = salaryItemIds;
this.setState({
modalParam
});
this.props.onAdd(fieldDate);
}
// 初始化Import数据
handleImportModalInit() {
const {
calculateStore: {
setPreviewAcctResultColumns,
setPreviewAcctResultDataSource,
setImportAcctResult
}
} = this.props;
setPreviewAcctResultColumns([]);
setPreviewAcctResultDataSource([]);
setImportAcctResult({});
}
render() {
const { calculateStore } = this.props;
const {
fetchPreviewAcctResult,
previewAcctResultColumns,
previewAcctResultDataSource,
importAcctResult,
fetchImportAcctResult
} = calculateStore;
const { step, selectFieldVisible, modalParam } = this.state;
const { visiable } = this.props;
return (
<div>
{
visiable && <ImportModal
init={() => {
this.handleImportModalInit();
}}
params={modalParam}
columns={previewAcctResultColumns}
step={step}
setStep={this.setStep.bind(this)}
slideDataSource={previewAcctResultDataSource}
importResult={importAcctResult}
onFinish={() => {
this.handleFinish();
}}
previewImport={(params) => {
fetchPreviewAcctResult(params);
}}
importFile={(params) => {
fetchImportAcctResult(params);
}}
templateLink={() => {
this.handleAccResultTemplateLink();
}}
renderFormComponent={() => this.renderFormComponent()}
visiable={visiable}
onCancel={() => {
this.props.onCancel();
}}
/>
}
}
componentWillMount() {
const { id } = this.props;
let modalParam = { ...this.state.modalParam }
modalParam.salaryAcctRecordId = id
this.setState({
modalParam
})
}
// 获取模板
handleAccResultTemplateLink() {
const { calculateStore: { getImportTemplate }} = this.props;
getImportTemplate(this.state.modalParam.salaryItemIds, this.state.modalParam.salaryAcctRecordId)
}
// 设置步骤
setStep(step) {
this.setState({step})
}
// 完成
handleFinish() {
this.setState({step: 0})
this.props.onCancel()
const { calculateStore: { acctResultList } } = this.props;
acctResultList(this.props.id)
}
// 关闭
handleCancel() {
this.setState({
modalVisiable: false,
step: 0
})
}
// 渲染第一步表单
renderFormComponent() {
return <Button onClick={() => {
this.handleSelectedField()
}}>请选择表单字段</Button>
}
// 选择表单字段
handleSelectedField() {
this.setState({
selectFieldVisible: true
})
}
// 添加表头字段
handleAdd(fieldDate) {
let salaryItemIdsList = []
fieldDate.formulaItems.map(item => {
if(item.checked) {
salaryItemIdsList.push(item.salaryItemId)
}
})
fieldDate.inputItems.map(item => {
if(item.checked) {
salaryItemIdsList.push(item.salaryItemId)
}
})
let salaryItemIds = ""
if(salaryItemIdsList.length > 0) {
salaryItemIds = salaryItemIdsList.join(",")
{
selectFieldVisible && <SelectFieldModal
id={this.props.id}
visible={selectFieldVisible}
fieldData={this.props.fieldData}
onAdd={(fieldDate) => {
this.handleAdd(fieldDate);
}}
onCancel={() => {
this.setState({
selectFieldVisible: false
});
}}
/>
}
let modalParam = { ...this.state.modalParam }
modalParam.salaryItemIds = salaryItemIds
this.setState({
modalParam
})
this.props.onAdd(fieldDate)
}
// 初始化Import数据
handleImportModalInit() {
const { calculateStore: {setPreviewAcctResultColumns, setPreviewAcctResultDataSource, setImportAcctResult}} = this.props;
setPreviewAcctResultColumns([])
setPreviewAcctResultDataSource([])
setImportAcctResult({})
}
render() {
const { calculateStore } = this.props;
const { fetchPreviewAcctResult, previewAcctResultColumns, previewAcctResultDataSource, importAcctResult, fetchImportAcctResult } = calculateStore
const { step, selectFieldVisible, modalParam } = this.state;
const { visiable } = this.props;
return (
<div>
{
visiable && <ImportModal
init={() => {
this.handleImportModalInit();
}}
params={modalParam}
columns={previewAcctResultColumns}
step={step}
setStep={this.setStep.bind(this)}
slideDataSource={previewAcctResultDataSource}
importResult={importAcctResult}
onFinish={() => {
this.handleFinish()
}}
previewImport={(params) => {
fetchPreviewAcctResult(params)
}}
importFile={(params) => {
fetchImportAcctResult(params)
}}
templateLink={ () => {
this.handleAccResultTemplateLink()
}}
renderFormComponent={() => this.renderFormComponent()}
visiable={visiable}
onCancel={() => {
this.props.onCancel()
}}
/>
}
{
selectFieldVisible && <SelectFieldModal
id={this.props.id}
visible={selectFieldVisible}
fieldData={this.props.fieldData}
onAdd={(fieldDate) => {
this.handleAdd(fieldDate)
}}
onCancel={() => {
this.setState({
selectFieldVisible: false
})
}}
/>
}
</div>
)
}
}
</div>
);
}
}

View File

@ -1,5 +1,4 @@
import React from "react";
import { salaryDetailColumns } from "./columns";
import { WeaHelpfulTip, WeaSlideModal } from "ecCom";
import WarningModal from "./warningModal";
import "./index.less";
@ -7,7 +6,7 @@ import EditSalaryDetail from "./editSalaryDetail";
import SlideModalTitle from "../../components/slideModalTitle";
import { getQueryString } from "../../util/url";
import { inject, observer } from "mobx-react";
import { toJS } from 'mobx';
import { toJS } from "mobx";
import CustomPaginationTable from "../../components/customPaginationTable";
@inject("calculateStore", "taxAgentStore")
@ -16,20 +15,10 @@ export default class SalaryDetail extends React.Component {
constructor(props) {
super(props);
this.state = {
columnIndex:"",
columnIndex: "",
visible: false,
slideVisiable: false,
columns: salaryDetailColumns.map(item => {
if (item.dataIndex == "cz") {
item.render = () => {
return (
<a onClick={() => {
this.setState({ slideVisiable: true });
}}>编辑</a>
);
};
}
})
columns: []
};
this.recordId = "";
this.id = "";
@ -40,38 +29,26 @@ export default class SalaryDetail extends React.Component {
let id = getQueryString("id");
this.id = id;
const { calculateStore: { acctResultList, getSalarySobCycle } } = this.props;
acctResultList({ salaryAcctRecordId: id });
acctResultList({ salaryAcctRecordId: id }).then(res => {
this.getColumns(res);
});
getSalarySobCycle(id);
}
headerSetCompoent() {
return (
<div style={{ display: "inline-block" }}>
<WeaCheckbox id="test" content="导出现有数据"/>
<WeaHelpfulTip
width={200}
title="提示建议先导出现有最新数据修改后再导入\n
若只需要导出部分数据请先筛选列表"
placement="topLeft"
/>
</div>
);
}
// 获取列表的列
getColumns() {
getColumns = (column) => {
const { calculateStore: { acctResultListColumns } } = this.props;
let columns = acctResultListColumns ? [...acctResultListColumns] : [];
let columns = toJS(acctResultListColumns) ? [...toJS(acctResultListColumns)] : [...column];
columns = columns.filter(item => item.hide == "FALSE").map(item => {
let result = { ...item };
result.title = <span onClick={()=>this.setState({columnIndex: item.column})}>{item.text}</span>;;
result.title = <span onClick={() => this.setState({ columnIndex: item.column })}>{item.text}</span>;
result.dataIndex = item.column;
result.oldWidth = result.width;
result.width = "150px";
if (result.children) {
result.width = (result.children.length * 150) + "px";
result.children.map(child => {
child.title = <span onClick={()=>this.setState({columnIndex: child.column})}>{child.text}</span>;
child.title = <span onClick={() => this.setState({ columnIndex: child.column })}>{child.text}</span>;
child.dataIndex = child.column;
child.width = "150px";
});
@ -97,8 +74,10 @@ export default class SalaryDetail extends React.Component {
}}>编辑</a>;
}
});
return columns;
}
this.setState({
columns
});
};
// 编辑时间回调
handleEdit(record) {
@ -132,7 +111,7 @@ export default class SalaryDetail extends React.Component {
}
render() {
const { slideVisiable, columnIndex } = this.state;
const { slideVisiable, columnIndex, columns } = this.state;
const { calculateStore, taxAgentStore: { showOperateBtn } } = this.props;
const {
acctResultListDateSource,
@ -170,9 +149,10 @@ export default class SalaryDetail extends React.Component {
</div>
<div className="tableWrapper">
<CustomPaginationTable
columnIndex={columnIndex}
loading={loading}
dataSource={acctResultListDateSource}
columns={this.getColumns()}
columns={columns}
total={acctResultListPageInfo.total}
current={acctResultListPageInfo.pageNum}
pageSize={this.pageInfo.pageSize}

View File

@ -1,257 +1,323 @@
import React from 'react'
import {Modal, Button, Icon } from 'antd'
import { WeaTextarea, WeaInput } from 'ecCom'
import { inject, observer } from 'mobx-react';
import ValidRuleEditModal from '../ledger/step5/ValidRuleEditModal';
import React from "react";
import { Button, Col, Icon, Modal, Row } from "antd";
import { WeaFormItem, WeaInput, WeaSelect, WeaTextarea } from "ecCom";
import { inject, observer } from "mobx-react";
import "./index.less";
@inject('salaryItemStore')
@inject("salaryItemStore")
@observer
export default class FormalFormModal extends React.Component {
constructor(props) {
super(props)
this.state = {
value: '',
returnValue: ""
constructor(props) {
super(props);
this.state = {
value: "",
extendParam:{
sqlReturnKey: '',
datasource:{
datasourceId: "",
}
this.group = {};
this.field = {};
this.parameters = []
this.referenceType = ""
}
},
returnValue: "",
formulaDatasourceList: []
};
this.group = {};
this.field = {};
this.parameters = [];
this.referenceType = "";
}
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
})
this.parameters = data.parameters
this.referenceType = data.referenceType
this.extendParam = data.extendParam
if(this.extendParam && this.extendParam.length > 0) {
this.extendParam.replace("\'", "\"")
let extendParam = {}
try {
extendParam = JSON.parse(this.extendParam)
} catch (ex) {
}
this.setState({
returnValue: extendParam.sqlReturnKey ? extendParam.sqlReturnKey : ""
})
}
let groupParams = {}
if(this.referenceType == 'sql') {
groupParams = {'referenceType':'sql'}
}
salaryAcctImportTemplateParam(groupParams);
})
} else {
let groupParams = {}
if(this.props.valueType == "3") {
groupParams = {'referenceType':'sql'}
}
salaryAcctImportTemplateParam(groupParams);
}
}
// 多行文本编辑
handleChange(value) {
if(value && value.trim() == "") {
this.parameters = []
}
componentWillMount() {
const { salaryItemStore } = this.props;
const { salaryAcctImportTemplateParam, setSearchFields, detailFormual } = salaryItemStore;
setSearchFields([]);
if (this.props.formulaId) {
detailFormual(this.props.formulaId).then(data => {
this.setState({
value
})
console.log("value: ", value);
}
value: data.formula
});
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) {
// 获取光标位置
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'
}
}
this.setState({
extendParam: {
sqlReturnKey: extendParam.sqlReturnKey,
datasource:{
datasourceId: extendParam.datasource ? extendParam.datasource.datasourceId : '',
}
}
});
}
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',
referenceType:'',
returnType:'number',
validateType:'number',
extendParam: this.state.returnValue && this.state.returnValue !== '' ? '{"sqlReturnKey":"'+this.state.returnValue+'"}' : "{}",
formula: this.state.value,
parameters: this.parameters,
referenceType: this.referenceType == "" ? this.props.valueType == "2" ? "formula" : this.props.valueType == "3" ? "sql" : "" : this.referenceType
let groupParams = {};
if (this.referenceType == "sql") {
groupParams = { "referenceType": "sql" };
}
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;
salaryAcctImportTemplateParam(groupParams);
});
} else {
let groupParams = {};
if (this.props.valueType == "3") {
groupParams = { "referenceType": "sql" };
}
salaryAcctImportTemplateParam(groupParams);
}
}
// 字段点击回调
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
componentDidMount() {
this.formulaDatasourceList();
}
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"
}
this.parameters.push(parameterItem)
let propsTextarea = this.contentProps.refs.textareaNormal.refs.input.refs.input; // 获取dom节点实例
let position = this.insertText(propsTextarea,fieldName); // 光标的位置
};
}
formualSearchField(item.key, params);
}
render() {
const {salaryItemStore} = this.props;
const { searchGroup, searchFields } = salaryItemStore
const { value } = this.state;
return (
<Modal title="函数公式" visible={this.props.visible}
maskClosable={false}
width={800}
footer={
<Button type="primary" onClick={() => {
this.handleSave()
}}>保存</Button>
}
onCancel={() => {
this.props.onCancel()
}}>
{
(this.props.valueType == "3" || this.referenceType == 'sql') && <div style={{marginBottom: '10px', lineHeight: "30px"}}>
返回字段<WeaInput style={{width: '150px'}} value={this.state.returnValue} onChange={(value) => {
this.setState({returnValue: value})
}} />
</div>
}
<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}}
/>
</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>
</Modal>
)
// 保存
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: "number",
validateType: "number",
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 (
<Modal title="函数公式" visible={this.props.visible}
maskClosable={false}
width={800}
footer={
<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) => {
this.setState({ extendParam: {...extendParam, datasource:{datasourceId}} });
}}
/>
</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 }}
/>
</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>
</Modal>
);
}
}

View File

@ -1,10 +1,7 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { Button, DatePicker, Dropdown, Menu, Modal, Switch } from "antd";
// import { WeaTableNew } from "comsMobx"
import { WeaInputSearch, WeaRightMenu, WeaSlideModal, WeaTop } from "ecCom";
import { renderNoright } from "../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import CustomTab from "../../components/customTab";
import SystemSalaryItemModal from "./systemSalaryItemModal";

View File

@ -1,6 +1,20 @@
.customSalaryItemSlide {
padding: 20px;
.formItem {
line-height: 40px;
padding: 20px;
.formItem {
line-height: 40px;
}
}
.dataList-wrapper {
.wea-select {
width: 100%;
.ant-select{
width: 100%;
.ant-select-selection{
border-radius: 0;
height: 30px;
}
}
}
}
}

View File

@ -331,20 +331,24 @@ export class calculateStore {
delete params[key];
}
}
API.acctResultList({ ...params }).then(res => {
if (res.status) {
let list = res.data.pageInfo.list ? res.data.pageInfo.list : [];
list.map(item => {
item.key = item.id;
});
this.acctResultListDateSource = list;
this.acctResultListPageInfo = res.data.pageInfo;
this.acctResultListColumns = res.data.columns;
this.getColumnDesc({ salaryAcctRecordId: params.salaryAcctRecordId });
} else {
message.error(res.errormsg || "");
}
this.loading = false;
return new Promise((resolve,reject) => {
API.acctResultList({ ...params }).then(res => {
if (res.status) {
let list = res.data.pageInfo.list ? res.data.pageInfo.list : [];
list.map(item => {
item.key = item.id;
});
this.acctResultListDateSource = list;
this.acctResultListPageInfo = res.data.pageInfo;
this.acctResultListColumns = res.data.columns;
this.getColumnDesc({ salaryAcctRecordId: params.salaryAcctRecordId });
resolve(res.data.columns);
} else {
message.error(res.errormsg || "");
reject();
}
this.loading = false;
});
});
};

View File

@ -34,11 +34,11 @@ export class SalaryItemStore {
@observable tableDataSource = []; // 主列表
@observable tableColumns = []; // 主列表列
@observable pageInfo = {}; // 分页数据
// 可以删除的项目
@observable canDeleteList = []
// ** 公式 **
// ** 公式 **
// 类型列表
@observable searchGroup = [];
// 字段列表
@ -46,7 +46,7 @@ export class SalaryItemStore {
// 公式详情
@observable formulaDetail = {};
// Modal
// Modal
@observable modalLoading = true;
// 设置字段列表
@ -91,7 +91,7 @@ export class SalaryItemStore {
@action
getTableDatas = (params) => {
this.loading = true;
API.getItemList(params).then(action(res => {
if (res.status) { // 接口请求成功/失败处理
this.tableDataSource = res.data.list
@ -103,7 +103,7 @@ export class SalaryItemStore {
}
this.loading = false;
}));
}
@action
@ -114,7 +114,13 @@ export class SalaryItemStore {
this.getTableDatas();
this.showSearchAd = false;
}
// 薪资项目-系统薪资项目列表
@action
formulaDatasourceList = () => {
return API.formulaDatasourceList();
}
// 薪资项目-系统薪资项目列表
@action
getSysItemList = (params) => {
@ -125,7 +131,7 @@ export class SalaryItemStore {
message.error(res.errormsg || '接口调用失败!')
}
})
}
}
//薪资项目-添加系统薪资项目
@action
@ -194,7 +200,7 @@ export class SalaryItemStore {
return
}
this.deleteItemRequest(ids)
}
}
@action
deleteItemRequest = (ids) => {
@ -245,9 +251,9 @@ export class SalaryItemStore {
//薪资项目-新增薪资项目
@action
saveItem = (params, continueFlag, searchParams = {}) => {
if(!this.validateForm(params)) {
return
return
}
API.saveItem(params).then(res => {
if(res.status) {
@ -262,7 +268,7 @@ export class SalaryItemStore {
}
})
}
// 获取公式变量类型
@action
salaryAcctImportTemplateParam = (params = {}) => {
@ -301,7 +307,7 @@ export class SalaryItemStore {
}
})
})
}
// 根据id获取formual
@ -342,4 +348,4 @@ export class SalaryItemStore {
this.modalLoading = false;
})
}
}
}