package com.qianwen.smartman.modules.perf.service.impl; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.compress.utils.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.qianwen.core.log.exception.ServiceException; import com.qianwen.core.mp.base.BaseEntity; import com.qianwen.core.mp.service.impl.BladeServiceImpl; import com.qianwen.core.mp.support.Condition; import com.qianwen.core.secure.utils.AuthUtil; import com.qianwen.core.tool.utils.DateUtil; import com.qianwen.core.tool.utils.Func; import com.qianwen.core.tool.utils.SpringUtil; import com.qianwen.smartman.common.cache.cps.EmployeeCache; import com.qianwen.smartman.common.constant.CommonGroupConstant; import com.qianwen.smartman.common.enums.CommonGroupTypeEnum; import com.qianwen.smartman.common.utils.DistinctKeyUtil; import com.qianwen.smartman.common.utils.ExtraLambdaQueryWrapper; import com.qianwen.smartman.common.utils.Lambda; import com.qianwen.smartman.common.utils.MessageUtils; import com.qianwen.smartman.common.utils.TimeUtils; import com.qianwen.smartman.common.utils.TreeUtils; import com.qianwen.smartman.modules.cps.entity.Workstation; import com.qianwen.smartman.modules.cps.service.IEmployeeService; import com.qianwen.smartman.modules.cps.service.IWorkstationService; import com.qianwen.smartman.modules.cps.vo.CommonGroupTypeVO; import com.qianwen.smartman.modules.cps.vo.EmployeeVO; import com.qianwen.smartman.modules.cps.vo.GroupTreeVO; import com.qianwen.smartman.modules.perf.dto.WorkstationBO; import com.qianwen.smartman.modules.perf.entity.EmployeeOnOffWork; import com.qianwen.smartman.modules.perf.enums.DbTypeEnum; import com.qianwen.smartman.modules.perf.enums.OnOffWorkEnum; import com.qianwen.smartman.modules.perf.enums.WorkStatusEnum; import com.qianwen.smartman.modules.perf.mapper.EmployeeOnOffWorkMapper; import com.qianwen.smartman.modules.perf.service.IEmployeeOnOffWorkService; import com.qianwen.smartman.modules.perf.service.IEmployeeSendService; import com.qianwen.smartman.modules.perf.vo.BatchOnWorkVO; import com.qianwen.smartman.modules.perf.vo.CurrWorkDetailVO; import com.qianwen.smartman.modules.perf.vo.CurrWorkLogVO; import com.qianwen.smartman.modules.perf.vo.EmployeeOnOffWorkVO; import com.qianwen.smartman.modules.perf.vo.EmployeeWorkStatusVO; import com.qianwen.smartman.modules.perf.vo.OffEmployeeTreeVO; import com.qianwen.smartman.modules.perf.vo.QueryEmployeeLogVO; import com.qianwen.smartman.modules.perf.vo.QueryWorkStatusVO; import com.qianwen.smartman.modules.perf.vo.SearchEmployeeWorkVO; import com.qianwen.smartman.modules.perf.vo.SearchWorkEmployeeVO; public class EmployeeOnOffWorkServiceImpl extends BladeServiceImpl implements IEmployeeOnOffWorkService { private static final Logger log = LoggerFactory.getLogger(com.qianwen.smartman.modules.perf.service.impl.EmployeeOnOffWorkServiceImpl.class); private final IEmployeeService employeeService; private final IWorkstationService workstationService; private final IEmployeeSendService employeeSendService; public EmployeeOnOffWorkServiceImpl(IEmployeeService employeeService, IWorkstationService workstationService, IEmployeeSendService employeeSendService) { this.employeeService = employeeService; this.workstationService = workstationService; this.employeeSendService = employeeSendService; } public List allWorkstationStatus(QueryWorkStatusVO vo) { List workstations = vo.getWorkstations(); if (Func.isEmpty(workstations)) { return Lists.newArrayList(); } WorkStatusEnum queryType = vo.getQueryType(); switch(queryType) { case ALL://0 return allWorkStatusList(workstations); case ON://1 return onWorkStatusList(workstations, OnOffWorkEnum.WILL_OFF.getCode()); case OFF://2 return offWorkStatusList(workstations, OnOffWorkEnum.WILL_OFF.getCode()); case MY: return currentEmployeeWork(workstations); } /* switch ($SwitchMap$com$qianwen$smartman$modules$perf$enums$WorkStatusEnum[queryType.ordinal()]) { //com.qianwen.smartman.modules.perf.enums.WorkStatusEnum case 1: return allWorkStatusList(workstations); case 2: return onWorkStatusList(workstations, OnOffWorkEnum.WILL_OFF.getCode()); case 3: return offWorkStatusList(workstations, OnOffWorkEnum.WILL_OFF.getCode()); case 4: return currentEmployeeWork(workstations); }*/ return Lists.newArrayList(); } public EmployeeVO currentEmployee() { return this.employeeService.currentEmployee(AuthUtil.getUserId()); } public Boolean batchOnOffWorkstation(BatchOnWorkVO vo) { Integer type = vo.getType(); List workstationIds = (List)vo.getWorks().stream().map(WorkstationBO::getId).collect(Collectors.toList()); EmployeeCache.clearPerfCache(workstationIds); switch (OnOffWorkEnum.of(type)) { case WILL_ON: batchOnWorkstation(vo); break; case WILL_OFF: batchOffWorkstation(vo); break; } /* switch ($SwitchMap$com$qianwen$smartman$modules$perf$enums$WorkStatusEnum[OnOffWorkEnum.of(type).ordinal()]) { case 1: batchOnWorkstation(vo); break; case 2: batchOffWorkstation(vo); break; } */ this.employeeSendService.sendMessageRocket(workstationIds); return Boolean.valueOf(true); } public List willOnWork() { List children = ((EmployeeOnOffWorkMapper)this.baseMapper).willOnWork(OnOffWorkEnum.WILL_OFF.getCode()); CommonGroupTypeVO commonGroupType = (new CommonGroupTypeVO()).setGroupType(CommonGroupTypeEnum.WORKSTATION.getName()).setGroupCategory(CommonGroupConstant.DEFAULT_CATEGORY); return TreeUtils.allGroupTree(commonGroupType, children); } public List willOffWork() { List children = ((EmployeeOnOffWorkMapper)this.baseMapper).willOffWork(OnOffWorkEnum.WILL_OFF.getCode()); CommonGroupTypeVO commonGroupType = (new CommonGroupTypeVO()).setGroupType(CommonGroupTypeEnum.WORKSTATION.getName()).setGroupCategory(CommonGroupConstant.DEFAULT_CATEGORY); return TreeUtils.allGroupTreeOff(commonGroupType, children); } public IPage queryOnOffLog(QueryEmployeeLogVO vo) { IPage page; if (Func.isEmpty(vo.getWorkstationIds())) return new Page<>(); String dbType = SpringUtil.getContext().getEnvironment().getProperty("datasource.type"); String startTime = TimeUtils.getStartTime(vo.getStartTime()); String endTime = TimeUtils.getEndTime(vo.getEndTime()); if (DbTypeEnum.ORACLE.getCode().equals(dbType)) { page = page(Condition.getPage(vo.getQuery()), Lambda.in(Func.isNotEmpty(vo.getEmployeeIds()), EmployeeOnOffWork::getOnEmployeeId, vo.getEmployeeIds()) .in(EmployeeOnOffWork::getWorkstationId, vo.getWorkstationIds()) .nested(nt -> { ExtraLambdaQueryWrapper extraLambdaQueryWrapper = nt.apply("(online_time between TO_DATE({0}, 'yyyy-mm-dd hh24:mi:ss') and TO_DATE({1}, 'yyyy-mm-dd hh24:mi:ss')) or (offline_time between TO_DATE({2}, 'yyyy-mm-dd hh24:mi:ss') and TO_DATE({3}, 'yyyy-mm-dd hh24:mi:ss'))", new Object[] { startTime, endTime, startTime, endTime }); })); } else { page = page(Condition.getPage(vo.getQuery()), Lambda.in(Func.isNotEmpty(vo.getEmployeeIds()), EmployeeOnOffWork::getOnEmployeeId, vo.getEmployeeIds()) .nested(n -> n.between(EmployeeOnOffWork::getOnlineTime, startTime, endTime).or().between(EmployeeOnOffWork::getOfflineTime, startTime, endTime)) .in(EmployeeOnOffWork::getWorkstationId, vo.getWorkstationIds())); } List records = page.getRecords(); if (Func.isEmpty(records)) return new Page<>(); Page page1 = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); page1.setRecords(records.stream() .map(com.qianwen.smartman.modules.perf.service.impl.EmployeeOnOffWorkServiceImpl::convertWork) .collect(Collectors.toList())); return page1; } public List employeeWork(SearchEmployeeWorkVO vo) { List works; String dbType = SpringUtil.getContext().getEnvironment().getProperty("datasource.type"); String startTime = DateUtil.formatDateTime(vo.getStartTime()); String endTime = DateUtil.formatDateTime(vo.getEndTime()); if (DbTypeEnum.ORACLE.getCode().equals(dbType)) { works = list(Lambda.eq(EmployeeOnOffWork::getOnEmployeeId, vo.getEmployeeId()) .nested(nt -> nt.apply("(online_time between TO_DATE({0}, 'yyyy-mm-dd hh24:mi:ss') and TO_DATE({1}, 'yyyy-mm-dd hh24:mi:ss'))", new Object[] { startTime, endTime }))); } else { works = list(Lambda.eq(EmployeeOnOffWork::getOnEmployeeId, vo.getEmployeeId()) .between(EmployeeOnOffWork::getOnlineTime, startTime, endTime)); } if (Func.isEmpty(works)) return Lists.newArrayList(); return (List)works.stream() .map(w -> WorkstationBO.builder().id(w.getWorkstationId()).workstationCode(w.getWorkstationCode()).workstationName(w.getWorkstationName()).build()) .filter(DistinctKeyUtil.distinctByKey(WorkstationBO::getId)) .collect(Collectors.toList()); } public List workEmployee(SearchWorkEmployeeVO vo) { List works; String dbType = SpringUtil.getContext().getEnvironment().getProperty("datasource.type"); String startTime = DateUtil.formatDateTime(vo.getStartTime()); String endTime = DateUtil.formatDateTime(vo.getEndTime()); if (DbTypeEnum.ORACLE.getCode().equals(dbType)) { works = list(Lambda.eq(EmployeeOnOffWork::getWorkstationId, vo.getWorkstationId()) .nested(nt -> nt.apply("(online_time between TO_DATE({0}, 'yyyy-mm-dd hh24:mi:ss') and TO_DATE({1}, 'yyyy-mm-dd hh24:mi:ss'))", new Object[] { startTime, endTime }))); } else { works = list(Lambda.eq(EmployeeOnOffWork::getWorkstationId, vo.getWorkstationId()) .between(EmployeeOnOffWork::getOnlineTime, startTime, endTime)); } if (Func.isEmpty(works)) return Lists.newArrayList(); return (List)works.stream() .map(w -> { EmployeeVO res = new EmployeeVO(); res.setId(w.getOnEmployeeId()); res.setCode(w.getOnEmployeeCode()); res.setName(w.getOnEmployeeName()); return res; }).filter(DistinctKeyUtil.distinctByKey(EmployeeVO::getId)) .collect(Collectors.toList()); } public List currWorkLog(CurrWorkLogVO vo) { return ((EmployeeOnOffWorkMapper)this.baseMapper).currWorkLog(vo.getWorkstationId()); } public void currentEmployeeWork(String employeeId, String workstationId) { List currEmployeeId = list(Wrappers.lambdaQuery() .eq(EmployeeOnOffWork::getOnEmployeeId, employeeId) .eq(EmployeeOnOffWork::getOnlineType, OnOffWorkEnum.WILL_OFF.getCode())); if (Func.isNotEmpty(currEmployeeId)) throw new ServiceException(MessageUtils.message("perf.current.employee.login", new Object[0])); List works = list(Wrappers.lambdaQuery() .eq(EmployeeOnOffWork::getWorkstationId, workstationId) .eq(EmployeeOnOffWork::getOnlineType, OnOffWorkEnum.WILL_OFF.getCode())); if (Func.isNotEmpty(works)) throw new ServiceException(MessageUtils.message("perf.current.work.login", new Object[0])); } private List allWorkStatusList(List workstations) { Map workstationMap = workstationMap(); List wIds = (List)workstations.stream().map(WorkstationBO::getId).collect(Collectors.toList()); List works = ((EmployeeOnOffWorkMapper)this.baseMapper).queryWork(wIds, null); Map onOffWorkMap = (Map)works.stream().collect(Collectors.toMap(EmployeeOnOffWork::getWorkstationId, v -> v)); return (List)workstations.stream() .map(c -> { Long workstationId = c.getId(); Workstation workstation = (Workstation)workstationMap.get(workstationId); if (Func.isNull(workstation)) return null; EmployeeOnOffWork employeeOnOffWork = (EmployeeOnOffWork)onOffWorkMap.get(workstationId); EmployeeWorkStatusVO res = EmployeeWorkStatusVO.builder().onType(OnOffWorkEnum.WILL_ON.getCode()).workstationId(workstationId).workstationCode(workstation.getCode()).workstationName(workstation.getName()).avatar(workstation.getAvatar()).build(); if (Func.isNull(employeeOnOffWork) || employeeOnOffWork.getOnlineType().equals(OnOffWorkEnum.WILL_ON.getCode())) return res; res.setId(employeeOnOffWork.getId()); res.setOnType(employeeOnOffWork.getOnlineType()); res.setOnEmployeeId(employeeOnOffWork.getOnEmployeeId()); res.setOnEmployeeCode(employeeOnOffWork.getOnEmployeeCode()); res.setOnEmployeeName(employeeOnOffWork.getOnEmployeeName()); res.setOnEmployeeAvatar(employeeOnOffWork.getOnEmployeeAvatar()); res.setOnlineTime(employeeOnOffWork.getOnlineTime()); return res; }).filter(Func::notNull) .collect(Collectors.toList()); } private List onWorkStatusList(List workstations, Integer onType) { List wIds = (List)workstations.stream().map(WorkstationBO::getId).collect(Collectors.toList()); List works = ((EmployeeOnOffWorkMapper)this.baseMapper).queryWork(wIds, onType); if (Func.isEmpty(works)) return Lists.newArrayList(); return (List)works.stream() .map(com.qianwen.smartman.modules.perf.service.impl.EmployeeOnOffWorkServiceImpl::convert) .collect(Collectors.toList()); } private List offWorkStatusList(List workstations, Integer onType) { Map workstationMap = workstationMap(); List wIds = (List)workstations.stream().map(WorkstationBO::getId).collect(Collectors.toList()); List works = ((EmployeeOnOffWorkMapper)this.baseMapper).queryWork(wIds, onType); Set workstationIds = (Set)works.stream().map(EmployeeOnOffWork::getWorkstationId).collect(Collectors.toSet()); return (List)workstations.stream() .filter(c -> !workstationIds.contains(c.getId())) .map(c -> { Long workstationId = c.getId(); Workstation workstation = (Workstation)workstationMap.get(workstationId); return Func.isNull(workstation) ? null : EmployeeWorkStatusVO.builder().onType(OnOffWorkEnum.WILL_ON.getCode()).workstationId(workstationId).workstationCode(workstation.getCode()).workstationName(workstation.getName()).avatar(workstation.getAvatar()).build(); }).filter(Func::notNull) .collect(Collectors.toList()); } private List currentEmployeeWork(List workstations) { EmployeeVO employee = currentEmployee(); if (Func.isNull(employee)) return Lists.newArrayList(); List wIds = workstations.stream().map(WorkstationBO::getId).collect(Collectors.toList()); List works = list(Lambda.create() .in(EmployeeOnOffWork::getWorkstationId, wIds) .eq(EmployeeOnOffWork::getOnEmployeeId, employee.getId()) .eq(EmployeeOnOffWork::getOnlineType, OnOffWorkEnum.WILL_OFF.getCode())); if (Func.isEmpty(works)) return Lists.newArrayList(); Map workMap = workstationMap(); return (List)works.stream() .map(w -> { EmployeeWorkStatusVO vo = convert(w); Workstation workstation = (Workstation)workMap.get(w.getWorkstationId()); if (Func.isNull(workstation)) return null; vo.setAvatar(workstation.getAvatar()); return vo; }).filter(Func::notNull) .collect(Collectors.toList()); } private static EmployeeWorkStatusVO convert(EmployeeOnOffWork work) { return EmployeeWorkStatusVO.builder() .id(work.getId()) .onType(work.getOnlineType()) .onEmployeeId(work.getOnEmployeeId()) .onEmployeeCode(work.getOnEmployeeCode()) .onEmployeeName(work.getOnEmployeeName()) .onEmployeeAvatar(work.getOnEmployeeAvatar()) .workstationId(work.getWorkstationId()) .workstationCode(work.getWorkstationCode()) .workstationName(work.getWorkstationName()) .onlineTime(work.getOnlineTime()) .build(); } private static EmployeeOnOffWorkVO convertWork(EmployeeOnOffWork work) { return EmployeeOnOffWorkVO.builder() .id(work.getId()) .employeeId(work.getOnEmployeeId()) .employeeName(work.getOnEmployeeName()) .employeeCode(work.getOnEmployeeCode()) .workstationId(work.getWorkstationId()) .workstationCode(work.getWorkstationCode()) .workstationName(work.getWorkstationName()) .onlineTime(work.getOnlineTime()) .offlineTime(work.getOfflineTime()) .createTime(work.getCreateTime()) .build(); } private void batchOnWorkstation(BatchOnWorkVO vo) { List works = vo.getWorks(); List onOffWorks = (List)works.stream().map(w -> convertWork(vo, w)).collect(Collectors.toList()); saveBatch(onOffWorks); } private void batchOffWorkstation(BatchOnWorkVO vo) { List works = vo.getWorks(); List offWorks = (List)works.stream().map(w -> { EmployeeOnOffWork work = (new EmployeeOnOffWork()).setOffEmployeeId(vo.getEmployeeId()).setOffEmployeeCode(vo.getEmployeeCode()).setOffEmployeeName(vo.getEmployeeName()).setOffEmployeeAvatar(vo.getEmployeeAvatar()).setOnlineType(OnOffWorkEnum.WILL_ON.getCode()).setOfflineTime(vo.getTime()); work.setId(w.getLogId()); return work; }).collect(Collectors.toList()); updateBatchById(offWorks); } private EmployeeOnOffWork convertWork(BatchOnWorkVO vo, WorkstationBO work) { return (new EmployeeOnOffWork()) .setOnlineTime(vo.getTime()) .setOnEmployeeId(vo.getEmployeeId()) .setOnEmployeeName(vo.getEmployeeName()) .setOnEmployeeCode(vo.getEmployeeCode()) .setOnEmployeeAvatar(vo.getEmployeeAvatar()) .setWorkstationId(work.getId()) .setWorkstationName(work.getWorkstationName()) .setWorkstationCode(work.getWorkstationCode()) .setWorkstationAvatar(work.getAvatar()) .setOnlineType(OnOffWorkEnum.WILL_OFF.getCode()); } private Map workstationMap() { List workstations = this.workstationService.list(); return (Map)workstations.stream().collect(Collectors.toMap(BaseEntity::getId, v -> v)); } }