diff --git a/src/com/api/matfron/web/StatisticsPortalAction.java b/src/com/api/matfron/web/StatisticsPortalAction.java index d92a5d3..bf17ec5 100644 --- a/src/com/api/matfron/web/StatisticsPortalAction.java +++ b/src/com/api/matfron/web/StatisticsPortalAction.java @@ -1,10 +1,14 @@ package com.api.matfron.web; +import javax.ws.rs.Path; + /** * @Author liang.cheng * @Date 2023/9/26 5:49 PM * @Description: 铭沣科技统计分析门户接口 * @Version 1.0 */ -public class StatisticsPortalAction { + +@Path("/matfron/portal/element") +public class StatisticsPortalAction extends com.engine.matfron.web.StatisticsPortalAction { } diff --git a/src/com/engine/matfron/entity/OptionVO.java b/src/com/engine/matfron/entity/OptionVO.java new file mode 100644 index 0000000..33118ae --- /dev/null +++ b/src/com/engine/matfron/entity/OptionVO.java @@ -0,0 +1,36 @@ +package com.engine.matfron.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.TreeSet; + +/** + * @Author liang.cheng + * @Date 2023/9/27 5:30 PM + * @Description: echarts option + * @Version 1.0 + */ + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class OptionVO { + + private String titleText; + + private TreeSet xData; + + private Integer yMin; + + private Integer yMax; + + private Integer yInterval; + + private TreeSet yData; + + +} diff --git a/src/com/engine/matfron/entity/PortalTopVO.java b/src/com/engine/matfron/entity/PortalTopVO.java new file mode 100644 index 0000000..158207a --- /dev/null +++ b/src/com/engine/matfron/entity/PortalTopVO.java @@ -0,0 +1,25 @@ +package com.engine.matfron.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Author liang.cheng + * @Date 2023/9/27 3:45 PM + * @Description: + * @Version 1.0 + */ + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PortalTopVO { + + private String title; + + private T count; + +} diff --git a/src/com/engine/matfron/exception/CustomizeRunTimeException.java b/src/com/engine/matfron/exception/CustomizeRunTimeException.java new file mode 100644 index 0000000..ce22409 --- /dev/null +++ b/src/com/engine/matfron/exception/CustomizeRunTimeException.java @@ -0,0 +1,22 @@ +package com.engine.matfron.exception; + +/** + * @Author weaver_cl + * @Description: + * @Date 2023/2/21 + * @Version V1.0 + **/ +public class CustomizeRunTimeException extends RuntimeException{ + + public CustomizeRunTimeException(String message) { + super(message); + } + + public CustomizeRunTimeException(Throwable cause) { + super(cause); + } + + public CustomizeRunTimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/com/engine/matfron/service/StatisticsPortalService.java b/src/com/engine/matfron/service/StatisticsPortalService.java index 5a98439..f003823 100644 --- a/src/com/engine/matfron/service/StatisticsPortalService.java +++ b/src/com/engine/matfron/service/StatisticsPortalService.java @@ -1,10 +1,34 @@ package com.engine.matfron.service; +import com.engine.matfron.entity.OptionVO; +import com.engine.matfron.entity.PortalTopVO; + +import java.util.TreeSet; + + /** * @Author liang.cheng * @Date 2023/9/26 5:51 PM - * @Description: TODO + * @Description: 统计分析门户 * @Version 1.0 */ public interface StatisticsPortalService { + + /** + * @Description: 门户顶部 + * @Author: liang.cheng + * @Date: 2023/9/27 4:02 PM + * @param: [] + * @return: com.engine.matfron.entity.PortalTopVO + */ + TreeSet getPortalTop(); + + /** + * @Description: 一级部门人数统计 + * @Author: liang.cheng + * @Date: 2023/9/27 5:40 PM + * @param: [] + * @return: com.engine.matfron.entity.OptionVO + */ + OptionVO getPortalDepartment(); } diff --git a/src/com/engine/matfron/service/impl/StatisticsPortalServiceImpl.java b/src/com/engine/matfron/service/impl/StatisticsPortalServiceImpl.java index 2a5fc7f..e907241 100644 --- a/src/com/engine/matfron/service/impl/StatisticsPortalServiceImpl.java +++ b/src/com/engine/matfron/service/impl/StatisticsPortalServiceImpl.java @@ -1,10 +1,70 @@ package com.engine.matfron.service.impl; +import com.engine.core.impl.Service; +import com.engine.matfron.entity.OptionVO; +import com.engine.matfron.entity.PortalTopVO; +import com.engine.matfron.service.StatisticsPortalService; +import com.engine.matfron.util.CommonDateUtil; +import com.engine.matfron.util.CommonUtils; +import weaver.conn.RecordSet; +import weaver.general.Util; + +import java.time.YearMonth; +import java.util.ArrayList; + +import java.util.List; +import java.util.TreeSet; + + /** * @Author liang.cheng * @Date 2023/9/26 5:52 PM * @Description: TODO * @Version 1.0 */ -public class StatisticsPortalServiceImpl { +public class StatisticsPortalServiceImpl extends Service implements StatisticsPortalService { + + + + @Override + public TreeSet getPortalTop() { + RecordSet rs = new RecordSet(); + TreeSet portalTopVOList = new TreeSet<>(); + + rs.executeQuery("select count(1) as count from hrmresource where status < 4"); + rs.next(); + Integer count = Util.getIntValue(rs.getString("count"), 0); + portalTopVOList.add(PortalTopVO.builder().title("在职人数总数").count(count).build()); + portalTopVOList.add(PortalTopVO.builder().title("社保缴纳人数").count(0).build()); + + List birthdayList = new ArrayList<>(); + rs.executeQuery("select birthday from hrmresource where status < 4"); + while (rs.next()) { + birthdayList.add(Util.null2String(rs.getString("birthday"))); + } + double averageAge = birthdayList.stream() + .map(CommonUtils::parseLocalDate) + .mapToInt(CommonUtils::calculateAge) + .average() + .orElse(0); + portalTopVOList.add(PortalTopVO.builder().title("平均年龄").count(averageAge).build()); + + String startMonth = CommonDateUtil.getFormatYear(CommonDateUtil.toDateStartOfMonth(YearMonth.now())); + String endMonth = CommonDateUtil.getFormatYear(CommonDateUtil.toDateEndOfMonth(YearMonth.now())); + rs.executeQuery("select count(1) as sum from hrmresource where status < 4 and companystartdate >= ? and companystartdate <= ?",startMonth,endMonth); + rs.next(); + Integer sum = Util.getIntValue(rs.getString("sum"),0); + portalTopVOList.add(PortalTopVO.builder().title("本月新入职人员").count(sum).build()); + + return portalTopVOList; + } + + @Override + public OptionVO getPortalDepartment() { + RecordSet rs = new RecordSet(); + + rs.executeQuery("select id,departmentname from hrmdepartment where supdepid = 0"); + + return null; + } } diff --git a/src/com/engine/matfron/util/CommonAssert.java b/src/com/engine/matfron/util/CommonAssert.java new file mode 100644 index 0000000..e51cda1 --- /dev/null +++ b/src/com/engine/matfron/util/CommonAssert.java @@ -0,0 +1,175 @@ +package com.engine.matfron.util; + +import com.engine.matfron.exception.CustomizeRunTimeException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.Collection; +import java.util.Map; + +/** + * @Author weaver_cl + * @description: + * @Date 2022/4/26 + * @Version V1.0 + **/ +public abstract class CommonAssert { + /** + * 判断入参不为null + * + * @param object 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void notNull(Object object, String message) { + if (object == null) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断入参不为null + * + * @param string 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void notNull(String string, String message) { + if (StringUtils.isBlank(string)) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断多个入参不为null + * + * @param message 检查失败返回的异常信息 + * @param objects 待检查参数 + */ + public static void notNull(String message, Object... objects) { + for (Object obj : objects) { + if (obj == null) { + throw new CustomizeRunTimeException(message); + } + } + } + + /** + * 判断入参为null + * + * @param object 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void isNull(Object object, String message) { + if (object != null) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断集合是否为空 + * + * @param collection 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void isEmpty(Collection collection, String message) { + if (!CollectionUtils.isEmpty(collection)) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断集合不为空 + * + * @param collection 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void notEmpty(Collection collection, String message) { + if (CollectionUtils.isEmpty(collection)) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断数组是否为空 + * + * @param arr 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void notEmpty(Object[] arr, String message) { + if (ObjectUtils.isEmpty(arr)) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断map是否为空 + * + * @param map 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void notEmpty(Map map, String message) { + if (CollectionUtils.isEmpty(map)) { + throw new CustomizeRunTimeException(message); + } + } + + /** + * 判断数组元素是否为空 + * + * @param arr 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void notNullElement(Object[] arr, String message) { + if (arr != null) { + for (Object obj : arr) { + if (obj == null) { + throw new CustomizeRunTimeException(message); + } + } + } + } + + /** + * 判断boolean + * + * @param expression 待检查参数 + * @param message 检查失败返回的异常信息 + */ + public static void isTrue(boolean expression, String message) { + if (!expression) { + throw new CustomizeRunTimeException(message); + } + } + + public static void isFalse(boolean expression, String message) { + if (expression) { + throw new CustomizeRunTimeException(message); + } + } + + public static void isBlank(CharSequence cs, String message) { + int strLen; + if (cs != null && (strLen = cs.length()) != 0) { + for (int i = 0; i < strLen; ++i) { + if (!Character.isWhitespace(cs.charAt(i))) { + throw new CustomizeRunTimeException(message); + } + } + } + } + + public static void notBlank(CharSequence cs, String message) { + int strLen; + if (cs != null && (strLen = cs.length()) != 0) { + for (int i = 0; i < strLen; ++i) { + if (Character.isWhitespace(cs.charAt(i))) { + throw new CustomizeRunTimeException(message); + } + } + } + if (cs == null || cs.length() == 0) { + throw new CustomizeRunTimeException(message); + } + + } +} diff --git a/src/com/engine/matfron/util/CommonDateUtil.java b/src/com/engine/matfron/util/CommonDateUtil.java new file mode 100644 index 0000000..fe44caa --- /dev/null +++ b/src/com/engine/matfron/util/CommonDateUtil.java @@ -0,0 +1,83 @@ +package com.engine.matfron.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.Objects; + +/** + * @Author liang.cheng + * @Date 2023/9/27 4:44 PM + * @Description: + * @Version 1.0 + */ + +@Slf4j +public class CommonDateUtil { + + public static final String DATE_FORMATTER_PATTERN = "yyyy-MM-dd"; + + /** + * YearMonth转Date + * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28 + * 如果要转换为当月最后一天,可以使用下面方法:toDateEndOfMonth(YearMonth) + * + * @param yearMonth + * @param dayOfMonth + * @return + */ + public static Date toDate(YearMonth yearMonth, int dayOfMonth) { + Objects.requireNonNull(yearMonth, "yearMonth"); + return localDateToDate(yearMonth.atDay(dayOfMonth)); + } + + + /** + * YearMonth转Date,转换为当月第一天 + * + * @param yearMonth + * @return + */ + public static Date toDateStartOfMonth(YearMonth yearMonth) { + return toDate(yearMonth, 1); + } + + /** + * YearMonth转Date,转换为当月最后一天 + * + * @param yearMonth + * @return + */ + public static Date toDateEndOfMonth(YearMonth yearMonth) { + Objects.requireNonNull(yearMonth, "yearMonth"); + return localDateToDate(yearMonth.atEndOfMonth()); + } + + public static Date localDateToDate(LocalDate localDate) { + if (null == localDate) { + return null; + } + ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); + return Date.from(zonedDateTime.toInstant()); + } + + public static String getFormatYear(Date localDate) { + if (localDate == null) { + return StringUtils.EMPTY; + } + try { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMATTER_PATTERN); + return simpleDateFormat.format(localDate); + } catch (Exception e) { + log.warn("格式化年份错误", e); + return StringUtils.EMPTY; + } + } + +} diff --git a/src/com/engine/matfron/util/CommonUtils.java b/src/com/engine/matfron/util/CommonUtils.java new file mode 100644 index 0000000..9d2cb39 --- /dev/null +++ b/src/com/engine/matfron/util/CommonUtils.java @@ -0,0 +1,24 @@ +package com.engine.matfron.util; + +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; + +/** + * @Author liang.cheng + * @Date 2023/9/27 4:52 PM + * @Description: TODO + * @Version 1.0 + */ +public class CommonUtils { + + public static LocalDate parseLocalDate(String dateString) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + return LocalDate.parse(dateString, formatter); + } + + public static int calculateAge(LocalDate birthday) { + LocalDate currentDate = LocalDate.now(); + return Period.between(birthday, currentDate).getYears(); + } +} diff --git a/src/com/engine/matfron/util/ExceptionUtil.java b/src/com/engine/matfron/util/ExceptionUtil.java new file mode 100644 index 0000000..3361513 --- /dev/null +++ b/src/com/engine/matfron/util/ExceptionUtil.java @@ -0,0 +1,20 @@ +package com.engine.matfron.util; + +/** + * @Author weaver_cl + * @Description: + * @Date 2023/2/21 + * @Version V1.0 + **/ +public class ExceptionUtil { + public static String getRealMessage(Throwable e) { + while (e != null) { + Throwable cause = e.getCause(); + if (cause == null) { + return e.getMessage(); + } + e = cause; + } + return ""; + } +} diff --git a/src/com/engine/matfron/util/ResponseResult.java b/src/com/engine/matfron/util/ResponseResult.java new file mode 100644 index 0000000..470d1e3 --- /dev/null +++ b/src/com/engine/matfron/util/ResponseResult.java @@ -0,0 +1,185 @@ +package com.engine.matfron.util; + + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import com.engine.core.exception.ECException; +import com.engine.matfron.exception.CustomizeRunTimeException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import weaver.general.BaseBean; +import weaver.hrm.User; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + + +@Slf4j +public class ResponseResult { + + private static final long serialVersionUID = 1L; + + private final User user; + + private final BaseBean baseBean = new BaseBean(); + + private final Boolean isLog = "true".equals(baseBean.getPropValue("hrmSalary", "log")); + + public ResponseResult(User user) { + this.user = user; + } + + /** + * 统一返回方法(自定义返回格式) + */ + public String customRun(Function f, T t) { + try { + if (isLog) { + log.info("run api , param {}", t); + } + return getJsonString(f.apply(t)); + } catch (CustomizeRunTimeException e) { + log.error("api run fail", e); + return Error(e.getMessage()); + } catch (ECException e) { + log.error("api run fail", e); + Throwable cause = e.getCause(); + return Error(cause.getMessage()); + } catch (Exception e) { + log.error("api run fail", e); + return Error("系统异常!"); + } + } + + /** + * 统一返回方法 + */ + public String run(Function f, T t) { + try { + if (isLog) { + log.info("run api , param {}", t); + } + return Ok(f.apply(t)); + } catch (CustomizeRunTimeException e) { + log.error("api run fail", e); + return Error(e.getMessage()); + } catch (ECException e) { + log.error("api run fail", e); + Throwable cause = e.getCause(); + return Error(cause.getMessage()); + } catch (Exception e) { + log.error("api run fail", e); + return Error("系统异常!"); + } + } + + /** + * 统一返回方法(有参无返回) + */ + public String run(Consumer f, T t) { + try { + if (isLog) { + log.info("run api , param {}", t); + } + f.accept(t); + return Ok(); + } catch (CustomizeRunTimeException e) { + log.error("api run fail", e); + return Error(e.getMessage()); + } catch (ECException e) { + log.error("api run fail", e); + return Error(ExceptionUtil.getRealMessage(e)); + } catch (Exception e) { + log.error("api run fail", e); + return Error("系统异常!", e); + } + } + + + /** + * 统一返回方法(无参有返回) + */ + public String run(Supplier f) { + try { + if (isLog) { + log.info("run api"); + } + return Ok(f.get()); + } catch (CustomizeRunTimeException e) { + log.error("api run fail", e); + return Error(e.getMessage()); + } catch (ECException e) { + log.error("api run fail", e); + Throwable cause = e.getCause(); + return Error(cause.getMessage()); + } catch (Exception e) { + log.error("api run fail", e); + return Error("系统异常!", e); + } + } + + + private static String getJsonString(Object apidatas) { + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.writeValueAsString(apidatas); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return ""; + } + + + /** + * 成功返回 + */ + private String Ok() { + Map apidatas = new HashMap<>(); + apidatas.put("status", true); + return JSONObject.toJSONString(apidatas, SerializerFeature.DisableCircularReferenceDetect); + } + + + /** + * 成功返回 + */ + private String Ok(R r) { + Map apidatas = new HashMap<>(); + apidatas.put("status", true); + apidatas.put("data", r); + String success = getJsonString(apidatas); + if (isLog) { + log.info("run salary api success return {}", success); + } + return success; + } + + + /** + * 失败返回 + */ + private static String Error(String message) { + Map apidatas = new HashMap<>(); + apidatas.put("status", false); + apidatas.put("errormsg", message); + return JSONObject.toJSONString(apidatas, SerializerFeature.DisableCircularReferenceDetect); + } + + + /** + * 系统异常失败返回 + */ + private static String Error(String message, Exception e) { + Map apidatas = new HashMap<>(); + apidatas.put("status", false); + apidatas.put("errormsg", message); + apidatas.put("error", e.getMessage()); + return JSONObject.toJSONString(apidatas, SerializerFeature.DisableCircularReferenceDetect); + } + +} diff --git a/src/com/engine/matfron/web/StatisticsPortalAction.java b/src/com/engine/matfron/web/StatisticsPortalAction.java index 59d51cf..2bbaeb8 100644 --- a/src/com/engine/matfron/web/StatisticsPortalAction.java +++ b/src/com/engine/matfron/web/StatisticsPortalAction.java @@ -1,10 +1,51 @@ package com.engine.matfron.web; +import com.engine.common.util.ServiceUtil; +import com.engine.matfron.entity.OptionVO; +import com.engine.matfron.entity.PortalTopVO; +import com.engine.matfron.service.StatisticsPortalService; +import com.engine.matfron.service.impl.StatisticsPortalServiceImpl; +import com.engine.matfron.util.ResponseResult; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.TreeSet; + /** * @Author liang.cheng * @Date 2023/9/26 5:51 PM - * @Description: TODO + * @Description: * @Version 1.0 */ public class StatisticsPortalAction { + + private StatisticsPortalService getCommonDutyService(User user) { + return ServiceUtil.getService(StatisticsPortalServiceImpl.class,user); + } + + + @GET + @Path("/statistics/top") + @Produces(MediaType.APPLICATION_JSON) + public String getPortalTop(@Context HttpServletRequest request, @Context HttpServletResponse response) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult>(user).run(getCommonDutyService(user) :: getPortalTop); + } + + @GET + @Path("/statistics/department") + @Produces(MediaType.APPLICATION_JSON) + public String getPortalDepartment(@Context HttpServletRequest request, @Context HttpServletResponse response) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult(user).run(getCommonDutyService(user) :: getPortalDepartment); + } + + } diff --git a/src/test/MainTest.java b/src/test/MainTest.java index 2bfc0b3..e7c0c8e 100644 --- a/src/test/MainTest.java +++ b/src/test/MainTest.java @@ -1,5 +1,10 @@ package test; +import com.engine.matfron.util.CommonDateUtil; + +import java.time.YearMonth; +import java.util.Date; + /** * @Author weaver_cl * @Description: @@ -9,6 +14,8 @@ package test; public class MainTest { public static void main(String[] args) { + String startMonth = CommonDateUtil.getFormatYear(CommonDateUtil.toDateEndOfMonth(YearMonth.now())); + String endMonth = CommonDateUtil.getFormatYear(CommonDateUtil.toDateEndOfMonth(YearMonth.now())); } }