|
|
|
|
package com.engine.common.util;
|
|
|
|
|
|
|
|
|
|
import com.engine.attendance.enums.AccountingUnitEnum;
|
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
|
import com.google.common.reflect.TypeToken;
|
|
|
|
|
import com.google.gson.Gson;
|
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
import weaver.general.BaseBean;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileFilter;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.lang.reflect.Type;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.math.MathContext;
|
|
|
|
|
import java.net.JarURLConnection;
|
|
|
|
|
import java.net.URL;
|
|
|
|
|
import java.net.URLDecoder;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Enumeration;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.jar.JarEntry;
|
|
|
|
|
import java.util.jar.JarFile;
|
|
|
|
|
|
|
|
|
|
public class Utils<T> {
|
|
|
|
|
public static Gson gson = new Gson();
|
|
|
|
|
public static Type list_map_type = new TypeToken<List<Map<String,String>>>(){}.getType();
|
|
|
|
|
public static Type map_type = new TypeToken<Map<String,Object>>(){}.getType();
|
|
|
|
|
public static BaseBean baseBean = new BaseBean();
|
|
|
|
|
/**
|
|
|
|
|
* 解析格式为[{a:b,c:d}]格式的json
|
|
|
|
|
* @param json
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static List<Map<String,String>> resolveList_Map(String json){
|
|
|
|
|
List<Map<String,String>> list= gson.fromJson(json,list_map_type);
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 解析格式为{a:b,c:d}格式的json
|
|
|
|
|
* @param json
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static Map<String,Object> resolveMap(String json){
|
|
|
|
|
Map<String,Object> list= gson.fromJson(json,map_type);
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 通过接口名取得某个接口下所有实现这个接口的类
|
|
|
|
|
*/
|
|
|
|
|
public List<T> getAllClassByInterface(Class<?> c) {
|
|
|
|
|
List<T> returnClassList = null;
|
|
|
|
|
if (c.isInterface()) {
|
|
|
|
|
try {
|
|
|
|
|
// 获取当前的包名
|
|
|
|
|
String packageName = c.getPackage().getName();
|
|
|
|
|
// 获取当前包下以及子包下所以的类
|
|
|
|
|
List<Class<?>> allClass = getClasses(packageName);
|
|
|
|
|
if (allClass != null) {
|
|
|
|
|
returnClassList = new ArrayList();
|
|
|
|
|
for (Class<?> cls : allClass) {
|
|
|
|
|
// 判断是否是同一个接口
|
|
|
|
|
if (c.isAssignableFrom(cls)) {
|
|
|
|
|
// 本身不加入进去
|
|
|
|
|
if (!c.equals(cls)) {
|
|
|
|
|
returnClassList.add((T)cls.newInstance());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}catch (Exception e){
|
|
|
|
|
baseBean.writeLog(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnClassList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从包package中获取所有的Class
|
|
|
|
|
*
|
|
|
|
|
* @param packageName
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
@NotNull
|
|
|
|
|
public static List<Class<?>> getClasses(String packageName) {
|
|
|
|
|
// 第一个class类的集合
|
|
|
|
|
List<Class<?>> classes = new ArrayList<Class<?>>();
|
|
|
|
|
// 是否循环迭代
|
|
|
|
|
boolean recursive = true;
|
|
|
|
|
// 获取包的名字 并进行替换
|
|
|
|
|
String packageDirName = packageName.replace('.', '/');
|
|
|
|
|
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
|
|
|
|
|
Enumeration<URL> dirs;
|
|
|
|
|
try {
|
|
|
|
|
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
|
|
|
|
// 循环迭代下去
|
|
|
|
|
while (dirs.hasMoreElements()) {
|
|
|
|
|
// 获取下一个元素
|
|
|
|
|
URL url = dirs.nextElement();
|
|
|
|
|
// 得到协议的名称
|
|
|
|
|
String protocol = url.getProtocol();
|
|
|
|
|
// 如果是以文件的形式保存在服务器上
|
|
|
|
|
if ("file".equals(protocol)) {
|
|
|
|
|
// 获取包的物理路径
|
|
|
|
|
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
|
|
|
|
|
// 以文件的方式扫描整个包下的文件 并添加到集合中
|
|
|
|
|
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
|
|
|
|
|
} else if ("jar".equals(protocol)) {
|
|
|
|
|
// 如果是jar包文件
|
|
|
|
|
// 定义一个JarFile
|
|
|
|
|
JarFile jar;
|
|
|
|
|
try {
|
|
|
|
|
// 获取jar
|
|
|
|
|
jar = ((JarURLConnection) url.openConnection()).getJarFile();
|
|
|
|
|
// 从此jar包 得到一个枚举类
|
|
|
|
|
Enumeration<JarEntry> entries = jar.entries();
|
|
|
|
|
// 同样的进行循环迭代
|
|
|
|
|
while (entries.hasMoreElements()) {
|
|
|
|
|
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
|
|
|
|
|
JarEntry entry = entries.nextElement();
|
|
|
|
|
String name = entry.getName();
|
|
|
|
|
// 如果是以/开头的
|
|
|
|
|
if (name.charAt(0) == '/') {
|
|
|
|
|
// 获取后面的字符串
|
|
|
|
|
name = name.substring(1);
|
|
|
|
|
}
|
|
|
|
|
// 如果前半部分和定义的包名相同
|
|
|
|
|
if (name.startsWith(packageDirName)) {
|
|
|
|
|
int idx = name.lastIndexOf('/');
|
|
|
|
|
// 如果以"/"结尾 是一个包
|
|
|
|
|
if (idx != -1) {
|
|
|
|
|
// 获取包名 把"/"替换成"."
|
|
|
|
|
packageName = name.substring(0, idx).replace('/', '.');
|
|
|
|
|
}
|
|
|
|
|
// 如果可以迭代下去 并且是一个包
|
|
|
|
|
if ((idx != -1) || recursive) {
|
|
|
|
|
// 如果是一个.class文件 而且不是目录
|
|
|
|
|
if (name.endsWith(".class") && !entry.isDirectory()) {
|
|
|
|
|
// 去掉后面的".class" 获取真正的类名
|
|
|
|
|
String className = name.substring(packageName.length() + 1, name.length() - 6);
|
|
|
|
|
try {
|
|
|
|
|
// 添加到classes
|
|
|
|
|
classes.add(Class.forName(packageName + '.' + className));
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
|
|
baseBean.writeLog(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
baseBean.writeLog(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
baseBean.writeLog(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return classes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 以文件的形式来获取包下的所有Class
|
|
|
|
|
*
|
|
|
|
|
* @param packageName
|
|
|
|
|
* @param packagePath
|
|
|
|
|
* @param recursive
|
|
|
|
|
* @param classes
|
|
|
|
|
*/
|
|
|
|
|
public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List<Class<?>> classes) {
|
|
|
|
|
// 获取此包的目录 建立一个File
|
|
|
|
|
File dir = new File(packagePath);
|
|
|
|
|
// 如果不存在或者 也不是目录就直接返回
|
|
|
|
|
if (!dir.exists() || !dir.isDirectory()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 如果存在 就获取包下的所有文件 包括目录
|
|
|
|
|
File[] dirfiles = dir.listFiles(new FileFilter() {
|
|
|
|
|
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
|
|
|
|
|
@Override
|
|
|
|
|
public boolean accept(File file) {
|
|
|
|
|
return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 循环所有文件
|
|
|
|
|
for (File file : dirfiles) {
|
|
|
|
|
// 如果是目录 则继续扫描
|
|
|
|
|
if (file.isDirectory()) {
|
|
|
|
|
findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果是java类文件 去掉后面的.class 只留下类名
|
|
|
|
|
String className = file.getName().substring(0, file.getName().length() - 6);
|
|
|
|
|
try {
|
|
|
|
|
// 添加到集合中去
|
|
|
|
|
classes.add(Class.forName(packageName + '.' + className));
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
baseBean.writeLog(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获得time时间内最近的前后打卡时间数据
|
|
|
|
|
* @param time
|
|
|
|
|
* @param clockInTimeList 打卡数据
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static Map<String,Map<String,Object>> getNearestClcokInTimeCmd(String time,List<Map<String, Object>> clockInTimeList){
|
|
|
|
|
Map<String,Map<String,Object>> resultMap = Maps.newHashMap();
|
|
|
|
|
for (int i=0;i<clockInTimeList.size();i++){
|
|
|
|
|
String signDateTime = clockInTimeList.get(i).get("signdate") +" "+clockInTimeList.get(i).get("signtime");
|
|
|
|
|
int j=i+1;
|
|
|
|
|
if (j > clockInTimeList.size()-1){
|
|
|
|
|
j = clockInTimeList.size()-1;
|
|
|
|
|
}
|
|
|
|
|
String afterSignDateTime = clockInTimeList.get(j).get("signdate") +" "+clockInTimeList.get(j).get("signtime");
|
|
|
|
|
if (i==0 && DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) <0){
|
|
|
|
|
resultMap.put("after",clockInTimeList.get(i));
|
|
|
|
|
}else if (i == clockInTimeList.size()-1 && DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) >0){
|
|
|
|
|
resultMap.put("before",clockInTimeList.get(i));
|
|
|
|
|
}else if (DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) >0 && DateUtil.getTime(time).compareTo(DateUtil.getTime(afterSignDateTime)) <0){
|
|
|
|
|
resultMap.put("before",clockInTimeList.get(i));
|
|
|
|
|
resultMap.put("after",clockInTimeList.get(j));
|
|
|
|
|
}else if (DateUtil.getTime(time).compareTo(DateUtil.getTime(signDateTime)) == 0){
|
|
|
|
|
resultMap.put("equal",clockInTimeList.get(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return resultMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据核算量、核算单位,计算出具体项目时长
|
|
|
|
|
* @param hsl 核算量
|
|
|
|
|
* @param hsdw 核算单位
|
|
|
|
|
* @param duration 时间值
|
|
|
|
|
* @param unit 时间值单位
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static double getItemduration(double hsl, String hsdw,int duration, AccountingUnitEnum unit){
|
|
|
|
|
double itemDuration = 0.0;
|
|
|
|
|
BigDecimal durationBig = new BigDecimal(duration);
|
|
|
|
|
BigDecimal hslBig = new BigDecimal(hsl);
|
|
|
|
|
if (AccountingUnitEnum.DAY.getKey().equals(hsdw) || AccountingUnitEnum.ONCE.getKey().equals(hsdw)){
|
|
|
|
|
itemDuration = hsl;
|
|
|
|
|
}else if (AccountingUnitEnum.HOUR.getKey().equals(hsdw)){
|
|
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
|
|
double durationHour = duration/60.0;
|
|
|
|
|
if (duration%60 > 0){
|
|
|
|
|
durationHour = durationHour +1;
|
|
|
|
|
}
|
|
|
|
|
durationBig = new BigDecimal(durationHour);
|
|
|
|
|
if ((durationHour/hsl) > Math.floor(durationHour/hsl)){
|
|
|
|
|
itemDuration=durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_DOWN)).doubleValue();
|
|
|
|
|
}else {
|
|
|
|
|
itemDuration = durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).doubleValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
|
|
if ((duration/hsl) > Math.floor(duration/hsl)){
|
|
|
|
|
itemDuration=durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_DOWN)).doubleValue();
|
|
|
|
|
}else {
|
|
|
|
|
itemDuration = durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).doubleValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}else if (AccountingUnitEnum.MINUTES.getKey().equals(hsdw)){
|
|
|
|
|
if (unit.equals(AccountingUnitEnum.MINUTES)){
|
|
|
|
|
if ((duration/hsl) > Math.floor(duration/hsl)){
|
|
|
|
|
itemDuration=durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_DOWN)).doubleValue();
|
|
|
|
|
}else {
|
|
|
|
|
itemDuration = durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).doubleValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}else if (unit.equals(AccountingUnitEnum.HOUR)){
|
|
|
|
|
int durationMinute = duration*60;
|
|
|
|
|
durationBig = new BigDecimal(durationMinute);
|
|
|
|
|
if ((durationMinute/hsl) > Math.floor(durationMinute/hsl)){
|
|
|
|
|
itemDuration=durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).add(hslBig,new MathContext(BigDecimal.ROUND_HALF_DOWN)).doubleValue();
|
|
|
|
|
}else {
|
|
|
|
|
itemDuration = durationBig.divide(hslBig,BigDecimal.ROUND_DOWN).multiply(hslBig).doubleValue();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return itemDuration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|