import React, { PureComponent } from 'react'; import { connect } from 'dva'; import { Tabs, Select, Input, Button, message, Modal, // Icon, DatePicker, Table, List, Card, Form, Alert } from 'antd'; import axios from 'axios'; import style from 'styled-components'; import moment from 'moment'; import "moment/locale/zh-cn"; import { getHostByPath } from '../../utils/request'; import store from 'store'; // import PTable from '../../components/Pro/PTable'; // import SalaryDetail from './SalaryDetail'; import './salarymanagement.less'; import { taskComSalaryCalSalary, //生成核算数据薪资 taskComSalaryPageForPersalary, //人员月度工资分页查询 getPerType, //获取人员类别 taskComSalaryBatchAccountSalary, //批量核算工资条 taskComSalarySalaryDetail, //查看工资条详情 taskComSalaryUpdateSalary, //修改工资条详情 taskComSalaryCheckIsAccount, taskComSalaryDeleteSalaryGrant //删除薪酬明细项 } from '../../services/api'; const { MonthPicker } = DatePicker; const monthFormat = 'YYYY-MM'; const { TabPane } = Tabs; // const dateFormat = 'YYYY-MM-DD'; const { Option } = Select; const { confirm } = Modal; const FormItem = Form.Item; const mapStateToProps = state => { return { companyName: state['global'].companyInfo.comName }; }; const preMonth = moment() .subtract(1, 'month') .format(monthFormat); //获取上个月日期格式 @connect(mapStateToProps) @Form.create() export default class Accounting extends PureComponent { constructor(props, context) { super(props, context); this.state = { selectedRowKeys: [], selectedRowIds: [], visible: false, recordData: {}, //当前行数据 salaryDetailData: { //工资条详情 dynamicMap: [], fixMap: [], perMap: { departName: '', name: '', perType: '010001', photoUrl: null }, salaryGrant: { //工资条信息 createTime: '', accountStatus: '', accountTime: '', isConfirm: '', confirmTime: '', actualAmount: 0, comId: '100794', createBy: null, grantYears: '2018-12', payableAmount: 8000, perId: '165651', perSalaryGrantId: '531771503419588610', remark: null, salaryTempName: null, sessionId: null, sumAmount: 8100, taxableAmount: 8100, updateBy: null, updateTime: null }, attendDetail: { absenceLeaveTime: '', absenceTime: '', absenteeismDays: '', attendDateSection: '', attendDays: '', breakOffTime: '', chargeLeaveTime: '', departName: '', holidayOverTime: '', lateTimes: '', leaveEarlyTimes: '', marriageLeaveTime: '', maternityLeaveTime: '', missCardTimes: '', mobilePhone: '', name: '', publicLeaveTime: '', restDayOverTime: '', restDays: '', sickLeaveTime: '', totalLateTime: '', totalLeaveEarlyTime: '', workDayOverTime: '', workHours: '', xh: '', yearLeaveTime: '' }, taskAttendDetail: null }, isEditState: false, //弹框薪资是否编辑 perTypeList: [], //人员类别-字典表数据 grantYears: preMonth, //发放年月 name: '', perType: '', isConfirm: '', accountStatus: '', listPage: [], //表格数据 salaryCheckState: '', //分页配置 salaryPage: { pageNumber: 1, pageSize: 10, grantYears: '', name: '', perType: '', isConfirm: '', accountStatus: '' }, total: 0, pagenav: { current: 1, //当前页数 pageSize: 10, //每页条数 defaultPageSize: 10, //默认的当前页数 total: 10, //数据总数 // showQuickJumper: true,//是否可以快速跳转至某页 // showTotal: total => `总共 ${total} 条`,//用于显示数据总量和当前数据顺序 pageSizeOptions: ['5', '10', '15', '20', '25'], //指定每页可以显示多少条 showSizeChanger: true, //是否可以改变 pageSize //pageSize 变化的回调 onShowSizeChange: (current, pageSize) => { console.log(current,pageSize); let pagenav = Object.assign({}, this.state.pagenav); pagenav.current = current; pagenav.pageSize = pageSize; pagenav.defaultPageSize = pageSize; this.setState({ pagenav }, () => { this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); }); }, //页码改变的回调,参数是改变后的页码及每页条数 onChange: (page, pageSize) => { console.log(page,pageSize); if (Object.prototype.toString.call(page) === '[object Object]') { return; } let pagenav = Object.assign({}, this.state.pagenav); pagenav.current = page; pagenav.pageSize = pageSize; this.setState({ pagenav }, () => { this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); }); } } }; } componentDidMount = () => { this.getPerType(); this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); this.taskComSalaryCheckIsAccount(); }; /*********************Ajax请求********************* */ //获取table分页 taskComSalaryPageForPersalary = salaryPage => { salaryPage.pageNumber = this.state.pagenav.current; salaryPage.pageSize = this.state.pagenav.pageSize; salaryPage.grantYears = this.state.grantYears; taskComSalaryPageForPersalary(salaryPage).then( res => { console.log(res, 'res'); let tmp = res.data.data.map((val, i) => { return Object.assign({}, val, { key: i }); }); //添加设置分页total let pagenav = { ...this.state.pagenav }; pagenav.total = res.data.total; // pagenav.current = res.data.pageNumber; this.setState({ listPage: tmp, pagenav }); }, err => { console.log('err', err); } ); }; //获取人员类别 getPerType = () => { getPerType({ codeType: 'perType' }).then( res => { console.log(res, 'res-获取人员类别'); if (res.data) { this.setState({ perTypeList: res.data }); } }, err => { console.log('err', err); } ); }; //是否核算过状态 taskComSalaryCheckIsAccount = () => { const { grantYears } = this.state; taskComSalaryCheckIsAccount({ grantYears }).then( res => { console.log(res, 'res'); this.setState({ salaryCheckState: res.data }); }, err => { console.log('err', err); } ); }; //生成核算数据薪资 taskComSalaryCalSalary = grantYears => { taskComSalaryCalSalary({ grantYears }).then( res => { console.log(res, 'res'); this.resetting(); this.taskComSalaryCheckIsAccount(); }, err => { console.log('err', err); } ); }; //选择月份核算 onPickMonth = (date, dateString) => { console.log(date, dateString); this.setState( { grantYears: dateString }, () => { this.resetting(); this.taskComSalaryCheckIsAccount(); } ); }; //生成核算数据 automaticAccounting = () => { const { grantYears, salaryCheckState } = this.state; if (!grantYears) { message.info('请选择月份'); return; } if (salaryCheckState === '0') { this.taskComSalaryCalSalary(grantYears); } if (salaryCheckState === '1') { const self = this; confirm({ title: '确认重新生成核算数据?', content: ( 重新生成核算数据,会将薪酬数据全部删除,重新生成 核算数据。(员工已确认的薪酬数据不会被删除、不再 重新生成) ), okText: '确认', cancelText: '取消', onOk() { console.log('OK'); self.taskComSalaryCalSalary(grantYears); }, onCancel() { console.log('Cancel'); } }); } }; //输入框的书写 inputKeywordChange = e => { console.log(e.target.value.trim()); this.setState({ name: e.target.value.trim() }); }; handleChangeAccountStatus = value => { console.log(`selected ${value}`); this.setState({ accountStatus: value }); }; handleChangeConfirmStatus = value => { console.log(`selected ${value}`); this.setState({ isConfirm: value }); }; handleChangePerType = value => { console.log(`selected ${value}`); this.setState({ perType: value }); }; //人员类别 perTypeList = () => { return this.state.perTypeList.map((val, key) => { return ( ); }); }; //点击搜索 search = () => { if (!this.state.grantYears) { message.info('请选择月份'); return; } let pagenav = { ...this.state.pagenav }; pagenav.current = 1; pagenav.pageSize = 10; const { salaryPage } = this.state; salaryPage.grantYears = this.state.grantYears; salaryPage.pageNumber = this.state.pagenav.current; salaryPage.pageSize = this.state.pagenav.pageSize; salaryPage.name = this.state.name; salaryPage.perType = this.state.perType; salaryPage.isConfirm = this.state.isConfirm; salaryPage.accountStatus = this.state.accountStatus; this.setState({ salaryPage, pagenav }, () => { this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); }); }; //重置 resetting = () => { let pagenav = { ...this.state.pagenav }; pagenav.current = 1; pagenav.pageSize = 10; const { salaryPage } = { ...this.state }; salaryPage.pageSize = 10; salaryPage.pageNumber = 1; salaryPage.name = ''; salaryPage.perType = ''; salaryPage.isConfirm = ''; salaryPage.accountStatus = ''; this.setState( { pagenav, salaryPage, name: '', perType: '', isConfirm: '', accountStatus: '' }, () => { this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); } ); }; // 批量确认核算 handleConfirmList = () => { const keyNumber = this.state.selectedRowIds; const keyId = this.state.selectedRowKeys; console.log('id集合', keyId); console.log('keyNumber', keyNumber); //使用selectedRowKeys判断,table的key值就是perSalaryGrantId if (keyId.length <= 0) { message.warning('请选择需要核算的信息!'); } else { const ids = keyId.toString(); console.log(ids, 'ids'); this.taskComSalaryBatchAccountSalary(ids); } }; //导出excel exportSalary = () => { if (!this.state.grantYears) { message.info('请选择月份'); return; } const { salaryPage } = { ...this.state }; salaryPage.pageSize = 10; salaryPage.pageNumber = 1; salaryPage.grantYears = this.state.grantYears; salaryPage.name = ''; salaryPage.perType = ''; salaryPage.isConfirm = ''; salaryPage.accountStatus = ''; taskComSalaryPageForPersalary(salaryPage).then( res => { console.log(res, 'res'); if (res.data.total === 0) { message.info('暂无数据'); return; } axios({ method: 'get', url: getHostByPath() + '/task/com/salary/export-per-month-salary', //后台请求地址 responseType: 'blob', params: { grantYears: this.state.grantYears }, headers: { access_token: store.get('saas')['access_token'], Accesstoken: store.get('saas')['access_token']|| sessionStorage.userV5Token, } }).then(data => { if (!data) { return; } let url = window.URL.createObjectURL(data.data); let link = document.createElement('a'); link.style.display = 'none'; link.href = url; link.setAttribute( 'download', `${this.props.companyName}_${this.state.grantYears.replace( '-', '' )}薪酬报表_${moment().format('YYYYMMDDHHmmss')}.xls` ); document.body.appendChild(link); link.click(); }); }, err => { console.log('err', err); } ); }; //批量核算工资条 taskComSalaryBatchAccountSalary = ids => { taskComSalaryBatchAccountSalary({ ids }).then( res => { console.log(res, 'res'); this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); this.setState({ selectedRowKeys: [] }); }, err => { console.log('err', err); } ); }; //查看工资条详情 taskComSalarySalaryDetail = id => { taskComSalarySalaryDetail({ id }).then( res => { console.log(res, 'res-查看工资条详情'); this.setState( { salaryDetailData: res.data }, () => { console.log(this.state.salaryDetailData, '查看工资条详情'); } ); }, err => { console.log('err', err); } ); }; //打开弹框 openDetailModal = record => { console.log(name, 'name'); this.setState( { visible: true, recordData: record }, () => { this.taskComSalarySalaryDetail(this.state.recordData.perSalaryGrantId); } ); }; handleCancel = () => { this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); this.setState({ visible: false, isEditState: false }); }; handleOk = () => { const ids = this.state.recordData.perSalaryGrantId; if (!ids) { return; } this.taskComSalaryBatchAccountSalary(ids); this.setState({ visible: false }); }; //表格渲染 renderTable = () => { const selectedRowKey = this.state.selectedRowKeys; const rowSelection = { selectedRowKeys: selectedRowKey, onChange: selectedRowKeys => { console.log('selectedRowKeys', selectedRowKeys); this.setState( { selectedRowKeys }, () => { console.log('selectedRowKeys-more', this.state.selectedRowKeys); } ); }, onSelect: (record, selected, selectedRows) => { const selectId = this.state.selectedRowIds; if (selected === true) { selectId.push(record.perSalaryGrantId); } else { for (let i = 0; i < selectId.length; i++) { if (selectId[i] === record.perSalaryGrantId) { selectId.splice(i, 1); break; } } } this.setState({ selectedRowIds: selectId }); console.log( `record:`, record.perSalaryGrantId, `selected:`, selected, `selectedRows:`, selectedRows ); }, onSelectAll: (selected, selectedRows, changeRows) => { let selectId = []; if (selected === true) { for (let i = 0; i < selectedRows.length; i++) { selectId.push(selectedRows[i].perSalaryGrantId); } } else { selectId = []; // selectedRowKeys:selectedRowKey } this.setState({ selectedRowIds: selectId }); console.log( `selected:`, selected, `selectedRows:`, selectedRows, `changeRows:`, changeRows ); } }; const columns = [ { title: '薪资月份', dataIndex: 'grantYears', key: 'grantYears' }, { title: '姓名', dataIndex: 'name', key: 'name' }, // { // title: '人员类别', // dataIndex: 'perTypeName', // key: 'perTypeName' // }, { title: '薪资模板', dataIndex: 'salaryTempName', key: 'salaryTempName' }, { title: '核算时间', dataIndex: 'accountTime', key: 'accountTime' }, { title: '应发工资', dataIndex: 'payableAmount', key: 'payableAmount' }, { title: '核算确认', dataIndex: 'accountStatusName', key: 'accountStatusName', render: (text, record) => ( {record.accountStatusName === '待核算' && ( {record.accountStatusName} )} {record.accountStatusName === '已核算' && ( {record.accountStatusName} )} ) }, { title: '员工确认', dataIndex: 'isConfirm', key: 'isConfirm', render: (text, record) => ( {record.isConfirm === '待确认' && ( {record.isConfirm} )} {record.isConfirm === '已确认' && ( {record.isConfirm} )} ) }, { title: '操作', dataIndex: 'operate', key: 'operate', render: (text, record) => (
{ this.openDetailModal(record); }} > 详情 { console.log(record); const id = record.perSalaryGrantId; Modal.confirm({ title: '提示', content: `确定删除${record.name}的薪酬明细`, okText: '确认', cancelText: '取消', onOk: () => { taskComSalaryDeleteSalaryGrant({id}).then(res => { this.taskComSalaryPageForPersalary({ ...{}, ...this.state.salaryPage }); }); } }); // taskComSalaryDeleteSalaryGrant }} > 删除
) } ]; const tmp = this.state.listPage.map(val => { const param = val; param.key = val.perSalaryGrantId; return param; }); return ( record.key} dataSource={tmp} columns={columns} rowSelection={rowSelection} onChange={this.state.pagenav.onChange} /> ); }; //弹框编辑 editSalary = () => { this.setState({ isEditState: true }); }; //弹框保存 handleSubmit = e => { e.preventDefault(); this.props.form.validateFields((err, values) => { console.log(values, 'values'); if (!err) { console.log(values, 'values'); values.perSalaryGrantId = this.state.recordData.perSalaryGrantId; if (!values.perSalaryGrantId) { return; } taskComSalaryUpdateSalary(values).then( response => { console.log(response, '保存'); this.taskComSalarySalaryDetail(values.perSalaryGrantId); this.setState({ isEditState: false }); }, err => { console.log(err, 'err-保存'); } ); } }); }; render() { const { getFieldDecorator } = this.props.form; const { recordData, grantYears } = this.state; const { dynamicMap, fixMap, perMap, salaryGrant, attendDetail, taskAttendDetail } = this.state.salaryDetailData; // const dynamicMapLength = dynamicMap.length; // const fixMapLength = fixMap.length; // if (dynamicMapLength > 0 && dynamicMapLength % 6 !== 0) { // for (let i = 0; i < 6 - (dynamicMapLength % 6); i++) { // dynamicMap.push({ // amount: 0, // salaryName: '无', // salaryType: '1401' // }); // } // } // if (fixMapLength > 0 && fixMapLength % 6 !== 0) { // for (let i = 0; i < 6 - (fixMapLength % 6); i++) { // fixMap.push({ // amount: 0, // salaryName: '无', // salaryType: '1401' // }); // } // } const firstDay = moment(grantYears) .startOf('month') .format('YYYY-MM-DD'); const lastDay = moment(grantYears) .endOf('month') .format('YYYY-MM-DD'); return (
1、生成核算数据:点击“生成核算数据”按钮,系统将根据薪酬模板、五险一金缴纳比例方案生成人员的薪酬数据;
2、导入工资数据:若不通过薪酬模板、五险一金缴纳比例方案来生成薪酬数据,可直接导入线下已核算的薪酬数据;
3、一个月份的薪酬报表数据可由两种方式来生成,但每个人员仅限一条薪酬数据,重复生成/导入将以最新操作为准;
4、请仔细检查人员的薪酬数据,核算正确的,请点击“确认核算”,系统会自动发送工资条给到员工,若核算错误的,请“编辑”核算结果,再进行确认。
} type='warning' showIcon style={{ marginBottom: '15px' }} />
* { return current && current > moment(parseInt(sessionStorage.getItem('requestDate'))).subtract(1, 'month'); }} placeholder='请选择月份' defaultValue={moment().subtract(1, 'month')} // format={monthFormat} // defaultPickerValue={moment().subtract(1, 'year')} />
姓名: {/* 人员类别: */} 核算状态: 员工确认状态:
{this.renderTable()} {/* 详情 */} {/* */}
打卡人头像

{recordData.name} {recordData.perTypeName ? ( | {recordData.perTypeName} ) : ( '' )} {perMap.departName ? ( | {perMap.departName} ) : ( '' )}

{recordData.salaryTempName}

{/* 薪资状态 */}

薪资状态

核算时间 核算确认 确认时间 员工确认 确认时间
{salaryGrant.createTime} {salaryGrant.accountStatus === '0' && ( 待核算 )} {salaryGrant.accountStatus === '1' && ( 已核算 )} {salaryGrant.accountTime ? ( {salaryGrant.accountTime} ) : ( '' )} {salaryGrant.isConfirm === '0' && ( 待确认 )} {salaryGrant.isConfirm === '1' && ( 已确认 )} {' '} {salaryGrant.confirmTime ? ( {salaryGrant.confirmTime} ) : ( '' )}
{/* 薪资核算 */}

薪资核算 ( 根据薪资模板规则自动核算,可修改;员工确认后,不可修改。

{this.state.isEditState ? (
( {getFieldDecorator(`${item.salaryType}`, { initialValue: item.amount, rules: [ { required: false, message: '请输入!' } ] })( )} )} /> {fixMap.length > 0 && ( ( {item.amount} )} /> )}
) : (
( {item.amount} )} /> {fixMap.length > 0 && ( ( {item.amount} )} /> )}
)}
{/* 内勤情况 */}

内勤情况{firstDay}~ {lastDay}

出勤天数 休息天数 工作总时长 迟到次数 早退次数 漏卡次数
{attendDetail ? attendDetail.attendDays : 0} {attendDetail ? attendDetail.restDays : 0} {attendDetail ? attendDetail.workHours : 0} {attendDetail ? attendDetail.lateTimes : 0} {attendDetail ? attendDetail.leaveEarlyTimes : 0} {attendDetail ? attendDetail.missCardTimes : 0}
缺勤天数 事假时长 病假时长 工作日加班 休息日加班 节假日加班
{attendDetail ? attendDetail.absenteeismDays : 0} {attendDetail ? attendDetail.absenceLeaveTime : 0} {attendDetail ? attendDetail.sickLeaveTime : 0} {attendDetail ? attendDetail.workDayOverTime : 0} {attendDetail ? attendDetail.restDayOverTime : 0} {attendDetail ? attendDetail.holidayOverTime : 0}
{/* 驻勤情况 (原来的任务)*/}

驻勤情况{firstDay}~ {lastDay}

{/* */} {/* */}
出勤天数 休息天数 工作总时长 迟到次数 早退次数 漏卡次数
{taskAttendDetail ? taskAttendDetail.attendDays : 0} {taskAttendDetail ? taskAttendDetail.restDays : 0} {taskAttendDetail ? taskAttendDetail.workHours : 0} {taskAttendDetail ? taskAttendDetail.lateTimes : 0} {taskAttendDetail ? taskAttendDetail.leaveEarlyTimes : 0} {taskAttendDetail ? taskAttendDetail.missCardTimes : 0}
缺勤天数 事假时长 病假时长工作日加班 休息日加班 节假日加班
{taskAttendDetail ? taskAttendDetail.absenteeismDays : 0} {taskAttendDetail ? taskAttendDetail.absenceLeaveTime : 0} {taskAttendDetail ? taskAttendDetail.sickLeaveTime : 0} {taskAttendDetail ? taskAttendDetail.workDayOverTime : 0} {taskAttendDetail ? taskAttendDetail.restDayOverTime : 0} {taskAttendDetail ? taskAttendDetail.holidayOverTime : 0}
); } } const Container = style.div` padding:10px 24px 24px; width:100%; height:100%; font-size: 14px; color: rgba(0,0,0,0.65); .searchpanel{ margin-bottom:16px; .post{ margin:0 8px 0 16px; } } `; const Opton = style.span`{ font-size: 12px; color: #0F71FF; cursor:pointer; margin-right:8px; }`;