<template>
  <div :ref="wrapId" :elid="wrapId" :style="[wrapStyle]">
    <div style="height:100%;width:100%" class="fviz-table-box">
      <div :id="wrapId + '_header'" class="fviz-table-header">
        <table :id="wrapId + '_tab1'">
          <thead></thead>
        </table>
      </div>
      <div :id="wrapId + '_body'" class="fviz-table-body">
        <table :id="wrapId + '_tab2'">
          <thead></thead>
          <tbody></tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
import bm from "../../mixins/base-mixins";
import $ from "jquery";
import { ToolTip } from "../../util/ToolTip";
import "./style.css";

export default {
  name: "fviz-table",
  mixins: [bm],
  data() {
    return {
      myMarq: null,
    };
  },
  watch: {
    objVal: {
      handler(val, oldVal) {
        this.$nextTick(function () {
          this.multiOp();
        });
      },
      deep: true,
    },
    dataObj: {
      handler(newValue, oldValue){
        this.$nextTick(function () {
          this.multiOp();
        });
      },
      deep: true
    }
  },
  computed: {
    //字段映射
    fieldBindObj() {
      let result = [];

      //界面上配置的字段映射优先级最高，会覆盖后端返回的字段映射配置
      let tableCol = null;

      if (this.objVal.tableCol) {
        tableCol = this.objVal.tableCol;
      }

      if (tableCol) {
        result = JSON.parse(tableCol);
      }

      if (result.length < 1) {
        this.$message.error("字段绑定不能为空");
      }

      //表头按排序字段排序
      result.sort((a, b) => {
        if (a.order && b.order) {
          return a.order - b.order;
        } else {
          return 0;
        }
      });
      return result;
    },
  },
  methods: {
    //表头样式
    thStyle() {
      let style = {
        "background-color": this.objVal.headBgColor,
        "font-size": this.objVal.headFontSize + "px",
        "color": this.objVal.headFontColor,
        "text-align": this.objVal.headerAlign,
        "font-weight": this.objVal.headFontWeight,
        "line-height": this.objVal.headLineHeight + "px",
        "border-style": this.objVal.tableBorderStyle,
        "border-width": this.objVal.tableBorderWidth,
        "border-color": this.objVal.tableBorderColor,
        "max-width": "0px",
        "white-space": "nowrap",
        "overflow": "hidden",
        "text-overflow": "ellipsis",
      };
      return style;
    },
    //表体样式
    tdStyle(index) {
      let style = {
        "background-color": this.objVal.bodyBgColor,
        "font-size": this.objVal.bodyFontSize + "px",
        "color": this.objVal.bodyFontColor,
        "text-align": this.objVal.bodyAlign,
        "font-weight": this.objVal.bodyFontWeight,
        "line-height": this.objVal.bodyLineHeight + "px",
      };

      if (index % 2 == 1 && this.objVal.evenBgColor) {
        style["background-color"] = this.objVal.evenBgColor;
      }
      return style;
    },
    tdBorderStyle() {
      let style = {
        "border-style": this.objVal.tableBorderStyle,
        "border-width": this.objVal.tableBorderWidth,
        "border-color": this.objVal.tableBorderColor,
        "max-width": "0px",
        "white-space": "nowrap",
        "overflow": "hidden",
        "text-overflow": "ellipsis",
      };
      return style;
    },
    //表头html
    buildHeader() {
      let me = this;

      $("#" + me.wrapId + "_tab1 thead").empty();
      $("#" + me.wrapId + "_tab2 thead").empty();

      let arr = [];
      arr.push("<tr>");
      if (me.objVal.numShow && eval(me.objVal.numShow)) {
        arr.push("<th style = 'width: " + this.objVal.numWidth + "px;'>序号</th>");
      }
      me.fieldBindObj.forEach((obj) => {
        arr.push(
          "<th style = 'width:" + obj.width + "px;'>" + obj.showName + "</th>"
        );
      });
      arr.push("</tr>");

      if (this.objVal.headerShow && eval(this.objVal.headerShow)) {
        let superHeader = [];
        if(eval(me.objVal.superHeaderShow)){
          (eval(me.objVal.superHeaderConfig) || []).forEach((superHeaderItem, i) => {
            superHeader.push("<tr>")
            superHeaderItem.forEach((item, j) => {
              superHeader.push("<th colspan=" + item.cols + ">" + item.name + "</th>");
            })
            superHeader.push("</tr>")
          })
          $("#" + me.wrapId + "_tab1 thead").append(superHeader.join(""));
          $("#" + me.wrapId + "_tab2 thead").append(superHeader.join(""));
          // 开启超级表头的情况下，如果合并的列并不能沾满整个列，则修改整个表头的背景色用来覆盖body滚动的内容
          $("#" + me.wrapId + "_tab1").css("background-color", this.objVal.headBgColor);
        }

        $("#" + me.wrapId + "_tab1 thead").append(arr.join(""));
        $("#" + me.wrapId + "_tab1 thead th").css(this.thStyle());

        $("#" + me.wrapId + "_tab2 thead").append(arr.join(""));
        $("#" + me.wrapId + "_tab2 thead th").css(this.thStyle());
      }

      //不开启轮播，固定表头，出滚动条
      if (!eval(this.objVal.rollOpen)) {
        $("#" + me.wrapId + "_body").css({
          "height": "100%",
          "overflow-y": "scroll",
        });
      } else {
        $("#" + me.wrapId + "_body").css({
          "height": "",
          "overflow-y": "",
        });
      }
    },
    //表体html
    buildBody() {
      let me = this;
      $("#" + me.wrapId + "_tab2 tbody").empty();
      let dataList = this.dataObj || []; //显示数据
      dataList.forEach((item, index) => {
        let row = [];
        row.push("<tr>");
        if (me.objVal.numShow && eval(me.objVal.numShow)) {
          row.push("<td>" + (index + 1) + "</td>");
        }
        me.fieldBindObj.forEach((obj) => {
          let value = item[obj.origName];
          let percentStr = "";
          let spanBef = "", spanAft = "";
          //标记为%
          if (obj.markPercent && eval(obj.markPercent)) {
            percentStr = "%";
          }

          //开启飘红飘绿
          if (obj.flyRedGreen && eval(obj.flyRedGreen)) {
            if (value && value > 0 && me.objVal.flyRedColor) {
              spanBef = "<span style='color:" + me.objVal.flyRedColor + "'>";
              spanAft = "</span>";
            }
            if (value && value < 0 && me.objVal.flyGreenColor) {
              spanBef = "<span style='color:" + me.objVal.flyGreenColor + "'>";
              spanAft = "</span>";
            }
          }

          row.push(
            "<td colname='" +
              obj.origName +
              "'>" +
              spanBef +
              value +
              percentStr +
              spanAft +
              "</td>"
          );
        });
        row.push("</tr>");
        let $row = $(row.join("")).css(me.tdStyle(index));
        $("#" + me.wrapId + "_tab2 tbody").append($row);
      });

      $("#" + me.wrapId + "_tab2 tbody td").css(this.tdBorderStyle());
    },
    //滚动
    roll() {
      let me = this;
      clearInterval(me.myMarq);
      let dataList = this.dataObj || []; //显示数据
      $("#" + me.wrapId + "_body").css("top", "0");
      if (dataList.length > 10) {
        $("#" + me.wrapId + "_body tbody").html(
          $("#" + me.wrapId + "_body tbody").html() +
            $("#" + me.wrapId + "_body tbody").html()
        );

        var tblTop = 0;
        var rollSpeed = me.objVal.rollSpeed || 50; // 数值越大越慢

        var outerHeight = $("#" + me.wrapId + "_body tbody").find("tr").outerHeight();

        function marqHandler() {
          if (tblTop <= -outerHeight * dataList.length) {
            tblTop = 0;
          } else {
            tblTop -= 1;
          }
          $("#" + me.wrapId + "_body").css("top", tblTop + "px");
        }

        if (this.objVal.rollOpen && eval(this.objVal.rollOpen)) {
          me.myMarq = setInterval(marqHandler, rollSpeed);

          $("#" + me.wrapId + "_body tbody").hover(
            function () {
              clearInterval(me.myMarq);
            },
            function () {
              clearInterval(me.myMarq);
              if (me.objVal.rollOpen && eval(me.objVal.rollOpen)) {
                me.myMarq = setInterval(marqHandler, rollSpeed);
              }
            }
          );
        }
      }
    },
    //纠正表头宽度
    correctHeader() {
      let me = this;
      if (!eval(this.objVal.rollOpen)) {
        //滚动条宽度
        let scrollWidth = 6;
    	  if (this.preview) {
    		  scrollWidth = 17;
    	  }
        $("#" + me.wrapId + "_header").width($("#" + me.wrapId + "_body").width() - scrollWidth);
      } else {
        $("#" + me.wrapId + "_header").width($("#" + me.wrapId + "_body").width());
      }

      $("[elid='" + me.wrapId + "']")
        .find("td")
        .mouseover(function (e) {
          if ($(this).text()) {
            ToolTip.createTip({
              elid: me.wrapId,
              text: $(this).text(),
              left:
                e.pageX - $("[elid='" + me.wrapId + "']").offset().left + 10,
              top: e.pageY - $("[elid='" + me.wrapId + "']").offset().top + 10,
            });
          }
        })
        .mouseout(function () {
          ToolTip.removeTip({ elid: me.wrapId });
        });
    },
    mergeRowspan(colIndex) {
      $("#" + this.wrapId + "_tab2").each(function(item){
        var that;
        $('tr', this).each(function (row) {
          $('td:eq(' + colIndex + ')', this).filter(':visible').each(function (col) {
            let rowspan;
            if (that != null && $(this).html() == $(that).html()) {
              rowspan = $(that).attr("rowSpan");
              if (rowspan == undefined) {
                $(that).attr("rowSpan", 1);
                rowspan = $(that).attr("rowSpan");
              }
              rowspan = Number(rowspan) + 1;
              $(that).attr("rowSpan", rowspan);
              $(this).hide();
            } else {
              that = this;
            }
          })
        })
      });
    },
    merge() {
      let me = this;
      me.fieldBindObj.forEach((item, index) => {
        if(eval(item.merge)){
          if (me.objVal.numShow && eval(me.objVal.numShow)) {
            me.mergeRowspan(index + 1);
          }else{
            me.mergeRowspan(index);
          }
        }
      });
    },
    //组合操作
    multiOp() {
      this.buildHeader();
      this.buildBody();
      this.roll();
      this.correctHeader();
      this.merge();
    },
    init() {
      this.queryData();
      this.multiOp();
    },
    refresh() {
      this.init();
    },
  },
  mounted() {
    if (!this.preview) {
      this.init();
    }

    let me = this;
    $(window).resize(function () {
      me.multiOp();
    });
  },
  destroyed() {
    clearInterval(this.myMarq);
  },
};
</script>
<style>
</style>
