考勤引用页面重构

This commit is contained in:
黎永顺 2023-02-23 17:25:45 +08:00
parent 94a8a6f05a
commit 667aa8808d
2 changed files with 932 additions and 913 deletions

View File

@ -1,921 +1,19 @@
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, WeaNewScroll, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
import moment from "moment";
import { renderNoright } from "../../../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);
};
/*
* Author: 黎永顺
* name: 考情引用
* Description:
* Date: 2023/2/23
*/
import React, { Component } from "react";
class Index extends Component {
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 className="attendanceContent">
<CustomTab
topTab={topTab}
searchOperationItem={renderSearchOperationItem()}
onChange={v => {
this.pageInfo = { current: 1, pageSize: 10 };
handleTabChange(v);
}}
/>
<CustomTab
leftOperation={renderLeftOperation()}
onChange={v => {
}}
/>
<div className="tableWrapper">
<WeaNewScroll height="100%">
<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);
}}
/>
</WeaNewScroll>
</div>
</div>
: <div className="attendanceContent">
<CustomTab
topTab={topTab}
searchOperationItem={renderRightOperation()}
onChange={v => {
this.setState({
tabSelectedKey: v
}, () => {
this.pageInfo = { current: 1, pageSize: 10 };
});
}}
/>
<TwoColContent
leftContent={
<div className="tableWrapper">
<WeaNewScroll height="100%">
<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);
}}
/>
</WeaNewScroll>
</div>
}
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();
}}
/>
<div>
<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>
);
}
}
export default Index;

View File

@ -0,0 +1,921 @@
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, WeaNewScroll, WeaSelect, WeaSlideModal, WeaTop } from "ecCom";
import moment from "moment";
import { renderNoright } from "../../../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 className="attendanceContent">
<CustomTab
topTab={topTab}
searchOperationItem={renderSearchOperationItem()}
onChange={v => {
this.pageInfo = { current: 1, pageSize: 10 };
handleTabChange(v);
}}
/>
<CustomTab
leftOperation={renderLeftOperation()}
onChange={v => {
}}
/>
<div className="tableWrapper">
<WeaNewScroll height="100%">
<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);
}}
/>
</WeaNewScroll>
</div>
</div>
: <div className="attendanceContent">
<CustomTab
topTab={topTab}
searchOperationItem={renderRightOperation()}
onChange={v => {
this.setState({
tabSelectedKey: v
}, () => {
this.pageInfo = { current: 1, pageSize: 10 };
});
}}
/>
<TwoColContent
leftContent={
<div className="tableWrapper">
<WeaNewScroll height="100%">
<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);
}}
/>
</WeaNewScroll>
</div>
}
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>
);
}
}