日历-填补数据

前因:需要展示年/月收益,月收益为0时后端不返回,仅返回有数据的日期
解决方案:获取月份的天数,进行填补数据,渲染时匹配渲染
效果图

<template>
  <div class="calendar-box">
    <div class="cumulative-income">
      <div class="incom-item">
        <span class="label"
          >{{
            mode == "year"
              ? `${dafaultTime}`
              : `${moment(dafaultTime).format("M")}`
          }}收益</span
        >
        <span :class="colorFun(sumInfo.sumProfit)">
          {{ sumInfo.sumProfit > 0 ? "+" : "" }}{{ sumInfo.sumProfit }}
        </span>
      </div>
      <div class="incom-item">
        <span class="label">收益率</span>
        <span :class="colorFun(sumInfo.sumProfitPercentage)">
          {{ sumInfo.sumProfitPercentage > 0 ? "+" : ""
          }}{{ sumInfo.sumProfitPercentage }}%
        </span>
      </div>
    </div>
    <a-calendar
      :class="mode === 'year' ? 'calendar-year' : ''"
      :disabledDate="disabledDate"
      @panelChange="handleDateSelect"
      :mode="mode"
    >
       <!--自定义---->
      <template slot="dateFullCellRender" slot-scope="value" class="events">
        <div
          class="month-box"
          :class="bgFun(item.profitToday)"
          v-for="(item, index) in data"
          :key="index"
        >
          <div
            class="data-item"
            v-if="
              item.tradeDate ==
              `${value.year()}-${value.month() + 1 < 10 ? '0' : ''}${
                value.month() + 1
              }-${value.date() < 10 ? '0' : ''}${value.date()}`
            "
          >
            <div class="data-title">{{ value.date() }}</div>
            <div :class="colorFun(item.profitToday)">
              <div>
                {{ item.profitToday > 0 ? "+" : "" }}{{ item.profitToday }}
              </div>
              <div>
                {{ item.percentageProfitToday > 0 ? "+" : ""
                }}{{ item.percentageProfitToday }}%
              </div>
            </div>
          </div>
        </div>
      </template>
       <!-- 自定义年--->
      <template slot="monthFullCellRender" slot-scope="value">
        <div
          :class="bgFun(item.profitToday)"
          v-for="item in data"
          :key="item.tradeDate"
        >
          <div
            v-if="moment(item.tradeDate).format('M') == `${value.month() + 1}`"
            class="data-item"
          >
            <div class="data-title">{{ value.month() + 1 }}</div>
            <div :class="colorFun(item.profitToday)">
              <div>
                {{ item.profitToday > 0 ? "+" : "" }}{{ item.profitToday }}
              </div>
              <div>
                {{ item.percentageProfitToday > 0 ? "+" : ""
                }}{{ item.percentageProfitToday }}%
              </div>
            </div>
          </div>
        </div>
      </template>
    </a-calendar>
    <div class="echarts-box" v-if="isShowEcharts">
      <histogram-echarts :data="data" :mode="mode"></histogram-echarts>
    </div>
  </div>
</template>

<script>
import moment from "moment";
// 接口文件
import customerProfitLossApi from "@/services/customerProfitLoss";
const { getEarningsCalendar } = customerProfitLossApi;
// 柱状图-不用管
import histogramEcharts from "./histogramEcharts.vue";
export default {
  components: { histogramEcharts },
  props: {
    marke: {
      type: String,
      required: false,
    },
    checkInfo: {
      type: Object,
      required: false,
    },
  },
  data() {
    return {
      moment,
      dafaultTime: moment().format("YYYY-MM"),
      mode: "month",
      data: [],
      sumInfo: {
        sumProfit: 0,
        sumProfitPercentage: 0,
      },
      isShowEcharts: false,
    };
  },
  created() {
    this.getEarningsCalendar();
  },
  methods: {
    colorFun(value) {
      let num = Number(value);
      if (num > 0) return "rise";
      if (num < 0) return "fall";
      if (num === 0) return "";
    },
    bgFun(value) {
      let num = Number(value);
      if (num > 0) return "rise-bg";
      if (num < 0) return "fall-bg";
      if (num === 0) return "com-bg";
    },
    // 补数据
    suppData(date) {
      let indexNum = 0;
      const days = moment(date, "YYYY-MM").daysInMonth();
      const valuableArr = [];
      if (this.mode === "year") {
        indexNum = 12;
      } else {
        indexNum = days;
      }
      for (let index = 0; index < indexNum; index += 1) {
        valuableArr.push(`${date}-${index + 1}`);
      }
      // 返回的数据的-日期
      const dataArr = [];
      const noDate = [];
      this.data.forEach((item) => {
        dataArr.push(item.tradeDate);
      });
      valuableArr.forEach((item) => {
        if (this.mode === "year") {
          item = moment(item).format("YYYY-MM");
        } else {
          item = moment(item).format("YYYY-MM-DD");
        }
        // 柱状图是否显示
        if (dataArr && dataArr.length > 0) {
          this.isShowEcharts = true;
        } else {
          this.isShowEcharts = false;
        }
        if (dataArr.indexOf(item) === -1) {
          // 补到存数据的数组
          this.data.push({
            tradeDate: item,
            percentageProfitToday: '0.00',
            profitToday: '0.00',
          });
          noDate.push(item);
        }
      });
      this.data.sort(this.dataFilter("tradeDate", true));
    },
    dataFilter(property, type) {
      return function (a, b) {
        let value1 = a[property];
        let value2 = b[property];
        if (type) {
          // 升序
          return Date.parse(value1) - Date.parse(value2);
        } else {
          // 降序
          return Date.parse(value2) - Date.parse(value1);
        }
      };
    },
    disabledDate(current) {
      return (
        (current && current < moment(this.dafaultTime).startOf("month")) ||
        current > moment(this.dafaultTime).endOf("month")
      );
    },
    handleDateSelect(date, mode) {
      this.mode = mode;
      if (mode === "month") {
        this.getEarningsCalendar(moment(date).format("YYYY-MM"));
      } else {
        this.getEarningsCalendar(moment(date).format("YYYY"));
      }
    },
    getEarningsCalendar(date) {
      this.dafaultTime = date || this.dafaultTime;
      this.data = [];
      let params = {
        exchangeType: this.marke,
        fundAccount: this.checkInfo.fundAccount,
        tradeDate: this.dafaultTime, // 日期(举例,月份为2022-06,年份为2022)
        type: this.mode === "year" ? 1 : 0, // 查询类型(0:月,1:年)
      };
      // 后端接口
      getEarningsCalendar(params).then((res) => {
        if (res.data.data) {
          this.sumInfo = {
            sumProfit: res.data.data.sumProfit,
            sumProfitPercentage: res.data.data.sumProfitPercentage,
          };
          this.data = res.data.data.vos || [];
          this.suppData(this.dafaultTime);
        }
      });
    },
  },
};
</script>

<style scoped lang="less">
.calendar-box {
  background-color: #fff;
  .month-box {
    text-align: center;
    margin: 2px 2px;
    font-size: 11px;
  }
  .events {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .events .ant-badge-status {
    overflow: hidden;
    white-space: nowrap;
    width: 100%;
    text-overflow: ellipsis;
    font-size: 12px;
  }
  .notes-month {
    text-align: center;
    font-size: 28px;
  }
  .notes-month section {
    font-size: 28px;
  }
  .data-item {
    padding: 4px;
    .data-title {
      font-size: 14px;
      font-weight: bold;
    }
  }
  .cumulative-income {
    background-color: #fff;
    display: flex;
    line-height: 30px;
    padding: 10px 20px;
    font-size: 15px;
    border-bottom: 1px solid #f0f0f0;
    margin-bottom: 10px;
    .incom-item {
      flex: 1;
      font-weight: 600;
      .label {
        margin-right: 15px;
      }
    }
  }
  .echarts-box {
    padding: 0 20px;
  }
}
::v-deep .ant-fullcalendar-fullscreen {
  // width: 680px;
  margin: auto;
  background: #fff;
}
::v-deep .ant-fullcalendar-date {
  border-top: 0;
  text-align: center;
}
::v-deep .ant-fullcalendar-value {
  text-align: center;
  color: #000;
  font-weight: 600;
}
::v-deep .ant-fullcalendar-column-header-inner {
  text-align: center;
  font-weight: 600;
}
::v-deep .ant-fullcalendar-content {
  height: 46px;
}
::v-deep .ant-fullcalendar-month {
  height: auto;
}
.calendar-year {
  //  width: 600px;
  // margin: 0 auto;
}
::v-deep .ant-fullcalendar-month-panel-cell {
  text-align: center;
  padding: 4px;
}
.rise {
  color: #f44345;
}
.fall {
  color: #16ba71;
}

.rise-bg {
  background-color: rgba(244, 67, 69, 0.1);
}
.fall-bg {
  background-color: rgba(22, 186, 113, 0.1);
}
.com-bg {
  background-color: rgba(246, 246, 249, 0.4);
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值