diff --git a/pc4mobx/hrmSalary/apis/calculate.js b/pc4mobx/hrmSalary/apis/calculate.js index 3090a5e5..0a16ec46 100644 --- a/pc4mobx/hrmSalary/apis/calculate.js +++ b/pc4mobx/hrmSalary/apis/calculate.js @@ -353,13 +353,73 @@ export const saveAcctResult = (params) => { }).then(res => res.json()) } +// 核算结果--导入核算结果前生成导入模板时可选的薪资项目 +export const getImportField = (params) => { + return WeaTools.callApi('/api/bs/hrmsalary/salaryacct/acctresult/importField', 'GET', params); +} +// 核算结果-导入模板 +export const getImportTemplate = (salaryItemIds, salaryAcctRecordId) => { + fetch('/api/bs/hrmsalary/salaryacct/acctresult/importtemplate/export?salaryItemIds=' + salaryItemIds + "&salaryAcctRecordId=" + salaryAcctRecordId).then(res => res.blob().then(blob => { + var filename=`薪资核算.xlsx` + var a = document.createElement('a'); + var url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + a.click(); + window.URL.revokeObjectURL(url); + })) +} + +// 核算结果-导入预览 +export const previewAcctResult= (params) => { + return fetch('/api/bs/hrmsalary/salaryacct/acctresult/preview', { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(res => res.json()) +} + +// 核算结果-导入 +export const importAcctResult = (params) => { + return fetch('/api/bs/hrmsalary/salaryacct/acctresult/importSalaryAcctResult', { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(res => res.json()) +} - - - - +// 核算结果-导出全部 +export const exportAcctResult = (salaryAcctRecordId) => { + fetch('/api/bs/hrmsalary/salaryacct/acctresult/export?salaryAcctRecordId=' + salaryAcctRecordId ).then(res => res.blob().then(blob => { + var filename=`薪资核算.xlsx` + var a = document.createElement('a'); + var url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + a.click(); + window.URL.revokeObjectURL(url); + })) +} + +// 线下对比-列表 +export const comparisonResultList = (params) => { + return fetch('/api/bs/hrmsalary/salaryacct/comparisonresult/list', { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(res => res.json()) +} diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js new file mode 100644 index 00000000..fb80c4a8 --- /dev/null +++ b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/acctResultImportModal.js @@ -0,0 +1,145 @@ +import React from 'react' +import ImportModal from '../../../../components/importModal' +import { Button } from 'antd' +import { inject, observer } from 'mobx-react'; +import SelectFieldModal from './selectFieldModal'; + +@inject('calculateStore') +@observer +export default class AcctResultImportModal extends React.Component { + 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; + 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 + } + + // 选择表单字段 + 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) + } + + render() { + const { calculateStore } = this.props; + const { fetchPreviewAcctResult, previewAcctResultColumns, previewAcctResultDataSource, importAcctResult, fetchImportAcctResult } = calculateStore + const { step, selectFieldVisible, modalParam } = this.state; + const { visiable } = this.props; + return ( +
+ { + visiable && { + this.handleFinish() + }} + previewImport={(params) => {fetchPreviewAcctResult(params)}} + importFile={(params) => {fetchImportAcctResult(params)}} + templateLink={ () => { this.handleAccResultTemplateLink()}} + renderFormComponent={() => this.renderFormComponent()} + visiable={visiable} + onCancel={() => { this.props.onCancel() }} + /> + } + { + selectFieldVisible && { + this.handleAdd(fieldDate) + }} + onCancel={() => { + this.setState({ + selectFieldVisible: false + }) + }} + /> + } +
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/selectFieldModal.js b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/selectFieldModal.js new file mode 100644 index 00000000..865ada7d --- /dev/null +++ b/pc4mobx/hrmSalary/pages/calculateDetail/acctResult/importModal/selectFieldModal.js @@ -0,0 +1,111 @@ +import React from 'react' +import { Modal, Row, Col, Button } from 'antd' +import { inject, observer } from 'mobx-react'; +import { WeaCheckbox } from 'ecCom' + +@inject('calculateStore') +@observer +export default class SelectFieldModal extends React.Component { + constructor(props) { + super(props) + this.state = { + fieldData: {} + } + } + + componentWillMount() { + const {calculateStore: { getImportField } } = this.props; + getImportField(this.props.id).then(data => { + let fieldData = {}; + let formulaItems = [] + formulaItems = data.formulaItems + if(this.props.fieldData.formulaItems) { + formulaItems = this.props.fieldData.formulaItems + } + let inputItems = [] + inputItems = data.inputItems + if(this.props.fieldData.inputItems) { + inputItems = this.props.fieldData.inputItems + } + fieldData.formulaItems = formulaItems; + fieldData.inputItems = inputItems; + + this.setState({ + fieldData + }) + this.fieldData = fieldData + }) + } + + // 公式项改变 + handleFormalChange(item, value, flag) { + item.checked = value == 1 ? true: false + if(flag) { // 公式项 + this.fieldData.formulaItems.map(fieldItem => { + if(item.salaryItemId == fieldItem.salaryItemId) { + fieldItem.checked = item.checked + } + }) + } else { // 输入项 + this.fieldData.inputItems.map(fieldItem => { + if(item.salaryItemId == fieldItem.salaryItemId) { + fieldItem.checked = item.checked + } + }) + } + + } + + // 添加按钮点击回调 + handleAddClick() { + this.props.onAdd(this.fieldData) + this.props.onCancel() + } + + render() { + const { fieldData } = this.state; + return ( + {this.props.onCancel()}} + footer={null} + > +
+ 添加表头字段 + +
+
+
+ +
+
+ + { fieldData.formulaItems && fieldData.formulaItems.map(item => ( + { + this.handleFormalChange(item, value, true) + }}/> + ))} + +
+
+ +
+
+ +
+
+ + { fieldData.inputItems && fieldData.inputItems.map(item => ( + { + this.handleFormalChange(item, value, true) + }}/> + ))} + +
+
+ +
+ +
+
+ ) + } +} \ No newline at end of file diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js b/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js index aecdd764..f4b03f42 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/compareDetail.js @@ -1,12 +1,33 @@ import React from 'react' import { Button, Table } from "antd" -import { WeaInputSearch, WeaCheckbox } from 'ecCom' +import { WeaInputSearch, WeaCheckbox, WeaTable } from 'ecCom' import { mergeDetailColumns, dataSource } from './columns' +import { getQueryString } from '../../util/url' import CustomTab from '../../components/customTab' +import { inject, observer } from 'mobx-react'; +@inject('calculateStore') +@observer export default class CompareDetail extends React.Component { - render() { + constructor(props) { + super(props) + this.id = "" + this.state = { + onlyDiffEmployee: true, + onlyDiffSalaryItem: true, + } + } + componentWillMount() { + let id = getQueryString("id"); + this.id = id; + + const { calculateStore: {fetchComparisonResultList}} = this.props; + const { onlyDiffEmployee, onlyDiffSalaryItem} = this.state; + fetchComparisonResultList(onlyDiffEmployee, onlyDiffSalaryItem, this.id) + } + + render() { const renderRightOperation = () => { return (
@@ -20,8 +41,18 @@ export default class CompareDetail extends React.Component { const renderLeftOperation = () => { return (
- - + { + this.setState({ + onlyDiffEmployee: value == 1 + }) + }} + /> + { + this.setState({ + onlyDiffSalaryItem: value == 1 + }) + }}/>
) } @@ -43,7 +74,7 @@ export default class CompareDetail extends React.Component {
- + diff --git a/pc4mobx/hrmSalary/pages/calculateDetail/index.js b/pc4mobx/hrmSalary/pages/calculateDetail/index.js index a238a1fe..d519cfa0 100644 --- a/pc4mobx/hrmSalary/pages/calculateDetail/index.js +++ b/pc4mobx/hrmSalary/pages/calculateDetail/index.js @@ -6,7 +6,7 @@ import SalaryDetail from './salaryDetail' import { Button, Menu, Dropdown, Modal } from 'antd' import { WeaInputSearch } from "ecCom" import { getQueryString } from '../../util/url' - +import AcctResultImportModal from './acctResult/importModal/acctResultImportModal'; @inject('calculateStore') @observer @@ -14,7 +14,9 @@ export default class CalculateDetail extends React.Component { constructor(props) { super(props) this.state = { - selectedKey: "0" + selectedKey: "0", + fieldData: {}, + acctResultImportVisiable: false } this.id = "" } @@ -23,7 +25,9 @@ export default class CalculateDetail extends React.Component { let id = getQueryString("id"); this.id = id; const { calculateStore: {checkTaxAgent}} = this.props; - checkTaxAgent(id) + checkTaxAgent(this.id) + let modalParam = {...this.state.modalParam , salaryAcctRecordId: id} + this.setState({modalParam}) } // 核算点击事件 @@ -41,17 +45,34 @@ export default class CalculateDetail extends React.Component { onCancel() {} }); } - - render() { - const { selectedKey } = this.state; - const handleMenuClick = (e) => { - if(e.key == "2") { - window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/compareDetail") - } + + // 更多选项点击 + handleMenuClick = (e) => { + if(e.key == "1") { // 导入 + this.setState({ + acctResultImportVisiable: true + }) + } else if(e.key == "2") { + window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/compareDetail?id=" + this.id) + } else if(e.key == "3") { + const {calculateStore: {exportAll}} = this.props; + exportAll(this.id) } + } + + // 导入表单添加表头回调 + handleAcctModalAdd(fieldData) { + this.setState({ + fieldData + }) + } + + render() { + const { selectedKey, modalParam, acctResultImportVisiable } = this.state; + const menu = ( - + 导入 线下对比 导出全部 @@ -97,7 +118,21 @@ export default class CalculateDetail extends React.Component { { selectedKey == 1 && } - + { + acctResultImportVisiable && { + this.handleAcctModalAdd(fieldData) + }} + onCancel={() => this.setState({ + acctResultImportVisiable: false, + fieldData: {} + })} + id={this.id} + /> + } + ) diff --git a/pc4mobx/hrmSalary/pages/payroll/index.js b/pc4mobx/hrmSalary/pages/payroll/index.js index 8e372d66..1236a942 100644 --- a/pc4mobx/hrmSalary/pages/payroll/index.js +++ b/pc4mobx/hrmSalary/pages/payroll/index.js @@ -183,7 +183,7 @@ export default class Payroll extends React.Component { } // 预览 - handlePreview() { + handlePreview() { window.open("/spa/hrmSalary/static/index.html#/main/hrmSalary/templatePreview") } diff --git a/pc4mobx/hrmSalary/stores/calculate.js b/pc4mobx/hrmSalary/stores/calculate.js index b0a2c94f..6fd6a6be 100644 --- a/pc4mobx/hrmSalary/stores/calculate.js +++ b/pc4mobx/hrmSalary/stores/calculate.js @@ -36,6 +36,13 @@ export class calculateStore { @observable acctResultListColumns = []; // 列 @observable acctresultDetailForm = {}; // 编辑薪资表单数据 @observable acctResultListTableStore = new TableStore() + // 导入 + @observable importFieldData = {}; // 表头选择列表 + @observable acctResultImportPreview = {}; // 核算结果预览 + @observable previewAcctResultList = {}; //预览数据 + @observable previewAcctResultColumns = []; // 预览列表 + @observable previewAcctResultDataSource = []; // 预览DataSource + @observable importAcctResult = {}; // 导入结果 //*** 线下比对 *** @observable comparisonresultListDataSource = [];// dataSource @@ -391,4 +398,88 @@ export class calculateStore { } + // 获取导入字段设置 + @action + getImportField = (salaryAcctRecordId) => { + return new Promise((resolve, reject) => { + API.getImportField({salaryAcctRecordId}).then(res => { + if(res.status) { + this.importFieldData = res.data + resolve(res.data) + } else { + message.error(res.errormsg || "获取失败") + reject() + } + }) + }) + + } + + // 下载薪资导入核算模板 + @action + getImportTemplate = (salaryItemIds, salaryAcctRecordId) => { + API.getImportTemplate(salaryItemIds, salaryAcctRecordId) + } + + // 核算结果-导入预览 + @action + fetchPreviewAcctResult = (params) => { + API.previewAcctResult(params).then((res) => { + if(res.status) { + this.previewAcctResultList = res.data + this.previewAcctResultColumns = res.data.headers.map((item, index) => { + let column = {} + column.title = item; + column.dataIndex = "" + index; + column.key = index + "" + return column + }) + + this.previewAcctResultDataSource = res.data.list.map((item) => { + let data = {} + item.map((i, index) => { + data[index + ''] = i + }) + return data + }) + } else { + message.error(res.errormsg || "获取失败") + } + }) + } + + // 核算结果-导入 + @action + fetchImportAcctResult = (params) => { + API.importAcctResult(params).then(res=> { + if(res.status) { + this.importAcctResult = res.data + } else { + message.error(res.errormsg || "导入失败") + } + }) + } + + // 核算结果-导出全部 + @action + exportAll = (salaryAcctRecordId) => { + API.exportAcctResult(salaryAcctRecordId) + } + + // 线下对比-列表 + @action + fetchComparisonResultList = (onlyDiffEmployee, onlyDiffSalaryItem, salaryAcctRecordId) => { + let params = { + onlyDiffEmployee, + onlyDiffSalaryItem, + salaryAcctRecordId + } + API.comparisonResultList(params).then(res => { + if(res.status) { + this.comparisonResultList = res.data + } else { + message.error(res.errormsg || "获取失败") + } + }) + } } \ No newline at end of file diff --git a/pc4mobx/hrmSalary/stores/payroll.js b/pc4mobx/hrmSalary/stores/payroll.js index 62df1c7c..dccf61e2 100644 --- a/pc4mobx/hrmSalary/stores/payroll.js +++ b/pc4mobx/hrmSalary/stores/payroll.js @@ -133,7 +133,7 @@ export class payrollStore { if(res.status) { let response = res.data.salaryTemplateBaseSet let templateBaseData = response.data - templateBaseData.salarySob = templateBaseData.salarySob !== undefined ? templateBaseData.salarySob : null; + templateBaseData.salarySob = templateBaseData.salarySob !== undefined ? templateBaseData.salarySob + "": null; this.templateBaseData = templateBaseData // 基础信息表单数据 this.salarySobOptions = response.salarySobOptions ?