diff --git a/src/main/java/com/weaver/seconddev/portal/controller/EmployeePortalController.java b/src/main/java/com/weaver/seconddev/portal/controller/EmployeePortalController.java new file mode 100644 index 0000000..4b459f3 --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/controller/EmployeePortalController.java @@ -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> getDurationOfEmployment(@RequestBody Map params) { + return employeePortalService.getDurationOfEmployment(params); + } + + + @PostMapping("/getEmployeeInfo") + private WeaResult getEmployeeInfo(@RequestHeader Map header, @RequestBody Map 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); + } + +} diff --git a/src/main/java/com/weaver/seconddev/portal/entity/param/EmployeePortalParam.java b/src/main/java/com/weaver/seconddev/portal/entity/param/EmployeePortalParam.java new file mode 100644 index 0000000..286571a --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/entity/param/EmployeePortalParam.java @@ -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; +} diff --git a/src/main/java/com/weaver/seconddev/portal/entity/po/EmployeeBasicInfoPo.java b/src/main/java/com/weaver/seconddev/portal/entity/po/EmployeeBasicInfoPo.java new file mode 100644 index 0000000..93bd2aa --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/entity/po/EmployeeBasicInfoPo.java @@ -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; +} diff --git a/src/main/java/com/weaver/seconddev/portal/enums/PersonnelStatusEnum.java b/src/main/java/com/weaver/seconddev/portal/enums/PersonnelStatusEnum.java new file mode 100644 index 0000000..21cbee2 --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/enums/PersonnelStatusEnum.java @@ -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 ""; + } +} diff --git a/src/main/java/com/weaver/seconddev/portal/mapper/EmployeePortalMapper.java b/src/main/java/com/weaver/seconddev/portal/mapper/EmployeePortalMapper.java new file mode 100644 index 0000000..bc5138b --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/mapper/EmployeePortalMapper.java @@ -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 { + +} diff --git a/src/main/java/com/weaver/seconddev/portal/service/EmployeePortalService.java b/src/main/java/com/weaver/seconddev/portal/service/EmployeePortalService.java new file mode 100644 index 0000000..b158fb5 --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/service/EmployeePortalService.java @@ -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> getDurationOfEmployment(Map params); + + /** + * 获取员工信息 + * + * @param params + * @return + */ + WeaResult getEmployeeInfo(Map params); + +} diff --git a/src/main/java/com/weaver/seconddev/portal/service/impl/EmployeePortalServiceImpl.java b/src/main/java/com/weaver/seconddev/portal/service/impl/EmployeePortalServiceImpl.java new file mode 100644 index 0000000..cdeeb56 --- /dev/null +++ b/src/main/java/com/weaver/seconddev/portal/service/impl/EmployeePortalServiceImpl.java @@ -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> getDurationOfEmployment(Map 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 returnMap = new HashMap<>(1); + returnMap.put("days", days); + return WeaResult.success(returnMap); + } + + @Override + public WeaResult getEmployeeInfo(Map 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 portalUrlDetails = portalMapper.getPortalUrlDetail(currentUser.getTenantKey(), PORTAL_KEY, "getEmployeeInfo"); + Map 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 params, EmployeeBasicInfoPo employeeBasicInfoPo) { + String url = Util.null2String(params.get("otherApiUrl")); + Map header = (Map) 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; + } + } + } + } + } + } + } + +} diff --git a/src/main/java/com/weaver/seconddev/portal/util/DateUtil.java b/src/main/java/com/weaver/seconddev/portal/util/DateUtil.java index 836d6eb..4c94e03 100644 --- a/src/main/java/com/weaver/seconddev/portal/util/DateUtil.java +++ b/src/main/java/com/weaver/seconddev/portal/util/DateUtil.java @@ -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) */ diff --git a/src/main/resources/mapper/EmployeePortalMapper.xml b/src/main/resources/mapper/EmployeePortalMapper.xml new file mode 100644 index 0000000..cb2384d --- /dev/null +++ b/src/main/resources/mapper/EmployeePortalMapper.xml @@ -0,0 +1,5 @@ + + + + +