weaver_trunk_cli/pc4mobx/hrmAttendance/stores/monthReport.js

801 lines
24 KiB
JavaScript

import ReactDOM from 'react-dom';
import {
observable,
action,
reaction,
} from "mobx";
import HrmBaseStore from "./baseStore";
import {
message,
Button,
Menu,
Dropdown,
Modal
} from 'antd';
import {
WeaSelect,
WeaBrowser,
WeaLocaleProvider,
WeaTools
} from 'ecCom';
import {
WeaTableNew
} from "comsMobx";
import * as api from "../apis/monthReport";
import find from 'lodash/find';
import findIndex from 'lodash/findIndex';
import filter from 'lodash/filter';
import flattenDeep from 'lodash/flattenDeep';
import remove from 'lodash/remove';
import {
i18n
} from '../public/i18n';
import {IEVersion} from '../util/pure-util';
import {addContentPath} from '../util/index.js'
const {
TableStore
} = WeaTableNew;
const getLabel = WeaLocaleProvider.getLabel;
const shiftBrowserProps = {
browserModalProps: {
closable: true,
},
closable: true,
checkStrictly: true,
completeParams: {},
conditionDataParams: {},
dataParams: {},
destDataParams: {},
expandfirstnode: false,
hasAddBtn: false,
hasAdvanceSerach: true,
hasBorder: false,
hideVirtualOrg: false,
icon: "icon-coms-hrm",
iconBgcolor: "#217346",
idSeparator: ",",
isAutoComplete: 1,
isDetail: 0,
isMultCheckbox: false,
isSingle: false,
linkUrl: "",
pageSize: 10,
quickSearchName: "serial",
showCheckStrictly: true,
title: "班次",
type: "mkqshift",
viewAttr: 2,
customized: true,
memorise: true
}
export class HrmAttendanceMonthReport extends HrmBaseStore {
/********************* unobservable list *********************/
shortWeekdays = this.getLocale().lang.format.veryShortWeekdays;
conditionData;
radioGroupVal = {}
// showColumns = [null, null];
displayColumnsDef = [];
selectedSerial = '';
detailTableInfo;
selectRefs = [];
detailParams = {};
tableRef;
/********************* unobservable list *********************/
/********************* dialog info setting *********************/
/********************* dialog info setting *********************/
/********************* observable list *********************/
@observable rightMenus = [];
@observable showColumns = [null, null];
@observable spinning = false;
@observable spinTip = '';
@observable pageIndex = 1;
@observable pageSize = 10;
@observable total = 0;
@observable radioGroupConfig = [];
@observable table = {
columns: [],
datas: []
}
@observable displayColumns = [];
@observable showHasNotAccount = false;
@observable replaceDatas = [];
@observable holidays = [];
@observable dialogParams = {
moduleName: 'hrm',
visible: false,
style: {
width: 1000,
height: 600
},
onCancel: () => {
this.dialogParams.visible = false;
this.detailParams = {};
}
};
@observable detailTable = new TableStore();
@observable tabConfig = {
tabs: [],
keyParam: "viewCondition",
activeTabKey: "1",
tabChangeHandle: key => this.setActiveTab(key, this.tabConfig.resourceId)
};
/********************* observable list *********************/
/********************* computed list *********************/
/********************* computed list *********************/
/********************* action list *********************/
@action clearData = () => {
this.pageIndex = 1;
this.pageSize = 10;
this.total = 0;
this.radioGroupVal = {};
this.showColumns = [null, null];
this.showHasNotAccount = false;
this.displayColumns = [];
this.replaceDatas.length = 0;
this.clearSerial();
};
@action clearSerial = () => {
this.selectedSerial = '';
}
@action getQueryParams = (pageIndex, pageSize) => {
this.pageIndex = pageIndex || 1;
const params = {
pageIndex: this.pageIndex,
...this.radioGroupVal,
isNoAccount: this.showHasNotAccount ? '1' : '0',
attendanceSerial: this.selectedSerial || ''
}
pageSize && Object.assign(params, {pageSize});
return params;
}
getShowColumns = () => {
return filter(this.toJS(this.showColumns), d => d != null).join(',');
}
@action init = () => {
this.clearData()
this.containerInitFinished.authorized = true;
this.containerInitFinished.init = true;
api.init().then(rs => {
rs.map((data, index) => {
if (data.status === "1" || data.status == null) {
switch (index) {
case 0:
this.conditionData = data;
this.displayColumnsDef = flattenDeep(data.showColumns);
this.generateRadioGroupConfig(data);
break;
case 1:
this.rightMenus = data.btnMenu;
break;
}
}
});
},
error => {})
}
@action replaceDisplayColumnsCondition = () => {
let tmp = this.toJS(this.showColumns);
const obj = {
label: getLabel('390081', '展示列'),
labelcol: 3,
fieldcol: 21,
com: (
<div>
{
this.conditionData.showColumns.map((c, i) => {
c.map((op, index) => {
const t = op.showname;
if(op.key === 'attendanceSerial'){
op.showname = (
<span title={t}>
<span>{t}</span>
<WeaBrowser ecId={`${this && this.props && this.props.ecId || ''}_WeaBrowser@tlhz7c@${index}`}
ref={dom => this.setBrowser(dom)}
{...shiftBrowserProps}
title={getLabel('24803','班次')}
inputStyle={{ width: 200 }}
onChange={this.onBrowserChange}
>
<span style={{marginLeft: '10px', color: '#4D7AD8'}}>{getLabel('500494','选择显示班次')}</span>
</WeaBrowser>
</span>
)
}
});
if(tmp[i] == null){
if(c.length > 1){
tmp[i] = c.reduce((pre, cur) => {
if(Array.isArray(pre)){
cur.selected && pre.push(cur.key);
return pre;
}else{
let arr = [];
pre.selected && arr.push(pre.key);
cur.selected && arr.push(cur.key);
return arr;
}
}).join(',');
}else{
c[0].selected && arr.push(c[0].key);
}
this.showColumns[i] = tmp[i];
}
return (
<div>
<WeaSelect ecId={`${this && this.props && this.props.ecId || ''}_WeaSelect@3wghsj@${i}`} ref={dom => this.setSelectRef(dom, i)}
options={c}
detailtype='2'
value={this.showColumns[i]}
onChange={(v, showname, key) => this.onSelectChange(v, key[0], i)}
/>
</div>
)
})
}
</div>
)
}
this.setDisplayColumns();
return obj;
}
@action generateRadioGroupConfig = (data) => {
let config = [];
config.push(this.replaceDisplayColumnsCondition());
config = config.concat(data.conditions);
this.radioGroupConfig = config;
}
@action onSelectChange = (v, key, i) => {
this.showColumns[i] = v;
if (i == 0) {
if (key == 'attendanceSerial') {
if (this.showColumns[i].indexOf('attendanceSerial') < 0) {
this.clearSerial();
this.setDisplayColumns();
} else {
this.browser.openModal();
}
} else {
this.setDisplayColumns();
}
} else {
this.setDisplayColumns();
}
}
@action setDisplayColumns = () => {
let arr = [];
this.toJS(this.showColumns).map(g => arr = arr.concat(g.split(',')));
let displayColumns = [];
this.displayColumnsDef.map(cf => {
const selected = (arr.indexOf(cf.key) > -1);
displayColumns.push({
key: cf.key,
selected
});
cf.cascadekey != null && cf.cascadekey != '' && cf.cascadekey.split(',').map(k => {
displayColumns.push({
key: k,
selected
});
})
})
this.displayColumns = displayColumns;
this.refreshTableColumns();
}
@action setSelectRef = (dom, i) => {
this.selectRefs[i] = dom;
}
@action setBrowser = dom => {
this.browser = dom;
}
@action onBrowserChange = (ids, names, datas) => {
let arr = [];
datas.map(d => arr.push({
id: d.id,
name: d.name
}));
this.replaceDatas = arr;
this.selectedSerial = ids;
let array = this.toJS(this.showColumns[0]).split(','),
value = '';
if (arr.length == 0) {
remove(array, v => v == 'attendanceSerial');
value = array.join(',');
} else {
findIndex(array, 'attendanceSerial') < 0 && array.push('attendanceSerial');
value = array.join(',');
}
this.showColumns[0] = value;
this.setDisplayColumns();
this.selectRefs[0].setState({
value
});
this.getKQReport(this.getQueryParams());
}
@action getDropDownMenu = () => (
<Menu ecId={`${this && this.props && this.props.ecId || ''}_Menu@7o7vr8`}>
{
[
{
key: 'attendancedays',
onClickHandle: () => this.showDetail(null, 'attendancedays'),
content: getLabel(391409, '出勤明细')
}, {
key: 'beLate',
onClickHandle: () => this.showDetail(null, 'beLate'),
content: getLabel(20088, '迟到明细')
}, {
key: 'leaveEearly',
onClickHandle: () => this.showDetail(null, 'leaveEearly'),
content: getLabel(20089, '早退明细')
}, {
key: 'absenteeism',
onClickHandle: () => this.showDetail(null, 'absenteeism'),
content: getLabel(20090, '旷工明细')
}, {
key: 'forgotCheck',
onClickHandle: () => this.showDetail(null, 'forgotCheck'),
content: getLabel(20091, '漏签明细')
}, {
key: 'leave',
onClickHandle: () => this.showDetail(null, 'leave'),
content: getLabel(20092, '请假明细')
}, {
key: 'businessLeave',
onClickHandle: () => this.showDetail(null, 'businessLeave'),
content: getLabel(20093, '出差明细')
}, {
key: 'officialBusiness',
onClickHandle: () => this.showDetail(null, 'officialBusiness'),
content: getLabel(20094, '公出明细')
}, {
key: 'overtimeTotal',
onClickHandle: () => this.showDetail(null, 'overtimeTotal'),
content: getLabel(33501, '加班明细')
}
].map((m, index) => {
return (
<Menu.Item ecId={`${this && this.props && this.props.ecId || ''}_undefined@f5w479@${index}`} key={m.key}>
<div onClick={m.onClickHandle}>{m.content}</div>
</Menu.Item>
)
})
}
</Menu>
)
@action getTopProps = () => {
let buttons = [
<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@09wejk`} op='setting' size="small" style={{ height: '28px' }} onClick={this.showAll} title={this.showHasNotAccount ? getLabel('31504','显示无账号人员') : getLabel('500013','不显示无账号人员')}>
<span>
{
this.showHasNotAccount ?
<i className='icon-coms-ShowNoAccount' style={{ color: '#2DB7F5' }} />
:
<i className='icon-coms-NoAccountNoDisplay' style={{ color: '#8A8A8A' }} />
}
</span>
</Button>,
<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@ao3s30`} type='primary' op='export' onClick={this.exportExcel}>{getLabel(28343, '导出Excel')}</Button>
];
let menus = [];
menus.push({
key: '0',
content: buttons[0].props.title,
icon: <i className={this.menuIconCollection[buttons[0].props.op]}/>,
onClick: () => this.showAll()
});
this.toJS(this.rightMenus).map((menu, index) => {
index > 0 && menus.push({
key: index.toString(),
content: menu.menuName,
icon: <i className={menu.menuIcon}/>,
onClick: () => {
switch (menu.type) {
case "BTN_Export_Excel":
this.exportExcel();
break;
case "BTN_KQ_REPORT_FORMAT":
this.formatData(menu.menuName);
break;
}
}
});
});
menus.push({
key: menus.length.toString(),
content: getLabel(354, '刷新'),
icon: <i className={this.menuIconCollection['sync']}/>,
onClick: () => this.getKQReport(this.getQueryParams())
});
buttons.push((
<Dropdown ecId={`${this && this.props && this.props.ecId || ''}_Dropdown@5su6cb`} overlay={this.getDropDownMenu()} trigger={['click']} >
<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@klzwdw`} type='primary'>{getLabel(501537, '查看汇总数据')}</Button>
</Dropdown>
));
return {
buttons,
menus: [
...menus,
// ...this.getBasicMenus("HRM_ENGINE_HRM_ANNUAL_MANAGER_SET")
]
};
};
@action checkDisplay = key => {
const v = (find(this.toJS(this.displayColumns), {key}) || {}).selected;
if(v == null)
return true;
return v;
}
@action refreshTableColumns = () => {
//TODO
// const columns = this.toJS(this.table.columns);
// this.table.columns = this.convertColumns(columns);
}
@action renderCol = column => {
column.children && column.children.map(c => {
const {
title,
unit,
dataIndex
} = c;
const date = this.moment(dataIndex, 'YYYY-MM-DD');
if (c.isCalendar == '1') {
const weekDay = date.day();
const holidayInfo = find(this.toJS(this.holidays), {
date: date.format('YYYY-MM-DD')
});
c.title = (
<div title={c.dataIndex} className='date' style={{ color: weekDay == 6 || weekDay == 0 || holidayInfo != null ? "red" : "#000" }}>
<div className='weekday text-elli'>{this.shortWeekdays[weekDay]}</div>
<div className='day'>{date.date()}</div>
{
holidayInfo != null &&
<img src={addContentPath(`/hrm/hrm_e9/images/${['1','3'].indexOf(holidayInfo.type) > -1 ? 'rest' : 'work'}.png`)} />
}
</div>
);
} else if (unit != null && unit != '') {
c.title = (
<div className='rSpan1' title={`${title}(${unit})`}>
<div className='title text-elli'>{title}</div>
<div className='unit'>({unit})</div>
</div>
)
}
c.render = (text, record, index) => {
let rs = text;
if (typeof(text) == 'object') {
rs = text.text;
}
const {
dataIndex
} = c, {
resourceId
} = record;
if (c.isCalendar == '1')
return <a onClick={() => this.showSignDetail({resourceId,kqDate:dataIndex})} title={this.removeBrTags(rs)}><div className='text-elli'>{rs}</div></a>
return c.showDetial == '1' ? <a onClick={() => this.showDetail(record.resourceId, c.dataIndex, c.type, record[c.dataIndex], c.isCalendar)} title={this.removeBrTags(rs)}><div className='text-elli'>{rs}</div></a> : <div>{rs}</div>;
}
this.renderCol(c);
})
}
removeBrTags = (str) => {
return str.replace(/<br\s*\/?>/gi, ' ');
}
@action convertColumns = (columns) => {
columns.map((c, i) => {
// if (IEVersion() == -1 && ['lastname', 'subcompany', 'department'].indexOf(c.dataIndex) > -1 && this.checkDisplay(c.dataIndex))
if (['lastname', 'subcompany', 'department'].indexOf(c.dataIndex) > -1 && this.checkDisplay(c.dataIndex))
c.fixed = 'left';
else
c.fixed = null;
const {
title,
unit
} = c;
if (unit != null && unit != '') {
c.title = (
<div className='rSpan2' title={`${title}(${unit})`}>
<div className='title text-elli'>{title}</div>
<div className='unit'>({unit})</div>
</div>
)
}
c.render = (text, record, index) => {
if (c.dataIndex == 'lastname') {
return <a href={`javaScript:openhrm(${record.resourceId});`} onClick={e => window.pointerXY(e)} title={text}><div className='text-elli'>{text}</div></a>;
} else if (c.dataIndex == 'subcompany') {
return <a onClick={() => window.open(`/spa/hrm/engine.html#/hrmengine/organization?showTree=false&isView=1&type=subcompany&id=${record.subcompanyId}`)} title={text}><div className='text-elli'>{text}</div></a>;
} else if (c.dataIndex == 'department') {
return <a onClick={() => window.open(`/spa/hrm/engine.html#/hrmengine/organization?showTree=false&isView=1&type=department&id=${record.departmentId}`)} title={text}><div className='text-elli'>{text}</div></a>;
} else if (c.dataIndex == 'jobtitle') {
return <a onClick={() => window.open(`/spa/hrm/engine.html#/hrmengine/posts?id=${record.jobtitleId}`)} title={text}><div className='text-elli'>{text}</div></a>;
} else if (c.dataIndex == 'workcode') {
return <a href={`javaScript:openhrm(${record.resourceId});`} onClick={e => window.pointerXY(e)} title={text}><div className='text-elli'>{text}</div></a>;
} else
return c.showDetial == '1' ? <a onClick={() => this.showDetail(record.resourceId, c.dataIndex, c.type, record[c.dataIndex])} title={this.removeBrTags(text) }><div className='text-elli'>{text}</div></a> : <div>{text}</div>;
}
this.renderCol(c);
});
return columns;
}
@action getKQReport = params => {
if (this.spinning)
return;
this.spinning = true;
api.getKQReport({
data: JSON.stringify(params)
}).then(data => {
if (data.status === '1' || data.status == null) {
this.holidays = data.holidays;
this.table.columns = this.convertColumns(data.columns);
this.table.datas = [...data.datas];
this.pageIndex = data.pageindex;
this.pageSize = data.pagesize || 10;
this.total = data.count;
this.resetScroll();
} else {
message.error(data.message);
}
this.spinning = false;
}, error => this.spinning = false);
}
@action onRadioGroupChange = params => {
this.radioGroupVal = params;
if (params.typeselect === '6' && (params.fromDate === '' || params.toDate === ''))
return;
switch (params.viewScope) {
case '1':
if (params.subCompanyId == null || params.subCompanyId == '') {
return;
}
break;
case '2':
if (params.departmentId == null || params.departmentId == '') {
return;
}
break;
case '3':
if (params.resourceId == null || params.resourceId == '') {
return;
}
break;
}
this.getKQReport(this.getQueryParams(1));
}
@action showAll = () => {
this.showHasNotAccount = !this.showHasNotAccount;
this.getKQReport(this.getQueryParams());
}
@action exportExcel = () => {
if (this.spinning)
return;
this.spinning = true;
this.spinTip = getLabel('500702', '导出数据中,请稍候');
const params = {
...this.getQueryParams(),
showColumns: this.getShowColumns()
};
api.exportExcel({
data: JSON.stringify(params)
}).then(data => {
this.spinning = false;
this.spinTip = '';
if (data.status === '1' && data.url != null && data.url.trim().length > 0){
WeaTools.downloadFile(addContentPath(data.url), "GET");
Modal.confirm({
title: getLabel(558,'提示') ,
content: getLabel('导出成功'),
});
}else if(data.status === '-1'){
Modal.confirm({
title: getLabel(558,'提示') ,
content: data.message,
});
}
}, error => {
this.spinning = false;
this.spinTip = '';
})
}
@action setActiveTab = (key, resourceId) => {
// const tabIndex = this.getTabIndex(this.toJS(this.tabConfig.tabs), key);
// if (tabIndex < 0) return;
this.tabConfig.activeTabKey = key || this.tabConfig.tabs[0].viewCondition;
this.detailParams.tabKey = this.tabConfig.activeTabKey;
this.callDetail(resourceId);
};
@action showDetail = (resourceId, dataIndex, columnType, source, isCalendar) => {
this.detailTableInfo = {};
let params = {
...this.radioGroupVal,
isNoAccount: this.showHasNotAccount ? '1' : '0',
attendanceSerial: this.selectedSerial || ''
};
if (resourceId != null)
params.resourceId = resourceId;
if (isCalendar) {
params = {
type: source.type,
date: dataIndex
};
} else {
params = { ...params,
type: dataIndex
};
}
this.detailParams = params;
api.getTabs({
type: params.type
}).then(data => {
if (data.status === '1') {
const {
tabs: tabArr
} = data;
let tabs = [],
activeIndex = '1';
if (tabArr != null && tabArr.length > 0) {
tabArr.map((tab, index) => {
let tabInfo = {
color: "#000000",
groupId: `g${index}`,
title: tab.title,
viewCondition: tab.key
};
tabs.push(tabInfo);
if (tab.selected)
activeIndex = tab.key;
});
}
this.tabConfig.tabs = tabs;
this.tabConfig.resourceId = resourceId;
this.setActiveTab(activeIndex, resourceId);
} else {
}
}, error => {})
}
disposer = reaction(() => this.dialogParams.visible, visible => {
if (!visible) this.iskqCalendarDialog = false;
})
@observable iskqCalendarDialog = false;
@observable detail = {
userInfo: {},
signInfo: '',
columns: [],
datas: [],
}
@action showSignDetail = (params) => {
this.iskqCalendarDialog = true;
api.getKQReportSignDetial(params).then(data => {
if (data.status === '1') {
const {
userInfo,
signInfo,
table,
dialogTitle
} = data;
Object.assign(this.detail.userInfo, userInfo);
this.detail.signInfo = signInfo.signInfo;
['columns', 'datas'].map(v => {
this.detail[v] = table[v];
});
this.dialogParams.title = dialogTitle;
this.dialogParams.visible = true;
} else {
message.error(data.message);
}
}, error => {})
}
@action callDetail = (resourceId) => {
let params = { ...this.detailParams
};
if (resourceId != null)
params.resourceId = resourceId;
api.getKQReportDetial(params).then(data => {
if (data.status === '1') {
const {
dialogTitle,
sessionkey
} = data;
this.dialogParams.title = dialogTitle;
this.detailTable = new TableStore();
this.detailTable.getDatas(sessionkey);
this.dialogParams.visible = true;
} else {
message.error(data.message);
}
}, error => {})
}
@action formatData = content => {
if(this.spinning)
return;
this.confirmInfo({
content:getLabel('510381', '重新计算时会以当前用户所在考勤组重新计算考勤情况,如果期间有用户调整过所在考勤组,可能会造成历史数据错误,请谨慎操作!'),
onOk: () => {
this.spinning = true;
api.formatData({
data: JSON.stringify(this.getQueryParams())
}).then(data => {
message.success(i18n.message.opSuccess());
this.getKQReport(this.getQueryParams());
this.spinning = false;
}, error => {this.spinning = false})
}
});
}
/********************* action list *********************/
@observable scrollY = 510;
@action setScrollY = (height) => {
this.dialogParams.style.height = height;
this.scrollY = height - 90;
}
@action resetScroll = () => {
let dom, d;
if(this.tableRef){
dom = ReactDOM.findDOMNode(this.tableRef);
if(dom){
try{
d = $(dom).find('.ant-table-scroll').find('.ant-table-body');
d.scrollTop(0) && d.scrollLeft(0);
}catch(e){
}
}
}
}
}
export const hrmAttendanceMonthReport = new HrmAttendanceMonthReport();