
package com.tmerclub.cloud.flow.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tmerclub.cloud.api.order.dto.FormExcelDTO;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.order.vo.FormExcelParamVO;
import com.tmerclub.cloud.common.cache.constant.FlowCacheNames;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.i18n.I18nMessage;
import com.tmerclub.cloud.common.i18n.LanguageEnum;
import com.tmerclub.cloud.common.util.Arith;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.flow.constant.FlowDateTypeEnum;
import com.tmerclub.cloud.flow.constant.FormItemEnum;
import com.tmerclub.cloud.flow.dto.FormDTO;
import com.tmerclub.cloud.flow.mapper.FormMapper;
import com.tmerclub.cloud.flow.model.Form;
import com.tmerclub.cloud.flow.service.FormService;
import com.tmerclub.cloud.flow.vo.FormExcelVO;
import com.tmerclub.cloud.flow.vo.FormItemVO;
import com.tmerclub.cloud.flow.vo.FormVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据表格
 *
 * @author TRACK
 */
@Service
public class FormServiceImpl implements FormService {

    @Autowired
    private FormMapper formMapper;
    @DubboReference
    private OrderFeignClient orderFeignClient;

    @Override
    public PageVO<Form> page(PageDTO pageDTO, FormDTO formParam) {
        return PageUtil.doPage(pageDTO, () -> formMapper.list(formParam));
    }

    @Override
    public Form getByFormId(Long formId) {
        return formMapper.getByFormId(formId);
    }

    @Override
    public void save(Form form) {
        formMapper.save(form);
    }

    @Override
    public void update(Form form) {
        formMapper.update(form);
    }

    @Override
    public void deleteById(Long formId) {
        formMapper.deleteById(formId);
    }

    @Override
    @Cacheable(cacheNames = FlowCacheNames.FORM_ITEM_KEY, key = "#type + '-' + #lang")
    public List<FormItemVO> getFormItem(Integer type, Integer lang) {
        //type 1:平台端  2：商家端
        //获取所有的枚举对象
        FormItemEnum[] formItemEnums = FormItemEnum.allEnum();
        FormItemVO formItem;
        List<FormItemVO> formItemList = Lists.newArrayList();
        //把枚举的数据保存到集合中
        for (FormItemEnum formItemEnum : formItemEnums) {
            if (formItemEnum.getType() == 0 || Objects.equals(formItemEnum.getType(), type)) {
                formItem = new FormItemVO();
                formItem.setId(formItemEnum.value());
                formItem.setValue(Objects.equals(lang, LanguageEnum.LANGUAGE_ZH_CN.getLang()) ? formItemEnum.getName() : formItemEnum.getNameEn());
                formItemList.add(formItem);
            }
        }
        return formItemList;
    }

    @Override
    public FormExcelParamVO getExcelParam(Form form) {
        FormExcelParamVO formExcelParam = new FormExcelParamVO();
        formExcelParam.setShopId(form.getShopId());
        formExcelParam.setTimeType(form.getTimeType());
        setDefault(formExcelParam);
        //设置开始/结束时间
        setTime(form, formExcelParam);
        //获取报表列名称的集合
        Set<String> formItemNameSet = new HashSet<>(Constant.INITIAL_CAPACITY);
        //模板中选择的报表指标
        List<Integer> formItemIdList = Lists.newArrayList();
        formItemNameSet.add("date");
        String[] formItemIds = form.getFormItemIds().split(",");
        //根据报表模板中的指标数据，设置需要查询的参数和报表的列名
        for (String formItemId : formItemIds) {
            setColumn(formExcelParam, formItemNameSet, formItemId, formItemIdList);
        }
        formExcelParam.setFormItemNames(formItemNameSet);
        formExcelParam.setFormItemIdList(formItemIdList);
        return formExcelParam;
    }

    private void setDefault(FormExcelParamVO formExcelParam) {
        formExcelParam.setOrderAmount(Boolean.FALSE);
        formExcelParam.setOrderNums(Boolean.FALSE);
        formExcelParam.setProductNums(Boolean.FALSE);
        formExcelParam.setUserNums(Boolean.FALSE);
        formExcelParam.setSelfOperatedAmount(Boolean.FALSE);
        formExcelParam.setSelfOperatedOrderNums(Boolean.FALSE);
        formExcelParam.setSelfOperatedProductNums(Boolean.FALSE);
        formExcelParam.setSelfOperatedUserNums(Boolean.FALSE);
        formExcelParam.setPayAmount(Boolean.FALSE);
        formExcelParam.setPayOrderNums(Boolean.FALSE);
        formExcelParam.setPayProductNums(Boolean.FALSE);
        formExcelParam.setPayUserNums(Boolean.FALSE);
        formExcelParam.setRefundAmount(Boolean.FALSE);
        formExcelParam.setRefundOrderNums(Boolean.FALSE);
    }

    private void setColumn(FormExcelParamVO formExcelParam, Set<String> formItemNameSet, String idStr, List<Integer> formItemIdList) {
        int id = Integer.parseInt(idStr);
        formItemIdList.add(id);
        if (Objects.equals(FormItemEnum.CUSTOMER_UNIT_PRICE.value(), id)) {
            //客单价 (支付金额/支付人数)
            formExcelParam.setPayAmount(Boolean.TRUE);
            formExcelParam.setPayUserNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.CUSTOMER_UNIT_PRICE.getColumnStr());
        } else if (FormItemEnum.TOTAL_TRANSACTION_AMOUNT.value() == id) {
            formExcelParam.setPayAmount(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.TOTAL_TRANSACTION_AMOUNT.getColumnStr());
        } else if (FormItemEnum.SELF_OPERATED_CUSTOMER_UNIT_PRICE.value() == id) {
            //自营客单价 (自营金额/自营下单人数)
            formExcelParam.setSelfOperatedAmount(Boolean.TRUE);
            formExcelParam.setSelfOperatedUserNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.SELF_OPERATED_CUSTOMER_UNIT_PRICE.getColumnStr());
        } else if (FormItemEnum.SELF_OPERATED_AMOUNT.value() == id) {
            formExcelParam.setSelfOperatedAmount(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.SELF_OPERATED_AMOUNT.getColumnStr());
        } else if (FormItemEnum.SELF_OPERATED_ORDER_NUMS.value() == id) {
            formExcelParam.setSelfOperatedOrderNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.SELF_OPERATED_ORDER_NUMS.getColumnStr());
        } else if (FormItemEnum.SELF_OPERATED_PRODUCT_NUMS.value() == id) {
            formExcelParam.setSelfOperatedProductNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.SELF_OPERATED_PRODUCT_NUMS.getColumnStr());
        } else if (FormItemEnum.SELF_OPERATED_NUMS.value() == id) {
            formExcelParam.setSelfOperatedUserNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.SELF_OPERATED_NUMS.getColumnStr());
        } else if (FormItemEnum.ORDER_AMOUNT.value() == id) {
            formExcelParam.setOrderAmount(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.ORDER_AMOUNT.getColumnStr());
        } else if (FormItemEnum.USER_NUMS.value() == id) {
            formExcelParam.setUserNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.USER_NUMS.getColumnStr());
        } else if (FormItemEnum.ORDER_NUMS.value() == id) {
            formExcelParam.setOrderNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.ORDER_NUMS.getColumnStr());
        } else if (FormItemEnum.PRODUCT_NUMS.value() == id) {
            formExcelParam.setProductNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.PRODUCT_NUMS.getColumnStr());
        } else if (FormItemEnum.PAY_AMOUNT.value() == id) {
            formExcelParam.setPayAmount(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.PAY_AMOUNT.getColumnStr());
        } else if (FormItemEnum.PAY_USER_NUMS.value() == id) {
            formExcelParam.setPayUserNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.PAY_USER_NUMS.getColumnStr());
        } else if (FormItemEnum.PAY_ORDER_NUMS.value() == id) {
            formExcelParam.setPayOrderNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.PAY_ORDER_NUMS.getColumnStr());
        } else if (FormItemEnum.PAY_PRODUCT_NUMS.value() == id) {
            formExcelParam.setPayProductNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.PAY_PRODUCT_NUMS.getColumnStr());
        } else if (FormItemEnum.SUCCESS_REFUND_AMOUNT.value() == id) {
            formExcelParam.setRefundAmount(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.SUCCESS_REFUND_AMOUNT.getColumnStr());
        } else if (FormItemEnum.REFUND_ORDER_NUMS.value() == id) {
            formExcelParam.setRefundOrderNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.REFUND_ORDER_NUMS.getColumnStr());
        } else if (FormItemEnum.ORDER_TO_PAY_RATE.value() == id) {
            //下单-支付转化率 （支付订单数量/下单订单数量）
            formExcelParam.setPayOrderNums(Boolean.TRUE);
            formExcelParam.setOrderNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.ORDER_TO_PAY_RATE.getColumnStr());
        } else if (FormItemEnum.REFUND_RATE.value() == id) {
            //退款率（退款订单数量/订单数量）
            formExcelParam.setRefundOrderNums(Boolean.TRUE);
            formExcelParam.setPayOrderNums(Boolean.TRUE);
            formItemNameSet.add(FormItemEnum.REFUND_RATE.getColumnStr());
        }
    }

    private void setTime(Form form, FormExcelParamVO formExcelParam) {
        if (Objects.equals(form.getTimeFormat(), FlowDateTypeEnum.DAY.value())) {
            // 自定义时间查询，直接set开始和结束时间
            if (Objects.equals(form.getTimeType(), FlowDateTypeEnum.DAY.value())) {
                formExcelParam.setStartTime(DateUtil.beginOfDay(form.getStartTime()));
                formExcelParam.setEndTime(DateUtil.endOfDay(form.getEndTime()));
            } else if (Objects.equals(form.getTimeType(), FlowDateTypeEnum.WEEK.value())) {
                formExcelParam.setStartTime(DateUtil.beginOfWeek(form.getStartTime()));
                formExcelParam.setEndTime(DateUtil.endOfWeek(form.getEndTime()));
            } else {
                formExcelParam.setStartTime(DateUtil.beginOfMonth(form.getStartTime()));
                formExcelParam.setEndTime(DateUtil.endOfMonth(form.getEndTime()));
            }
        } else {
            //获取当天的开始时间
            Calendar calendar = DateUtil.beginOfDay(Calendar.getInstance());
            int timeRange = form.getTimeRange() - 1;
            //当天开始时间减去报表模板的时间范围，得到报表数据的开始时间
            if (Objects.equals(formExcelParam.getTimeType(), FlowDateTypeEnum.DAY.value())) {
                calendar.add(Calendar.DAY_OF_YEAR, -timeRange);
            } else if (Objects.equals(formExcelParam.getTimeType(), FlowDateTypeEnum.WEEK.value())) {
                //设置周一为每周的开始日期
                calendar.setFirstDayOfWeek(Calendar.MONDAY);
                calendar.add(Calendar.WEEK_OF_YEAR, -timeRange);
                //时间周期-周，开始时间为该周的周一
                calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            } else {
                calendar.add(Calendar.MONTH, -timeRange);
                //时间周期-月，开始时间为该月的1号
                calendar.set(Calendar.DAY_OF_MONTH, 1);
            }
            formExcelParam.setStartTime(calendar.getTime());
            //结束时间为当前时间
            formExcelParam.setEndTime(new Date());
        }
    }

    @Override
    public List<FormExcelVO> listExcel(Form form, FormExcelParamVO formExcelParamVO) {
        List<FormExcelDTO> mongoDataList = orderFeignClient.listFormExcelByParam(formExcelParamVO);

        mongoDataList.sort(Comparator.comparing(FormExcelDTO::getFormatTime));
        // 将数据转换为时间-数据格式
        Map<String, FormExcelDTO> formDateMap = mongoDataList.stream().collect(Collectors.toMap(FormExcelDTO::getFormatTime, formExcelDto -> formExcelDto));
        // 根据查询到的数据拼接为报表数据
        Date startTime = formExcelParamVO.getStartTime();
        List<FormExcelDTO> formExcelDtoList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        while (startTime.getTime() <= formExcelParamVO.getEndTime().getTime()) {
            Map<String, Object> dateInfo = this.getDateInfoByTimeAndType(startTime, formExcelParamVO.getTimeType());
            FormExcelDTO formExcelDTO;
            if (Objects.equals(formExcelParamVO.getTimeType(), FlowDateTypeEnum.DAY.value())) {
                formExcelDTO = formDateMap.get((String) dateInfo.get("dateTime"));
            } else {
                formExcelDTO = formDateMap.get((String) dateInfo.get("weekOrMonth"));
            }
            if (Objects.isNull(formExcelDTO)) {
                formExcelDTO = new FormExcelDTO();
                setDefaultInfo(formExcelDTO);
            }
            formExcelDTO.setFormatTime((String) dateInfo.get("dateTime"));
            formExcelDtoList.add(formExcelDTO);
            startTime = (Date) dateInfo.get("date");
        }
        if (CollUtil.isEmpty(formExcelDtoList)) {
            return new ArrayList<>(0);
        }
        List<FormExcelVO> excelList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Integer> formItemIdList = formExcelParamVO.getFormItemIdList();
        getExcelList(formExcelDtoList, excelList, formItemIdList);
        return excelList;
    }

    private void getExcelList(List<FormExcelDTO> formExcelDtoList, List<FormExcelVO> excelList, List<Integer> formItemIdList) {
        for (FormExcelDTO formExcelDTO : formExcelDtoList) {
            FormExcelVO formExcelVO = new FormExcelVO();
            formExcelVO.setDate(formExcelDTO.getFormatTime());
            long totalAmount = formExcelDTO.getPayAmount();
            if (Objects.nonNull(formExcelDTO.getPlatformAmount())) {
                totalAmount += formExcelDTO.getPlatformAmount();
            }
            if (formItemIdList.contains(FormItemEnum.TOTAL_TRANSACTION_AMOUNT.value())) {
                formExcelVO.setTotalTransactionAmount(String.valueOf(Arith.div(totalAmount, 100)));
            }
            if (formItemIdList.contains(FormItemEnum.CUSTOMER_UNIT_PRICE.value())) {
                //客单价
                double customerUnitPrice = Arith.div(Arith.div(totalAmount, formExcelDTO.getPayUserNums()), 100, 2);
                formExcelVO.setCustomerUnitPrice(String.valueOf(customerUnitPrice));
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_CUSTOMER_UNIT_PRICE.value())) {
                //自营客单价 (自营金额/自营下单人数)
                double selfCustomerUnitPrice = Arith.div(Arith.div(formExcelDTO.getSelfOperatedAmount(), formExcelDTO.getSelfOperatedUserNums()), 100, 2);
                formExcelVO.setSelfCustomerUnitPrice(String.valueOf(selfCustomerUnitPrice));
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_AMOUNT.value())) {
                formExcelVO.setSelfAmount(String.valueOf(Arith.div(formExcelDTO.getSelfOperatedAmount(), 100)));
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_ORDER_NUMS.value())) {
                formExcelVO.setSelfOrders(formExcelDTO.getSelfOperatedOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_PRODUCT_NUMS.value())) {
                formExcelVO.setSelfProducts(formExcelDTO.getSelfOperatedProductNums());
            }
            if (formItemIdList.contains(FormItemEnum.SELF_OPERATED_NUMS.value())) {
                formExcelVO.setSelfNums(formExcelDTO.getSelfOperatedUserNums());
            }
            if (formItemIdList.contains(FormItemEnum.ORDER_AMOUNT.value())) {
                formExcelVO.setOrderAmount(String.valueOf(Arith.div(formExcelDTO.getOrderAmount(), 100)));
            }
            if (formItemIdList.contains(FormItemEnum.USER_NUMS.value())) {
                formExcelVO.setPeopleOrderNums(formExcelDTO.getUserNums());
            }
            if (formItemIdList.contains(FormItemEnum.ORDER_NUMS.value())) {
                formExcelVO.setOrderNums(formExcelDTO.getOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.PRODUCT_NUMS.value())) {
                formExcelVO.setOrderProducts(formExcelDTO.getProductNums());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_AMOUNT.value())) {
                formExcelVO.setPaymentAmount(String.valueOf(Arith.div(formExcelDTO.getPayAmount(), 100)));
            }
            if (formItemIdList.contains(FormItemEnum.PAY_USER_NUMS.value())) {
                formExcelVO.setPayPeopleNums(formExcelDTO.getPayUserNums());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_ORDER_NUMS.value())) {
                formExcelVO.setPayOrderNums(formExcelDTO.getPayOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.PAY_PRODUCT_NUMS.value())) {
                formExcelVO.setPayProductNums(formExcelDTO.getPayProductNums());
            }
            if (formItemIdList.contains(FormItemEnum.SUCCESS_REFUND_AMOUNT.value())) {
                formExcelVO.setSuccessRefundAmount(String.valueOf(Arith.div(formExcelDTO.getRefundAmount(), 100)));
            }
            if (formItemIdList.contains(FormItemEnum.REFUND_ORDER_NUMS.value())) {
                formExcelVO.setRefundOrderNums(formExcelDTO.getRefundOrderNums());
            }
            if (formItemIdList.contains(FormItemEnum.ORDER_TO_PAY_RATE.value())) {
                //下单-支付转化率 （支付订单数量/下单订单数量）
                double orderPayRate;
                orderPayRate = Arith.div(Arith.mul(Arith.div(formExcelDTO.getPayOrderNums(), formExcelDTO.getOrderNums()), 100), 100, 2);
                formExcelVO.setOrderPaymentRate(String.valueOf(orderPayRate));
            }
            if (formItemIdList.contains(FormItemEnum.REFUND_RATE.value())) {
                //退款率
                double refundRate = Arith.div((long) Arith.mul(Arith.div(formExcelDTO.getRefundOrderNums(), formExcelDTO.getPayOrderNums()), 100), 100, 2);
                formExcelVO.setRefundRate(String.valueOf(refundRate));
            }
            excelList.add(formExcelVO);
        }
    }

    private Map<String, Object> getDateInfoByTimeAndType(Date time, Integer type) {
        //date ： 下次循环的开始时间
        //day/weekOrMonth ：用于map对象获取数据时，所需的key的值
        //dateTime ： 时间格式化后，在报表中显示的时间数据（报表第一列的时间字符串）
        Map<String, Object> map = Maps.newHashMap();
        if (Objects.equals(type, FlowDateTypeEnum.DAY.value())) {
            //时间周期：日
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            map.put("day", time);
            map.put("date", DateUtil.offset(time, DateField.DAY_OF_MONTH, 1));
            map.put("dateTime", simpleDateFormat.format(time));
        } else if (Objects.equals(type, FlowDateTypeEnum.WEEK.value())) {
            //时间周期：周
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            //设置周的开始时间为周一
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.setTime(time);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            // 获取该周，周一零时的时间（周的开始时间）
            Date mondayTime = calendar.getTime();
            //把开始时间由该周一切换成下周一，为下次循环的周一时间
            map.put("date", DateUtil.offset(mondayTime, DateField.DAY_OF_MONTH, 7));
            String dateTime;
            if (time.getTime() > mondayTime.getTime()) {
                dateTime = simpleDateFormat.format(time);
            } else {
                dateTime = simpleDateFormat.format(mondayTime);
            }
            //设置周的结束时间为周日
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
            //周的开始时间与结束时间拼接
            dateTime = dateTime + "~" + simpleDateFormat.format(calendar.getTime());
            map.put("weekOrMonth", calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.WEEK_OF_YEAR) <= 10 ? ("0" + (calendar.get(Calendar.WEEK_OF_YEAR) - 1)) : (calendar.get(Calendar.WEEK_OF_YEAR) - 1)));
            map.put("dateTime", dateTime);
        } else if (Objects.equals(type, FlowDateTypeEnum.MONTH.value())) {
            //时间周期：月
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(time);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            String date = simpleDateFormat.format(calendar.getTime());
            calendar.add(Calendar.MONTH, 1);
            map.put("date", calendar.getTime());
            map.put("weekOrMonth", date);
            map.put("dateTime", date);
        }
        return map;
    }

    private void setDefaultInfo(FormExcelDTO info) {
        if (Objects.isNull(info.getOrderAmount())) {
            info.setOrderAmount(0L);
        }
        if (Objects.isNull(info.getOrderNums())) {
            info.setOrderNums(0);
        }
        if (Objects.isNull(info.getProductNums())) {
            info.setProductNums(0);
        }
        if (Objects.isNull(info.getUserNums())) {
            info.setUserNums(0);
        }
        if (Objects.isNull(info.getSelfOperatedAmount())) {
            info.setSelfOperatedAmount(0L);
        }
        if (Objects.isNull(info.getSelfOperatedOrderNums())) {
            info.setSelfOperatedOrderNums(0);
        }
        if (Objects.isNull(info.getSelfOperatedProductNums())) {
            info.setSelfOperatedProductNums(0);
        }
        if (Objects.isNull(info.getSelfOperatedUserNums())) {
            info.setSelfOperatedUserNums(0);
        }
        if (Objects.isNull(info.getPayAmount())) {
            info.setPayAmount(0L);
        }
        if (Objects.isNull(info.getPayOrderNums())) {
            info.setPayOrderNums(0);
        }
        if (Objects.isNull(info.getPayProductNums())) {
            info.setPayProductNums(0);
        }
        if (Objects.isNull(info.getPayUserNums())) {
            info.setPayUserNums(0);
        }
        if (Objects.isNull(info.getRefundAmount())) {
            info.setRefundAmount(0L);
        }
        if (Objects.isNull(info.getRefundOrderNums())) {
            info.setRefundOrderNums(0);
        }
    }

    @Override
    @Cacheable(cacheNames = FlowCacheNames.FORM_RECOMMEND_LIST_KEY, key = "'recommendFormList'")
    public List<FormVO> getRecommendFormList() {
        FormDTO formDTO = new FormDTO();
        formDTO.setRecommendForm(Boolean.TRUE);
        List<Form> list = formMapper.list(formDTO);
        List<FormVO> formList = BeanUtil.mapAsList(list, FormVO.class);
        FormServiceImpl formService = (FormServiceImpl) AopContext.currentProxy();
        List<FormItemVO> formItem = formService.getFormItem(2, I18nMessage.getLang());
        Map<Integer, FormItemVO> formItemMap = formItem.stream().collect(Collectors.toMap(FormItemVO::getId, formItemNew -> formItemNew));
        List<FormItemVO> formItemList;
        for (FormVO form : formList) {
            formItemList = Lists.newArrayList();
            for (String id : form.getFormItemIds().split(Constant.COMMA)) {
                formItemList.add(formItemMap.get(Integer.valueOf(id)));
            }
            form.setFormItemList(formItemList);
        }
        return formList;
    }

    @Override
    public PageVO<Form> getRecommendFormPage(PageDTO page, FormDTO form) {
        form.setRecommendForm(Boolean.TRUE);
        return PageUtil.doPage(page, () -> formMapper.list(form));
    }

    @Override
    @CacheEvict(cacheNames = FlowCacheNames.FORM_RECOMMEND_LIST_KEY, key = "'recommendFormList'")
    public void removeCache() {
    }
}
