数据采集-考勤引用页面重构

This commit is contained in:
黎永顺 2023-03-08 18:35:27 +08:00
parent 7500887660
commit 7a4604a860
9 changed files with 120 additions and 1561 deletions

View File

@ -1,93 +0,0 @@
/*
* Author: 黎永顺
* Description:
* Date: 2022-05-19 15:18:09
* LastEditTime: 2022-06-29 10:06:13
*/
import React from "react";
import { WeaCheckbox, WeaInputSearch, WeaDialog } from "ecCom";
import { Button, Dropdown, Menu, Modal } from "antd";
import "../../pages/dataAcquisition/attendance/index.less"
export const items = [
{
key: "1",
title: "测试",
checked: false
},
{
key: "2",
title: "测试2",
checked: true
}
];
export default class SelectItemModal extends React.Component {
constructor(props) {
super(props);
this.state = {
searchValue: ""
};
}
handleShowChecked(value) {
value = value == 1 ? true : false;
this.props.onShowChecked(value);
}
handleMenuClick(e) {
if (e.key == "1") { //恢复默认设置
this.props.onRestoreDefault();
} else if (e.key == "2") {
this.props.onSetDefault();
} else if (e.key == "3") {
}
}
render() {
const menu = (
<Menu onClick={(e) => this.handleMenuClick(e)}>
<Menu.Item key="1">恢复默认设置</Menu.Item>
<Menu.Item key="2">设置默认设置</Menu.Item>
{/* <Menu.Item key="3">操作日志</Menu.Item> */}
</Menu>
);
return (
<WeaDialog
visible={this.props.visible}
style={{width:800}}
onCancel={this.props.onCancel}
initLoadCss
className="fieldSetWrapper"
title="导入字段设置"
buttons={[
<Button type="primary" style={{ marginRight: "10px" }} onClick={() => {
this.props.onSave();
}}>保存</Button>,
<Dropdown.Button overlay={menu}>更多</Dropdown.Button>
]}
>
<div className="searchWrapper">
<WeaInputSearch
placeholder={"请输入关键字"}
value={this.state.searchValue}
onChange={(value) => {
this.setState({ searchValue: value });
}}
onSearch={(value) => {
this.props.onSearch(value);
}}
/>
</div>
{this.props.children}
<div className="allInWrapper">
<WeaCheckbox content="只显示已选中字段" onChange={(value) => {
this.handleShowChecked(value);
}}/>
</div>
</WeaDialog>
);
}
}

View File

@ -1,78 +0,0 @@
import React from "react";
import { WeaCheckbox } from "ecCom";
import { Col, Icon, Row } from "antd";
export default class SelectItemsWrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
showContent: true,
checkStatus: false
};
}
handleAllChecked(value) {
value = value == 1 ? true : false;
let items = [...this.props.items];
items.map(item => {
item.checked = value;
});
this.setState({
checkStatus: value
});
this.props.onChange(items);
}
handleItemChange(value, record) {
value = value == 1 ? true : false;
let items = [...this.props.items];
items.map(item => {
if (item.id == record.id) {
item.checked = value;
}
});
this.props.onChange(items);
}
render() {
return (
<div>
<div style={{ margin: "10px 0", cursor: "pointer" }}>
<div style={{ display: "inline-block" }}><WeaCheckbox
content={<span style={{ fontWeight: "600" }}>{this.props.title}</span>} onChange={(value) => {
this.handleAllChecked(value);
}} value={this.state.checkStatus}/></div>
<div style={{ float: "right", fontWeight: "600" }} onClick={() => this.setState({
showContent: !this.state.showContent
})}>已选中{this.props.items ? this.props.items.filter(item => item.checked).length : 0}个字段
<span style={{ marginLeft: "10px", fontWeight: "400" }}>
{
this.state.showContent ? <Icon type="down"/> : <Icon type="left"/>
}
</span>
</div>
</div>
{
this.state.showContent && <div style={{
height: "160px",
border: "1px solid #eee",
padding: "10px",
overflowY: "scroll",
borderRadius: "5px"
}}>
<Row>
{
this.props.items && this.props.items.map(item => (
<Col span={6}><WeaCheckbox content={item.name} value={item.checked} onChange={(value) => {
this.handleItemChange(value, item);
}}/></Col>
))
}
</Row>
</div>
}
</div>
);
}
}

View File

@ -10,7 +10,14 @@ import { WeaDialog } from "ecCom";
import { Button, message } from "antd";
import { reFrenceConditions } from "../columns";
import { getSearchs } from "../../../../util";
import { checkOperation, getLedgerList, syncAttendanceRefer } from "../../../../apis/attendance";
import {
checkOperation,
getAttendanceFieldSettingList,
getLedgerList, returnToAttendanceFieldSettingDefault, saveAttendanceFieldSetting, saveAttendanceFieldSettingAsDefault,
syncAttendanceRefer
} from "../../../../apis/attendance";
import SelectItemModal from "../../../../components/selectItemsModal";
import SelectItemsWrapper from "../../../../components/selectItemsModal/selectItemsWrapper";
import "./index.less";
@inject("attendanceStore")
@ -20,7 +27,9 @@ class AttendanceRefrenceDataModal extends Component {
super(props);
this.state = {
loading: false,
condition: []
headerSetLoading: false,
condition: [],
headerSetPayload: { visible: false, title: "", children: null }
};
}
@ -92,12 +101,112 @@ class AttendanceRefrenceDataModal extends Component {
const { attendanceStore: { refenceform } } = this.props;
refenceform.resetForm();
};
/*
* Author: 黎永顺
* Description: 表头设置
* Params:
* Date: 2023/3/8
*/
handleHeaderSetting = () => {
const { headerSetPayload } = this.state;
this.setState({ headerSetLoading: true });
getAttendanceFieldSettingList({ sourceType: "QUOTE" }).then(({ status, data }) => {
this.setState({ headerSetLoading: false });
if (status) {
this.setState({
headerSetPayload: {
...headerSetPayload,
visible: true, title: "引用考勤字段设置",
children: <SelectItemsWrapper
ref={dom => this.setItemRef = dom}
dataSource={data}
onSelectGroupAll={this.handleSelectGroupAll}
onSelectItem={this.handleSelectItem}
/>
}
});
}
}).catch(() => this.setState({ headerSetLoading: false }));
};
handleCloseSettings = () => {
const { headerSetPayload } = this.state;
this.setState({
headerSetPayload: {
...headerSetPayload,
visible: false, title: "", children: null
}
});
};
handleSearchItemSet = (val) => this.setItemRef.handleSearchItemSet(val);
handleShowOnlyChecked = (checked) => this.setItemRef.handleShowOnlyChecked(checked);
handleSelectGroupAll = (groupId, checked) => this.setItemRef.handleSelectGroupAll(groupId, checked);
handleSelectItem = (id, checked) => this.setItemRef.handleSelectItem(id, checked);
handleMoreOpts = (key) => {
switch (key) {
case "recovery":
returnToAttendanceFieldSettingDefault({ sourceType: "QUOTE" }).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功");
this.handleHeaderSetting({ sourceType: "QUOTE" });
} else {
message.error(errormsg || "操作失败");
}
});
break;
case "setting":
const { state, props } = this.setItemRef;
let currentSettingFields = [];
const { selectItem } = state, { dataSource } = props;
_.forEach(dataSource, item => {
currentSettingFields = _.map([...currentSettingFields, ...item.items], child => {
return {
id: child.id,
checked: selectItem.includes(child.id)
};
});
});
const payload = { currentSettingFields, sourceType: "QUOTE" };
saveAttendanceFieldSettingAsDefault(payload).then(({ status, errormsg }) => {
if (status) {
message.success("操作成功");
} else {
message.error(errormsg || "操作失败");
}
});
break;
default:
break;
}
};
handleSave = () => {
const { state, props } = this.setItemRef;
let currentSettingFields = [];
const { selectItem } = state, { dataSource } = props;
_.forEach(dataSource, item => {
currentSettingFields = _.map([...currentSettingFields, ...item.items], child => {
return {
id: child.id,
checked: selectItem.includes(child.id)
};
});
});
const payload = { currentSettingFields, sourceType: "QUOTE" };
saveAttendanceFieldSetting(payload).then(({ status, errormsg }) => {
if (status) {
message.success("保存成功");
this.handleCloseSettings();
} else {
message.error(errormsg || "保存失败");
}
});
};
render() {
const { condition, loading } = this.state;
const { condition, loading, headerSetLoading, headerSetPayload } = this.state;
const { attendanceStore: { refenceform } } = this.props;
const buttons = [
<Button type="primary" onClick={this.handleSubmitFields} loading={loading}>同步</Button>
<Button type="primary" onClick={this.handleSubmitFields} loading={loading}>同步</Button>,
<Button type="ghost" onClick={this.handleHeaderSetting} loading={headerSetLoading}>表头设置</Button>
];
return (
<WeaDialog
@ -106,6 +215,13 @@ class AttendanceRefrenceDataModal extends Component {
className="modalWrapper"
>
{getSearchs(refenceform, condition, 1)}
{/* 表头设置 */}
<SelectItemModal {...headerSetPayload}
onCancel={this.handleCloseSettings}
onSearchItemSet={this.handleSearchItemSet}
onShowOnlyChecked={this.handleShowOnlyChecked}
onMoreOpts={this.handleMoreOpts} onSave={this.handleSave}
/>
</WeaDialog>
);
}

View File

@ -1,103 +0,0 @@
import React from "react";
import { DatePicker } from "antd";
import { inject, observer } from "mobx-react";
import { WeaTable } from "ecCom";
import "./editSlideContent.less";
const { MonthPicker } = DatePicker;
let emptyItem = {
incomeLowerLimit: "0.00",
incomeUpperLimit: "0.00",
dutyFreeValue: "0.00",
dutyFreeRate: "0.00",
taxableIncomeLl: "0.00",
taxableIncomeUl: "0.00",
taxRate: "0.00",
taxDeduction: "0.00"
};
@inject("attendanceStore")
@observer
export default class EditSlideContent extends React.Component {
constructor(props) {
super(props);
}
componentWillMount() {
// 初始化渲染页面
const { attendanceStore: { viewAttendQuote } } = this.props;
viewAttendQuote({ attendQuoteId: this.props.id });
}
getColumns(columns) {
let result = [...columns];
return result.filter(item => item.hide == "false");
}
getScrollWidth() {
const { attendanceStore } = this.props;
const { attendQuoteDetailTableStore } = attendanceStore;
return (
this.getColumns(
attendQuoteDetailTableStore.columns
? attendQuoteDetailTableStore.columns
: []
).length * 150
);
}
render() {
const {
attendanceStore,
attendanceStore: { viewAttendQuote }
} = this.props;
const {
attendQuoteDetailPageInfo,
attendQuoteDetailTableStore
} = attendanceStore;
const pagination = {
total: attendQuoteDetailPageInfo.total,
showTotal: total => `${total}`,
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"],
onShowSizeChange: (current, pageSize) => {
viewAttendQuote({ attendQuoteId: this.props.id, current, pageSize });
},
onChange: current => {
viewAttendQuote({
attendQuoteId: this.props.id,
current,
pageSize: attendQuoteDetailPageInfo.pageSize
});
}
};
return (
<div className="attendSlide">
<div className="titleWrapper">
{this.props.salaryYearMonth != "" &&
<div className="slideLeftTitle">
考勤周期 {this.props.salaryYearMonth}
</div>}
</div>
<div>
<WeaTable
columns={this.getColumns(
attendQuoteDetailTableStore.columns
? attendQuoteDetailTableStore.columns
: []
)}
dataSource={
attendQuoteDetailPageInfo.list
? attendQuoteDetailPageInfo.list
: []
}
pagination={pagination}
scroll={{ x: this.getScrollWidth() }}
/>
</div>
</div>
);
}
}

View File

@ -1,26 +0,0 @@
.attendSlide {
.titleWrapper {
height: 47px;
line-height: 47px;
overflow: hidden;
padding-left: 10px;
padding-right: 10px;
.slideLeftTitle {
float: left;
}
.rightTitle {
float: right;
}
}
.weaRangePickerWrapper {
display: inline-block;
.monthPickerWrapper {
width: 100px;
display: inline-block;
}
.betweenLable {
margin-left: 10px;
margin-right: 10px;
}
}
}

View File

@ -1,14 +0,0 @@
import React from 'react'
import { Modal } from 'antd'
import SelectItemModal, { items } from '../../../components/selectItemsModal/selectItemsWrapper';
export default class HeaderSetModal extends React.Component {
render() {
return (
<Modal width={800} visible={this.props.visible} onCancel={this.props.onCancel}>
<SelectItemsWrapper items={items} title={"考勤模块"}/>
</Modal>
)
}
}

View File

@ -1,921 +0,0 @@
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>
);
}
}

View File

@ -1,124 +0,0 @@
import React from "react";
import { Button, Col, Row, Switch } from "antd";
import { inject, observer } from "mobx-react";
import { WeaDialog, WeaInput, WeaSelect } from "ecCom";
import "./index.less";
@inject("attendanceStore")
@observer
export default class ItemMangeFormModal extends React.Component {
componentWillMount() {
const { attendanceStore: { currentItem, currentItemOperate } } = this.props;
if (currentItemOperate == "add") {
this.state = {
request: {
fieldName: "",
fieldType: "1",
enableStatus: 0,
description: ""
}
};
} else {
this.state = {
request: currentItem
};
}
}
handleChange(params) {
const { request } = this.state;
let result = { ...request, ...params };
this.setState({ request: result });
}
convertFieldType = (fileTypeStr) => {
if (fileTypeStr == "数值") {
return "1";
} else if (fileTypeStr == "文本") {
return "2";
} else if (fileTypeStr == "1" || fileTypeStr == "2") {
return fileTypeStr;
}
return "";
};
render() {
const options = [
{
key: "1",
selected: true,
showname: "数值"
},
{
key: "2",
selected: false,
showname: "文本"
}
];
const { request } = this.state;
const { fieldName, fieldType, enableStatus, description } = request;
let fileTypeKey = this.convertFieldType(fieldType);
const { attendanceStore: { currentItemOperate } } = this.props;
return (
<WeaDialog style={{ width: 600 }} visible={this.props.visible} onCancel={this.props.onCancel}
title="新建考勤自定义字段"
initLoadCss
className="itemManageModalWrapper"
buttons={[
<Button type="primary" onClick={() => {
currentItemOperate == "add" ? this.props.onSave(this.state.request) :
this.props.onUpdate(this.state.request);
}
}>保存</Button>
]}>
<div style={{ padding: "16px 120px" }}>
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
<Col span={8}>
字段名称
</Col>
<Col span={16}>
<WeaInput viewAttr={3} style={{ width: "200px" }} value={fieldName} onChange={(v) => {
this.handleChange({ fieldName: v });
}}/>
</Col>
</Row>
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
<Col span={8}>
类型
</Col>
<Col span={16}>
<WeaSelect style={{ width: "200px" }} options={options} value={fileTypeKey}
onChange={(v) => this.handleChange({ fieldType: v })}
/>
</Col>
</Row>
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
<Col span={8}>
是否启用
</Col>
<Col span={16}>
<Switch checked={enableStatus == 1} onChange={(value) => {
let enableStatus = 0;
if (value) {
enableStatus = 1;
}
this.handleChange({ enableStatus });
}}/>
</Col>
</Row>
<Row gutter={[10, 10]} style={{ marginBottom: "10px" }}>
<Col span={8}>
备注
</Col>
<Col span={16}>
<WeaInput style={{ width: "200px" }} value={description} onChange={(v) => {
this.handleChange({ description: v });
}}/>
</Col>
</Row>
</div>
</WeaDialog>
);
}
}

View File

@ -1,198 +0,0 @@
import React from "react";
import { Button, Col, message, Row, Select } from "antd";
import moment from "moment";
import { WeaDatePicker, WeaDialog, WeaError, WeaInput, WeaSelect } from "ecCom";
import SelectItemModal from "../../../components/selectItemsModal";
import SelectItemsWrapper from "../../../components/selectItemsModal/selectItemsWrapper";
import { inject, observer } from "mobx-react";
import { notNull } from "../../../util/validate";
const { Option } = Select;
@inject("attendanceStore")
@observer
export default class RefereAttendFormModal extends React.Component {
constructor(props) {
super(props);
this.state = {
headerSetVisible: false,
inited: false,
request: {
salarySobId: "",
salaryYearMonth: moment(new Date()).format("YYYY-MM"),
employeeIds: [],
description: ""
}
};
}
handleHeaderSet() {
this.setState({ headerSetVisible: true });
this.props.onHeaderSet();
}
componentWillMount() {
const { attendanceStore: { getLedgerList } } = this.props;
getLedgerList().then(() => {
this.setState({
inited: true
});
});
}
// 请求参数改变事件
handleRequestChange(params) {
const { request } = this.state;
let result = { ...request, ...params };
this.setState({ request: result });
}
// 同步点击回调
handleSync = () => {
if (!this.handleAsync) {
this.handleAsync = _.debounce(() => {
const { attendanceStore: { syncAttendanceRefer, checkOperation } } = this.props;
if (!this.validate()) {
return;
}
const { salarySobId, salaryYearMonth: salaryYearMonthStr } = this.state.request;
const payload = {
salaryYearMonthStr,
salarySobId
};
checkOperation(payload).then(({ status, data, errorMsg }) => {
if (status && data) {
syncAttendanceRefer(this.state.request).then(() => {
this.props.onCancel();
});
} else {
message.warning("已经核算过不可操作");
}
});
this.handleAsync = null;
}, 500);
}
this.handleAsync();
};
// 校验数据
validate() {
const { request } = this.state;
if (!notNull(request.salarySobId) && !notNull(request.salaryYearMonth)) {
this.refs.weaError.showError();
this.refs.weaError1.showError();
return false;
}
if (!notNull(request.salarySobId)) {
this.refs.weaError1.showError();
return false;
}
if (!notNull(request.salaryYearMonth)) {
this.refs.weaError.showError();
return false;
}
return true;
}
render() {
const { attendanceStore: { importLedgerList } } = this.props;
return (
<WeaDialog
initLoadCss
className="attendenceImportWrapper"
style={{ width: 600 }}
title="引用考勤数据"
buttons={[
<Button type="primary" onClick={this.handleSync}>同步</Button>,
<Button type="default" onClick={() => {
this.handleHeaderSet();
}}>表头设置</Button>
]}
visible={this.props.visible}
onCancel={this.props.onCancel}>
<Row style={{ marginBottom: "10px" }}>
<Col span={8}>薪资所属月</Col>
<Col span={16}>
<WeaError
style={{ width: "100%" }}
tipPosition="bottom"
ref="weaError"
error="请选择薪资所属月">
<WeaDatePicker
viewAttr={3}
format="YYYY-MM"
style={{ width: "100%" }}
value={this.state.request.salaryYearMonth}
onChange={(value) => {
if (value === "") this.refs.weaError.showError();
this.handleRequestChange({ salaryYearMonth: value });
}}
/>
</WeaError>
</Col>
</Row>
<Row style={{ marginBottom: "10px" }}>
<Col span={8}>薪资账套</Col>
<Col span={16}>
{
this.state.inited &&
<WeaError
style={{ width: "100%" }}
tipPosition="bottom"
ref="weaError1"
error="请选择薪资账套">
<WeaSelect
viewAttr={3}
value={this.state.request.salarySobId}
style={{ width: "100%" }}
options={
_.isEmpty(importLedgerList) ? [{ key: "", showname: "" }] :
[{ key: "", showname: "" }, ..._.map(importLedgerList, it => ({
key: it.id,
showname: it.content
}))]
}
onChange={(value) => {
if (value === "") this.refs.weaError1.showError();
this.handleRequestChange({ salarySobId: value });
}}/>
</WeaError>
}
</Col>
</Row>
<Row style={{ marginBottom: "10px" }}>
<Col span={8}>备注</Col>
<Col span={16}>
<WeaInput style={{ width: "100%" }} value={this.state.request.description} onChange={(value) => {
this.handleRequestChange({ description: value });
}}/>
</Col>
</Row>
<SelectItemModal
onShowChecked={(value) => {
this.props.onShowChecked(value);
}}
onRestoreDefault={() => {
this.props.onRestoreDefault();
}}
onSetDefault={() => {
this.props.onSetDefault();
}}
onSearch={(value) => {
this.props.onSearch(value);
}}
onSave={(value) => {
this.props.onSave(value);
}}
visible={this.state.headerSetVisible} onCancel={() => this.setState({ headerSetVisible: false })}>
<SelectItemsWrapper items={this.props.items} title={"考勤模块"} onChange={(value) => {
this.props.onChange(value);
}}/>
</SelectItemModal>
</WeaDialog>
);
}
}