员工门户接口

This commit is contained in:
dxfeng 2025-07-15 11:05:46 +08:00
parent 972a751328
commit 92597d7cf2
9 changed files with 492 additions and 5 deletions

View File

@ -0,0 +1,43 @@
package com.weaver.seconddev.portal.controller;
import com.weaver.common.authority.annotation.WeaPermission;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.seconddev.portal.entity.po.EmployeeBasicInfoPo;
import com.weaver.seconddev.portal.service.EmployeePortalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* @author:dxfeng
* @createTime: 2025/07/11
* @version: 1.0
*/
@Slf4j
@RestController
@RequestMapping("/api/secondev/portal/employee")
@WeaPermission(publicPermission = true)
public class EmployeePortalController {
@Autowired
EmployeePortalService employeePortalService;
@PostMapping("/getDurationOfEmployment")
private WeaResult<Map<String, Object>> getDurationOfEmployment(@RequestBody Map<String, String> params) {
return employeePortalService.getDurationOfEmployment(params);
}
@PostMapping("/getEmployeeInfo")
private WeaResult<EmployeeBasicInfoPo> getEmployeeInfo(@RequestHeader Map<String, String> header, @RequestBody Map<String, Object> params) {
String origin = header.get("origin");
// 考勤标准接口
String otherApiUrl = origin + "/api/attend/web/attendInfoV2/getAttendInfoStatis";
params.put("otherApiUrl", otherApiUrl);
params.put("header",header);
return employeePortalService.getEmployeeInfo(params);
}
}

View File

@ -0,0 +1,15 @@
package com.weaver.seconddev.portal.entity.param;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author:dxfeng
* @createTime: 2025/07/14
* @version: 1.0
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class EmployeePortalParam extends BaseParam {
private Long employeeId;
}

View File

@ -0,0 +1,95 @@
package com.weaver.seconddev.portal.entity.po;
import com.weaver.teams.domain.user.Avatar;
import lombok.Data;
import java.util.Date;
/**
* @author:dxfeng
* @createTime: 2025/07/14
* @version: 1.0
*/
@Data
public class EmployeeBasicInfoPo {
private Long employeeId;
/**
* 姓名
*/
private String userName;
/**
* 头像
*/
private Avatar avatar;
/**
* 工号
*/
private String workCode;
/**
* 公司名称
*/
private String companyName;
/**
* 入职日期
*/
private Date hireDate;
/**
* 人员状态
*/
private String employeeStatus;
/**
* 直接上级
*/
private String directSuperior;
/**
* 年假余额
*/
private String annualLeaveBalance;
private String annualLeaveBalanceUrl;
/**
* 调休余额
*/
private String leaveBalance;
private String leaveBalanceUrl;
/**
* 带薪病假余额
*/
private String paidSickLeaveBalance;
private String paidSickLeaveBalanceUrl;
/**
* 应出勤天数
*/
private String expectedAttendance;
private String expectedAttendanceUrl;
/**
* 实际出勤
*/
private String actualAttendance;
private String actualAttendanceUrl;
/**
* 请假
*/
private String leave;
private String leaveUrl;
/**
* 出差
*/
private String travel;
private String travelUrl;
/**
* 加班
*/
private String overtime;
private String overtimeUrl;
/**
* 公出
*/
private String publicLeave;
private String publicLeaveUrl;
/**
* 异常出勤
*/
private String exceptionalAttendance;
private String exceptionalAttendanceUrl;
}

View File

@ -0,0 +1,60 @@
package com.weaver.seconddev.portal.enums;
/**
* @author:dxfeng
* @createTime: 2025/07/14
* @version: 1.0
*/
public enum PersonnelStatusEnum {
/**
* 1 试用2 试用延期3 正式4 临时5 实习6 离职7 退休9 解聘10 无效
*/
TRY_OUT("1", "试用"),
TRY_OUT_DELAY("2", "试用延期"),
FORMAL("3", "正式"),
TEMPORARY("4", "临时"),
INTERNSHIP("5", "实习"),
LEAVE("6", "离职"),
RETIRED("7", "退休"),
INVALID("9", "解聘"),
QUIT("10", "无效");
PersonnelStatusEnum(String value, String showName) {
this.value = value;
this.showName = showName;
}
private String value;
private String showName;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getShowName() {
return showName;
}
public void setShowName(String showName) {
this.showName = showName;
}
/**
* 根据value获取showName
*
* @param value
* @return
*/
public static String getShowNameByValue(String value) {
for (PersonnelStatusEnum item : PersonnelStatusEnum.values()) {
if (item.getValue().equalsIgnoreCase(value)) {
return item.getShowName();
}
}
return "";
}
}

View File

@ -0,0 +1,13 @@
package com.weaver.seconddev.portal.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author:dxfeng
* @createTime: 2025/07/11
* @version: 1.0
*/
@Mapper
public interface EmployeePortalMapper {
}

View File

@ -0,0 +1,30 @@
package com.weaver.seconddev.portal.service;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.seconddev.portal.entity.po.EmployeeBasicInfoPo;
import java.util.Map;
/**
* @author:dxfeng
* @createTime: 2025/07/11
* @version: 1.0
*/
public interface EmployeePortalService {
/**
* 获取员工工作时长
*
* @param params
* @return
*/
WeaResult<Map<String, Object>> getDurationOfEmployment(Map<String, String> params);
/**
* 获取员工信息
*
* @param params
* @return
*/
WeaResult<EmployeeBasicInfoPo> getEmployeeInfo(Map<String, Object> params);
}

View File

@ -0,0 +1,208 @@
package com.weaver.seconddev.portal.service.impl;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.hr.util.Util;
import com.weaver.common.hrm.dao.HrmCommonEmployeeDao;
import com.weaver.seconddev.portal.entity.po.EmployeeBasicInfoPo;
import com.weaver.seconddev.portal.entity.po.PortalUrlDetail;
import com.weaver.seconddev.portal.enums.PersonnelStatusEnum;
import com.weaver.seconddev.portal.mapper.PortalMapper;
import com.weaver.seconddev.portal.service.EmployeePortalService;
import com.weaver.seconddev.portal.util.DateUtil;
import com.weaver.teams.domain.user.Avatar;
import com.weaver.teams.domain.user.SimpleEmployee;
import com.weaver.teams.security.context.UserContext;
import com.weaver.teams.security.user.User;
import com.weaver.workflow.common.cfg.org.service.DepartMentService;
import com.weaver.workflow.common.entity.org.WeaDepartMent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author:dxfeng
* @createTime: 2025/07/11
* @version: 1.0
*/
@Slf4j
@Service
public class EmployeePortalServiceImpl implements EmployeePortalService {
private static final String PORTAL_KEY = "employeePortal";
@Autowired
HrmCommonEmployeeDao hrmCommonEmployeeDao;
@Autowired
DepartMentService departMentService;
@Autowired
PortalMapper portalMapper;
@Override
public WeaResult<Map<String, Object>> getDurationOfEmployment(Map<String, String> params) {
User currentUser = UserContext.getCurrentUser();
SimpleEmployee byId = hrmCommonEmployeeDao.getById(currentUser.getEmployeeId());
LocalDate localDate = DateUtil.toLocalDate(byId.getHiredate());
// 计算入职日期到现在的天数
long days = DateUtil.daysBetween(DateUtil.formatDate(localDate), DateUtil.getCurrentDateStr());
Map<String, Object> returnMap = new HashMap<>(1);
returnMap.put("days", days);
return WeaResult.success(returnMap);
}
@Override
public WeaResult<EmployeeBasicInfoPo> getEmployeeInfo(Map<String, Object> params) {
User currentUser = UserContext.getCurrentUser();
EmployeeBasicInfoPo employeeBasicInfoPo = new EmployeeBasicInfoPo();
employeeBasicInfoPo.setEmployeeId(currentUser.getEmployeeId());
SimpleEmployee byId = hrmCommonEmployeeDao.getById(currentUser.getEmployeeId());
log.error("byId===" + JSON.toJSONString(byId));
Avatar avatar = byId.getAvatar();
employeeBasicInfoPo.setAvatar(avatar);
employeeBasicInfoPo.setUserName(byId.getUsername());
employeeBasicInfoPo.setWorkCode(byId.getJobNum());
WeaDepartMent departmentById = departMentService.getDepartMentById(byId.getDepartmentId());
log.error("departmentById===" + departmentById);
employeeBasicInfoPo.setCompanyName(null != departmentById ? departmentById.getDepartMentName() : "");
employeeBasicInfoPo.setHireDate(byId.getHiredate());
employeeBasicInfoPo.setEmployeeStatus(PersonnelStatusEnum.getShowNameByValue(byId.getPersonnelStatus()));
SimpleEmployee superior = byId.getSuperior();
log.error("superior===" + JSON.toJSONString(superior));
employeeBasicInfoPo.setDirectSuperior(null != superior ? superior.getUsername() : "");
// 考勤信息
buildAttendance(params, employeeBasicInfoPo);
// 穿透地址处理
List<PortalUrlDetail> portalUrlDetails = portalMapper.getPortalUrlDetail(currentUser.getTenantKey(), PORTAL_KEY, "getEmployeeInfo");
Map<String, String> urlMap = portalUrlDetails.stream().collect(Collectors.toMap(PortalUrlDetail::getDetailKey, PortalUrlDetail::getUrlAddress));
employeeBasicInfoPo.setAnnualLeaveBalanceUrl(urlMap.get("annualLeaveBalance"));
employeeBasicInfoPo.setLeaveBalanceUrl(urlMap.get("leaveBalance"));
employeeBasicInfoPo.setPaidSickLeaveBalanceUrl(urlMap.get("paidSickLeaveBalance"));
employeeBasicInfoPo.setExpectedAttendanceUrl(urlMap.get("expectedAttendance"));
employeeBasicInfoPo.setActualAttendanceUrl(urlMap.get("actualAttendance"));
employeeBasicInfoPo.setLeaveUrl(urlMap.get("leave"));
employeeBasicInfoPo.setTravelUrl(urlMap.get("travel"));
employeeBasicInfoPo.setOvertimeUrl(urlMap.get("overtime"));
employeeBasicInfoPo.setPublicLeaveUrl(urlMap.get("publicLeave"));
employeeBasicInfoPo.setExceptionalAttendanceUrl(urlMap.get("exceptionalAttendance"));
return WeaResult.success(employeeBasicInfoPo);
}
/**
* 构建考勤信息
*
* @param params
* @param employeeBasicInfoPo
*/
private void buildAttendance(Map<String, Object> params, EmployeeBasicInfoPo employeeBasicInfoPo) {
String url = Util.null2String(params.get("otherApiUrl"));
Map<String, String> header = (Map<String, String>) params.get("header");
String beginDate = DateUtil.getFirstDayOfMonth();
String endDate = DateUtil.getLastDayOfMonth();
Long userId = employeeBasicInfoPo.getEmployeeId();
JSONObject jsonObject = new JSONObject();
jsonObject.put("beginDate", beginDate);
jsonObject.put("endDate", endDate);
jsonObject.put("userId", String.valueOf(userId));
String resultStr = HttpRequest.post(url).headerMap(header, true)
.body(jsonObject.toJSONString()).execute().body();
if (resultStr != null) {
JSONObject response = JSON.parseObject(resultStr);
if (response.getBoolean("status") && 200 == response.getIntValue("code")) {
JSONObject data = response.getJSONObject("data");
// 考勤信息
JSONObject attendStatis = data.getJSONObject("attendStatis");
if (attendStatis != null) {
JSONObject periodLength = attendStatis.getJSONObject("periodLength");
employeeBasicInfoPo.setExpectedAttendance(null == periodLength ? "0" : periodLength.getString("value"));
JSONObject actual = attendStatis.getJSONObject("actual");
employeeBasicInfoPo.setActualAttendance(null == actual ? "0" : actual.getString("value"));
JSONObject lostLength = attendStatis.getJSONObject("lostLength");
employeeBasicInfoPo.setExceptionalAttendance(null == lostLength ? "0" : lostLength.getString("value"));
}
JSONArray attendSummaryData = data.getJSONObject("attendSummary").getJSONArray("data");
if (attendSummaryData != null) {
for (int i = 0; i < attendSummaryData.size(); i++) {
JSONObject item = attendSummaryData.getJSONObject(i);
String key = item.getString("key");
String value = item.getString("value");
switch (key) {
case "LEAVE":
employeeBasicInfoPo.setLeave(value);
break;
case "BUSINESS":
employeeBasicInfoPo.setTravel(value);
break;
case "OUT_SIDE":
employeeBasicInfoPo.setPublicLeave(value);
break;
case "OVERTIME":
employeeBasicInfoPo.setOvertime(value);
break;
default:
break;
}
}
}
// 假期余额信息
JSONArray vacationBalanceList = data.getJSONArray("vacationBalanceList");
if (vacationBalanceList != null) {
for (int i = 0; i < vacationBalanceList.size(); i++) {
JSONObject vacationItem = vacationBalanceList.getJSONObject(i);
String title = vacationItem.getString("title");
JSONArray dataArray = vacationItem.getJSONArray("data");
if (dataArray != null && dataArray.size() > 0) {
JSONObject totalItem = dataArray.getJSONObject(dataArray.size() - 1);
String totalValue = totalItem.getString("value");
switch (title) {
case "年假":
employeeBasicInfoPo.setAnnualLeaveBalance(totalValue);
break;
case "调休假":
employeeBasicInfoPo.setLeaveBalance(totalValue);
break;
case "带薪病假":
employeeBasicInfoPo.setPaidSickLeaveBalance(totalValue);
break;
default:
break;
}
}
}
}
}
}
}
}

View File

@ -4,6 +4,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
/**
@ -25,9 +26,11 @@ public class DateUtil {
public static String getCurrentDateStr() {
return LocalDate.now().format(DEFAULT_DATE_FORMATTER);
}
public static String getCurrentYearStr() {
return LocalDate.now().format(DEFAULT_YEAR_FORMATTER);
}
public static String getCurrentMonthStr() {
return LocalDate.now().format(DEFAULT_MONTH_FORMATTER);
}
@ -104,6 +107,7 @@ public class DateUtil {
/**
* 获取指定日期所在月份的第一天
*
* @param date 输入日期
* @return 当月第一天的 LocalDate
*/
@ -121,8 +125,18 @@ public class DateUtil {
return LocalDate.now().withDayOfMonth(1).format(DEFAULT_DATE_FORMATTER);
}
/**
* 获取当前月份的最后一天
*
* @return
*/
public static String getLastDayOfMonth() {
return LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).format(DEFAULT_DATE_FORMATTER);
}
/**
* 获取指定日期字符串所在月份的第一天字符串形式
*
* @param dateStr 输入日期字符串 (yyyy-MM-dd)
* @return 当月第一天的字符串
*/
@ -202,14 +216,15 @@ public class DateUtil {
/**
* 获取指定日期字符串上个月的第一天字符串形式
*
* @param dateStr 输入日期字符串 (yyyy-MM-dd)
* @return 上个月第一天的字符串
*/
public static String getFirstDayOfPreviousMonthStr(String dateStr) {
return getFirstDayOfPreviousMonthStr(dateStr,1);
return getFirstDayOfPreviousMonthStr(dateStr, 1);
}
public static String getFirstDayOfPreviousMonthStr(String dateStr,int month) {
public static String getFirstDayOfPreviousMonthStr(String dateStr, int month) {
LocalDate date = parseDate(dateStr);
if (date == null) {
return null;
@ -221,26 +236,28 @@ public class DateUtil {
/**
* 获取指定日期字符串上个月的最后一天字符串形式
*
* @param dateStr 输入日期字符串 (yyyy-MM-dd)
* @return 上个月最后一天的字符串
*/
public static String getLastDayOfPreviousMonthStr(String dateStr) {
return getLastDayOfPreviousMonthStr(dateStr,1);
return getLastDayOfPreviousMonthStr(dateStr, 1);
}
public static String getLastDayOfPreviousMonthStr(String dateStr,int month) {
public static String getLastDayOfPreviousMonthStr(String dateStr, int month) {
LocalDate date = parseDate(dateStr);
if (date == null) {
return null;
}
// 获取当月第一天再减一天得到上个月最后一天
LocalDate firstDayOfCurrentMonth = date.minusMonths(month-1).withDayOfMonth(1);
LocalDate firstDayOfCurrentMonth = date.minusMonths(month - 1).withDayOfMonth(1);
LocalDate lastDayOfPrevMonth = firstDayOfCurrentMonth.minusDays(1);
return formatDate(lastDayOfPrevMonth);
}
/**
* LocalDate 格式化为 yyyy-MM 字符串
*
* @param date 输入日期
* @return 年月字符串 (yyyy-MM)
*/
@ -260,6 +277,7 @@ public class DateUtil {
/**
* 将日期字符串 (yyyy-MM-dd) 转换为年月字符串 (yyyy-MM)
*
* @param dateStr 输入日期字符串
* @return 年月字符串 (yyyy-MM)
*/

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.weaver.seconddev.portal.mapper.EmployeePortalMapper">
</mapper>