weaver_trunk_cli/pc4mobx/hrmAttendance/components/absenceDetail/Detail.js

316 lines
6.8 KiB
JavaScript
Raw Normal View History

2024-12-11 15:32:14 +08:00
import {
WeaLocaleProvider
} from 'ecCom';
import {
Tooltip
} from 'antd';
const getLabel = WeaLocaleProvider.getLabel;
export default class Detail extends React.Component {
constructor(props) {
super(props);
this.baseKd = 756; //基础宽度
}
//计算宽度
//参数的数据格式为:['09:00-12:00','13:00-18:00']
calKd = (times) => {
let kds = [];
times.forEach(time => {
const a = time.split('-'); //['09:00','12:00']
const p = this.calZb(a[0], a[1]); //0.125
const kd = this.baseKd * p;
kds.push(kd);
})
return kds;
}
//计算占比
//参数的数据格式为:'09:00','12:00'
calZb = (start, end) => {
const s = start.split(':'); //['09','00']
const e = end.split(':'); //['12','00']
const a = parseInt(e[0]) - parseInt(s[0]); //3
const b = parseInt(e[1]) - parseInt(s[1]); //0
const p = (a * 60 + b) / (24 * 60); //0.125
return p
}
//计算偏移量
//参数的数据格式为:['09:00-12:00','13:00-18:00']
calPyl = (times) => {
let pyls = [];
times.forEach(time => {
const a = time.split('-'); //['09:00','12:00']
const s = a[0].split(':'); //['09','00']
const t = parseInt(s[0]) * 60 + parseInt(s[1]); //540
const pyl = (t / (24 * 60)) * this.baseKd; //283.5
pyls.push(pyl);
});
return pyls;
}
//计算时刻
calSjd = (kds, pyls, times) => {
//开始时刻
const start = {
dot: '00:00',
pyl: 0
};
//结束时刻
const end = {
dot: '23:59',
pyl: (this.baseKd - 32)
};
return [start, end];
//时间点容器
const moments = [];
//收集时间点
times.map(time => {
//['09:00','12:00']
time.split('-').map(moment => {
moments.push(moment);
});
})
//时间点、相应偏移量容器
const dots = [];
//收集时间点和时间点的偏移量
//moments['09:00','12:00','13:00','18:00']
moments.map((moment, index) => {
const o = {
dot: moment
};
if (index % 2 === 0) { //奇数位:['09:00','13:00']
Object.assign(o, {
pyl: pyls[index / 2] - 16
});
} else { //偶数位:['12:00','18:00']
Object.assign(o, {
pyl: pyls[(index - 1) / 2] + kds[(index - 1) / 2] - 16
});
}
dots.push(o);
});
dots.unshift(start);
dots.push(end);
return dots;
}
//整合缺勤时间段,返回缺勤时间段的宽度和偏移量
//absences缺勤时间段。数据格式:['09:00-10:00','13:00-15:00','16:00-18:00']
calAllAbs = (absences) => {
let all = ''; //整合后的时间段
const p = [];
absences.forEach(abs => {
if (!all) { //all = ''
all = abs;
} else { //all = '09:00-10:00'
if (this.isClose(all, abs)) { //'09:00-10:00','10:00-15:00'
const c = this.combine(all, abs);
all = c; //'09:00-15:00'
} else { //'09:00-10:00','13:00-15:00'
p.push(all);
all = abs;
}
}
});
//all:'16:00-18:00'
//p:['09:00-10:00','13:00-15:00']
p.push(all);
const kds = this.calKd(p);
const pyls = this.calPyl(p);
return {
kds,
pyls,
p,
}
}
//判断两个时间段是否重合
isClose = (period, nextPeriod) => {
const m = period.split('-'); //['13:00','15:30']
const nm = nextPeriod.split('-'); //['14:30','18:00']
const e = m[1]; //'15:30'
const s = nm[0]; //'14:30'
const eh = e.split(':'); //['15':'30']
const sh = s.split(':'); //['14':'30']
const ehs = parseInt(eh[0]); //15
const ehe = parseInt(eh[1]); //30
const shs = parseInt(sh[0]); //14
const she = parseInt(sh[1]); //30
if (shs < ehs) {
return true;
}
if ((shs === ehs) && (she < ehe)) {
return true;
}
return false;
}
//合并时间段
combine = (period, nextPeriod) => {
const m = period.split('-'); //['13:00','15:30']
const nm = nextPeriod.split('-'); //['14:30','18:00']
const p = `${m[0]}-${nm[1]}`; //'13:00-18:00'
return p;
}
//计算休息时间段
calRestPeriods = (sclTime) => {
const raw = [];
const restPeriods = [];
let str = '';
sclTime.forEach(time => {
time.split('-').forEach(dot => {
raw.push(dot);
});
})
const arr = raw.slice(1, raw.length - 1);
arr.forEach((dot, index) => {
if (index % 2 === 0) {
str = dot;
} else {
str = `${str}-${dot}`;
restPeriods.push(str);
}
});
return restPeriods;
}
render() {
const {
detail
} = this.props, {
day,
date,
sclTime,
absTime,
} = detail;
//排班时段宽度
const sclKds = this.calKd(sclTime);
//排班时段偏移量
const sclPyls = this.calPyl(sclTime);
//休息时段宽度
const restKds = sclKds.map((kd, index) => {
return sclPyls[index + 1] - (sclPyls[index] + sclKds[index]);
});
//休息时段偏移量
const restPyls = sclKds.map((kd, index) => {
return sclPyls[index] + sclKds[index];
});
//从缺勤数据中提炼出时间数据
const pureTime = absTime.map(t => t.time);
//缺勤时间段宽度
const absKds = this.calKd(pureTime);
//缺勤时间段偏移量
const absPyls = this.calPyl(pureTime);
//时间点
const timeDots = this.calSjd(sclKds, sclPyls, sclTime);
//整合后的缺勤时间段的宽度和偏移量
const absAll = this.calAllAbs(pureTime);
//计算休息时间段
const restPeriods = this.calRestPeriods(sclTime)
return (
<div className='detail'>
<div className='day'>
{`${day}${getLabel('503882','天') }`}
</div>
<div className='date'>
{date}
</div>
<div>
<div className='scale'>
{
absTime.map( (time,index) => {
const {bgColor} = time;
const {tips} = absTime[index];
return (
<Tooltip ecId={`${this && this.props && this.props.ecId || ''}_Tooltip@eyxb24@${index}`} title={tips && <ul>{tips.map(tip => <li dangerouslySetInnerHTML={{__html: tip}}></li>)}</ul>}>
<div className='abs' style={{backgroundColor: bgColor,width:absKds[index],marginLeft: absPyls[index]}}></div>
</Tooltip>
)
})
}
{
restKds.map( (restKd,index) => {
return (
<Tooltip ecId={`${this && this.props && this.props.ecId || ''}_Tooltip@d1zefx@${index}`} placement='bottom' title={`${getLabel(505603,'休息时间')}: ${restPeriods[index]}`}>
<div className='rest' style={{width:restKd,marginLeft: restPyls[index]}}></div>
</Tooltip>
)
})
}
{
sclKds.map( (kd,index) => {
return (
<Tooltip ecId={`${this && this.props && this.props.ecId || ''}_Tooltip@a1kv0p@${index}`} placement='bottom' title={`${getLabel(505592,'上班时间')}: ${sclTime[index]}`}>
<div className='scl' style={{width:kd, marginLeft:sclPyls[index]}}></div>
</Tooltip>
)
})
}
<div className='base'></div>
</div>
<div className='moments'>
{
timeDots.map(item => {
const {dot,pyl} = item;
return(
<span style={{left:pyl}} className='moment'>{dot}</span>
)
})
}
</div>
</div>
</div>
);
}
}