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

626 lines
24 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 { toJS } from 'mobx';
import { WeaTableNew } from "comsMobx"
import { Button, Table, DatePicker, Row, Col, Menu, Dropdown, Switch, Select, message } from 'antd';
import { WeaInputSearch, WeaSlideModal, WeaHelpfulTip, WeaCheckbox, WeaDatePicker, WeaTop, WeaTab, WeaRightMenu, WeaRangePicker, WeaSelect, WeaTable } from 'ecCom';
import moment from 'moment'
import { renderNoright, getSearchs } from '../../../util'; // 渲染form数据的方法因为多个页面都会使用所以抽的公共方法在util中
import CustomTab from '../../../components/customTab';
import ContentWrapper from '../../../components/contentWrapper';
import { columns, dataSource, tab2Columns, slideDataSource } from './columns';
import MonthRange from '../../../components/monthRange'
import ImportModal from '../../../components/importModal'
import HeaderSet from "../../../components/importModal/headerSet"
import SelectItemModal, {items} 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 CustomTable from '../../../components/customTable';
const { RangePicker } = DatePicker;
const { Option } = Select
@inject('attendanceStore')
@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",
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 = {}
this.recordId = ""; // 考勤数据列表查看选择项
this.salaryYearMonth = ""; // 考勤数据查看,当前数据的薪资所属月
}
componentWillMount() {
const { attendanceStore: { doInit, getLedgerList }} = this.props;
doInit()
getLedgerList().then(() => {
this.setState({
inited: true
})
})
}
onShowSlide() {
const {attendanceStore : {setSlideVisiable}} = this.props;
setSlideVisiable(true)
}
onItemOperatesClick(record, index, operate, flag) {
switch(operate.index.toString()){
case '0': // 查看明细
this.onItemEdit(record);
break;
}
};
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
getAttendanceFieldList(this.fieldSearch)
}
// 列表
handleDataPageChange(value) {
const { attendanceStore: { getAttendanceList }} = this.props;
this.listSearch.current = value
getAttendanceList(this.listSearch)
}
// 下载导入模板链接点击
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})
}
// 考情引用的列
getColumns(columns) {
let result = [...columns]
result.push({
title: "操作",
key: "operate",
render: (text, record) => {
return <a onClick={() => this.handleViewAttendance(record)}>查看</a>
}
})
return result;
}
// 查看考勤详情
handleViewAttendance(record) {
const { attendanceStore: {setSlideVisiable}} = this.props;
this.recordId = record.id
this.salaryYearMonth = record.salaryYearMonth
setSlideVisiable(true)
}
// 引用同步Cancel事件
handleRefereCancel() {
this.setState({refereAttendFormVisible: false})
const { attendanceStore: { getAttendanceList }} = this.props;
this.listSearch.current = 1
getAttendanceList(this.listSearch)
}
render() {
const { attendanceStore } = this.props;
const { modalParam } = this.state;
const { loading, hasRight, form, condition, tableStore, showSearchAd, getTableDatas, doSearch, setShowSearchAd } = attendanceStore;
const { step, setStep, setSlideVisiable, slideVisiable, doBatchDelete, attendTableStore, fieldSettingAttendList, fieldSettingCustomList, setFieldSettingAttendList, setFieldSettingCustomList, searchFieldSettingList } = attendanceStore;
const { getAttendanceFieldSettingList, saveAttendanceFieldSetting, fieldDataSource, fieldTableStore, fieldPageInfo, attendanceDataSource, attendanceColumns, attendancePageInfo, importLedgerList,
previewAttendQuoteColumns, previewAttendQuoteDataSource, importResult} = attendanceStore
const selectedRowKeys = toJS(tableStore.selectedRowKeys) || []; // tableStore 右侧选中数组
if (!hasRight && !loading) { // 无权限处理
return renderNoright();
}
const batchDelete = () => {
doBatchDelete()
this.fieldSearch = {fieldName: this.state.fieldName}
getAttendanceFieldList({fieldName: this.state.fieldName})
}
const rightMenu = [// 右键菜单
{
key: 'BTN_COLUMN',
icon: <i className='icon-coms-Custom' />,
content: '显示列定制',
onClick: this.showColumn
},
{
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 adBtn = [ // 高级搜索内部按钮
<Button type="primary" onClick={doSearch}>搜索</Button>,
<Button type="ghost" onClick={() => form.resetForm()}>重置</Button>,
<Button type="ghost" onClick={() => setShowSearchAd(false)}>取消</Button>,
];
const topTab = [{
title: "考勤数据",
viewcondition: "0"
},
{
title: "字段管理",
viewcondition: "1"
}];
const renderSearchOperationItem = () => {
return <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>
}
const renderLeftOperation = () => {
const { attendanceStore: {getAttendanceList}} = this.props;
return <div style={{marginLeft: "20px", marginTop: "10px"}}>薪资所属月: <RangePicker picker="month" format="yyyy-MM" onChange={(range) => {
this.listSearch = {
salaryYearMonth: range.map(item => moment(item).format("YYYY-MM"))
}
getAttendanceList(this.listSearch)
}}/></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}})
}}
/>
</Col>
<Col span={12}>
<span className="formLabel" style={{ lineHeight: "30px", marginRight: "10px" }}>薪资账套</span>
{
this.state.inited &&
<Select
defaultValue={this.state.modalParam.salarySobId} value={this.state.modalParam.salarySobId} style={{ width: "200px" }} onChange={(value) => {
this.setState({modalParam: {...modalParam, salarySobId: value}})
}}>
{importLedgerList.map(item => (
<Option value={item.id} key={item.id}>{item.content}</Option>
))}
</Select>
}
</Col>
<Col span={12}>
<span className="formLabel" style={{ lineHeight: "30px", marginRight: "10px" }}>薪资周期</span>
{
moment(this.state.modalParam.salaryYearMonth + "-01").startOf("month").format("YYYY-MM-DD")
}
~
{
moment(this.state.modalParam.salaryYearMonth + "-01").endOf("month").format("YYYY-MM-DD")
}
</Col>
<Col span={12}>
<span className="formLabel" style={{ lineHeight: "30px", marginRight: "10px" }}>考勤周期</span>
{
moment(this.state.modalParam.salaryYearMonth + "-01").startOf("month").format("YYYY-MM-DD")
}
~
{
moment(this.state.modalParam.salaryYearMonth + "-01").endOf("month").format("YYYY-MM-DD")
}
</Col>
</Row>
)}
const renderCustomOperate = () => {
return (
<div style={{display: "inline-block"}}>
<Dropdown.Button overlay={menu} type="primary">导出</Dropdown.Button>
<Button type="default" style={{marginLeft: "10px", marginRight: "10px"}}>自定义列</Button>
<WeaInputSearch
placeholder="请输入姓名/部门/工号/手机号"
/>
</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"}}>
<Button type="primary" style={{marginRight: "10px"}} onClick={() => handleNewClick()}>新建</Button>
<WeaInputSearch value={this.state.fieldName} onChange={(value) => {this.setState({fieldName: value})}} 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 = {}
getAttendanceList(this.listSearch)
}
}
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'} onChange={(value) => {handleSwitchItemChange(record, value)}}/>
default:
return <div dangerouslySetInnerHTML={{ __html: valueSpan }} />
}
}
return newColumn;
});
newColumns.push({
title: "操作",
dataIndex: "operate",
render: (text, record) => {
return (
<a onClick={() => {this.onItemEdit(record)}}>查看明细</a>
)
}
})
return newColumns;
}
// 保存回调
const handleItemMangeSave = (value) => {
const { attendanceStore: { saveAttendanceField, getAttendanceFieldList }} = this.props;
value.fieldType = value.fieldType == "1" ? "NUMBER" : "TEXT"
saveAttendanceField(value)
this.fieldSearch = {fieldName: this.state.fieldName}
getAttendanceFieldList(this.fieldSearch)
this.setState({itemMangeVisible: false})
}
const handleItemMangeUpdate = (value) => {
const { attendanceStore: {updateAttendanceField, getAttendanceFieldList }} = this.props;
// alert(JSON.stringify(value));
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">
<WeaRightMenu
datas={rightMenu} // 右键菜单
collectParams={collectParams} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
>
<WeaTop
title="考勤引用" // 文字
icon={<i className='icon-coms-meeting' />} // 左侧图标
iconBgcolor='#F14A2D' // 左侧图标背景色
showDropIcon={true} // 是否显示下拉按钮
dropMenuDatas={rightMenu} // 下拉菜单(和页面的右键菜单相同)
dropMenuProps={{ collectParams }} // 收藏功能: 配置之后显示 收藏、帮助、显示页面地址 这3个功能
>
{
this.state.tabSelectedKey == 0 ?
<div>
<CustomTab topTab={topTab}
searchOperationItem={
renderSearchOperationItem()
}
onChange={(v) => {
handleTabChange(v)
}}
/>
<CustomTab
leftOperation={
renderLeftOperation()
}
onChange={(v) => {
}}
/>
{/* <WeaTable // table内部做了loading加载处理页面就不需要再加了
comsWeaTableStore={attendTableStore} // table store
hasOrder={true} // 是否启用排序
needScroll={true} // 是否启用table内部列表滚动将自适应到父级高度
// getColumns={this.getColumns}
// onOperatesClick={this.onOperatesClick.bind(this)}
/> */}
<CustomTable // table内部做了loading加载处理页面就不需要再加了
loading={loading}
columns={this.getColumns(attendanceColumns)}
dataSource={attendanceDataSource}
// getColumns={this.getColumns}
// onOperatesClick={this.onOperatesClick.bind(this)}
pagination={{
onChange: (value) => {this.handleDataPageChange(value)},
total: attendancePageInfo.total,
current: attendancePageInfo.pageNum
}}
/>
</div>
:
<div>
<CustomTab topTab={topTab}
searchOperationItem={
renderRightOperation()
}
onChange={(v) => {
this.setState({
tabSelectedKey: v
})
}}
/>
<TwoColContent
leftContent={
// <WeaTable // table内部做了loading加载处理页面就不需要再加了
// comsWeaTableStore={tableStore} // table store
// hasOrder={true} // 是否启用排序
// needScroll={true} // 是否启用table内部列表滚动将自适应到父级高度
// getColumns={getFieldColumns}
// onOperatesClick={this.onItemOperatesClick.bind(this)}
// />
<CustomTable // table内部做了loading加载处理页面就不需要再加了
loading={loading}
dataSource={fieldDataSource}
columns={getFieldColumns(fieldTableStore.columns ? fieldTableStore.columns : [])}
pagination={{
onChange: (value) => {this.handleFieldPageChange(value)},
total: fieldPageInfo.total,
current: fieldPageInfo.pageNum
}}
/>
}
rightContent={
<TipLabel tipList={
[
"1、考勤字段包含自定义字段和考勤模块的统计字段所有字段不可重名",
"2、停用自定义字段将影响其参与计算的账套核算"
]
}/>
}
/>
</div>
}
</WeaTop>
</WeaRightMenu>
<ImportModal
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.setState({modalVisiable: false})}}
/>
<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 visible={slideVisiable}
top={0}
width={40}
height={100}
direction={'right'}
measure={'%'}
title={
<SlideModalTitle
subtitle={"考勤数据"}
editable={false}
customOperate={
renderCustomOperate()
}
/>
}
content={(<EditSlideContent salaryYearMonth={this.salaryYearMonth} id={this.recordId} editable={this.state.editable}/>)}
onClose={() => setSlideVisiable(false)}
showMask={true}
closeMaskOnClick={() => setSlideVisiable(false)} />
}
</div>
)
}
}