package com.bocloud.ims.service.resource.azure.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.common.BillingDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.NotifyMessage;
import com.bocloud.cmp.model.PublicCloudBillModel;
import com.bocloud.common.enums.BoCloudExchange;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.common.enums.AzureTaskStatus;
import com.bocloud.ims.entity.common.Dictionary;
import com.bocloud.ims.entity.common.ServiceTenant;
import com.bocloud.ims.entity.common.Tenant;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.azure.network.PublicIPAddress;
import com.bocloud.ims.entity.resource.azure.price.BillSyncRecord;
import com.bocloud.ims.interfaces.resource.VMApplyService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.repository.resource.azure.network.PublicIPAddressRepository;
import com.bocloud.ims.repository.resource.azure.price.BillSyncRecordRepository;
import com.bocloud.ims.service.internal.CosInternalService;
import com.bocloud.ims.service.internal.SmsTenantService;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: AzureBillConvertor
 * @Description:
 * @author: zhenpingLi/李振平
 * @date: 2021/1/20 10:36
 */
@Component
public class AzureBillServiceUtils {

    private static Logger logger = LoggerFactory.getLogger(AzureBillServiceUtils.class);

    @Autowired
    private CloudBillRepository cloudBillRepository;
    @Autowired
    private TenantCloudBillRepository tenantCloudBillRepository;
    @Autowired
    private ObjectRelationRepository relationRepository;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private SmsTenantService smsTenantService;
    @Autowired
    private CloudServerRepository serverRepository;
    @Autowired
    private VolumeRepository volumeRepository;
    @Autowired
    private PublicIPAddressRepository publicIPAddressRepository;
    @Autowired
    private CosInternalService cosInternalService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private VMApplyService vmApplyService;
    @Autowired
    private BillingDriver billingDriver;
    @Autowired
    private DictionaryRepository dictionaryRepository;
    @Autowired
    private BillSyncRecordRepository billSyncRecordRepository;
    /**
     * 消息通知队列
     */
    private static final String NOTICE_QUEUE = "event.notice.queue";

    public void syncBills(List<PublicCloudBillModel> billModels, CloudVendor vendor) throws Exception {
        if (ListTool.isEmpty(billModels)) {
            return;
        }
        Map<String, CloudBill> map = new HashMap<>();
        List<CloudBill> cloudBills = cloudBillRepository.listByVendor(vendor.getId(), null);
        for (CloudBill cloudBill : cloudBills) {
            map.put(cloudBill.getOrderSn().toLowerCase(), cloudBill);
        }
        for (PublicCloudBillModel model : billModels) {
            if (map.containsKey(model.getOrderSn().toLowerCase())) {
                CloudBill cloudBill = map.get(model.getOrderSn().toLowerCase());
                BeanUtils.copyProperties(model, cloudBill);
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                cloudBillRepository.update(cloudBill);
            } else {
                CloudBill cloudBill = JSONObject.parseObject(JSONObject.toJSONString(model), CloudBill.class);
                cloudBill.setVendorId(vendor.getId());
                cloudBill.setVendorType(vendor.getType());
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                cloudBillRepository.save(cloudBill);
            }
            map.remove(model.getOrderSn().toLowerCase());
        }
    }

    public void syncBillMonths(List<PublicCloudBillModel> billModels, CloudVendor vendor, String month) throws Exception {
        if (ListTool.isEmpty(billModels)) {
            return;
        }
        Map<String, CloudBill> map = new HashMap<>();
        List<CloudBill> cloudBills = cloudBillRepository.listByMonth(vendor.getId(), month);
        for (CloudBill cloudBill : cloudBills) {
            map.put(cloudBill.getOrderSn().toLowerCase(), cloudBill);
        }
        for (PublicCloudBillModel model : billModels) {
            if (map.containsKey(model.getOrderSn().toLowerCase())) {
                CloudBill cloudBill = map.get(model.getOrderSn().toLowerCase());
                BeanUtils.copyProperties(model, cloudBill);
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                cloudBillRepository.update(cloudBill);
            } else {
                CloudBill cloudBill = JSONObject.parseObject(JSONObject.toJSONString(model), CloudBill.class);
                cloudBill.setVendorId(vendor.getId());
                cloudBill.setVendorType(vendor.getType());
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                cloudBillRepository.save(cloudBill);
            }
            map.remove(model.getOrderSn().toLowerCase());
        }
    }

    public void syncTenantBills(List<PublicCloudBillModel> billModels, CloudVendor vendor) throws Exception {
        if (ListTool.isEmpty(billModels)) {
            return;
        }
        List<TenantCloudBill> cloudBills = tenantCloudBillRepository.listByVendor(vendor.getId(), null);
        Map<String, TenantCloudBill> map = Maps.newHashMap();
        for (TenantCloudBill cloudBill : cloudBills) {
            map.put(cloudBill.getOrderSn().toLowerCase(), cloudBill);
        }
        for (PublicCloudBillModel model : billModels) {
            if (map.containsKey(model.getOrderSn().toLowerCase())) {
                TenantCloudBill cloudBill = map.get(model.getOrderSn().toLowerCase());
                BeanUtils.copyProperties(model, cloudBill);
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                tenantCloudBillRepository.update(cloudBill);
            } else {
                TenantCloudBill cloudBill = JSONObject.parseObject(JSONObject.toJSONString(model), TenantCloudBill.class);
                cloudBill.setVendorId(vendor.getId());
                cloudBill.setVendorType(vendor.getType());
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                tenantCloudBillRepository.save(cloudBill);
            }
            map.remove(model.getOrderSn().toLowerCase());
        }
    }

    public void syncTenantBillMonths(List<PublicCloudBillModel> billModels, CloudVendor vendor, String month) throws Exception {
        if (ListTool.isEmpty(billModels)) {
            return;
        }
        List<TenantCloudBill> cloudBills = tenantCloudBillRepository.listByMonth(vendor.getId(), month);
        Map<String, TenantCloudBill> map = Maps.newHashMap();
        for (TenantCloudBill cloudBill : cloudBills) {
            map.put(cloudBill.getOrderSn().toLowerCase(), cloudBill);
        }
        for (PublicCloudBillModel model : billModels) {
            if (map.containsKey(model.getOrderSn().toLowerCase())) {
                TenantCloudBill cloudBill = map.get(model.getOrderSn().toLowerCase());
                BeanUtils.copyProperties(model, cloudBill);
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                tenantCloudBillRepository.update(cloudBill);
            } else {
                TenantCloudBill cloudBill = JSONObject.parseObject(JSONObject.toJSONString(model), TenantCloudBill.class);
                cloudBill.setVendorId(vendor.getId());
                cloudBill.setVendorType(vendor.getType());
                cloudBill.setStatus("paid"); // 已支付
                cloudBill.setChargeMode("PostCharge"); // 后付费
                tenantCloudBillRepository.save(cloudBill);
            }
            map.remove(model.getOrderSn().toLowerCase());
        }
    }

    public void syncTenantBill() throws Exception {
        List<String> types = Arrays.asList(new String[]{CloudProvider.AZURE.name()});
        List<CloudVendor> cloudVendors = cloudVendorRepository.listByTypes(types, null);
        List<TenantCloudBill> bills = new ArrayList<>();
        for (CloudVendor vendor : cloudVendors) {
            List<TenantCloudBill> cloudBills = tenantCloudBillRepository.listByVendor(vendor.getId(), null);
            if (!ListTool.isEmpty(cloudBills)) {
                bills.addAll(cloudBills);
            }
        }
        BocloudResult<List<Tenant>> result = smsTenantService.listAll(new ArrayList<>());
        //查询云主机
        List<CloudServer> servers = serverRepository.list(1, Integer.MAX_VALUE, new ArrayList<>(), new HashMap<>());
        Map<String, CloudServer> serverMap = servers.stream().filter(server -> StringUtils.hasText(server.getInstanceId())).collect(Collectors.toMap(CloudServer::getInstanceId, Function.identity(), (v1, v2) -> v2));
        //查询云硬盘
        List<Volume> volumes = volumeRepository.list(1, Integer.MAX_VALUE, new ArrayList<>(), new HashMap<>());
        Map<String, Volume> volumeMap = volumes.stream().filter(volume -> StringUtils.hasText(volume.getVolumeUuid())).collect(Collectors.toMap(Volume::getVolumeUuid, Function.identity(), (v1, v2) -> v2));
        //查询弹性IP
        List<PublicIPAddress> publicIPAddresses = publicIPAddressRepository.list(1, Integer.MAX_VALUE, new ArrayList<>(), new HashMap<>());
        Map<String, PublicIPAddress> publicIPAddressMap = publicIPAddresses.stream().filter(publicIPAddress -> StringUtils.hasText(publicIPAddress.getUuid())).collect(Collectors.toMap(PublicIPAddress::getUuid, Function.identity(), (v1, v2) -> v2));
        if (result.isSuccess()) {
            List<Tenant> tenants = result.getData();
            if (!ListTool.isEmpty(tenants)) {
                //查询租户授权服务列表
                Map<String, BigDecimal> discountMap = new HashMap<>();
                for (Tenant tenant : tenants) {
                    List<ServiceTenant> serviceTenants = cosInternalService.listTenantServices(tenant.getId());
                    if (ListTool.isEmpty(serviceTenants)) {
                        continue;
                    }
                    for (ServiceTenant serviceTenant : serviceTenants) {
                        BigDecimal discount = serviceTenant.getDiscount();
                        if (null == discount) {
                            discount = BigDecimal.valueOf(1);
                        }
                        if ("azure.standard.server".equalsIgnoreCase(serviceTenant.getServiceCode())) {
                            discountMap.put(tenant.getId() + ResourceCategory.Computer.name(), discount);
                        } else if ("azure.standard.volume".equalsIgnoreCase(serviceTenant.getServiceCode())) {
                            discountMap.put(tenant.getId() + ResourceCategory.Storage.name(), discount);
                        }
                    }
                }
                for (TenantCloudBill bill : bills) {
                    String resourceId = bill.getResourceId();
                    if (StringUtils.isEmpty(resourceId)) {
                        continue;
                    }
                    if (null != serverMap.get(resourceId)) {
                        CloudServer server = serverMap.get(resourceId);
                        bill.setTenantId(server.getTenantId());
                        bill.setProjectId(server.getProjectId());
                        ObjectRelation relation = relationRepository.get(server.getId(), ResourceCategory.Computer.name());
                        if (null != relation) {
                            if (RequestContext.Catalog.User.name().equalsIgnoreCase(relation.getCatalog())) {
                                bill.setUserId(relation.getTarget());
                            }
                        }
                        //计算租户价格
                        BigDecimal discount = discountMap.get(bill.getTenantId() + ResourceCategory.Computer.name());
                        if (null != discount) {
//                            OrderItem orderItem = cosInternalService.queryByItemSn(server.getUuid());
//                            if (null != orderItem && null != orderItem.getBasicPrice()) {
//                                bill.setTenantMoney(orderItem.getBasicPrice().multiply(discount).multiply(BigDecimal.valueOf(getTimeHours(bill.getFeeBeginTime(), bill.getFeeEndTime()))));
//                            } else {
//                                //未找到原始单价，按照账单金额算
//                                bill.setTenantMoney(bill.getMoney());
//                            }
                            BigDecimal totalCost = null == bill.getTotalCost() ? BigDecimal.valueOf(0L) : bill.getTotalCost();
                            bill.setTenantMoney(totalCost.multiply(discount));
                        }
                        tenantCloudBillRepository.update(bill);
                    } else if (null != volumeMap.get(resourceId)) {
                        Volume volume = volumeMap.get(resourceId);
                        bill.setTenantId(volume.getTenantId());
                        bill.setProjectId(volume.getProjectId());
                        ObjectRelation relation = relationRepository.get(volume.getId(), ResourceCategory.Storage.name());
                        if (null != relation) {
                            if (RequestContext.Catalog.User.name().equalsIgnoreCase(relation.getCatalog())) {
                                bill.setUserId(relation.getTarget());
                            }
                        }
                        //计算租户价格
                        BigDecimal discount = discountMap.get(bill.getTenantId() + ResourceCategory.Storage.name());
                        if (null != discount) {
//                            OrderItem orderItem = cosInternalService.queryByItemSn(volume.getUuid());
//                            if (null != orderItem && null != orderItem.getBasicPrice()) {
//                                bill.setTenantMoney(orderItem.getBasicPrice().multiply(discount).multiply(BigDecimal.valueOf(getTimeHours(bill.getFeeBeginTime(), bill.getFeeEndTime()))));
//                            } else {
//                                //未找到原始单价，按照账单金额算
//                                bill.setTenantMoney(bill.getMoney());
//                            }
                            BigDecimal totalCost = null == bill.getTotalCost() ? BigDecimal.valueOf(0L) : bill.getTotalCost();
                            bill.setTenantMoney(totalCost.multiply(discount));
                        }
                        tenantCloudBillRepository.update(bill);
                    } else if (null != publicIPAddressMap.get(resourceId)) {
                        PublicIPAddress publicIPAddress = publicIPAddressMap.get(resourceId);
                        bill.setTenantId(publicIPAddress.getTenantId());
                        bill.setProjectId(publicIPAddress.getProjectId());
                        bill.setUserId(publicIPAddress.getCreatorId());
                        BigDecimal totalCost = null == bill.getTotalCost() ? BigDecimal.valueOf(0L) : bill.getTotalCost();
                        bill.setTenantMoney(totalCost);
                        tenantCloudBillRepository.update(bill);
                    }
                }
            }
        }
        new Thread(() -> {
            try {
                this.processLineOfCredit();
            } catch (Exception e) {
                logger.error("Get error message:{}", e);
            }
        }).start();
    }

    public List<PublicCloudBillModel> getTotalCost(List<PublicCloudBillModel> billModels, BigDecimal parities) throws Exception {
        AzurePriceProviderUtils priceProvider = new AzurePriceProviderUtils();
        for (PublicCloudBillModel model : billModels) {
            String api = "/api/retail/prices";
            String queryParams = new StringBuffer()
                    .append("meterId eq ")
                    .append("'")
                    .append(model.getMeterId())
                    .append("'")
                    .toString();
            JSONObject paramsJson = new JSONObject();
            paramsJson.put("$filter", queryParams);
            String response = priceProvider.request(AzurePriceProviderUtils.RequestStatus.GET, api, paramsJson.toJSONString());
            List<JSONObject> objects = Optional.ofNullable(JSONObject.parseObject(response))
                    .map(responseJson -> Optional.ofNullable(responseJson.getJSONArray("Items")).map(items -> items.stream()
                            .map(JSONArray::toJSONString)
                            .map(JSONObject::parseObject)
                            .collect(Collectors.toList())).orElse(new ArrayList<>())
                    ).orElse(new ArrayList<>());
            if (!CollectionUtils.isEmpty(objects)) {
                JSONObject jsonObject = objects.stream().filter(obj -> obj.getString("type").equalsIgnoreCase("Consumption")).findFirst().get();
                BigDecimal unitPrice = jsonObject.getBigDecimal("unitPrice");
                BigDecimal cnyUnitPrice = unitPrice.multiply(parities);
                BigDecimal totalCost = cnyUnitPrice.multiply(model.getQuantity());
                model.setTotalCost(totalCost);
            } else {
                logger.info("定价信息找不到meterId：" + model.getMeterId());
            }
        }
        return billModels;
    }

    /**
     * 处理授信额度
     */
    @Scheduled(cron = "${line.of.credit.scheduler:0 0 0/1 * * ?}")
    public void processLineOfCredit() throws Exception {
        BocloudResult<List<Tenant>> tenantResult = smsTenantService.listAll(new ArrayList<>());

        if (tenantResult.isFailed() || ListTool.isEmpty(tenantResult.getData())) {
            return;
        }
        List<Tenant> tenants = tenantResult.getData();
        Map<Long, Tenant> tenantMap = tenants.stream().collect(Collectors.toMap(Tenant::getId, Function.identity(), (t1, t2) -> t2));
        for (Long tenantId : tenantMap.keySet()) {
            Tenant tenant = tenantMap.get(tenantId);
            if (null == tenant.getOnTrial() || !tenant.getOnTrial()) {
                continue;
            }
            BigDecimal money = tenant.getMoney();
            if (null == money) {
                continue;
            }
            BigDecimal summary = tenantCloudBillRepository.summary(tenantId);
            if (null == summary) {
                continue;
            }
            //超过授信额度
            if (summary.compareTo(money) > 0) {
                //把租户下所有虚拟机放入回收站
                List<CloudServer> servers = serverRepository.listByTenantId(tenantId);
                for (CloudServer server : servers) {

                    if (null != server && null != server.getUuid() && !server.getUuid().equals("") && null != server.getRecycle() && !server.getRecycle()) {
                        ObjectRelation relation = relationRepository.get(server.getId(), ResourceCategory.Computer.name());
                        if (null != relation && null != tenant.getRecycleAfterArrears() && tenant.getRecycleAfterArrears()) {
//                            RequestContext context = new RequestContext(RequestContext.Catalog.valueOf(relation.getCatalog()), relation.getTarget(), server.getTenantId(), server.getProjectId(), null);
//                            BocloudResult result = vmApplyService.recycle(server.getId(), context);
//                            logger.info("虚拟机{}放入回收站结果：{}", server.getName(), JSONObject.toJSON(result));
                            logger.info("虚拟机{}授信额度不足，暂时不做处理", server.getName());
                        }
                    }
                }
//                List<TenantCloudBill> bills = tenantCloudBillRepository.listByTenantId(tenantId);
//                for (TenantCloudBill bill : bills) {
//                    String resourceId = bill.getResourceId();
//                    if (StringUtils.isEmpty(resourceId)) {
//                        continue;
//                    }
//                    CloudServer server = serverRepository.getByInstanceId(resourceId);
//                    if (null != server && !StringUtil.isEmpty(server.getUuid()) && null != server.getRecycle() && !server.getRecycle()) {
//                        ObjectRelation relation = relationRepository.get(server.getId(), ResourceCategory.Computer.name());
//                        if (null != relation) {
//                            RequestContext context = new RequestContext(RequestContext.Catalog.valueOf(relation.getCatalog()), relation.getTarget(), server.getTenantId(), server.getProjectId(), null);
//                            BocloudResult result = vmApplyService.recycle(server.getId(), context);
//                            logger.info("虚拟机{}放入回收站结果：{}", server.getName(), JSONObject.toJSON(result));
//                        }
//                    }
//                }
                RequestContext context = new RequestContext(RequestContext.Catalog.Tenant, tenantId, tenantId, 0L, null);
                amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(), NOTICE_QUEUE, new NotifyMessage(context, "租户试用额度不足提醒", "您好，您的试用额度已达到上限，请及时申请新的试用额度", true, false));
            }
        }
    }

    /**
     * 根据平台获取全量账单
     */
    public void syncAllBill(CloudVendor vendor) {
        BillSyncRecord billSyncRecord = new BillSyncRecord(vendor.getId(), AzureTaskStatus.SYNC.name(), new Date(), "同步全量账单中......", "ALLAMOUNT");
        try {
            billSyncRecordRepository.save(billSyncRecord);
            logger.info(vendor.getName() + ":拉取账单......");
            BocloudResult bocloudResult = billingDriver.billBySubscriptionId(vendor.getUuid());
            if (bocloudResult.isFailed()) {
                throw new RuntimeException("API拉取失败：" + bocloudResult.getMessage());
            }
            List<PublicCloudBillModel> billModels = (List<PublicCloudBillModel>) bocloudResult.getData();
            if (ListTool.isEmpty(billModels)) {
                throw new RuntimeException("没有账单数据更新");
            }

            //获取汇率
            String strParities = "7";
            com.bocloud.ims.entity.common.Dictionary dictionary = dictionaryRepository.query("PARITIES", "0");
            if (!ObjectUtils.isEmpty(dictionary)) {
                strParities = dictionary.getName();
            }
            BigDecimal parities = new BigDecimal(strParities);

            logger.info(vendor.getName() + ":账单二次处理获取原价......");
            List<PublicCloudBillModel> totalCostModel = this.getTotalCost(billModels, parities);
            logger.info(vendor.getName() + ":成功!");

            logger.info(vendor.getName() + ":账单数据同步......");
            this.syncBills(totalCostModel, vendor);
            logger.info(vendor.getName() + ":成功!");

            logger.info(vendor.getName() + ":租户账单数据同步......");
            this.syncTenantBills(totalCostModel, vendor);
            logger.info(vendor.getName() + ":成功!");

            logger.info(vendor.getName() + ":计算租户二次计价金额......");
            this.syncTenantBill();
            logger.info(vendor.getName() + ":成功!");

            billSyncRecord.setStatus(AzureTaskStatus.SUCCESS.name());
            billSyncRecord.setEndTime(new Date());
            billSyncRecord.setMessage("同步全量账单成功！");
            billSyncRecordRepository.update(billSyncRecord);
        } catch (Exception e) {
            billSyncRecord.setStatus(AzureTaskStatus.ERROR.name());
            billSyncRecord.setEndTime(new Date());
            billSyncRecord.setMessage(e.getMessage());
            billSyncRecordRepository.update(billSyncRecord);
        }
    }

    /**
     * 根据平台获取当前月账单
     */
    public void syncMonthBill(CloudVendor vendor) {
        BillSyncRecord billSyncRecord = new BillSyncRecord(vendor.getId(), AzureTaskStatus.SYNC.name(), new Date(), "同步月账单中......", "ADDAMOUNT");
        try {
            billSyncRecordRepository.save(billSyncRecord);
            logger.info("开始同步" + vendor.getName() + "账单");
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            String month = format.format(new Date());

            BocloudResult bocloudResult = billingDriver.billDetailList(vendor.getUuid(), month, null);
            if (bocloudResult.isFailed()) {
                throw new RuntimeException("API拉取失败：" + bocloudResult.getMessage());
            }
            List<PublicCloudBillModel> billModels = (List<PublicCloudBillModel>) bocloudResult.getData();
            if (ListTool.isEmpty(billModels)) {
                throw new RuntimeException("没有账单数据更新");
            }
            //获取汇率
            String strParities = "7";
            Dictionary dictionary = dictionaryRepository.query("PARITIES", "0");
            if (!ObjectUtils.isEmpty(dictionary)) {
                strParities = dictionary.getName();
            }
            BigDecimal parities = new BigDecimal(strParities);

            logger.info(vendor.getName() + ":账单二次处理获取原价......");
            List<PublicCloudBillModel> totalCostModel = this.getTotalCost(billModels, parities);
            logger.info(vendor.getName() + ":成功!");

            logger.info(vendor.getName() + ":账单数据同步......");
            this.syncBillMonths(totalCostModel, vendor, month);
            logger.info(vendor.getName() + ":成功!");

            logger.info(vendor.getName() + ":租户账单数据同步......");
            this.syncTenantBillMonths(totalCostModel, vendor, month);
            logger.info(vendor.getName() + ":成功!");

            logger.info(vendor.getName() + ":计算租户二次计价金额......");
            this.syncTenantBill();
            logger.info(vendor.getName() + ":成功!");
            billSyncRecord.setStatus(AzureTaskStatus.SUCCESS.name());
            billSyncRecord.setEndTime(new Date());
            billSyncRecord.setMessage("同步月账单成功！");
            billSyncRecordRepository.update(billSyncRecord);
        } catch (Exception e) {
            billSyncRecord.setStatus(AzureTaskStatus.ERROR.name());
            billSyncRecord.setEndTime(new Date());
            billSyncRecord.setMessage(e.getMessage());
            billSyncRecordRepository.update(billSyncRecord);
        }

    }
}