salary-management-front/pc4mobx/hrmSalary/pages/dataAcquisition/attendance/index.js

915 lines
29 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react";
import { inject, observer } from "mobx-react";
import { Button, Col, DatePicker, Dropdown, Menu, message, Modal, Row, Switch } from "antd";
import { WeaDatePicker, WeaInputSearch, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
import moment from "moment";
import { renderNoright } from "../../../util"; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import CustomTab from "../../../components/customTab";
import { columns } from "./columns";
import ImportModal from "../../../components/importModal";
import HeaderSet from "../../../components/importModal/headerSet";
import SelectItemModal from "../../../components/selectItemsModal";
import RefereAttendFormModal from "./refereAttendFormModal";
import SelectItemsWrapper from "../../../components/selectItemsModal/selectItemsWrapper";
import SlideModalTitle from "../../../components/slideModalTitle";
import EditSlideContent from "./editSlideContent";
import TwoColContent from "../../../components/twoColContent";
import TipLabel from "../../../components/TipLabel";
import ItemMangeFormModal from "./itemMangeFormModal";
import CustomPaginationTable from "../../../components/customPaginationTable";
import "../otherDeduct/index.less";
const MonthPicker = DatePicker.MonthPicker;
@inject("attendanceStore", "taxAgentStore")
@observer
export default class Attendance extends React.Component {
constructor(props) {
super(props);
columns.map(item => {
if (item.key == "cz") {
item.render = (text, record) => {
return (
<div style={{ display: "inline-block" }}>
<a type="link" onClick={() => this.onShowSlide()}>
查看
</a>
<a
type="link"
onClick={() => this.onDelete()}
style={{ marginLeft: "10px" }}>
删除
</a>
</div>
);
};
}
});
this.state = {
value: "",
selectedKey: "0",
searchValue: "",
modalParam: {
salarySobId: "",
salaryYearMonth: moment(new Date()).format("YYYY-MM") // 薪资所属月
},
modalVisiable: false,
selectItemVisible: false,
refereAttendFormVisible: false,
tabSelectedKey: "0",
itemMangeVisible: false,
itemMangeValue: {},
fieldName: "",
fieldSettingSearchValue: "",
fieldCurrent: 1,
inited: false
};
this.fieldSearch = {};
this.listSearch = {
salaryYearMonth: [moment(new Date()).startOf("year").format("YYYY-MM"), moment(new Date()).startOf("month").format("YYYY-MM")],
current: 1
};
this.recordId = ""; // 考勤数据列表查看选择项
this.salaryYearMonth = ""; // 考勤数据查看,当前数据的薪资所属月
this.pageInfo = { current: 1, pageSize: 10 };
}
componentWillMount() {
const { attendanceStore: { doInit, getLedgerList } } = this.props;
doInit(this.listSearch);
getLedgerList().then(() => {
this.setState({
inited: true
});
});
}
onShowSlide() {
const { attendanceStore: { setSlideVisiable } } = this.props;
setSlideVisiable(true);
}
onItemEdit(record) {
this.setState({
itemMangeVisible: true
});
const {
attendanceStore: { setCurrentItemOperate, setCurrentItem }
} = this.props;
setCurrentItemOperate("update");
setCurrentItem(record);
}
// 字段列表分页
handleFieldPageChange(value) {
const { attendanceStore: { getAttendanceFieldList } } = this.props;
this.fieldSearch.current = value;
this.fieldSearch.pageSize = this.pageInfo.pageSize;
getAttendanceFieldList(this.fieldSearch);
}
handleFieldShowSizeChange(pageInfo) {
const { attendanceStore: { getAttendanceFieldList } } = this.props;
this.fieldSearch.current = pageInfo;
getAttendanceFieldList({ ...this.fieldSearch, ...pageInfo });
}
// 列表
handleDataPageChange(value) {
const { attendanceStore: { getAttendanceList } } = this.props;
this.listSearch.current = value;
getAttendanceList(this.listSearch);
}
handleDataShowSizeChange(pageInfo) {
const { attendanceStore: { getAttendanceList } } = this.props;
getAttendanceList({ ...this.listSearch, ...pageInfo });
}
// 下载导入模板链接点击
handleTemplateLinkClick() {
const { attendanceStore: { downloadTemplate } } = this.props;
const { modalParam: { salarySobId, salaryYearMonth } } = this.state;
if (!salaryYearMonth || salaryYearMonth == "") {
message.warning("薪资所属月不能为空");
return;
}
if (!salarySobId || salarySobId == "") {
message.warning("薪资账套不能为空");
return;
}
downloadTemplate(salaryYearMonth, salarySobId);
}
// 导入预览
handlePreviewImport(params) {
const { attendanceStore: { previewAttendQuote } } = this.props;
previewAttendQuote(params);
}
// 考勤导入
handleImport(params) {
const { attendanceStore: { importAttendQuoteData } } = this.props;
importAttendQuoteData(params);
}
// 导入完成
handleFinish() {
this.setState({ modalVisiable: false });
const { attendanceStore: { getAttendanceList, step } } = this.props;
if (step === 2) {
getAttendanceList({ ...this.pageInfo });
}
}
// 考情引用的列
getColumns(columns) {
const {
attendanceStore: { deleteAttendance, doInit },
taxAgentStore: { showOperateBtn }
} = this.props;
let result = [...columns];
result.push({
title: "操作",
key: "operate",
render: (text, record) => {
return (
<div className="linkWapper">
<a onClick={() => this.handleViewAttendance(record)}>查看</a>
{showOperateBtn &&
<Dropdown
overlay={
<Menu
onClick={item => {
Modal.confirm({
title: "信息确认",
content: "确认删除",
onOk: () => {
deleteAttendance([
record.id
]).then(({ status, errormsg }) => {
if (status) {
message.success("删除成功");
doInit(this.listSearch);
} else {
message.error(errormsg || "删除失败");
}
});
},
onCancel: () => {
}
});
}}>
<Menu.Item key="1">删除</Menu.Item>
</Menu>
}>
<a className="ant-dropdown-link" href="javaScript:void(0);">
<i className="icon-coms-more" style={{ marginLeft: 18 }}/>
</a>
</Dropdown>}
</div>
);
}
});
return result;
}
// 查看考勤详情
handleViewAttendance(record) {
const { attendanceStore: { setSlideVisiable } } = this.props;
this.recordId = record.id;
this.salaryYearMonth = record.attendCycle;
setSlideVisiable(true);
}
// 引用同步Cancel事件
handleRefereCancel() {
this.setState({ refereAttendFormVisible: false });
const { attendanceStore: { getAttendanceList } } = this.props;
this.listSearch.current = 1;
getAttendanceList(this.listSearch);
}
// 获取周期
handleLoadCycle(month, sob) {
if (!month || month == "") {
return;
}
if (!sob || sob == "") {
return;
}
const { attendanceStore: { getSalaryCycleAndAttendCycle } } = this.props;
getSalaryCycleAndAttendCycle(month, sob);
}
// 初始导入参数
handleInitImportModal() {
const {
attendanceStore: {
setPreviewAttendQuoteColumns,
setPreviewAttendQuoteDataSource,
setImportResult
}
} = this.props;
setPreviewAttendQuoteColumns([]);
setPreviewAttendQuoteDataSource([]);
setImportResult({});
}
// 引用详情列表搜索
handleSearch(params) {
const { attendanceStore: { viewAttendQuote } } = this.props;
let request = { attendQuoteId: this.recordId, ...params };
viewAttendQuote(request);
}
handleExportAttendQuote = () => {
const url = `${window.location
.origin}/api/bs/hrmsalary/attendQuote/export?attendQuoteId=${this
.recordId}`;
window.open(url, "_self");
};
handleChangeMonth = (type, val) => {
const { attendanceStore: { getAttendanceList } } = this.props;
this.listSearch.salaryYearMonth[type] = val && moment(val).format("YYYY-MM");
!this.listSearch.salaryYearMonth[0] && (this.listSearch.salaryYearMonth[0] = moment(new Date()).startOf("year").format("YYYY-MM"));
!this.listSearch.salaryYearMonth[1] && (this.listSearch.salaryYearMonth = this.listSearch.salaryYearMonth.filter(n => n));
getAttendanceList(this.listSearch);
};
render() {
const { attendanceStore, taxAgentStore: { showOperateBtn } } = this.props;
const { modalParam } = this.state;
const { loading, hasRight, tableStore } = attendanceStore;
const {
step, setStep, setSlideVisiable, slideVisiable, doBatchDelete, searchFieldSettingList,
fieldSettingAttendList, fieldSettingCustomList, setFieldSettingAttendList, setFieldSettingCustomList
} = attendanceStore;
const {
getAttendanceFieldSettingList, saveAttendanceFieldSetting, fieldDataSource,
fieldTableStore, fieldPageInfo, attendanceDataSource, attendanceColumns,
attendancePageInfo, importLedgerList, previewAttendQuoteColumns, previewAttendQuoteDataSource,
importResult, cycle
} = attendanceStore;
if (!hasRight && !loading) {
// 无权限处理
return renderNoright();
}
const rightMenu = [
// 右键菜单
// {
// key: 'BTN_DEL',
// icon: <i className='icon-coms-delete'/>,
// content : '批量删除',
// disable: selectedRowKeys.length === 0, // 没有选中禁用
// onClick : batchDelete,
// }
];
const collectParams = {
// 收藏功能配置
favname: "考勤引用",
favouritetype: 1,
objid: 0,
link: "wui/index.html#/ns_demo03/index",
importantlevel: 1
};
const topTab = [
{
title: "考勤数据",
viewcondition: "0"
},
{
title: "字段管理",
viewcondition: "1"
}
];
const renderSearchOperationItem = () => {
const { taxAgentStore: { showOperateBtn } } = this.props;
return showOperateBtn
? <div>
<Button
type="primary"
style={{ marginRight: "10px" }}
onClick={() => {
this.setState({ refereAttendFormVisible: true });
}}>
引用
</Button>
<Button
type="default"
onClick={() => {
this.setState({ modalVisiable: true });
setStep(0);
}}>
导入
</Button>
</div>
: null;
};
const renderLeftOperation = () => {
return (
<div style={{ marginLeft: "20px", marginTop: "10px", display: "flex", alignItems: "center" }}>
<span style={{ marginRight: 10 }}>薪资所属月:</span>
<MonthPicker
value={!_.isEmpty(this.listSearch.salaryYearMonth) ? this.listSearch.salaryYearMonth[0] : ""}
disabledDate={(current) => {
return current && this.listSearch.salaryYearMonth[1] && current.getTime() > new Date(this.listSearch.salaryYearMonth[1]).getTime();
}}
format="YYYY-MM"
onChange={(val) => this.handleChangeMonth("0", val)}
/>
<span className="to" style={{ margin: "0 10px" }}></span>
<MonthPicker
value={!_.isEmpty(this.listSearch.salaryYearMonth) ? this.listSearch.salaryYearMonth[1] : ""}
disabledDate={(current) => {
return current && this.listSearch.salaryYearMonth[0] && current.getTime() < new Date(this.listSearch.salaryYearMonth[0]).getTime();
}}
format="YYYY-MM"
onChange={(val) => this.handleChangeMonth("1", val)}
/>
</div>
);
};
const renderHeaderSetCompoent = () => {
return (
<HeaderSet
onSetClick={() => {
getAttendanceFieldSettingList({ sourceType: "IMPORT" });
this.setState({
selectItemVisible: true
});
}}
/>
);
};
const renderFormComponent = () => {
return (
<Row>
<Col span={12}>
<span
className="formLabel"
style={{ lineHeight: "30px", marginRight: "10px" }}>
薪资所属月
</span>
<WeaDatePicker
format="yyyy-MM"
value={this.state.modalParam.salaryYearMonth}
onChange={value => {
this.setState({
modalParam: { ...modalParam, salaryYearMonth: value }
});
this.handleLoadCycle(value, this.state.modalParam.salarySobId);
}}
/>
</Col>
<Col span={12}>
<span
className="formLabel"
style={{ lineHeight: "30px", marginRight: "10px" }}>
薪资账套
</span>
{this.state.inited &&
<WeaSelect
value={this.state.modalParam.salarySobId}
style={{ width: "200px" }}
options={
!_.isEmpty(importLedgerList) ? [{
key: "",
showname: ""
}, ..._.map(importLedgerList, it => ({ key: it.id, showname: it.content }))] : [{
key: "",
showname: ""
}]
}
onChange={value => {
this.setState({
modalParam: { ...modalParam, salarySobId: value }
});
this.handleLoadCycle(
this.state.modalParam.salaryYearMonth,
value
);
}}/>}
</Col>
<Col span={12}>
<span
className="formLabel"
style={{ lineHeight: "30px", marginRight: "10px" }}>
薪资周期
</span>
{cycle.salaryCycle}
</Col>
<Col span={12}>
<span
className="formLabel"
style={{ lineHeight: "30px", marginRight: "10px" }}>
考勤周期
</span>
{cycle.attendCycle}
</Col>
</Row>
);
};
const renderCustomOperate = () => {
return ([
<div style={{ display: "inline-block" }}>
{showOperateBtn &&
<Button type="primary" onClick={this.handleExportAttendQuote}>
导出全部
</Button>
// <Dropdown.Button onClick={this.handleExportAttendQuote} overlay={menu} type="primary" visible={ false }>导出全部</Dropdown.Button>
}
<WeaInputSearch
style={{ marginLeft: 10 }}
placeholder="请输入姓名/部门/工号/手机号"
onChange={v => {
this.setState({ searchValue: v });
}}
onSearch={v => {
this.handleSearch({ keyword: v });
}}
/>
</div>
]);
};
const handleItemSearch = value => {
const { attendanceStore: { getAttendanceFieldList } } = this.props;
this.fieldSearch = { fieldName: value };
getAttendanceFieldList(this.fieldSearch);
};
const handleNewClick = () => {
const { attendanceStore: { setCurrentItemOperate } } = this.props;
this.setState({ itemMangeVisible: true });
setCurrentItemOperate("add");
};
const renderRightOperation = () => {
return (
<div style={{ display: "inline-block" }}>
{showOperateBtn &&
<Button
type="primary"
style={{ marginRight: "10px" }}
onClick={() => handleNewClick()}>
新建
</Button>}
<WeaInputSearch
value={this.state.fieldName}
onChange={value => {
this.setState({ fieldName: value });
}}
placeholder="请输入字段名称"
onSearch={value => {
this.setState({ fieldSettingSearchValue: value });
handleItemSearch(value);
}}
/>
</div>
);
};
const menu = (
<Menu>
<Menu.Item key="1">导出选中</Menu.Item>
</Menu>
);
const handleTabChange = v => {
const {
attendanceStore: { getAttendanceFieldList, getAttendanceList }
} = this.props;
this.setState({
tabSelectedKey: v
});
if (v == "1") {
this.fieldSearch = { fieldName: this.state.fieldName };
getAttendanceFieldList(this.fieldSearch);
} else if (v == "0") {
this.listSearch = {
salaryYearMonth: []
};
getAttendanceList({});
}
};
const handleSwitchItemChange = (record, value) => {
const {
attendanceStore: { updateAttendanceFieldStatus, getAttendanceFieldList }
} = this.props;
let request = {
id: record.id,
enableStatus: value
};
updateAttendanceFieldStatus(request).then(result => {
this.fieldSearch = { fieldName: this.state.fieldName };
getAttendanceFieldList(this.fieldSearch);
});
};
// 字段Columns
const getFieldColumns = columns => {
let newColumns = columns.filter(item => item.hide == "false");
newColumns = newColumns.map(column => {
let newColumn = column;
newColumn.render = (text, record, index) => {
//前端元素转义
let valueSpan =
record[newColumn.dataIndex + "span"] !== undefined
? record[newColumn.dataIndex + "span"]
: record[newColumn.dataIndex];
switch (newColumn.dataIndex) {
case "username":
return (
<a
onClick={() => {
this.onItemEdit(record);
}}
dangerouslySetInnerHTML={{ __html: valueSpan }}
/>
);
case "enableStatus":
return (
<Switch
checked={text == "1"}
disabled={!showOperateBtn}
onChange={value => {
handleSwitchItemChange(record, value);
}}
/>
);
default:
return <div dangerouslySetInnerHTML={{ __html: valueSpan }}/>;
}
};
return newColumn;
});
// 与e10保持一致先去掉字段管理页面的操作列
// newColumns.push({
// title: "操作",
// dataIndex: "operate",
// render: (text, record) => {
// return (
// <a onClick={() => {this.onItemEdit(record)}}>查看明细</a>
// )
// }
// })
return [
{
title: "序号",
dataIndex: "index",
width: 80,
render: (text, record, index) => {
const { current, pageSize } = this.pageInfo;
return (current - 1) * pageSize + index + 1;
}
},
...newColumns
];
};
// 保存回调
const handleItemMangeSave = value => {
const {
attendanceStore: { saveAttendanceField, getAttendanceFieldList }
} = this.props;
value.fieldType = value.fieldType == "1" ? "NUMBER" : "TEXT";
saveAttendanceField(value).then(() => {
this.fieldSearch = { fieldName: this.state.fieldName };
getAttendanceFieldList(this.fieldSearch);
this.setState({ itemMangeVisible: false });
});
};
const handleItemMangeUpdate = value => {
const {
attendanceStore: { updateAttendanceField, getAttendanceFieldList }
} = this.props;
value.fieldType = value.fieldType == "1" ? "NUMBER" : "TEXT";
updateAttendanceField(value);
this.fieldSearch = { fieldName: this.state.fieldName };
getAttendanceFieldList(this.fieldSearch);
this.setState({ itemMangeVisible: false });
};
const handleShowChecked = value => {
const {
attendanceStore: {
fieldSettingAttendList,
fieldSettingCustomList,
setFieldSettingAttendList,
setFieldSettingCustomList,
searchFieldSettingList
}
} = this.props;
if (value) {
let attendList = [...fieldSettingAttendList];
let customList = [...fieldSettingCustomList];
setFieldSettingAttendList(
attendList.filter(item => item.checked == value)
);
setFieldSettingCustomList(
customList.filter(item => item.checked == value)
);
} else {
searchFieldSettingList(this.state.fieldSettingSearchValue);
}
};
const handleonRestoreDefault = (sourceType = "IMPORT") => {
const {
attendanceStore: { returnToAttendanceFieldSettingDefault }
} = this.props;
returnToAttendanceFieldSettingDefault(sourceType);
};
const handleSetDefault = (sourceType = "IMPORT") => {
const {
attendanceStore: { saveAttendanceFieldSettingAsDefault }
} = this.props;
saveAttendanceFieldSettingAsDefault(sourceType);
};
const handleRefereHeaderSet = () => {
const { attendanceStore: { getAttendanceFieldSettingList } } = this.props;
getAttendanceFieldSettingList({ sourceType: "QUOTE" });
};
return (
<div className="mySalaryBenefitsWrapper">
<WeaTop
title="考勤引用" // 文字
icon={<i className="icon-coms-fa"/>} // 左侧图标
iconBgcolor="#F14A2D" // 左侧图标背景色
showDropIcon={false} // 是否显示下拉按钮
dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同)
dropMenuProps={{ collectParams }}>
{this.state.tabSelectedKey == 0
? <div>
<CustomTab
topTab={topTab}
searchOperationItem={renderSearchOperationItem()}
onChange={v => {
this.pageInfo = { current: 1, pageSize: 10 };
handleTabChange(v);
}}
/>
<CustomTab
leftOperation={renderLeftOperation()}
onChange={v => {
}}
/>
<CustomPaginationTable
loading={loading}
columns={this.getColumns(attendanceColumns)}
dataSource={attendanceDataSource}
total={attendancePageInfo.total}
current={attendancePageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
onPageChange={value => {
this.pageInfo.current = value;
this.handleDataPageChange(value);
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handleDataShowSizeChange(this.pageInfo);
}}
/>
</div>
: <div>
<CustomTab
topTab={topTab}
searchOperationItem={renderRightOperation()}
onChange={v => {
this.setState({
tabSelectedKey: v
}, () => {
this.pageInfo = { current: 1, pageSize: 10 };
});
}}
/>
<TwoColContent
leftContent={
<CustomPaginationTable
loading={loading}
dataSource={fieldDataSource}
columns={getFieldColumns(
fieldTableStore.columns ? fieldTableStore.columns : []
)}
total={fieldPageInfo.total}
current={fieldPageInfo.pageNum}
pageSize={this.pageInfo.pageSize}
onPageChange={value => {
this.pageInfo.current = value;
this.handleFieldPageChange(value);
}}
onShowSizeChange={(current, pageSize) => {
this.pageInfo = { current, pageSize };
this.handleFieldShowSizeChange(this.pageInfo);
}}
/>
}
rightContent={
<TipLabel
tipList={[
"1、考勤字段包含自定义字段和考勤模块的统计字段所有字段不可重名",
"2、停用自定义字段将影响其参与计算的账套核算"
]}
/>
}
/>
</div>}
</WeaTop>
<ImportModal
init={() => {
this.handleInitImportModal();
}}
params={this.state.modalParam}
columns={previewAttendQuoteColumns}
step={step}
setStep={setStep}
slideDataSource={previewAttendQuoteDataSource}
importResult={importResult}
onFinish={() => {
this.handleFinish();
}}
previewImport={params => {
this.handlePreviewImport(params);
}}
importFile={params => {
this.handleImport(params);
}}
headerSetCompoent={renderHeaderSetCompoent()}
templateLink={() => {
this.handleTemplateLinkClick();
}}
renderFormComponent={() => renderFormComponent()}
visiable={this.state.modalVisiable}
onCancel={() => {
this.handleFinish();
}}
/>
<SelectItemModal
onRestoreDefault={() => {
handleonRestoreDefault();
}}
onSetDefault={() => {
handleSetDefault();
}}
onSave={() => {
saveAttendanceFieldSetting();
}}
onShowChecked={value => {
handleShowChecked(value);
}}
onSearch={value => {
searchFieldSettingList(value);
}}
visible={this.state.selectItemVisible}
onCancel={() => this.setState({ selectItemVisible: false })}>
<div>
<SelectItemsWrapper
onChange={value => {
setFieldSettingAttendList(value);
}}
items={fieldSettingAttendList}
title="考勤模块"
/>
<SelectItemsWrapper
onChange={value => {
setFieldSettingCustomList(value);
}}
items={fieldSettingCustomList}
title={"自定义"}
/>
</div>
</SelectItemModal>
{this.state.refereAttendFormVisible &&
<RefereAttendFormModal
onSave={() => {
saveAttendanceFieldSetting("QUOTE");
}}
onRestoreDefault={() => {
handleonRestoreDefault("QUOTE");
}}
onSetDefault={() => {
handleSetDefault("QUOTE");
}}
onShowChecked={value => {
handleShowChecked(value);
}}
onSearch={value => {
searchFieldSettingList(value);
}}
onChange={value => {
setFieldSettingAttendList(value);
}}
items={fieldSettingAttendList}
onHeaderSet={() => {
handleRefereHeaderSet();
}}
visible={this.state.refereAttendFormVisible}
onCancel={() => {
this.handleRefereCancel();
}}
/>}
{this.state.itemMangeVisible &&
<ItemMangeFormModal
visible={this.state.itemMangeVisible}
onUpdate={value => {
handleItemMangeUpdate(value);
}}
onSave={value => handleItemMangeSave(value)}
onCancel={() => {
this.setState({ itemMangeVisible: false });
}}
/>}
{slideVisiable &&
<WeaSlideModal
className="slideOuterWrapper"
visible={slideVisiable}
top={0}
width={60}
height={100}
direction={"right"}
measure={"%"}
title={
<SlideModalTitle
subtitle="考勤数据"
editable={false}
showOperateBtn={showOperateBtn}
customOperate={renderCustomOperate()}
/>
}
content={
<EditSlideContent
salaryYearMonth={this.salaryYearMonth}
id={this.recordId}
editable={this.state.editable}
/>
}
onClose={() => setSlideVisiable(false)}
showMask={true}
closeMaskOnClick={() => setSlideVisiable(false)}
/>}
</div>
);
}
}