<template>
  <view class="section" :style="{
    position: 'relative',
    zIndex: dropdownOpen || dropdownRegionOpen ? 9 : 'auto',
  }">
    <view v-if="showHeader" class="section-header">
      <text class="section-title">{{ title }}</text>
      <view :style="{ display: 'flex' }">
        <view v-if="showSelector && tableType === 'variety'" class="selector-wrap">
          <view class="selector" @click.stop="toggleDropdownRegion">
            <text class="selector-text">{{
              region?.regionCode ? region.regionName : "选择片区"
            }}</text>
            <text class="selector-arrow" :class="{ open: dropdownRegionOpen }"></text>
          </view>
          <view class="dropdown" v-show="dropdownRegionOpen" :style="dropdownDirection === 'top'
            ? { top: 'auto', bottom: '48rpx' }
            : {}
            " @click.stop>
            <view class="dropdown-search-bar">
              <input class="dropdown-search-input" v-model="regionSearchText" @input="onRegionSearch"
                placeholder="搜索..." />
            </view>
            <scroll-view scroll-y="true" class="dropdown-scroll-view" lower-threshold="80"
              @scrolltolower="loadMoreRegions">
              <view class="dropdown-item" v-for="(p, i) in regionList" :key="p.regionCode || i" :style="p.regionCode === region?.regionCode ||
                (!region?.regionCode && i == 0)
                ? {
                  backgroundColor: '#2c69ff',
                  color: '#fff',
                }
                : {}
                " @click.stop="selectProduct('region', p)">{{ p.regionName || p }}</view>
              <view v-if="regionList.length === 0" class="dropdown-item" style="text-align: center; color: #999">暂无数据
              </view>
            </scroll-view>
          </view>
        </view>
        <view v-if="showSelector" class="selector-wrap">
          <view class="selector" @click.stop="toggleDropdown">
            <text class="selector-text">{{
              product?.drugEntBaseInfoId ? product.physicName : "选择品种"
            }}</text>
            <text class="selector-arrow" :class="{ open: dropdownOpen }"></text>
          </view>
          <view class="dropdown" v-show="dropdownOpen" :style="dropdownDirection === 'top'
            ? {
              top: 'auto',
              bottom: '48rpx',
            }
            : {}
            " @click.stop>
            <view class="dropdown-search-bar">
              <input class="dropdown-search-input" v-model="productSearchText" @input="onProductSearch"
                placeholder="搜索..." />
            </view>
            <scroll-view scroll-y="true" class="dropdown-scroll-view" lower-threshold="80"
              @scrolltolower="loadMoreProducts">
              <view class="dropdown-item" v-for="(p, i) in productList" :key="p.drugEntBaseInfoId || i" :style="p.drugEntBaseInfoId === product?.drugEntBaseInfoId ||
                (!product?.drugEntBaseInfoId && i == 0)
                ? {
                  backgroundColor: '#2c69ff',
                  color: '#fff',
                }
                : {}
                " @click.stop="selectProduct('product', p)">{{ p.physicName }}</view>
              <view v-if="productList.length === 0" class="dropdown-item" style="text-align: center; color: #999">暂无数据
              </view>
            </scroll-view>
          </view>
        </view>
      </view>
    </view>

    <view class="table-scroll-x" :style="{
      height:
        tableHeightAuto || list.length < 7
          ? 'auto'
          : _tableBodyHeight + 80 + 'rpx',
      maxHeight: tableHeightAuto,
    }">
      <scroll-view class="no-scrollbar" :style="{ height: '100%' }" scroll-x="true" scroll-y="true" enhanced
        :show-scrollbar="false" @scrolltolower="onScrollToLower">
        <view class="card" :style="{ width: tableWidth }">
          <view class="table-header" :style="{
            position: 'sticky',
            top: '0',
            zIndex: 10,
            fontWeight: headerBold ? 'bold' : 'normal',
          }">
            <view v-for="(col, ci) in columnList" :key="getUid()" class="cell" :style="{
              ...headerCellStyle(ci, col),
            }">
              <view v-if="isPlainTitle(col.title)" :style="{
                display: 'flex',
                alignItems: 'center',
                position: 'relative',
              }">
                <text>{{ col.title }}</text>
                <uni-icons v-if="col.tooltip" type="help" size="16" color="#2c69ff"
                  @tap.stop.prevent="toggleHeaderTooltip(ci)"></uni-icons>
                <view v-if="headerTooltip[ci]" class="header-tooltip-wrap" @click.stop>
                  <view class="header-tooltip">{{ col.tooltip }}</view>
                  <view class="header-tooltip-arrow"></view>
                </view>
              </view>
              <rich-text v-else :nodes="titleNodes(col.title)" />
            </view>
          </view>
          <view v-if="!loading && list && list.length > 0" class="table-body">
            <template>
              <view class="row" v-for="(item, i) in list" :key="getUid()">
                <view v-for="(col, ci) in columnList" :key="getUid()" class="cell" :class="{
                  underline: col.underline,
                  striped: striped && (i + 1) % 2 === 0,
                }" :style="bodyCellStyle(ci, col)" @click="handleClick(item, col)">{{ renderCell(item, col) }}</view>
              </view>
              <view class="row loading-row" v-if="hasmore">
                <view class="loading-wrapper">
                  <image class="loading-icon" :src="loadingImg" />
                </view>
              </view>
              <view class="row" v-if="showSummary" :style="{
                position: 'sticky',
                bottom: '0',
                zIndex: 5,
                backgroundColor: '#fff',
                borderTop: '1rpx solid #eef0f4',
                color: summaryFontColor,
              }">
                <view v-for="(col, ci) in columnList" :key="getUid()" class="cell" :style="{
                  ...bodyCellStyle(ci, col),
                  fontWeight: summaryBold ? 'bold' : 'normal',
                }">{{ getSummary(col, ci) }}</view>
              </view>
            </template>
          </view>
        </view>
        <view v-if="loading" class="no-data-placeholder" :style="{ height: 'auto' }">
          <view class="row loading-row">
            <view class="loading-wrapper">
              <image class="loading-icon" :src="loadingImg" />
            </view>
          </view>
        </view>
        <view v-if="!loading && (!list || list.length === 0)" class="no-data-placeholder">
          <EmptyView />
        </view>
      </scroll-view>
      <view v-if="loading" class="no-data" :style="{ height: 'auto', top: cellHeight }">
        <view class="row loading-row">
          <view class="loading-wrapper">
            <image class="loading-icon" :src="loadingImg" />
          </view>
        </view>
      </view>
      <view v-if="!loading && (!list || list.length === 0)" class="no-data" :style="{ top: cellHeight }">
        <EmptyView />
      </view>
    </view>
  </view>
</template>

<script>
import EmptyView from "../../../../wigets/empty.vue";
import loadingImg from "../../../../static/images/loading.png";
import { getUid } from "../../../../utils/utils.js";
import request from "../../../../request/index.js";
import Select from "../../../../wigets/select.vue";
export default {
  name: "ScanRateTable",
  components: { EmptyView, Select },
  props: {
    params: {
      type: Object,
      default: null,
    },
    scanType: { type: String, default: "1" },
    api: {
      type: String,
      default: "",
    },
    tableType: { type: String, default: "customer" },
    title: { type: String, default: "客户扫码率" },
    showSelector: { type: Boolean, default: true },
    showHeader: { type: Boolean, default: true },
    dropdownDirection: { type: String, default: "bottom" },
    showSummary: { type: Boolean, default: true },
    striped: { type: Boolean, default: true },
    summaryStructure: {
      type: Array,
      default: () => [
        {
          key: "totalInRate",
          title: "入库扫码率",
          unit: "%",
        },
        {
          key: "totalOutRate",
          title: "出库扫码率",
          unit: "%",
        },
        {
          key: "totalSelfExaminationRate",
          title: "自验证率",
          unit: "%",
        },
      ],
    },
    summaryBold: { type: Boolean, default: false },
    summaryFontColor: {
      type: String,
      default: "#2c69ff",
    },
    initial: { type: Array, default: () => [] },
    products: { type: Array, default: () => [] },
    regions: { type: Array, default: () => [] },
    cellHeight: {
      type: String,
      default: "76rpx",
    },
    headerFontSize: {
      type: String,
      default: "32rpx",
    },
    headerBold: {
      type: Boolean,
      default: true,
    },
    bodyFontSize: {
      type: String,
      default: "32rpx",
    },
    bodyFontColor: {
      type: String,
      default: "",
    },
    //若需要横向滚动且左侧固定，则tableWidth需等于columns所有width之和（可以略小于）
    tableWidth: {
      type: String,
      default: "100%",
    },
    tableHeightAuto: {
      type: Boolean,
      default: false,
    },
    pageSize: {
      type: Number,
      default: 10,
    },
    tableBodyHeight: {
      type: Number,
      default: 0,
    },
    columns: {
      type: Array,
      default: () => [
        {
          key: "regionName",
          title: "区域",
          underline: true,
          fixed: true,
          width: "",
        },
        {
          key: "inScanRate",
          title: "入库扫码率",
          fixed: false,
          width: "",
          tooltip:
            "客户入库扫码量（与上游出库单中相同的追溯码）/上游企业出库扫码量",
          unit: "%",
        },
        {
          key: "outScanRate",
          title: "出库扫码率",
          fixed: false,
          width: "",
          tooltip:
            "客户出库扫码量（与下游入库单中相同的追溯码）/下游企业入库扫码量",
          unit: "%",
        },
        {
          key: "selfExaminationRate",
          title: "自验证率",
          fixed: false,
          width: "",
          tooltip: "客户出库扫码量（与入库单中相同的追溯码）/入库扫码量",
          unit: "%",
        },
      ],
    },
  },
  data() {
    return {
      dropdownOpen: false,
      dropdownRegionOpen: false,
      list: [],
      totalCount: 0,
      hasmore: true,
      loading: true,
      fetchLoading: false,
      loadingImg,
      product: null,
      region: null,
      tablePage: 1,
      tablePageSize: this.pageSize,
      summaryData: [],
      headerTooltip: {},
      regionSearchText: "",
      productSearchText: "",
      regionList: [],
      productList: [],
    };
  },
  computed: {
    filteredRegions() {
      if (!this.regionSearchText) return this.regions;
      const lower = this.regionSearchText.toLowerCase();
      return this.regions.filter(
        (r) =>
          (r.regionName || r.name || r || "")
            .toString()
            .toLowerCase()
            .indexOf(lower) > -1,
      );
    },
    filteredProducts() {
      if (!this.productSearchText) return this.products;
      const lower = this.productSearchText.toLowerCase();
      return this.products.filter(
        (p) => (p.physicName || "").toLowerCase().indexOf(lower) > -1,
      );
    },
    _tableBodyHeight() {
      if (this.tableBodyHeight) return this.tableBodyHeight;
      return 6 * 80;
    },
    columnList() {
      if (this.params) {
        const type = this.params?.type;
        if (type === "1" || type === "2")
          return this.columns.filter((i) => i.key !== "selfExaminationRate");
      }
      return this.columns;
    },
  },
  watch: {
    dropdownRegionOpen(val) {
      if (val) {
        this.regionSearchText = "";
        this.initRegionList();
      }
    },
    dropdownOpen(val) {
      if (val) {
        this.productSearchText = "";
        this.initProductList();
      }
    },
    product(val) {
      this.resetFetch();
    },
    region: {
      handler(val) {
        this.resetFetch();
      },
      deep: true,
    },
    params: {
      handler(newVal, oldVal) {
        if (
          newVal !== oldVal &&
          JSON.stringify(newVal) === JSON.stringify(oldVal)
        )
          return;
        this.resetFetch();
      },
      deep: true,
    },
    products: {
      handler(newVal, oldVal) {
        if (this.dropdownOpen) {
          this.initProductList();
        }
      },
      deep: true,
    },
    regions: {
      handler(newVal, oldVal) {
        if (this.dropdownRegionOpen) {
          this.initRegionList();
        }
      },
      deep: true,
    },
  },
  created() {
    // this.fetchLoading = false;
    // this.isLoading = false;
    // this.loading = false;
    // this.list =
    //   this.initial && this.initial.length ? this.initial : this.genRows(7);
    // if (this.list.length > this.totalCount) {
    //   this.list = this.list.slice(0, this.totalCount);
    // }
    // if (!this.showHeader) {
    //   this.fetchList();
    // } else {
    //   Promise.all([this.getProviceList(), this.getDrugInfoName()]).then(
    //     () => { }
    //   );
    // }
    this.fetchList();
  },
  methods: {
    renderCell(item, col) {
      if (!item[col.key]) return "--";
      const reg = /rate/i;
      if (reg.test(col.key))
        return Math.floor(Number(item[col.key])) + (col.unit || "");
      return item[col.key];
    },
    initRegionList() {
      this.regionList = this.filteredRegions.slice(0, 10);
    },
    loadMoreRegions(e) {
      if (this.regionList.length >= this.filteredRegions.length) return;
      const currentLen = this.regionList.length;
      const more = this.filteredRegions.slice(currentLen, currentLen + 10);
      this.regionList = this.regionList.concat(more);
    },
    onRegionSearch() {
      this.initRegionList();
    },
    initProductList() {
      this.productList = this.filteredProducts.slice(0, 10);
    },
    loadMoreProducts() {
      if (this.productList.length >= this.filteredProducts.length) return;
      const currentLen = this.productList.length;
      const more = this.filteredProducts.slice(currentLen, currentLen + 10);
      this.productList = this.productList.concat(more);
    },
    onProductSearch() {
      this.initProductList();
    },
    getUid,
    getSummary(col, ci) {
      if (ci == 0) return "合计";
      return Math.floor(Number(this.summaryData[ci])) + (col.unit || "");
    },
    closeAllTooltip() {
      this.headerTooltip = {};
    },
    toggleHeaderTooltip(i) {
      const value = !this.headerTooltip[i];
      this.headerTooltip = {};
      this.$set(this.headerTooltip, i, value);
    },
    // getUid(len = 16) {
    //   const ts = Date.now().toString(36);
    //   const rand = Math.random().toString(36).slice(2);
    //   return (ts + rand).slice(0, len);
    // },
    // getProviceList() {
    //   request('/common/getProviceList', {
    //     path: 'customerScanningRate/wigets/ScanRateTable.vue',
    //   }).then(res => {
    //     if (res.code == 200) {
    //       const _data = res.data;
    //       this.regions = _data;
    //       this.region = this.regions[0];
    //     }
    //   })
    // },
    // getDrugInfoName() {
    //   request('/bills/getDrugInfoName', {
    //     path: 'customerScanningRate/wigets/ScanRateTable.vue',
    //   }).then(res => {
    //     if (res.code == 200) {
    //       const _data = res.data;
    //       this.products = _data;
    //       this.product = this.products[0];
    //     }
    //   })
    // },
    toggleDropdown() {
      if (this.fetchLoading) return;
      const next = !this.dropdownOpen;
      if (next) this.$emit("dropdown-open", this);
      this.dropdownOpen = next;
    },
    toggleDropdownRegion() {
      if (this.fetchLoading) return;
      const next = !this.dropdownRegionOpen;
      if (next) this.$emit("dropdown-open", this);
      this.dropdownRegionOpen = next;
    },
    selectProduct(type, p) {
      // this.$emit("change-product", p);
      if (type === "product") {
        this.product = p;
        this.dropdownOpen = false;
      } else if (type === "region") {
        this.region = p;
        this.dropdownRegionOpen = false;
      }
    },
    closeDropdown() {
      this.dropdownOpen = false;
      this.dropdownRegionOpen = false;
    },
    // genRows(n) {
    //   const regions = ["广东", "广西", "湖南", "湖北", "四川", "浙江", "江苏"];
    //   const res = [];
    //   for (let i = 0; i < n; i++) {
    //     const r = regions[i % regions.length];
    //     res.push({
    //       regionName: r,
    //       outScanRate: `${(95 + (i % 5) * 0.5).toFixed(1)}%`,
    //       inScanRate: `${(94 + (i % 5) * 0.6).toFixed(1)}%`,
    //     });
    //   }
    //   return res;
    // },
    onScrollToLower(e) {
      if (e?.detail?.direction === "right") return;
      // if (!Array.isArray(this.list)) this.list = [];
      // if (this.list.length - 1 >= this.totalCount) return;
      // if (this.isLoading) return;
      // this.isLoading = true;
      // const remain = this.totalCount - this.list.length;
      // const toAdd = Math.min(7, remain);
      // setTimeout(() => {
      //   if (this.list.length < this.totalCount) {
      //     const more = this.genRows(toAdd);
      //     this.list = this.list.concat(more);
      //   }
      //   this.isLoading = false;
      // }, 1000);
      this.fetchList();
    },
    resetFetch() {
      this.tablePage = 1;
      this.list = [];
      this.loading = true;
      this.hasmore = true;
      this.fetchList();
    },
    fetchList() {
      if (this._fetchDebounceTimer) clearTimeout(this._fetchDebounceTimer);
      const delay = 500;
      this._fetchDebounceTimer = setTimeout(() => {
        if (!this.hasmore) {
          setTimeout(() => {
            this.fetchLoading = false;
            this.loading = false;
          }, 500);
          return;
        }
        if (this.fetchLoading) return;
        this.fetchLoading = true;
        request(this.api, {
          physicName: this.product
            ? this.product?.physicName == "全品种"
              ? ""
              : this.product?.physicName
            : "",
          regionCode: this.region ? this.region?.regionCode || "" : "",
          pageNum: this.tablePage,
          pageSize: this.tablePageSize,
          path: "customerScanningRate/wigets/ScanRateTable.vue",
          ...(this.params || {}),
        }).then((res) => {
          if (res.code == 200) {
            const _data = res.data || {};
            let pageInfo = _data || {};

            if (this.tableType !== "variety") {
              this.summaryData = [];
              this.summaryData[0] = undefined;
              this.summaryStructure.forEach((item) => {
                this.summaryData.push(_data[item.key] || "--");
              });
              pageInfo = _data?.pageInfo || {};
            }

            const { list, total } = pageInfo;
            this.totalCount = total || 0;
            if (this.list.length >= this.totalCount) {
              this.fetchLoading = false;
              this.hasmore = false;
              this.loading = false;
              return;
            }
            this.list = Array.isArray(list)
              ? [...this.list, ...list]
              : [...this.list];
            if (this.list.length < this.totalCount) {
              this.hasmore = true;
              this.tablePage++;
            } else {
              this.hasmore = false;
            }
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
            // this.list.push(this.list[0]);
          }
          this.fetchLoading = false;
          this.loading = false;
        });
      }, delay);
    },
    headerCellStyle(ci, col) {
      const base = this.cellBaseStyle(ci, col);
      base.height = this.cellHeight;
      base.fontSize = this.headerFontSize;
      base.position = "sticky";
      base.zIndex = 2;
      base.top = "0rpx";
      base.background = "#eaf2ff";
      // base.display = 'flex';
      // base.alignItems = 'center';
      // base.justifyContent = 'center';
      if (ci === 0) {
        base.zIndex = 3;
      }
      if (col.fixed) {
        base.left = this.stickyLeft(ci);
      }
      return base;
    },
    bodyCellStyle(ci, col) {
      const base = this.cellBaseStyle(ci, col);
      // base.lineHeight = this.cellHeight;
      base.padding = "12rpx";
      base.fontSize = this.bodyFontSize;
      if (this.bodyFontColor) {
        base.color = this.bodyFontColor;
      }
      if (col.fixed) {
        base.position = "sticky";
        base.left = this.stickyLeft(ci);
        base.zIndex = 2;
      }
      return base;
    },
    cellBaseStyle(ci, col) {
      const style = {};
      // style.height = this.cellHeight;
      if (col && col.width) {
        style.width = col.width;
        style.flex = `0 0 ${col.width}`;
      } else {
        style.flex = 1;
      }
      return style;
    },
    stickyLeft(ci) {
      const parts = [];
      for (let i = 0; i < ci; i++) {
        const c = this.columns[i];
        if (c && c.fixed && c.width) parts.push(c.width);
      }
      if (!parts.length) return "0rpx";
      if (parts.length === 1) return parts[0];
      return `calc(${parts.join(" + ")})`;
    },
    isPlainTitle(t) {
      return typeof t === "string" ? t.indexOf("<") === -1 : true;
    },
    titleNodes(t) {
      if (typeof t !== "string") return t;
      let html = String(t);
      html = html
        .replace(/<\s*view/g, "<div")
        .replace(/<\/\s*view\s*>/g, "</div>");
      html = html.replace(
        /:style=\"\{\s*textAlign:\s*'center'\s*\}\"/g,
        'style="text-align:center;"',
      );
      return html;
    },
    handleClick(data, col) {
      if (
        this.tableType === "variety" ||
        this.tableType === "customerDetail" ||
        col.key !== "regionName"
      )
        return;
      uni.navigateTo({
        url:
          "/traceCodePackages/traceabilityReport/pages/customerScanningRate/detail/index?regionCode=" +
          data.regionCode +
          "&regionName=" +
          encodeURIComponent(data.regionName) +
          "&drugEntBaseInfoId=" +
          (data.druGentBaseInfoId || "") +
          "&physicName=" +
          encodeURIComponent(this.product?.physicName || "") +
          "&scanType=" +
          this.scanType +
          (this.params.type ? "&type=" + this.params.type : ""),
      });
    },
  },
};
</script>

<style scoped>
.section {
  margin-top: 24rpx;
  transform: translate3d(0, 0, 0);
}

.section-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8rpx 8rpx;
}

.section-title {
  position: relative;
  font-size: 30rpx;
  font-weight: bold;
  color: #2c69ff;
}

.section-title::after {
  content: "";
  position: absolute;
  left: -20rpx;
  bottom: 13rpx;
  width: 8rpx;
  height: 50%;
  background: #2c69ff;
  border-radius: 10px;
}

.selector-wrap {
  position: relative;
  margin-right: 40rpx;
}

.selector {
  position: relative;
  display: flex;
  align-items: center;
  color: #2c69ff;
  padding-right: 30rpx;
}

.selector-text {
  font-size: 30rpx;
  max-width: 180rpx;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  display: inline-block;
}

.selector-arrow {
  position: absolute;
  right: 0rpx;
  bottom: 14rpx;
  font-size: 30rpx;
  display: inline-block;
  width: 15rpx;
  height: 15rpx;
  border: 5rpx solid #2c69ff;
  border-top: none;
  border-left: none;
  transform-origin: 50% 50%;
  transform: rotate(45deg);
  transition: transform 0.2s;
}

.selector-arrow.open {
  bottom: 7rpx;
  transform: rotate(225deg);
}

.dropdown {
  position: absolute;
  right: 0rpx;
  top: 54rpx;
  width: 310rpx;
  max-height: 380rpx;
  background: #fff;
  border: 1rpx solid #eef0f4;
  border-radius: 12rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
  z-index: 93;
  overflow: hidden;
}

.dropdown-search-bar {
  padding: 10rpx;
  border-bottom: 1rpx solid #f0f2f5;
  background: #fff;
  z-index: 94;
}

.dropdown-search-input {
  width: 100%;
  height: 60rpx;
  background: #f5f7fa;
  border-radius: 8rpx;
  padding: 0 20rpx;
  font-size: 28rpx;
  box-sizing: border-box;
}

.dropdown-scroll-view {
  flex: 1;
  width: 100%;
  max-height: 260rpx;
  /* Adjusted height to fit search bar */
  overflow-y: auto;
}

.dropdown-item {
  padding: 16rpx 24rpx;
  font-size: 28rpx;
  color: #333;
  text-wrap: wrap;
}

.dropdown-item+.dropdown-item {
  border-top: 1rpx solid #f0f2f5;
}

.table-scroll-x {
  position: relative;
  margin-top: 12rpx;
  width: 100%;
  min-height: 120rpx;
  border-radius: 16rpx;
  overflow: visible;
}

.card {
  background: #fff;
  font-size: 32rpx;
}

.table-header {
  display: flex;
  background: #eaf2ff;
  font-weight: bold;
  color: #2c69ff;
  border-top-left-radius: 16rpx;
  border-top-right-radius: 16rpx;
}

/* .table-body {
  margin-top: 8rpx;
} */
.row {
  display: flex;
  align-items: stretch;
  border-bottom: 1rpx solid #eef0f4;
}

.row:last-child,
.row:nth-last-child(2) {
  border-bottom: none;
}

.loading-row {
  justify-content: flex-start;
}

.loading-wrapper {
  width: calc(100vw - 60rpx);
  height: 76rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  position: sticky;
  top: 50%;
  left: 0;
}

.loading-icon {
  width: 40rpx;
  height: 40rpx;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.cell {
  flex: 1;
  box-sizing: border-box;
  width: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  /* text-align: center; */
  word-break: break-all;
}

.table-body .cell {
  background-color: #fff;
  text-align: center;
}

.table-body .striped {
  background: #f7f7f7;
}

.underline {
  text-decoration: underline;
  color: #2c69ff;
}

/* hide scrollbars for H5/App while preserving scroll behavior */
.no-scrollbar {
  position: relative;
  -ms-overflow-style: none;
  scrollbar-width: none;
  z-index: 2;
}

::v-deep .no-scrollbar::-webkit-scrollbar {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
  -webkit-appearance: none;
  background: transparent;
}

.header-tooltip-wrap {
  position: absolute;
  top: 60rpx;
  right: 0rpx;
  z-index: 93;
}

.header-tooltip {
  background: #000;
  color: #fff;
  border-radius: 8rpx;
  padding: 8rpx 12rpx;
  font-size: 24rpx;
  width: 270rpx;
}

.header-tooltip-arrow {
  position: absolute;
  top: -11rpx;
  right: 20rpx;
  width: 0;
  height: 0;
  border-left: 10rpx solid transparent;
  border-right: 10rpx solid transparent;
  border-bottom: 12rpx solid #000;
  margin: 0 auto;
}

.no-data-placeholder {
  opacity: 0;
}

.no-data {
  position: absolute;
  top: 76rpx;
  left: 0;
  width: 100%;
  z-index: 1;
}
</style>
