package com.ruoyi.app.pay;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.app.order.ZaloPayCommonService;
import com.ruoyi.app.pay.dto.QsBillingDto;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.system.domain.vo.ShBillingDto;
import com.ruoyi.app.utils.DateUtil;
import com.ruoyi.app.utils.zaloPay.ZaloPay;
import com.ruoyi.app.utils.zaloPay.ZaloPayConfig;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.BillDTO;
import com.ruoyi.system.mapper.UserBillingMapper;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * BillingController
 *
 * @author ruoyi
 * @date 2023-09-06
 */
@RestController
@RequestMapping("/Billing/billing")
public class UserBillingController extends BaseController {
    @Autowired
    private IUserBillingService userBillingService;
    @Autowired
    private UserBillingMapper userBillingMapper;
    @Autowired
    private IPosOrderService posOrderService;
    @Autowired
    private IInfoUserService infoUserService;
    @Autowired
    private ZaloPayCommonService zaloPayCommonService;
    @Autowired
    private ZaloPayConfig zaloPayConfig;
    @Autowired
    private ZaloPay zaloPay;
    @Autowired
    private IPosOrderRatingService posOrderRatingService;
    @Autowired
    private ICommissionRatesService commissionRatesService;
    @Autowired
    private IPosStoreService posStoreService;

    /**
     * 商家端账单列表
     */
    @Anonymous
    @Auth
    @GetMapping("/storeBillingList")
    public AjaxResult storeBillingList(@RequestHeader String token,
                                       @RequestParam Integer pageNum,
                                       @RequestParam Integer pageSize,
                                       @RequestParam(required = false) Long mdId,
                                       @RequestParam(required = false) String type,
                                       @RequestParam(required = false) String startDate,
                                       @RequestParam(required = false) String endDate) {
        JwtUtil jwtUtil = new JwtUtil();
        Long userId = Long.valueOf(jwtUtil.getusid(token));
        InfoUser user = infoUserService.getById(userId);
        if (user == null) {
            return error(MessageUtils.message("no.user.not.exist"));
        }

        QueryWrapper<UserBilling> wrapper = new QueryWrapper<>();
        String userType = user.getUserType();

        if ("1".equals(userType) || "3".equals(userType)) {
            // 商家/夜市用户：查自己名下所有门店的账单
            wrapper.eq("user_id", userId);
            if (mdId != null) {
                wrapper.eq("md_id", mdId);
            }
        } else if ("4".equals(userType)) {
            // 摊位主/门店：仅查自己关联门店的账单
            Long storeId = user.getStoreId();
            if (storeId == null) {
                return error("未关联门店");
            }
            wrapper.eq("md_id", storeId);
        } else {
            return error("无权限访问");
        }

        if (type != null && !type.isEmpty()) {
            wrapper.eq("type", type);
        }
        if (startDate != null && !startDate.isEmpty()) {
            wrapper.apply("date_format(cretim,'%Y-%m-%d %H:%i:%s') >= date_format('" + startDate + " 00:00:00','%Y-%m-%d %H:%i:%s')");
        }
        if (endDate != null && !endDate.isEmpty()) {
            wrapper.apply("date_format(cretim,'%Y-%m-%d %H:%i:%s') <= date_format('" + endDate + " 23:59:59','%Y-%m-%d %H:%i:%s')");
        }
        wrapper.orderByDesc("id");

        Page<UserBilling> page = new Page<>(pageNum, pageSize);
        IPage<UserBilling> pageResult = userBillingService.page(page, wrapper);

        // 填充门店名称
        List<UserBilling> records = pageResult.getRecords();
        fillStoreName(records);

        JSONObject org = new JSONObject();
        org.put("list", records);
        org.put("total", pageResult.getTotal());
        org.put("pageNum", pageResult.getCurrent());
        org.put("pageSize", pageResult.getSize());
        return success(MessageUtils.message("no.success"), org);
    }

    /**
     * 商家端账单汇总
     */
    @Anonymous
    @Auth
    @GetMapping("/storeBillingSummary")
    public AjaxResult storeBillingSummary(@RequestHeader String token,
                                           @RequestParam(required = false) Long mdId,
                                           @RequestParam(required = false) String type,
                                           @RequestParam(required = false) String startDate,
                                           @RequestParam(required = false) String endDate) {
        JwtUtil jwtUtil = new JwtUtil();
        Long userId = Long.valueOf(jwtUtil.getusid(token));
        InfoUser user = infoUserService.getById(userId);
        if (user == null) {
            return error(MessageUtils.message("no.user.not.exist"));
        }

        QueryWrapper<UserBilling> wrapper = new QueryWrapper<>();
        String userType = user.getUserType();

        if ("1".equals(userType) || "3".equals(userType)) {
            wrapper.eq("user_id", userId);
            if (mdId != null) {
                wrapper.eq("md_id", mdId);
            }
        } else if ("4".equals(userType)) {
            Long storeId = user.getStoreId();
            if (storeId == null) {
                return error("未关联门店");
            }
            wrapper.eq("md_id", storeId);
        } else {
            return error("无权限访问");
        }

        if (type != null && !type.isEmpty()) {
            wrapper.eq("type", type);
        }
        if (startDate != null && !startDate.isEmpty()) {
            wrapper.apply("date_format(cretim,'%Y-%m-%d %H:%i:%s') >= date_format('" + startDate + " 00:00:00','%Y-%m-%d %H:%i:%s')");
        }
        if (endDate != null && !endDate.isEmpty()) {
            wrapper.apply("date_format(cretim,'%Y-%m-%d %H:%i:%s') <= date_format('" + endDate + " 23:59:59','%Y-%m-%d %H:%i:%s')");
        }

        wrapper.select(
            "IFNULL(SUM(amount),0) as amount",
            "IFNULL(SUM(divvy),0) as divvy"
        );

        UserBilling summary = userBillingService.getOne(wrapper);
        double totalAmount = summary != null && summary.getAmount() != null ? summary.getAmount() : 0;
        double totalDivvy = summary != null && summary.getDivvy() != null ? summary.getDivvy() : 0;
        double netIncome = totalAmount - totalDivvy;

        JSONObject org = new JSONObject();
        org.put("totalAmount", totalAmount);
        org.put("totalDivvy", totalDivvy);
        org.put("netIncome", netIncome);
        return success(MessageUtils.message("no.success"), org);
    }

    /**
     * 填充门店名称
     */
    private void fillStoreName(List<UserBilling> list) {
        if (list == null || list.isEmpty()) return;
        List<Integer> mdIds = list.stream()
                .map(UserBilling::getMdId)
                .filter(id -> id != null)
                .map(Long::intValue)
                .distinct()
                .collect(Collectors.toList());
        if (mdIds.isEmpty()) return;
        List<PosStore> stores = posStoreService.listByIds(mdIds);
        list.forEach(billing -> {
            if (billing.getMdId() != null) {
                stores.stream()
                        .filter(s -> Long.valueOf(s.getId()).equals(billing.getMdId()))
                        .findFirst()
                        .ifPresent(s -> billing.setMdName(s.getPosName()));
            }
        });
    }

    /**
     * 商家日账单数据
     *
     * @param token
     * @param page
     * @param size
     * @param riqi
     * @return
     */
    @Anonymous
    @Auth
    @GetMapping("/getzddaylist")
    public AjaxResult getzddaylist(@RequestHeader String token,
                                   @RequestParam Long page,
                                   @RequestParam Long size,
                                   @RequestParam String riqi,
                                   @RequestParam(required = false) Boolean isCancel,
                                   @RequestParam(required = false) Long mdId
    ) {
        JwtUtil jwtUtil = new JwtUtil();
        Long id = Long.valueOf(jwtUtil.getusid(token));
        InfoUser user = infoUserService.getById(id);
        //获取日的取消订单列表
        if (isCancel != null && isCancel) {
            return getDayCancleOrderList(page, size, riqi, user);
        }
        List<UserBilling> list = userBillingMapper.getdaylist(id, riqi, mdId, (page - 1) * size, size);
        setYhInfo(list);
        BillDTO sum = userBillingMapper.getdaysum(id, riqi, mdId);
        JSONObject org = new JSONObject();
        org.put("shul", sum.getSul());
        org.put("sum", sum.getShouru());
        org.put("commission", sum.getCommission());
        org.put("tax", sum.getTax());
        org.put("behalfAmount", sum.getBehalfAmount());
        LambdaQueryWrapper<PosOrder> queryWrapper = new LambdaQueryWrapper<PosOrder>()
                .in(PosOrder::getState, new ArrayList<Long>(Arrays.asList(9L, 10L)))
                .apply("(sh_id=" + id + " or qs_id=" + id + ") and date_format (cretim,'%Y-%m-%d %H:%i:%s') >= date_format ('" + riqi + " 00:00:00','%Y-%m-%d %H:%i:%s') and date_format (cretim,'%Y-%m-%d %H:%i:%s') <= date_format ('" + riqi + " 23:59:59','%Y-%m-%d %H:%i:%s')");
        // 取消总数 ，作废、客服介入的数据
        long cancleCount = posOrderService.count(queryWrapper);
        org.put("cancelCount", cancleCount);

        if ("2".equals(user.getUserType())) {
            setQsList(list, org);
        } else {
            ShBillingDto shBillingDto = userBillingMapper.getShDaysum(id, riqi, mdId);
            org.put("foodAmount", shBillingDto.getFoodAmount());
            org.put("shYh", shBillingDto.getShYh());
            setShList(list, org, user);
        }
        return success(MessageUtils.message("no.success"), org);
    }

    //按日获取取消订单列表
    public AjaxResult getDayCancleOrderList(Long page, Long size, String riqi, InfoUser user) {
        JSONObject org = new JSONObject();
        Page<PosOrder> pageInput = new Page<>(page, size);
        LambdaQueryWrapper<PosOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(PosOrder::getState, new ArrayList<Long>(Arrays.asList(9L, 10L)));
        queryWrapper.apply("(sh_id=" + user.getUserId() + " or qs_id=" + user.getUserId() + ") and date_format (cretim,'%Y-%m-%d %H:%i:%s') >= date_format ('" + riqi + " 00:00:00','%Y-%m-%d %H:%i:%s') and date_format (cretim,'%Y-%m-%d %H:%i:%s') <= date_format ('" + riqi + " 23:59:59','%Y-%m-%d %H:%i:%s')");
        queryWrapper.orderByDesc(PosOrder::getCretim);
        IPage<PosOrder> datas = posOrderService.page(pageInput, queryWrapper);
        org.put("list", datas.getRecords());
        return success(MessageUtils.message("no.success"), org);
    }

    /**
     * 商家周账单数据
     *
     * @param token
     * @param page
     * @param size
     * @param riqi
     * @return
     */
    @Anonymous
    @Auth
    @GetMapping("/getzdmeeklist")
    public AjaxResult getzdmeeklist(@RequestHeader String token,
                                    @RequestParam Long page,
                                    @RequestParam Long size,
                                    @RequestParam String riqi,
                                    @RequestParam(required = false) Boolean isCancel,
                                    @RequestParam(required = false) Long mdId) {
        JwtUtil jwtUtil = new JwtUtil();
        Long id = Long.valueOf(jwtUtil.getusid(token));
        InfoUser user = infoUserService.getById(id);
        //获取日的取消订单列表
        if (isCancel != null && isCancel) {
            return getWeekCancleOrderList(page, size, riqi, user);
        }
        List<UserBilling> list = userBillingMapper.getmeeklist(id, riqi, mdId, (page - 1) * size, size);
        setYhInfo(list);
        BillDTO sum = userBillingMapper.getmeeksum(id, riqi, mdId);
        JSONObject org = new JSONObject();
        org.put("shul", sum.getSul()); //数量
        org.put("sum", sum.getShouru());
        org.put("commission", sum.getCommission());
        org.put("tax", sum.getTax());
        org.put("behalfAmount", sum.getBehalfAmount());
        LambdaQueryWrapper<PosOrder> queryWrapper = new LambdaQueryWrapper<PosOrder>()
                .in(PosOrder::getState, new ArrayList<Long>(Arrays.asList(9L, 10L)))
                .apply("(sh_id=" + id + " or qs_id=" + id + ") and WEEK(cretim) = WEEK(" + riqi + ") and  YEAR(cretim) = YEAR(" + riqi + ")");
        // 取消总数 ，作废、客服介入的数据
        long cancleCount = posOrderService.count(queryWrapper);
        org.put("cancelCount", cancleCount);
        if ("2".equals(user.getUserType())) {
            setQsList(list, org);
        } else {
            ShBillingDto shBillingDto = userBillingMapper.getShMeeksum(id, riqi, mdId);
            org.put("foodAmount", shBillingDto.getFoodAmount());
            org.put("shYh", shBillingDto.getShYh());
            setShList(list, org, user);

        }
        return success(MessageUtils.message("no.success"), org);
    }

    //按周获取取消订单列表
    public AjaxResult getWeekCancleOrderList(Long page, Long size, String riqi, InfoUser user) {
        JSONObject org = new JSONObject();
        Page<PosOrder> pageInput = new Page<>(page, size);
        LambdaQueryWrapper<PosOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(PosOrder::getState, new ArrayList<Long>(Arrays.asList(9L, 10L)));
        queryWrapper.apply("(sh_id=" + user.getUserId() + " or qs_id=" + user.getUserId() + ") and WEEK(cretim) = WEEK(" + riqi + ") and  YEAR(cretim) = YEAR(" + riqi + ")");
        queryWrapper.orderByDesc(PosOrder::getCretim);
        IPage<PosOrder> datas = posOrderService.page(pageInput, queryWrapper);
        org.put("list", datas.getRecords());
        return success(MessageUtils.message("no.success"), org);
    }

    //返回商户账单信息
    private void setShList(List<UserBilling> list, JSONObject org, InfoUser user) {
        List<ShBillingDto> result = new ArrayList<>();
        if (!list.isEmpty()) {
            List<String> ddIds = list.stream().map(x -> x.getDdId()).collect(Collectors.toList());
            List<PosOrder> orders = posOrderService.list(new LambdaQueryWrapper<PosOrder>().in(PosOrder::getDdId, ddIds));
            List<PosOrderRating> ratings = posOrderRatingService.list(new LambdaQueryWrapper<PosOrderRating>().in(PosOrderRating::getDdId, ddIds));
            list.forEach(x -> {
                ShBillingDto dto = Convert.convert(ShBillingDto.class, x);
                //货到付款的订单金额
                orders.stream().filter(o -> o.getDdId().equals(x.getDdId())).findFirst().ifPresent(o -> {
                    dto.setFoodAmount(o.getFoodAmount());
                    int shYh = (o.getMdDiscountAmount() == null ? 0 : o.getMdDiscountAmount()) + (o.getMdSalesReduction() == null ? 0 : o.getMdSalesReduction());
                    dto.setShYh((double) shYh);
                });
                ratings.stream().filter(r -> r.getDdId().equals(x.getDdId())).findFirst().ifPresent(r -> dto.setShStarts(r.getQsStars()));
                result.add(dto);
            });
        }
        double bl = user.getCommission() == null ? 0.00 : user.getCommission();
        bl = commissionRatesService.getShCommissionRate(bl, user.getUserId());
        org.put("commissionRate", bl);
        org.put("list", result);
    }

    //骑手返回骑手账单信息
    private void setQsList(List<UserBilling> list, JSONObject org) {
        List<QsBillingDto> result = new ArrayList<>();
        if (!list.isEmpty()) {
            List<String> ddIds = list.stream().map(x -> x.getDdId()).collect(Collectors.toList());
            List<PosOrder> orders = posOrderService.list(new LambdaQueryWrapper<PosOrder>().in(PosOrder::getDdId, ddIds));
            List<PosOrderRating> ratings = posOrderRatingService.list(new LambdaQueryWrapper<PosOrderRating>().in(PosOrderRating::getDdId, ddIds));
            list.forEach(x -> {
                QsBillingDto dto = Convert.convert(QsBillingDto.class, x);
                //货到付款的订单金额
                orders.stream().filter(o -> o.getDdId().equals(x.getDdId())).findFirst().ifPresent(o -> {
                    if ("1".equals(o.getCollectPayment())) {
                        dto.setOrderAmount(o.getAmount());
                    }
                    dto.setFreight(o.getFreight());
                    dto.setJvli(o.getJvli());
                });
                ratings.stream().filter(r -> r.getDdId().equals(x.getDdId())).findFirst().ifPresent(r -> dto.setQsStarts(r.getQsStars()));
                result.add(dto);
            });
        }
        String taxRate="0";
        List<SysDictData> taxBlData = DictUtils.getDictCache("sys_qs_freight_bl");

        if (taxBlData != null && taxBlData.get(0) != null) {
            taxRate = taxBlData.get(0).getDictValue();
        }
        org.put("taxRate", taxRate);
        org.put("list", result);
    }


    private void setYhInfo(List<UserBilling> list) {
        if (!list.isEmpty()) {
            List<String> orderIds = list.stream().map(UserBilling::getDdId).collect(Collectors.toList());
            LambdaQueryWrapper<PosOrder> query = new LambdaQueryWrapper<>();
            query.in(PosOrder::getDdId, orderIds);
            List<PosOrder> orders = posOrderService.list(query);
            list.forEach(billing -> {
                orders.stream().filter(o -> o.getDdId().toString().equals(billing.getDdId())).findFirst().ifPresent(o -> {
                    billing.setActivity(o.getActivity());
                    billing.setMdActivity(o.getMdActivity());
                    billing.setMdActivity(o.getMdActivity());
                    billing.setYhId(o.getYhId());
                    billing.setYhName(o.getYhName());
                    billing.setDiscountAmount(o.getDiscountAmount());
                    billing.setMdYhId(o.getMdYhId());
                    billing.setMdYhName(o.getMdYhName());
                    billing.setMdDiscountAmount(o.getMdDiscountAmount());
                    billing.setSalesName(o.getSalesName());
                    billing.setMdSalesName(o.getMdSalesName());
                    billing.setSalesReduction(o.getSalesReduction());
                    billing.setMdSalesReduction(o.getMdSalesReduction());
                    billing.setPoints(o.getPoints());
                    billing.setPointsReduction(o.getPointsReduction());
                });
            });
        }
    }

    /**
     * 商家月账单数据
     *
     * @param token
     * @param page
     * @param size
     * @param riqi
     * @return
     */
    @Anonymous
    @Auth
    @GetMapping("/getzdmatlist")
    public AjaxResult getzdmatlist(@RequestHeader String token,
                                   @RequestParam Long page,
                                   @RequestParam Long size,
                                   @RequestParam String riqi,
                                   @RequestParam(required = false) Boolean isCancel,
                                   @RequestParam(required = false) Long mdId) {
        JwtUtil jwtUtil = new JwtUtil();
        Long id = Long.valueOf(jwtUtil.getusid(token));
        InfoUser user = infoUserService.getById(id);
        if (isCancel != null && isCancel) {
            return getMonthCancleOrderList(page, size, riqi, user);
        }
        List<UserBilling> list = userBillingMapper.getmatlist(id, riqi, mdId, (page - 1) * size, size);
        setYhInfo(list);
        BillDTO sum = userBillingMapper.getmatsum(id, riqi, mdId);
        JSONObject org = new JSONObject();
        org.put("shul", sum.getSul());
        org.put("sum", sum.getShouru());
        org.put("commission", sum.getCommission());
        org.put("tax", sum.getTax());
        org.put("behalfAmount", sum.getBehalfAmount());
        LambdaQueryWrapper<PosOrder> queryWrapper = new LambdaQueryWrapper<PosOrder>()
                .in(PosOrder::getState, new ArrayList<Long>(Arrays.asList(9L, 10L)))
                .apply("(sh_id=" + id + " or qs_id=" + id + ") and DATE_FORMAT(cretim, '%Y-%m') = " + riqi);
        // 取消总数 ，作废、客服介入的数据
        long cancleCount = posOrderService.count(queryWrapper);
        org.put("cancelCount", cancleCount);
        if ("2".equals(user.getUserType())) {
            setQsList(list, org);
        } else {
            ShBillingDto shBillingDto = userBillingMapper.getshMonthsum(id, riqi, mdId);
            org.put("foodAmount", shBillingDto.getFoodAmount());
            org.put("shYh", shBillingDto.getShYh());
            setShList(list, org, user);
        }
        return success(MessageUtils.message("no.success"), org);
    }

    //按周获取取消订单列表
    public AjaxResult getMonthCancleOrderList(Long page, Long size, String riqi, InfoUser user) {
        JSONObject org = new JSONObject();
        Page<PosOrder> pageInput = new Page<>(page, size);
        LambdaQueryWrapper<PosOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(PosOrder::getState, new ArrayList<Long>(Arrays.asList(9L, 10L)));
        queryWrapper.apply("(sh_id=" + user.getUserId() + " or qs_id=" + user.getUserId() + ") and DATE_FORMAT(cretim, '%Y-%m') = " + riqi);
        queryWrapper.orderByDesc(PosOrder::getCretim);
        IPage<PosOrder> datas = posOrderService.page(pageInput, queryWrapper);
        org.put("list", datas.getRecords());
        return success(MessageUtils.message("no.success"), org);
    }



    //查询用户账户及余额
    @Anonymous
    @Auth
    @GetMapping("/getUsbalance")
    public AjaxResult getUsbalance(@RequestHeader String token,
                                   @RequestParam Integer page,
                                   @RequestParam Integer size,
                                   @RequestParam boolean sort,
                                   @RequestParam(defaultValue = "") String type) {
        Long userId = Long.valueOf(new JwtUtil().getusid(token));
        BigDecimal sum = userBillingService.getUserBalance(userId);

        QueryWrapper<UserBilling> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        if (!type.isEmpty()) {
            wrapper.eq("type", type);
            userBillingMapper.gettypesum(userId, Long.valueOf(type));
        }
        wrapper.orderBy(true, sort, "cretim");

        IPage<UserBilling> mmlist = userBillingService.page(new Page<>(page, size), wrapper);
        JSONArray arr = buildBillingList(mmlist.getRecords());

        JSONObject org = new JSONObject();
        org.put("sum", sum);
        org.put("list", arr);
        return success(MessageUtils.message("no.success"), org);
    }

    private JSONArray buildBillingList(List<UserBilling> list) {
        DateUtil dateUtil = new DateUtil();
        JSONArray arr = new JSONArray();
        for (UserBilling item : list) {
            JSONObject ject = new JSONObject();
            ject.put("id", item.getId());
            ject.put("user", infoUserService.getById(item.getUserId()));
            ject.put("type", item.getType());
            PosOrder order = posOrderService.getById(item.getDdId());
            ject.put("ddId", order == null ? item.getDdId() : order.getDdId());
            ject.put("amount", item.getAmount());
            ject.put("divvy", item.getDivvy());
            ject.put("state", item.getState());
            ject.put("mdId", item.getMdId());
            ject.put("illustrate", item.getIllustrate());
            ject.put("paymentMethod", item.getPaymentMethod());
            ject.put("accountNumber", item.getAccountNumber());
            ject.put("url", item.getUrl());
            ject.put("cretim", dateUtil.setDate(item.getCretim()));
            arr.add(ject);
        }
        return arr;
    }



    /**
     * 查询Billing列表
     */
    @PreAuthorize("@ss.hasPermi('Billing:billing:list')")
    @GetMapping("/list")
    public TableDataInfo list(UserBilling userBilling) {
        startPage();
        String[] dr = userBilling.getDateRange();
        if (dr != null && dr.length == 2) {
            userBilling.setCretimStart(dr[0]);
            userBilling.setCretimEnd(dr[1]);
        }
        List<UserBilling> list = userBillingService.selectUserBillingList(userBilling);
        if (!list.isEmpty()) {
            List<Long> userIds = list.stream().map(UserBilling::getUserId).collect(Collectors.toList());
            List<InfoUser> users = infoUserService.list(new LambdaQueryWrapper<InfoUser>().in(InfoUser::getUserId, userIds));
            list.forEach(x -> {
                users.stream().filter(u -> u.getUserId().equals(x.getUserId())).findFirst().ifPresent(y -> {
                    x.setUserName(y.getUserName());
                    if ("0".equals(y.getUserType())) {
                        x.setUserName(y.getPhone());
                    }
                    x.setUserType(y.getUserType());
                });
            });
        }
        return getDataTable(list);
    }

    /**
     * 导出Billing列表
     */
    @PreAuthorize("@ss.hasPermi('Billing:billing:export')")
    @Log(title = "Billing", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, UserBilling userBilling) {
        String[] dr = userBilling.getDateRange();
        if (dr != null && dr.length == 2) {
            userBilling.setCretimStart(dr[0]);
            userBilling.setCretimEnd(dr[1]);
        }
        List<UserBilling> list = userBillingService.selectUserBillingList(userBilling);
        if (!list.isEmpty()) {
            List<Long> userIds = list.stream().map(UserBilling::getUserId).collect(Collectors.toList());
            List<InfoUser> users = infoUserService.list(new LambdaQueryWrapper<InfoUser>().in(InfoUser::getUserId, userIds));
            list.forEach(x -> {
                users.stream().filter(u -> u.getUserId().equals(x.getUserId())).findFirst().ifPresent(y -> {
                    x.setUserName(y.getUserName());
                    if ("0".equals(y.getUserType())) {
                        x.setUserName(y.getPhone());
                    }
                    x.setUserType(y.getUserType());
                });
            });
        }
        ExcelUtil<UserBilling> util = new ExcelUtil<UserBilling>(UserBilling.class);
        util.exportExcel(response, list, MessageUtils.message("no.export.excel.billing"));
    }

    /**
     * 获取Billing详细信息
     */
    @PreAuthorize("@ss.hasPermi('Billing:billing:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        UserBilling result = userBillingService.selectUserBillingById(id);
        if (result != null) {
            InfoUser user = infoUserService.getById(result.getUserId());
            result.setUserName(user.getUserName());
            if ("0".equals(user.getUserType())) {
                result.setUserName(user.getPhone());
            }
            result.setUserType(user.getUserType());
        }
        return success(result);
    }

    /**
     * 新增Billing
     */
    @PreAuthorize("@ss.hasPermi('Billing:billing:add')")
    @Log(title = "Billing", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody UserBilling userBilling) {
        return toAjax(userBillingService.insertUserBilling(userBilling));
    }

    /**
     * 修改Billing
     */
    @PreAuthorize("@ss.hasPermi('Billing:billing:edit')")
    @Log(title = "Billing", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody UserBilling userBilling) {
        return toAjax(userBillingService.updateUserBilling(userBilling));
    }

    /**
     * 删除Billing
     */
    @PreAuthorize("@ss.hasPermi('Billing:billing:remove')")
    @Log(title = "Billing", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(userBillingService.deleteUserBillingByIds(ids));
    }
}
