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

This commit is contained in:
黎永顺 2023-03-06 15:06:56 +08:00
parent 64375f681d
commit 33e96c4437
7 changed files with 474 additions and 172 deletions

View File

@ -1,20 +1,20 @@
import React from "react"
import { Button } from "antd"
import { WeaCheckbox, WeaHelpfulTip } from "ecCom";
import React from "react";
import { Button } from "antd";
export default class HeaderSet extends React.Component {
render() {
return (
<div style={{display: "inline-block"}}>
<Button type="default" style={{marginLeft: "10px", marginRight: "10px"}} onClick={this.props.onSetClick}>表头设置</Button>
{/*<WeaCheckbox style={{marginRight: "10px"}}/>*/}
{/*<WeaHelpfulTip*/}
{/* className="headSetTips"*/}
{/* width={200}*/}
{/* title="提示:勾选此项,则导出模板的考勤模块字段自动填充考勤模块的数据,导入时默认为覆盖导入"*/}
{/* placement="topLeft"*/}
{/*/>*/}
</div>
)
}
render() {
return (
<div style={{ display: "inline-block" }}>
<Button type="default" style={{ marginLeft: "10px", marginRight: "10px" }} onClick={this.props.onSetClick}
loading={this.props.loading}>表头设置</Button>
{/*<WeaCheckbox style={{marginRight: "10px"}}/>*/}
{/*<WeaHelpfulTip*/}
{/* className="headSetTips"*/}
{/* width={200}*/}
{/* title="提示:勾选此项,则导出模板的考勤模块字段自动填充考勤模块的数据,导入时默认为覆盖导入"*/}
{/* placement="topLeft"*/}
{/*/>*/}
</div>
);
}
}

View File

@ -5,24 +5,11 @@
* 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"
import { WeaCheckbox, WeaDialog, WeaInputSearch } from "ecCom";
import { Button } from "antd";
import "./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);
@ -31,62 +18,49 @@ export default class SelectItemModal extends React.Component {
};
}
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") {
}
componentWillReceiveProps(nextProps, nextContext) {
if (
nextProps.visible !== this.props.visible &&
!nextProps.visible
) this.setState({ searchValue: "" });
}
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>
);
const { searchValue } = this.state;
const { title, onSearchItemSet, onShowOnlyChecked, comp: children, ...extra } = this.props;
const btns = [<Button type="primary">保存</Button>];
const moreBtn = {
datas: [
{
key: "recovery",
content: "恢复默认设置",
icon: <i className="icon-coms-Flow-setting"/>,
onClick: key => alert(`点击事物处理函数接受的实参为 ${key}`)
},
{
key: "setting",
content: "设为默认设置",
icon: <i className="icon-coms-Flow-setting"/>,
onClick: key => alert(`点击事物处理函数接受的实参为 ${key}`)
}
]
};
const titleComp = <div className="setHeaderWrapper">
<span>{title}</span>
<WeaInputSearch value={searchValue} onChange={searchValue => this.setState({ searchValue })}
placeholder="请输入关键字" style={{ width: 200 }}
onSearch={onSearchItemSet}
/>
</div>;
const bottomLeft = <WeaCheckbox content="只显示已选中字段" onChange={onShowOnlyChecked}/>;
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>
]}
<WeaDialog {...extra} hasScroll title={titleComp}
style={{ width: 592, height: 248 }}
buttons={btns} moreBtn={moreBtn}
initLoadCss className="setWrapper"
bottomLeft={bottomLeft}
>
<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>
{children}
</WeaDialog>
);
}

View File

@ -0,0 +1,67 @@
.setWrapper {
.setHeaderWrapper, .setGroupWrapper {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.wea-title .ant-checkbox-wrapper > span:last-child, .setGroupWrapper > .checkedtitle {
color: #111;
font-weight: 600;
font-size: 12px;
padding-right: 8px;
}
.itemContUl {
display: flex;
align-items: center;
flex-wrap: wrap;
li {
width: 124px;
overflow: hidden;
padding: 4px 0;
.wea-checkbox {
width: 100%;
}
.ant-checkbox-wrapper {
display: flex;
align-items: center;
width: 100%;
span:last-child {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
.itemsWrapper {
height: 160px;
overflow: scroll;
border: 1px solid #e5e5e5;
border-radius: 4px;
padding: 16px;
width: 100%;
.empty {
line-height: 160px;
text-align: center;
font-size: 14px;
display: inline-block;
width: 100%;
}
}
.wea-more-button {
ul > li:last-child {
display: none !important;
}
}
}

View File

@ -0,0 +1,93 @@
/*
* 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 +1,56 @@
import React from "react";
import { WeaCheckbox } from "ecCom";
import { Col, Icon, Row } from "antd";
/*
* Author: 黎永顺
* name: 设置项目
* Description:
* Date: 2023/3/6
*/
import React, { Component } from "react";
import { WeaCheckbox, WeaSearchGroup } from "ecCom";
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);
}
class SelectItemsWrapper extends Component {
renderTitle = (item) => {
const { groupName } = item;
return <div className="setGroupWrapper">
<WeaCheckbox content={groupName}/>
<span className="checkedtitle">已选择0个字段</span>
</div>;
};
render() {
const { dataSource } = this.props;
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>
<React.Fragment>
{
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>
_.map(dataSource, item => {
const { items } = item;
return <WeaSearchGroup title={this.renderTitle(item)} showGroup>
<div className="itemsWrapper">
{
_.isEmpty(items) ?
<span className="empty">暂无数据</span> :
<ul className="itemContUl">
{
_.map(items, child => {
const { name, checked } = child;
return <li title={name}>
<WeaCheckbox
content={name} value={checked ? "1" : "0"}
onChange={(value) => {
console.log(value);
}}
/>
</li>;
})
}
</ul>
}
</div>
</WeaSearchGroup>;
})
}
</div>
</React.Fragment>
);
}
}
export default SelectItemsWrapper;

View File

@ -0,0 +1,78 @@
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

@ -9,25 +9,31 @@ import { WeaTable } from "ecCom";
import { message, Modal } from "antd";
import {
deleteAttendance,
getAttendanceFieldSettingList,
getAttendanceList,
getLedgerList,
getSalaryCycleAndAttendCycle,
importAttendQuoteData,
previewAttendQuote
} from "../../../../apis/attendance";
import ImportModal from "../../../../components/importModal";
import HeaderSet from "../../../../components/importModal/headerSet";
import ImportFormOptions from "./importFormOptions";
import SelectItemModal from "../../../../components/selectItemsModal";
import moment from "moment";
import SelectItemsWrapper from "../../../../components/selectItemsModal/selectItemsWrapper";
class AttendanceDataComp extends Component {
constructor(props) {
super(props);
this.state = {
loading: {
query: false
query: false,
headset: false
},
dataSource: [],
columns: [],
fieldSetList: [],
pageInfo: {
current: 1,
pageSize: 10,
@ -40,7 +46,8 @@ class AttendanceDataComp extends Component {
importFormPayload: {
salaryYearMonth: moment().format("YYYY-MM"), salarySobList: [],
salarySobId: "", salaryCycle: "", attendCycle: ""
}
},
fieldSetPayload: { visible: false, title: "", data: [] }
};
}
@ -137,15 +144,47 @@ class AttendanceDataComp extends Component {
};
setStep = step => this.setState({ importData: { ...this.state.importData, step } });
handleFinish = () => {
console.log("finish");
const { importData } = this.state;
const { step } = importData;
this.setState({
importData: {
...importData, visiable: false, params: {}, step: 0,
columns: [], slideDataSource: [], importResult: []
}
});
step === 2 && this.getAttendanceList();
};
handlePreviewImport = (params) => {
previewAttendQuote(params).then(({status, data})=>{
console.log("handlePreviewImport", data);
})
const { importData } = this.state;
previewAttendQuote(params).then(({ status, data }) => {
if (status) {
const { headers, list } = data;
this.setState({
importData: {
...importData,
columns: _.map(headers, (it, dataIndex) => ({ title: it, dataIndex })),
slideDataSource: _.map(list, item => {
return _.reduce(item, (pre, cur, key) => (_.assign(pre, { [key]: cur })), {});
})
}
});
}
});
};
handleImport = (params) => {
console.log("handleImport", params);
const { importData } = this.state;
const { step } = importData;
importAttendQuoteData(params).then(({ status, data }) => {
if (status) {
this.setState({
importData: {
...importData,
step: step + 1,
importResult: data
}
});
}
});
};
handleTemplateLinkClick = () => {
const { importFormPayload } = this.state;
@ -156,9 +195,81 @@ class AttendanceDataComp extends Component {
}
window.open(`/api/bs/hrmsalary/attendQuote/downloadTemplate?salaryYearMonth=${salaryYearMonth}&salarySobId=${salarySobId}`);
};
/*
* Author: 黎永顺
* Description: 表头设置
* Params:
* Date: 2023/3/6
*/
handleHeaderSettings = (params) => {
const { fieldSetPayload, loading } = this.state;
this.setState({ loading: { ...loading, headset: true } });
getAttendanceFieldSettingList(params).then(({ status, data }) => {
this.setState({ loading: { ...loading, headset: false } });
if (status) {
this.setState({
fieldSetList: data,
fieldSetPayload: {
...fieldSetPayload,
visible: true, title: "导入字段设置", data
}
});
}
}).catch(() => this.setState({ loading: { ...loading, headset: false } }));
};
handleCloseSettings = () => {
const { fieldSetPayload } = this.state;
this.setState({
fieldSetPayload: {
...fieldSetPayload,
visible: false, title: "", data: []
}
});
};
handleSearchItemSet = (val) => {
const { fieldSetPayload, fieldSetList } = this.state;
this.setState({
fieldSetPayload: {
...fieldSetPayload,
data: _.map(_.cloneDeep(fieldSetList), item => {
return {
...item,
items: _.filter(item.items || [], child => {
return child.name.indexOf(val) !== -1;
})
};
})
}
});
};
handleShowOnlyChecked = (checked) => {
const { fieldSetPayload, fieldSetList } = this.state;
if (!!NUmber(checked)) {
this.setState({
fieldSetPayload: {
...fieldSetPayload,
data: _.map(_.cloneDeep(fieldSetList), item => {
return {
...item,
items: _.map(item.items || [], child => !!child.checked)
};
})
}
});
} else {
this.setState({
fieldSetPayload: {
...fieldSetPayload,
data: _.cloneDeep(fieldSetList)
}
});
}
};
render() {
const { dataSource, columns, pageInfo, loading, importData, importFormPayload } = this.state;
const {
dataSource, columns, pageInfo, loading, importData, importFormPayload, fieldSetPayload
} = this.state;
const { showOperateBtn, salaryYearMonth } = this.props;
const pagination = {
...pageInfo,
@ -207,19 +318,20 @@ class AttendanceDataComp extends Component {
previewImport={this.handlePreviewImport} importFile={this.handleImport}
templateLink={this.handleTemplateLinkClick} onCancel={this.handleFinish}
headerSetCompoent={<HeaderSet
onSetClick={() => {
// getAttendanceFieldSettingList({ sourceType: "IMPORT" });
// this.setState({
// selectItemVisible: true
// });
}}
/>}
renderFormComponent={
() => <ImportFormOptions
{...importFormPayload}
onChangeImportForm={this.handleChangeImportPayload}/>
loading={loading.headset}
onSetClick={() => this.handleHeaderSettings({ sourceType: "IMPORT" })}/>}
renderFormComponent={() => <ImportFormOptions
{...importFormPayload}
onChangeImportForm={this.handleChangeImportPayload}/>
}
/>
{/* 表头设置 */}
<SelectItemModal {...fieldSetPayload}
comp={<SelectItemsWrapper dataSource={fieldSetPayload.data}/>}
onCancel={this.handleCloseSettings}
onSearchItemSet={this.handleSearchItemSet}
onShowOnlyChecked={this.handleShowOnlyChecked}
/>
</React.Fragment>
);
}