package com.boco.nbd.wios.flow.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.Week;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bestvike.linq.Linq;
import com.boco.nbd.cams.core.constant.CamsConstant;
import com.boco.nbd.cams.core.util.LambdaUtils;
import com.boco.nbd.framework.common.util.SpringContextUtil;
import com.boco.nbd.framework.workflow.annotation.AnnotationUtils;
import com.boco.nbd.framework.workflow.entity.constant.FlowConstants;
import com.boco.nbd.framework.workflow.entity.exception.FlowException;
import com.boco.nbd.framework.workflow.flow.AbstractFlow;
import com.boco.nbd.wios.export.bo.UploadPic;
import com.boco.nbd.wios.flow.entity.FlowConstant;
import com.boco.nbd.wios.flow.entity.bo.ColumnBO;
import com.boco.nbd.wios.flow.entity.bo.FilterFieldsBO;
import com.boco.nbd.wios.flow.entity.bo.TransferRightBO;
import com.boco.nbd.wios.flow.entity.po.MenuFieldPO;
import com.boco.nbd.wios.flow.entity.po.OrderPO;
import com.boco.nbd.wios.flow.entity.po.PmUserPO;
import com.boco.nbd.wios.flow.entity.qo.CamsOrderQo;
import com.boco.nbd.wios.flow.entity.react.SelectBO;
import com.boco.nbd.wios.flow.entity.react.TreeSelectBO;
import com.boco.nbd.wios.flow.enums.FiledTypeEnum;
import com.boco.nbd.wios.flow.enums.FlowNodeEnum;
import com.boco.nbd.wios.flow.enums.ValueTypeEnum;
import com.boco.nbd.wios.manage.entity.bo.OemBo;
import com.boco.nbd.wios.manage.entity.bo.OemVo;
import com.boco.nbd.wios.manage.entity.bo.RegionVo;
import com.boco.nbd.wios.manage.entity.cams.enums.IOperator;
import com.boco.nbd.wios.manage.entity.cams.enums.OrderStatus;
import com.boco.nbd.wios.manage.entity.cams.enums.OverTimeType;
import com.boco.nbd.wios.manage.entity.common.bo.UploadFile;
import com.boco.nbd.wios.manage.service.impl.OemService;
import com.boco.nbd.wios.manage.service.impl.RegionService;
import com.boco.nbd.wios.manage.service.impl.TokenService;
import com.deepoove.poi.data.HyperLinkTextRenderData;
import com.deepoove.poi.data.NumbericRenderData;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.RenderData;
import com.deepoove.poi.util.BytePictureUtils;
import com.ihidea.core.support.exception.ServiceException;
import com.ihidea.core.support.session.SessionInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.sl.usermodel.PictureData;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author:cao hai
 * @date:2022/6/30 17:07
 * @version:V1.0
 * @description:ProcessUtil
 * @modify:
 */
@Slf4j
public class ProcessUtil {

    /**
     * 服务名
     */
    private static String OEM_SERVICE = "oemService";
    private static String REGION_SERVICE = "regionService";
    public static final String RE_LOGIN = "请重新登录";
    private static final String TOKEN_SERVICE_BEAN = "tokenService";
    public static final String HOLIDAY_TYPE = "节假日";
    public static final String WORK_TYPE = "调休工作日";
    /**
     * 勘测转派节点
     */
    private static final Integer[] SURVEY_TRANSFER_NODE = {104, 105, 106, 115};
    /**
     * 安装转派节点
     */
    private static final Integer[] INSTALL_TRANSFER_NODE = {108, 109, 110, 111};


    /**
     * 一期操蛋逻辑,导入时候 各种日期不为空添加一个_1,空加_0后缀,因为涉及前端部分逻辑调整,所以这部分逻辑还沿用
     */
    public static final String EMPTY_ADD = "_0";
    public static final String NOT_EMPTY_ADD = "_1";


    /**
     * 空对象正则
     */
    public final static Pattern EMPTY_PATTERN = Pattern.compile("^(\\[)?(\\{\\})?(])?$");

    /**
     * 转派对象处理
     *
     * @param po
     * @param userId
     * @return
     */
    public static TransferRightBO getTransferRightBO(OrderPO po, String userId) {
        TransferRightBO bo = new TransferRightBO();
        bo.setTransferRight(false);
        if (StrUtil.isEmpty(po.getTransferUser()) || StrUtil.isEmpty(userId)) {
            return bo;
        }
        List<String> user = Arrays.asList(po.getTransferUser().split(CamsConstant.COMMA));
        if (areSurveyTransfer(po.getNodeFlag()) && user.contains(userId)) {
            bo.setTransferRight(true);
            bo.setCurrentSupplierId(po.getSurveySupplierId());
            bo.setCurrentSupplierName(po.getSurveySupplierName());
            bo.setCurrentStaffId(po.getSurveyStaffId());
            bo.setCurrentStaffName(po.getSurveyStaffName());
        } else if (areInstallTransfer(po.getNodeFlag()) && user.contains(userId)) {
            bo.setTransferRight(true);
            bo.setCurrentSupplierId(po.getInstallSupplierId());
            bo.setCurrentSupplierName(po.getInstallSupplierName());
            bo.setCurrentStaffId(po.getInstallStaffId());
            bo.setCurrentStaffName(po.getInstallStaffName());
        }
        return bo;
    }

    /**
     * 是否勘测转派节点
     *
     * @param currentNode
     * @return
     */
    public static boolean areSurveyTransfer(Integer currentNode) {
        return Arrays.asList(SURVEY_TRANSFER_NODE).contains(currentNode);
    }

    /**
     * 是否安装转派节点
     *
     * @param currentNode
     * @return
     */
    public static boolean areInstallTransfer(Integer currentNode) {
        return Arrays.asList(INSTALL_TRANSFER_NODE).contains(currentNode);
    }

    /**
     * 获取当前工单的区域
     *
     * @param users
     * @param po
     * @return
     */
    public static List<String> getTransferUser(List<PmUserPO> users, OrderPO po) {
        if (CollUtil.isEmpty(users)) {
            throw new FlowException("请配置区域PM账号!");
        }
        List<String> user = new ArrayList<>(8);
        String areaId = po.findAreaId();
        for (PmUserPO pm : users) {
            if (StrUtil.isEmpty(pm.getRegionId())) {
                continue;
            }
            List<String> regionIdList = Arrays.asList(pm.getRegionId().split(CamsConstant.COMMA));
            if (regionIdList.contains(areaId)) {
                user.add(pm.getAccountId());
            }
        }
        if (CollUtil.isEmpty(user)) {
            String areaName = po.findAreaName();
            throw new FlowException(areaName + "未配置区域PM账号!");
        }
        return user;
    }

    /**
     * 图片数据处理
     *
     * @param url
     * @return
     */
    public static PictureRenderData pictureRenderData(String url) {
        try {
            return new PictureRenderData(50, 50, PictureData.PictureType.PNG.extension, BytePictureUtils.getUrlBufferedImage(url));
        } catch (Exception e) {
            log.error("{} PictureRenderData error:{}", url, e);
        }
        return null;
    }

    /**
     * 获取文件后缀
     *
     * @param fileName
     * @return
     */
    public static String getFileSuffix(String fileName) {
        if (StrUtil.isEmpty(fileName)) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf(CamsConstant.CIRCLE_FLAG));
    }

    /**
     * 超链接文本处理
     *
     * @param fileName
     * @param url
     * @return
     */
    public static HyperLinkTextRenderData hyperLinkTextRenderData(String fileName, String url) {
        try {
            return new HyperLinkTextRenderData(fileName, url);
        } catch (Exception e) {
            log.error("{} PictureRenderData error:{}", url, e);
        }
        return null;
    }

    /**
     * 附件数据处理
     *
     * @param files
     * @return
     */
    public static Map<String, Object> handleFiles(List<UploadFile> files) {
        Map<String, Object> data = new HashMap<>(2);
        data.put(FlowConstant.PIC_FILES, null);
        data.put(FlowConstant.ATTACH_FILES, null);
        if (CollUtil.isEmpty(files)) {
            return data;
        }
        List<RenderData> attachFileList = new ArrayList<>();
        List<UploadPic> picList = new ArrayList<>();
        files.stream().forEach(pic -> {
            if (pic.getName().endsWith(PictureData.PictureType.JPEG.extension) || pic.getName().endsWith(PictureData.PictureType.PNG.extension)) {
                PictureRenderData pictureRenderData = pictureRenderData(pic.getUrl());
                if (pictureRenderData != null) {
                    UploadPic up = new UploadPic();
                    up.setPrd(pictureRenderData);
                    up.setName(pic.getName());
                    up.setTime(DateUtil.format(pic.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
                    picList.add(up);
                }
            } else {
                HyperLinkTextRenderData row = hyperLinkTextRenderData(pic.getName(), pic.getUrl());
                if (row != null) {
                    attachFileList.add(row);
                }
            }
        });
        data.put(FlowConstant.PIC_FILES, picList);
        data.put(FlowConstant.ATTACH_FILES, new NumbericRenderData(attachFileList));
        return data;
    }


    /**
     * json 处理==>如果存在json转换个性处理的,在相应的实现类中个性化实现
     * 异常:JSONObject cannot be cast to com.boco.nbd.wios.manage.entity.settlement.po.Invoice
     * 说明 转换后对象 并没有转换成T 而是 JSONObject对象,如果使用需要进一步处理
     *
     * @param json
     * @return
     */
    public static List<JSONObject> jsonHandle(String json) {
        if (StringUtils.isEmpty(json)) {
            return new ArrayList<>(1);
        }
        try {
            return JSONUtil.toBean(JSONUtil.parse(json), new TypeReference<List<JSONObject>>() {
            }, true);
        } catch (Exception ex) {
            log.error(json + "数据转换异常:", ex);
            throw new ServiceException("数据转换异常");
        }
    }


    /**
     * 一期操蛋逻辑 日期处理
     *
     * @param date
     * @return
     */
    public static String dayHandle(String date) {
        String addStr = StrUtil.isNotBlank(date) ? NOT_EMPTY_ADD : EMPTY_ADD;
        return date + addStr;
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    public static SessionInfo getUserInfo() {
        TokenService tokenService = (TokenService) SpringContextUtil.getBean(TOKEN_SERVICE_BEAN);
        return tokenService.getUser();
    }

    /**
     * 转换处理实体中特定字段:目前主要处理时间类型、枚举类型转换
     *
     * @param entry
     * @param filterFieldsBO
     * @param enumMap
     * @param <T>
     * @return
     */
    public static <T> Map<String, Object> getFilterFields(T entry, FilterFieldsBO filterFieldsBO, Map<String, Map<Object, String>> enumMap) {
        return getFilterFields(entry, filterFieldsBO.getFilterFields(), filterFieldsBO.getMatchField(), filterFieldsBO.getRepeatField(), enumMap);
    }

    /**
     * 转换处理实体中特定字段:目前主要处理时间类型、枚举类型转换
     *
     * @param entry
     * @param filterFields:过滤字段
     * @param matchField:转意处理字段
     * @param matchField:特殊字符转义处理字段如果是原先就存在的删除 有问题
     * @param <T>
     * @return
     */
    public static <T> Map<String, Object> getFilterFields(T entry, List<String> filterFields, Map<String, String> matchField, List<String> repeatField, Map<String, Map<Object, String>> enumMap) {
        if (filterFields == null) {
            return new HashMap<>(1);
        }
        Map<String, Object> result = AnnotationUtils.convert(entry, filterFields, enumMap);
        if (matchField.size() > 0) {
            matchField.entrySet().stream().forEach(s -> {
                if (result.containsKey(s.getKey())) {
                    result.put(s.getValue(), result.get(s.getKey()));
                    //转义字段非存在字段删除
                    boolean keep = (CollUtil.isNotEmpty(repeatField) && repeatField.contains(s.getKey()));
                    if (!keep) {
                        result.remove(s.getKey());
                    }
                }
            });
        }
        return result;
    }

    /**
     * 字符串类型时间转换
     *
     * @param dateStr
     * @param dateFormat
     * @return
     */
    public static Date dateParse(CharSequence dateStr, String dateFormat) {
        return DateUtil.parse(dateStr, dateFormat);
    }

    /**
     * 对比
     *
     * @param source
     * @param compare
     * @return
     */
    public static boolean compare(Integer source, int compare) {
        log.info("compare data:" + source);
        if (source == null) {
            return false;
        }

        return source == compare;
    }

    /**
     * 天粒度处理==》过滤非工作日
     *
     * @param time
     * @param limit
     * @return
     */
    public static Date offsetDay(Date time, int limit, Map<String, List<String>> map) {
        Date dueDate = ProcessUtil.getDueStartDate(time);
        //没带节假日数据结算的dueDate可能是假日
        dueDate = getWorkDate(dueDate, map);
        for (int i = 0; i < limit; i++) {
            dueDate = DateUtil.offsetDay(dueDate, 1);
            dueDate = getWorkDate(dueDate, map);
        }
        return dueDate;
    }

    /**
     * 时间粒度处理==》过滤非工作日
     *
     * @param time
     * @param limit
     * @return
     */
    public static Date offsetHour(Date time, int limit, Map<String, List<String>> map) {
        Date dueDate = ProcessUtil.getDueStartDate(time);
        //没有过滤节假日的dueDate可能是假日
        dueDate = getWorkDate(dueDate, map);
        for (int i = 0; i < limit; i++) {
            dueDate = DateUtil.offsetHour(dueDate, 1);
            dueDate = getWorkDate(dueDate, map);
        }
        return dueDate;
    }

    /**
     * 获取工作日时间
     *
     * @param time
     * @param map
     * @return
     */
    private static Date getWorkDate(Date time, Map<String, List<String>> map) {
        if (areHoliday(time, map)) {
            time = DateUtil.offsetDay(time, 1);
            return getWorkDate(time, map);
        }
        return time;
    }

    /**
     * 判断是否节假日
     *
     * @param time
     * @param map
     * @return
     */
    private static boolean areHoliday(Date time, Map<String, List<String>> map) {
        String dayTime = DateUtil.format(time, DatePattern.NORM_DATE_PATTERN);
        if (map.get(HOLIDAY_TYPE).contains(dayTime)) {
            return true;
        }
        if (map.get(WORK_TYPE).contains(dayTime)) {
            return false;
        }
        Week week = DateUtil.dayOfWeekEnum(time);
        return (Week.SUNDAY.equals(week) || Week.SATURDAY.equals(week));
    }


    /**
     * 获取起始计算时间
     * 如果接到单子的时间为当天0点-8点59分59秒之间则从当天的9点开始计算24小时
     * 如果接到单子的时间为9点-17点59分59秒之间则直接开始计算24小时,
     * 如果接到单子的时间为18点-23点59分59秒之间则从第二天的9点开始计算24小时,
     *
     * @param startTime
     * @return
     */
    public static Date getDueStartDate(Date startTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int firstFlag = 9;
        int secondFlag = 18;
        if (hour < firstFlag) {
            calendar.set(Calendar.HOUR_OF_DAY, firstFlag);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            return calendar.getTime();
        }
        if (hour < secondFlag) {
            return calendar.getTime();
        }
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, day + 1);
        calendar.set(Calendar.HOUR_OF_DAY, firstFlag);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();

    }

    /**
     * 获取节点的执行类
     *
     * @param currentNode
     * @return
     */
    public static AbstractFlow getBaseProcess(Integer currentNode) {
        try {
            if (currentNode == -1) {
                return null;
            }
            if (Boolean.TRUE.equals(FlowNodeEnum.contains(currentNode))) {
                //modify 2022-11-23 SpringContextLoader.getBean  调度模块无法读取Bean对象
                return (AbstractFlow) SpringContextUtil.getBean("Process" + currentNode);
            }
            return null;

        } catch (Exception e) {
            log.error(currentNode + "find Process error:", e);
            return null;
        }
    }

    /**
     * 生成字段
     * nodeName 是react的关键字(定义的方法吧) 添加matchField存在做二次隐射
     *
     * @param fields
     * @return
     */
    public static List<ColumnBO> creatListField(List<MenuFieldPO> fields) {
        Map<String, ColumnBO> map = listFieldHandle(fields);
        createQoField(map);

        List<ColumnBO> result = map.values().stream().sorted(Comparator.comparing(ColumnBO::getOrderBy)).collect(Collectors.toList());
        return result;

    }

    /**
     * 合并from字段
     *
     * @param fields
     * @return
     */
    private static Map<String, ColumnBO> listFieldHandle(List<MenuFieldPO> fields) {
        Map<String, ColumnBO> map = new HashMap<>(10);
        if (fields == null || fields.isEmpty()) {
            return map;
        }
        List<MenuFieldPO> tableFields = Linq.of(fields).where(s -> FiledTypeEnum.TABLE_FIELD.getKey().equals(s.getFiledType())).toList();
        if (tableFields == null || tableFields.isEmpty()) {
            return map;
        }
        map = tableFields.stream().map(s -> s.toTableBo()).collect(Collectors.toMap(ColumnBO::getDataIndex, Function.identity()));
        List<MenuFieldPO> fromFields = Linq.of(fields).where(s -> FiledTypeEnum.FROM_FIELD.getKey().equals(s.getFiledType())).toList();
        for (MenuFieldPO po : fromFields) {
            ColumnBO bo;
            if (map.containsKey(po.getDataIndex())) {
                bo = map.get(po.getDataIndex());
                if (!bo.getTitle().equals(po.getTitle())) {
                    bo.setFormTitle(po.getTitle());
                }
                bo.setValueType(po.getValueType());
                bo.setHideInForm(false);
                bo.setOrder(-po.getOrder());
            } else {
                bo = po.toFormBo();
            }
            map.put(po.getDataIndex(), bo);
        }

        return map;
    }


    /**
     * map to bean,如果maps中不包含bean字段赋值不成功
     *
     * @param maps
     * @param clazz
     * @return
     */
    public static <T> T fillBeanWithMap(Map<String, Object> maps, Class<?> clazz) {
        try {
            if (CollUtil.isEmpty(maps)) {
                log.info("表单数据为空.");
                return null;
            }
            Field[] fields = clazz.getDeclaredFields();
            Field field = Linq.of(fields).where(s -> maps.containsKey(s.getName())).firstOrDefault();
            if (field == null) {
                return null;
            }
            //兼容处理实体类字段是String,前端传递的为非字符串对象类型
            //兼容处理空对象转换成{},[{}]字符串
            List<Field> handleField = Linq.of(fields).where(s -> s.getType().equals(String.class)).toList();
            handleField.forEach(s -> {
                if (maps.containsKey(s.getName())) {
                    if (maps.get(s.getName()) != null) {
                        Class<?> mapClazz = maps.get(s.getName()).getClass();
                        if (mapClazz.equals(HashMap.class) || mapClazz.equals(ArrayList.class)) {
                            String jsonStr = JSONUtil.toJsonStr(maps.get(s.getName()));
                            if (EMPTY_PATTERN.matcher(jsonStr).matches()) {
                                jsonStr = null;
                            }
                            maps.put(s.getName(), jsonStr);
                        }
                    }
                }
            });
            return (T) BeanUtil.fillBeanWithMap(maps, clazz.newInstance(), true);
        } catch (
                Exception ex) {
            log.error(clazz.getName() + " fillBeanWithMap error:", ex);
            return null;
        }

    }

    /**
     * 根据查询条件返回字段
     */
    private static void createQoField(Map<String, ColumnBO> map) {
        //个性赋值
        String regionId = LambdaUtils.getFieldName(CamsOrderQo::getRegionId);
        if (map.containsKey(regionId)) {
            if (ValueTypeEnum.CASCADER.getKey().equals(map.get(regionId).getValueType())) {
                map.get(regionId).setValueEnum(getRegionData());
            }
        }

        String omeId = LambdaUtils.getFieldName(CamsOrderQo::getOemId);
        if (map.containsKey(omeId)) {
            if (ValueTypeEnum.SELECT.getKey().equals(map.get(omeId).getValueType())) {
                map.get(omeId).setValueEnum(getOemData());
            }
        }

        String status = LambdaUtils.getFieldName(CamsOrderQo::getStatus);
        if (map.containsKey(status)) {
            if (ValueTypeEnum.SELECT.getKey().equals(map.get(status).getValueType())) {
                map.get(status).setValueEnum(getSelectBO(OrderStatus.values()));
            }
        }

        String overtimeType = LambdaUtils.getFieldName(CamsOrderQo::getOvertimeType);
        if (map.containsKey(overtimeType)) {
            if (ValueTypeEnum.SELECT.getKey().equals(map.get(overtimeType).getValueType())) {
                map.get(overtimeType).setValueEnum(getSelectBO(OverTimeType.values()));
            }
        }
    }

    /**
     * 车企品牌
     *
     * @return
     */
    private static List getOemData() {
        try {
            OemService oemService = (OemService) SpringContextUtil.getBean(OEM_SERVICE);
            OemBo condition = new OemBo();
            condition.setType(1);
            List<OemVo> oemVos = oemService.getList(condition);
            return SelectBO.createOem(oemVos);
        } catch (Exception ex) {
            log.error("find RegionService error:", ex);
            return new ArrayList(1);
        }
    }

    /**
     * 枚举
     *
     * @return
     */
    public static List getSelectBO(IOperator[] statuses) {
        List<SelectBO> list = new ArrayList<>(10);
        list.add(SelectBO.crateBase());
        for (IOperator status : statuses) {
            SelectBO bo = SelectBO.crate(status.getValue(), status.getType());
            list.add(bo);
        }
        return list;
    }

    /**
     * 生成区域TreeSelect数据
     *
     * @return
     */
    private static List getRegionData() {
        try {
            RegionService regionService = (RegionService) SpringContextUtil.getBean(REGION_SERVICE);
            List<RegionVo> regionVos = regionService.selectAll(1);
            return TreeSelectBO.createRegion(regionVos);
        } catch (Exception ex) {
            log.error("find RegionService error:", ex);
            return new ArrayList(1);
        }
    }

    /**
     * 获取指定时间区间的所有数据(包含日期和月份)
     *
     * @param dBegin
     * @param dEnd
     * @param rule   日历规则 如:Calendar.DAY_OF_MONTH
     * @return
     */
    public static List<Date> findDates(Date dBegin, Date dEnd, int rule) {
        List lDate = new ArrayList();
        if (dEnd.before(dBegin)) {
            return lDate;
        }
        lDate.add(dBegin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
            calBegin.add(rule, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

    /**
     * 天
     */
    private static Integer d = 24;
    /**
     * 分钟、秒
     */
    private static Integer m = 60;
    /**
     * 毫秒
     */
    private static Integer s = 1000;

    /**
     * 时间戳转换 天 小时 分钟
     *
     * @param time 时间戳
     */
    public static StringBuffer timeFormat(long time) {
        long day = 0;
        long hour = 0;
        long min = 0;
        StringBuffer sBuffer = new StringBuffer();
        if (time >= m * m * s) {

            if (time >= d * m * m * s) {
                day = time / (d * m * m * s);
                hour = time / (m * m * s) - day * d;
                sBuffer.append(day + "天");
            } else {
                hour = time / (m * m * s);
            }

            min = time - (hour * m * m * s) - (day * d * m * m * s);
            sBuffer.append(hour + "小时");

            min = min / (m * s);
            sBuffer.append(min + "分钟");
        } else {
            sBuffer.append(time / (m * s) + "分钟");
        }
        return sBuffer;
    }


    /**
     * 处理List集合数据进行分页
     *
     * @param currentPage
     * @param pageSize
     * @param list
     * @param <T>
     * @return
     */
    public static <T> List<T> getPageInfo(int currentPage, int pageSize, List<T> list) {
        List<T> newList = new ArrayList<>();
        if (list != null && list.size() > 0) {
            int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0);
            for (int i = 0; i < pageSize && i < list.size() - currIdx; i++) {
                newList.add(list.get(currIdx + i));
            }
        }
        return newList;
    }


    /**
     * 根据尾号判断是否存在操作权限
     *
     * @param id
     * @param endNumber
     * @return
     */
    public static boolean hasOrderRight(String id, String endNumber) {
        if (StrUtil.isEmpty(endNumber)) {
            return false;
        }
        List<String> items = Arrays.asList(endNumber.split(FlowConstants.COMMA));
        String find = Linq.of(items).where(s -> id.endsWith(s)).firstOrDefault();
        return StrUtil.isNotEmpty(find);
    }


}