wanshenmean
2024-09-11 28f1259ec675a191d2a852f74566400e6cc40b50
Code Management/WMS/WIDESEA_WMSClient/src/components/basic/VolTable.vue
@@ -1,333 +1,171 @@
<template>
  <!-- 2021.11.18移除voltable方法@cell-mouse-leave="rowEndEdit" -->
  <div
    class="vol-table"
    :class="[
      textInline ? 'text-inline' : '',
      fxRight ? 'fx-right' : '',
      isChrome ? 'chrome' : '',
      smallCell?'small-table':''
    ]"
  >
  <div class="vol-table" :class="[
    textInline ? 'text-inline' : '',
    fxRight ? 'fx-right' : '',
    isChrome ? 'chrome' : '',
    smallCell ? 'small-table' : ''
  ]">
    <div class="mask" v-show="loading"></div>
    <div class="message" v-show="loading">加载中.....</div>
    <el-table
      :show-summary="summary"
      :summary-method="getSummaryData"
      :row-key="rowKey"
      :key="randomTableKey"
      :lazy="lazy"
      :defaultExpandAll="defaultExpandAll"
      :expand-row-keys="rowKey ? expandRowKeys : undefined"
      stripe
      :load="loadTreeChildren"
      @select="userSelect"
      @select-all="userSelect"
      @selection-change="selectionChange"
      @row-dblclick="rowDbClick"
      @row-click="rowClick"
      @header-click="headerClick"
      :highlight-current-row="highlightCurrentRow"
      ref="table"
      class="v-table"
      @sort-change="sortChange"
      tooltip-effect="dark"
      :height="realHeight"
      :max-height="realMaxHeight"
      :data="url ? rowData : tableData"
      border
      :row-class-name="initIndex"
      :cell-style="getCellStyle"
      style="width: 100%"
      :scrollbar-always-on="true"
      :span-method="cellSpanMethod"
      @expand-change="expandChange"
    >
      <el-table-column
        v-if="columnIndex"
        type="index"
        :fixed="fixed"
        width="55"
      ></el-table-column>
      <el-table-column
        v-if="ck"
        type="selection"
        :fixed="fixed"
        :selectable="selectable"
        width="55"
      ></el-table-column>
    <el-table :show-summary="summary" :summary-method="getSummaryData" :row-key="rowKey" :key="randomTableKey"
      :lazy="lazy" :defaultExpandAll="defaultExpandAll" :expand-row-keys="rowKey ? expandRowKeys : undefined" stripe
      :load="loadTreeChildren" @select="userSelect" @select-all="userSelect" @selection-change="selectionChange"
      @row-dblclick="rowDbClick" @row-click="rowClick" @header-click="headerClick"
      :highlight-current-row="highlightCurrentRow" ref="table" class="v-table" @sort-change="sortChange"
      tooltip-effect="dark" :height="realHeight" :max-height="realMaxHeight" :data="url ? rowData : tableData" border
      :row-class-name="initIndex" :cell-style="getCellStyle" style="width: 100%" :scrollbar-always-on="true"
      :span-method="cellSpanMethod" @expand-change="expandChange">
      <el-table-column v-if="columnIndex" type="index" :fixed="fixed" width="55"></el-table-column>
      <el-table-column v-if="ck" type="selection" :fixed="fixed" :selectable="selectable" width="55"></el-table-column>
      <!-- 2020.10.10移除table第一行强制排序 -->
      <el-table-column
        v-for="(column, cindex) in filterColumns"
        :prop="column.field"
        :label="column.title"
        :min-width="column.width"
        :formatter="formatter"
        :fixed="column.fixed"
        :key="column.field + cindex"
        :align="column.align"
        :sortable="column.sort ? 'custom' : false"
        :show-overflow-tooltip="column.showOverflowTooltip"
      >
      <el-table-column v-for="(column, cindex) in filterColumns" :prop="column.field" :label="column.title"
        :min-width="column.width" :formatter="formatter" :fixed="column.fixed" :key="column.field + cindex"
        :align="column.align" :sortable="column.sort ? 'custom' : false"
        :show-overflow-tooltip="column.showOverflowTooltip">
        <template #header>
          <span
            v-if="(column.require || column.required) && column.edit"
            class="column-required"
            >*</span
          >{{ column.title }}
          <span v-if="(column.require || column.required) && column.edit" class="column-required">*</span>{{
            column.title }}
        </template>
        <template #default="scope">
          <!-- 2022.01.08增加多表头,现在只支持常用功能渲染,不支持编辑功能(涉及到组件重写) -->
          <el-table-column
            style="border: none"
            v-for="columnChildren in filterChildrenColumn(column.children)"
            :key="columnChildren.field"
            :min-width="columnChildren.width"
            :class-name="columnChildren.class"
            :prop="columnChildren.field"
            :align="columnChildren.align"
            :label="columnChildren.title"
          >
          <el-table-column style="border: none" v-for="columnChildren in filterChildrenColumn(column.children)"
            :key="columnChildren.field" :min-width="columnChildren.width" :class-name="columnChildren.class"
            :prop="columnChildren.field" :align="columnChildren.align" :label="columnChildren.title">
            <template #default="scopeChildren">
              <a
                href="javascript:void(0);"
                style="text-decoration: none"
                @click="link(scopeChildren.row, columnChildren, $event)"
                v-if="columnChildren.link"
                v-text="scopeChildren.row[columnChildren.field]"
              ></a>
              <table-render
                  v-else-if="columnChildren.render && typeof columnChildren.render == 'function'"
                  :row="scopeChildren.row"
                  key="rd-01"
                  :index="scope.$index"
                  :column="columnChildren"
                  :render="columnChildren.render"
                ></table-render>
              <div
                v-else-if="columnChildren.formatter"
                @click="
                  columnChildren.click &&
                    columnChildren.click(
                      scopeChildren.row,
                      columnChildren,
                      scopeChildren.$index
                    )
                "
                v-html="
                  columnChildren.formatter(
                    scopeChildren.row,
                    columnChildren,
                    scopeChildren.$index
                  )
                "
              ></div>
              <a href="javascript:void(0);" style="text-decoration: none"
                @click="link(scopeChildren.row, columnChildren, $event)" v-if="columnChildren.link"
                v-text="scopeChildren.row[columnChildren.field]"></a>
              <table-render v-else-if="columnChildren.render && typeof columnChildren.render == 'function'"
                :row="scopeChildren.row" key="rd-01" :index="scope.$index" :column="columnChildren"
                :render="columnChildren.render"></table-render>
              <div v-else-if="columnChildren.formatter" @click="
                columnChildren.click &&
                columnChildren.click(
                  scopeChildren.row,
                  columnChildren,
                  scopeChildren.$index
                )
                " v-html="columnChildren.formatter(
                  scopeChildren.row,
                  columnChildren,
                  scopeChildren.$index
                )
                  "></div>
              <div v-else-if="columnChildren.bind">
                {{ formatter(scopeChildren.row, columnChildren, true) }}
              </div>
              <span v-else-if="columnChildren.type == 'date'">{{
                formatterDate(scopeChildren.row, columnChildren)
              }}</span>
                }}</span>
              <template v-else>
                {{ scopeChildren.row[columnChildren.field] }}
              </template>
            </template>
          </el-table-column>
          <!-- 2020.06.18增加render渲染自定义内容 -->
          <table-render
            v-if="column.render && typeof column.render == 'function'"
            :row="scope.row"
            key="rd-01"
            :index="scope.$index"
            :column="column"
            :render="column.render"
          ></table-render>
          <table-render v-if="column.render && typeof column.render == 'function'" :row="scope.row" key="rd-01"
            :index="scope.$index" :column="column" :render="column.render"></table-render>
          <!-- 启用双击编辑功能,带编辑功能的不会渲染下拉框文本背景颜色 -->
          <!-- @click="rowBeginEdit(scope.$index,cindex)" -->
          <!-- 2021.09.21增加编辑时对readonly属性判断 -->
           <template v-else-if="column.edit&&!column.readonly&&['file', 'img','excel'].indexOf(column.edit.type) != -1" >
                <div style="display:flex;align-items: center;" @click.stop>
                  <i v-if="!column.showUpload||column.showUpload(scope.row, column)"
                  style="padding: 3px;margin-right: 10px;color:#8f9293;cursor: pointer;"
                  @click="showUpload(scope.row, column)" class="el-icon-upload"></i>
                   <template v-if="column.edit.type == 'img'">
                    <img
                    v-for="(file, imgIndex) in getFilePath(
                      scope.row[column.field],
                      column
                    )"
                    :key="imgIndex"
                    @error="handleImageError"
                    @click="viewImg(scope.row, column, file.path, $event,imgIndex)"
                    class="table-img"
                    :src="file.path"
                  />
                   </template>
                  <a
                    style="margin-right: 8px"
                    v-else
                    class="t-file"
                    v-for="(file, fIndex) in getFilePath(
                      scope.row[column.field],
                      column
                    )"
                    :key="fIndex"
                    @click="dowloadFile(file)"
                    >{{ file.name }}</a
                  >
                </div>
          <template v-else-if="column.edit && !column.readonly && ['file', 'img', 'excel'].indexOf(column.edit.type) != -1">
            <div style="display:flex;align-items: center;" @click.stop>
              <i v-if="!column.showUpload || column.showUpload(scope.row, column)"
                style="padding: 3px;margin-right: 10px;color:#8f9293;cursor: pointer;"
                @click="showUpload(scope.row, column)" class="el-icon-upload"></i>
              <template v-if="column.edit.type == 'img'">
                <img v-for="(file, imgIndex) in getFilePath(
                  scope.row[column.field],
                  column
                )" :key="imgIndex" @error="handleImageError"
                  @click="viewImg(scope.row, column, file.path, $event, imgIndex)" class="table-img" :src="file.path" />
              </template>
              <a style="margin-right: 8px" v-else class="t-file" v-for="(file, fIndex) in getFilePath(
                scope.row[column.field],
                column
              )" :key="fIndex" @click="dowloadFile(file)">{{ file.name }}</a>
            </div>
          </template>
          <div
            v-else-if="
              column.edit &&
                !column.readonly &&
                (column.edit.keep || edit.rowIndex == scope.$index)
            "
            class="edit-el"
          >
          <div v-else-if="
            column.edit &&
            !column.readonly &&
            (column.edit.keep || edit.rowIndex == scope.$index)
          " class="edit-el">
            <div @click.stop class="e-item">
              <div>
                <!-- 2020.07.24增加日期onChange事件 -->
                <el-date-picker
                  clearable
                  size="default"
                  style="width: 100%"
                  v-if="['date', 'datetime'].indexOf(column.edit.type) != -1"
                  v-model="scope.row[column.field]"
                  @change="
                    (val) => {
                <el-date-picker clearable size="default" style="width: 100%"
                  v-if="['date', 'datetime'].indexOf(column.edit.type) != -1" v-model="scope.row[column.field]" @change="(val) => {
                      column.onChange &&
                        column.onChange(scope.row, column, val);
                    }
                  "
                  :type="column.edit.type"
                  :placeholder="column.placeholder || column.title"
                  :disabledDate="(val) => getDateOptions(val, column)"
                  :value-format="getDateFormat(column)"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                    " :type="column.edit.type" :placeholder="column.placeholder || column.title"
                  :disabledDate="(val) => getDateOptions(val, column)" :value-format="getDateFormat(column)"
                  :disabled="initColumnDisabled(scope.row, column)">
                </el-date-picker>
                <el-time-picker
                  clearable
                  size="default"
                  style="width: 100%"
                  v-else-if="column.edit.type == 'time'"
                  v-model="scope.row[column.field]"
                  @change="
                    (val) => {
                <el-time-picker clearable size="default" style="width: 100%" v-else-if="column.edit.type == 'time'"
                  v-model="scope.row[column.field]" @change="(val) => {
                      column.onChange &&
                        column.onChange(scope.row, column, val);
                    }
                  "
                  :placeholder="column.placeholder || column.title"
                  :value-format="column.format || 'HH:mm:ss'"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                    " :placeholder="column.placeholder || column.title" :value-format="column.format || 'HH:mm:ss'"
                  :disabled="initColumnDisabled(scope.row, column)">
                </el-time-picker>
                <el-switch
                  v-else-if="column.edit.type == 'switch'"
                  v-model="scope.row[column.field]"
                  active-color="#0f84ff"
                  inactive-color="rgb(194 194 194)"
                  active-text="是"
                  inactive-text="否"
                  inline-prompt
                  @change="
                    (val) => {
                <el-switch v-else-if="column.edit.type == 'switch'" v-model="scope.row[column.field]"
                  active-color="#0f84ff" inactive-color="rgb(194 194 194)" active-text="是" inactive-text="否"
                  inline-prompt @change="(val) => {
                      switchChange(val, scope.row, column);
                    }
                  "
                  :active-value="
                    typeof scope.row[column.field] == 'boolean'
                    " :active-value="typeof scope.row[column.field] == 'boolean'
                      ? true
                      : typeof scope.row[column.field] == 'string'
                      ? '1'
                      : 1
                  "
                  :inactive-value="
                    typeof scope.row[column.field] == 'boolean'
                        ? '1'
                        : 1
                    " :inactive-value="typeof scope.row[column.field] == 'boolean'
                      ? false
                      : typeof scope.row[column.field] == 'string'
                      ? '0'
                      : 0
                  "
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                        ? '0'
                        : 0
                    " :disabled="initColumnDisabled(scope.row, column)">
                </el-switch>
                <template
                  v-else-if="
                    ['select', 'selectList'].indexOf(column.edit.type) != -1
                  "
                >
                  <el-select-v2
                    style="width: 100%"
                    :size="size"
                    v-if="column.bind.data.length >= select2Count"
                    v-model="scope.row[column.field]"
                    filterable
                    :multiple="column.edit.type == 'select' ? false : true"
                    :placeholder="column.placeholder || column.title"
                    :autocomplete="column.autocomplete"
                    :options="column.bind.data"
                    @change="
                <template v-else-if="
                  ['select', 'selectList'].indexOf(column.edit.type) != -1
                ">
                  <el-select-v2 style="width: 100%" :size="size" v-if="column.bind.data.length >= select2Count"
                    v-model="scope.row[column.field]" filterable :multiple="column.edit.type == 'select' ? false : true"
                    :placeholder="column.placeholder || column.title" :autocomplete="column.autocomplete"
                    :options="column.bind.data" @change="
                      column.onChange && column.onChange(scope.row, column)
                    "
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
                      " clearable :disabled="initColumnDisabled(scope.row, column)">
                    <template #default="{ item }">
                      {{ item.label }}
                    </template>
                  </el-select-v2>
                  <el-select
                    size="default"
                    style="width: 100%"
                    v-else
                    v-model="scope.row[column.field]"
                    :filterable="
                      column.filter || column.bind.data.length > 10
                        ? true
                        : false
                    "
                    :multiple="column.edit.type == 'select' ? false : true"
                    :placeholder="column.placeholder || column.title"
                    :allow-create="column.autocomplete"
                    @change="
                  <el-select size="default" style="width: 100%" v-else v-model="scope.row[column.field]" :filterable="column.filter || column.bind.data.length > 10
                      ? true
                      : false
                    " :multiple="column.edit.type == 'select' ? false : true"
                    :placeholder="column.placeholder || column.title" :allow-create="column.autocomplete" @change="
                      column.onChange && column.onChange(scope.row, column)
                    "
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
                    <el-option
                      v-for="item in column.bind.data"
                      :key="item.key"
                      v-show="!item.hidden"
                      :disabled="item.disabled"
                      :label="item.value"
                      :value="item.key"
                      >{{ item.value }}
                      " clearable :disabled="initColumnDisabled(scope.row, column)">
                    <el-option v-for="item in column.bind.data" :key="item.key" v-show="!item.hidden"
                      :disabled="item.disabled" :label="item.value" :value="item.key">{{ item.value }}
                    </el-option>
                  </el-select>
                </template>
                <el-tree-select
                  style="width: 100%"
                  v-else-if="column.edit.type == 'treeSelect'||column.edit.type == 'cascader'"
                  v-model="scope.row[column.field]"
                  :data="column.bind.data"
                  :multiple="column.multiple===undefined?true:column.multiple"
                  :render-after-expand="false"
                  :show-checkbox="true"
                  :check-strictly="column.checkStrictly===undefined?true:column.checkStrictly"
                  check-on-click-node
                  node-key="key"
                  @change="column.onChange && column.onChange(scope.row, column)"
                <el-tree-select style="width: 100%"
                  v-else-if="column.edit.type == 'treeSelect' || column.edit.type == 'cascader'"
                  v-model="scope.row[column.field]" :data="column.bind.data"
                  :multiple="column.multiple === undefined ? true : column.multiple" :render-after-expand="false"
                  :show-checkbox="true" :check-strictly="column.checkStrictly === undefined ? true : column.checkStrictly"
                  check-on-click-node node-key="key" @change="column.onChange && column.onChange(scope.row, column)"
                  :props="{ label: 'label' }">
                   <template #default="{ data, node }">
                  {{data.label}}</template>
                  <template #default="{ data, node }">
                    {{ data.label }}</template>
                </el-tree-select>
                <!-- <div     v-else-if="column.edit.type == 'cascader'">4444444</div> -->
                <!-- <el-cascader
@@ -342,41 +180,21 @@
                  @change="column.onChange && column.onChange(scope.row, column)"
                >
                </el-cascader> -->
                <el-input
                  v-else-if="column.edit.type == 'textarea'"
                  type="textarea"
                  :placeholder="column.placeholder || column.title"
                  v-model="scope.row[column.field]"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                <el-input v-else-if="column.edit.type == 'textarea'" type="textarea"
                  :placeholder="column.placeholder || column.title" v-model="scope.row[column.field]"
                  :disabled="initColumnDisabled(scope.row, column)">
                </el-input>
                <input
                  class="table-input"
                  v-else-if="!column.summary && !column.onKeyPress"
                  v-model.lazy="scope.row[column.field]"
                  :placeholder="column.placeholder || column.title"
                  :disabled="initColumnDisabled(scope.row, column)"
                />
                <el-input
                  v-else
                  @change="inputKeyPress(scope.row, column, $event)"
                <input class="table-input" v-else-if="!column.summary && !column.onKeyPress"
                  v-model.lazy="scope.row[column.field]" :placeholder="column.placeholder || column.title"
                  :disabled="initColumnDisabled(scope.row, column)" />
                <el-input v-else @change="inputKeyPress(scope.row, column, $event)"
                  @input="inputKeyPress(scope.row, column, $event)"
                  @keyup.enter="inputKeyPress(scope.row, column, $event)"
                  size="default"
                  v-model="scope.row[column.field]"
                  :placeholder="column.placeholder || column.title"
                  :disabled="initColumnDisabled(scope.row, column)"
                ></el-input>
                  @keyup.enter="inputKeyPress(scope.row, column, $event)" size="default"
                  v-model="scope.row[column.field]" :placeholder="column.placeholder || column.title"
                  :disabled="initColumnDisabled(scope.row, column)"></el-input>
              </div>
              <div
                class="extra"
                v-if="column.extra && edit.rowIndex == scope.$index"
              >
                <a
                  :style="column.extra.style"
                  style="text-decoration: none"
                  @click="extraClick(scope.row, column)"
                >
              <div class="extra" v-if="column.extra && edit.rowIndex == scope.$index">
                <a :style="column.extra.style" style="text-decoration: none" @click="extraClick(scope.row, column)">
                  <i v-if="column.extra.icon" :class="[column.extra.icon]" />
                  {{ column.extra.text }}
                </a>
@@ -385,78 +203,42 @@
          </div>
          <!--没有编辑功能的直接渲染标签-->
          <template v-else>
            <a
              href="javascript:void(0)"
              style="text-decoration: none;line-height: 1.3;"
              @click="link(scope.row, column, $event)"
              v-if="column.link"
              v-text="scope.row[column.field]"
            ></a>
            <img
              v-else-if="column.type == 'img'"
              v-for="(file, imgIndex) in getFilePath(
                scope.row[column.field],
                column
              )"
              :key="imgIndex"
              @error="handleImageError"
              @click="viewImg(scope.row, column, file.path, $event, imgIndex)"
              class="table-img"
              :src="file.path"
            />
            <a
              style="margin-right: 8px"
              v-else-if="column.type == 'file' || column.type == 'excel'"
              class="t-file"
            <a href="javascript:void(0)" style="text-decoration: none;line-height: 1.3;"
              @click="link(scope.row, column, $event)" v-if="column.link" v-text="scope.row[column.field]"></a>
            <img v-else-if="column.type == 'img'" v-for="(file, imgIndex) in getFilePath(
              scope.row[column.field],
              column
            )" :key="imgIndex" @error="handleImageError"
              @click="viewImg(scope.row, column, file.path, $event, imgIndex)" class="table-img" :src="file.path" />
            <a style="margin-right: 8px" v-else-if="column.type == 'file' || column.type == 'excel'" class="t-file"
              v-for="(file, fIndex) in getFilePath(
                scope.row[column.field],
                column
              )"
              :key="fIndex"
              @click="dowloadFile(file)"
              >{{ file.name }}</a
            >
              )" :key="fIndex" @click="dowloadFile(file)">{{ file.name }}</a>
            <span v-else-if="column.type == 'date'">{{
              formatterDate(scope.row, column)
            }}</span>
            <div
              v-else-if="column.formatter"
              @click="formatterClick(scope.row, column, $event)"
              v-html="column.formatter(scope.row, column)"
            ></div>
              }}</span>
            <div v-else-if="column.formatter" @click="formatterClick(scope.row, column, $event)"
              v-html="column.formatter(scope.row, column)"></div>
            <!-- 2021.11.18修复table数据源设置为normal后点击行$event缺失的问题 -->
            <div
              v-else-if="column.bind && (column.normal || column.edit)"
            <div v-else-if="column.bind && (column.normal || column.edit)"
              @click="formatterClick(scope.row, column, $event)"
              :style="column.getStyle && column.getStyle(scope.row, column)"
            >
              :style="column.getStyle && column.getStyle(scope.row, column)">
              {{ formatter(scope.row, column, true) }}
            </div>
            <div
              v-else-if="column.click && !column.bind"
              @click="formatterClick(scope.row, column)"
            >
            <div v-else-if="column.click && !column.bind" @click="formatterClick(scope.row, column)">
              {{ scope.row[column.field] }}
            </div>
            <div
              @click="
                () => {
                  column.click && formatterClick(scope.row, column);
                }
              "
              v-else-if="column.bind"
            >
              <el-tag
                v-if="useTag"
                 class="cell-tag"
                :class="[isEmptyTag(scope.row, column)]"
                :type="getColor(scope.row, column)"
                :effect="column.effect"
                >{{ formatter(scope.row, column, true) }}</el-tag
              >
            <div @click="() => {
                column.click && formatterClick(scope.row, column);
              }
              " v-else-if="column.bind">
              <el-tag v-if="useTag" class="cell-tag" :class="[isEmptyTag(scope.row, column)]"
                :type="getColor(scope.row, column)" :effect="column.effect">{{ formatter(scope.row, column, true)
                }}</el-tag>
              <template v-else>{{
                formatter(scope.row, column, true)
              }}</template>
                }}</template>
            </div>
            <span v-else>{{ formatter(scope.row, column, true) }}</span>
@@ -467,53 +249,29 @@
    <template v-if="!paginationHide">
      <div class="block pagination" key="pagination-01" style="display: flex">
        <div style="flex: 1"></div>
        <el-pagination
          key="pagination-02"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="paginations.page"
          :page-sizes="paginations.sizes"
          :page-size="paginations.size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="paginations.total"
        ></el-pagination>
        <el-pagination key="pagination-02" @size-change="handleSizeChange" @current-change="handleCurrentChange"
          :current-page="paginations.page" :page-sizes="paginations.sizes" :page-size="paginations.size"
          layout="total, sizes, prev, pager, next, jumper" :total="paginations.total"></el-pagination>
      </div>
    </template>
  </div>
  <VolBox
    v-model="uploadModel"
    title="上传"
    :height="228"
    :width="500"
    :padding="15"
    lazy
  >
  <VolBox v-model="uploadModel" title="上传" :height="228" :width="500" :padding="15" lazy>
    <!-- 上传图片、excel或其他文件、文件数量、大小限制都可以,参照volupload组件api -->
    <div style="height: 200px;display: flex;align-items: center;">
      <VolUpload
      style="text-align: center; "
      :autoUpload="currentColumn.edit.autoUpload"
      :multiple="currentColumn.edit.multiple"
      :url="uploadUrl"
      :max-file="currentColumn.edit.maxFile"
      :img="currentColumn.edit.type == 'img'"
      :excel="currentColumn.edit.type == 'excel'"
      :fileTypes="currentColumn.edit.fileTypes ? currentColumn.edit.fileTypes : []"
      :fileInfo="fileInfo"
      :upload-after="uploadAfter"
      :upload-before="uploadBefore"
      :append="currentColumn.edit.accept"
    >
      <div>{{ currentColumn.message}}</div>
    </VolUpload>
      <VolUpload style="text-align: center; " :autoUpload="currentColumn.edit.autoUpload"
        :multiple="currentColumn.edit.multiple" :url="uploadUrl" :max-file="currentColumn.edit.maxFile"
        :img="currentColumn.edit.type == 'img'" :excel="currentColumn.edit.type == 'excel'"
        :fileTypes="currentColumn.edit.fileTypes ? currentColumn.edit.fileTypes : []" :fileInfo="fileInfo"
        :upload-after="uploadAfter" :upload-before="uploadBefore" :append="currentColumn.edit.accept">
        <div>{{ currentColumn.message }}</div>
      </VolUpload>
    </div>
    <template #footer>
        <div style="text-align: center; ">
          <el-button type="default" size="small" @click="uploadModel=false">关闭</el-button >
          <el-button type="primary" size="small" @click="saveUpload" >保存</el-button >
        </div>
      <div style="text-align: center; ">
        <el-button type="default" size="small" @click="uploadModel = false">关闭</el-button>
        <el-button type="primary" size="small" @click="saveUpload">保存</el-button>
      </div>
    </template>
  </VolBox>
  <vol-image-viewer ref="viewer"></vol-image-viewer>
@@ -521,9 +279,9 @@
<script>
import VolTableRender from './VolTable/VolTableRender';
let _errMsg;
import { defineComponent,defineAsyncComponent } from 'vue';
import { defineComponent, defineAsyncComponent } from 'vue';
export default defineComponent({
  emits:['loadBefore','loadAfter','rowChange', 'rowClick', 'rowDbClick', 'selectionChange'],
  emits: ['loadBefore', 'loadAfter', 'rowChange', 'rowClick', 'rowDbClick', 'selectionChange'],
  //https://github.com/element-plus/element-plus/issues/1483
  //没有原先的selection属性了,看issue上使用select/selectall获取
  //监听数组长度,如果删除了数据,现在只能被迫清除所有选中的行
@@ -540,9 +298,9 @@
    }
  },
  components: {
    'vol-image-viewer':defineAsyncComponent(() => import("./VolImageViewer.vue")),
    'vol-image-viewer': defineAsyncComponent(() => import("./VolImageViewer.vue")),
    'table-render': VolTableRender,
    VolUpload: defineAsyncComponent(() =>import("./VolUpload.vue") ),
    VolUpload: defineAsyncComponent(() => import("./VolUpload.vue")),
    VolBox: defineAsyncComponent(() => import("./VolBox.vue")),
  },
  props: {
@@ -555,9 +313,9 @@
      // 树形结构加载子节点
      type: Function,
      default: (tree, treeNode, resolve) => {
          if(resolve){
        if (resolve) {
          return resolve([]);
         }
        }
      }
    },
    textInline: {
@@ -586,13 +344,13 @@
    },
    linkView: {
      type: Function,
      default: function() {
      default: function () {
        return 1;
      }
    },
    pagination: {
      type: Object,
      default: function() {
      default: function () {
        return { total: 0, size: 30, sortName: '' };
      }
    },
@@ -639,21 +397,21 @@
    beginEdit: {
      // 编辑开始
      type: Function,
      default: function(row, column, index) {
      default: function (row, column, index) {
        return true;
      }
    },
    endEditBefore: {
      // 结束编辑前
      type: Function,
      default: function(row, column, index) {
      default: function (row, column, index) {
        return true;
      }
    },
    endEditAfter: {
      // 结束编辑前
      type: Function,
      default: function(row, column, index) {
      default: function (row, column, index) {
        return true;
      }
    },
@@ -683,9 +441,9 @@
        return true;
      }
    },
    spanMethod:{
    spanMethod: {
      type: Function,
      default: ({row,column,rowIndex, columnIndex}) => {
      default: ({ row, column, rowIndex, columnIndex }) => {
      }
    },
    lazy: { //树形表格是否默认延迟加载
@@ -696,15 +454,15 @@
      type: Boolean,
      default: false
    },
    expandRowKeys:{ //默认展开行
      type:Array,
      default:()=>{
    expandRowKeys: { //默认展开行
      type: Array,
      default: () => {
        return []
      }
    },
    rowParentField:{ //树形表格父级id
          type:String,
          default:""
    rowParentField: { //树形表格父级id
      type: String,
      default: ""
    }
  },
  data() {
@@ -718,14 +476,14 @@
      realMaxHeight: 0,
      enableEdit: false, // 是否启表格用编辑功能
      empty: this.allowEmpty ? '' : '--',
      defaultImg:new URL('@/assets/imgs/error-img.png', import.meta.url).href,
      defaultImg: new URL('@/assets/imgs/error-img.png', import.meta.url).href,
      loading: false,
      footer: {},
      total: 0,
      formatConfig: {},
      // defaultColor: "",
      // 2020.09.06调整table列数据源的背景颜色
      colors:["primary", "success", "info", "warning", "danger"],// ["warning", "success", "danger", "info"],
      colors: ["primary", "success", "info", "warning", "danger"],// ["warning", "success", "danger", "info"],
      rule: {
        phone: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
        decimal: /(^[\-0-9][0-9]*(.[0-9]+)?)$/,
@@ -760,18 +518,18 @@
      //vol-table带数据源的单元格是否启用tag标签(下拉框等单元格以tag标签显示)
      //2023.04.02更新voltable与main.js
      useTag: true,
      currentRow:{},
      currentColumn:[],
      fileInfo:[],
      uploadUrl:"",
      uploadModel:false,
      smallCell:true
      currentRow: {},
      currentColumn: [],
      fileInfo: [],
      uploadUrl: "",
      uploadModel: false,
      smallCell: true
    };
  },
  created() {
    try {
      this.useTag = this.$global.table&&this.$global.table.useTag;
      this.smallCell=this.$global.table&&this.$global.table.smallCell;
      this.useTag = this.$global.table && this.$global.table.useTag;
      this.smallCell = this.$global.table && this.$global.table.smallCell;
    } catch (error) {
      console.log(error.message);
    }
@@ -812,7 +570,7 @@
    }
    this.initCellStyleColumns();
    this.columns.forEach((x, _index) => {
      if (!x.hidden) {
        // this.summaryIndex[x.field] = _index;
        // 2020.10.11修复求和列错位的问题
@@ -823,15 +581,15 @@
      if (x.summary && !this.summary) {
        this.summary = true;
      }
      if (x.children&&Array.isArray(x.children)) {
          x.children.forEach(cl=>{
               if (cl.bind && cl.bind.key && (!cl.bind.data || cl.bind.data.length == 0)) {
                keys.push(cl.bind.key);
                cl.bind.valueType = cl.type;
                columnBind.push(cl.bind);
               }
          })
      }else if (x.bind && x.bind.key && (!x.bind.data || x.bind.data.length == 0)) {
      if (x.children && Array.isArray(x.children)) {
        x.children.forEach(cl => {
          if (cl.bind && cl.bind.key && (!cl.bind.data || cl.bind.data.length == 0)) {
            keys.push(cl.bind.key);
            cl.bind.valueType = cl.type;
            columnBind.push(cl.bind);
          }
        })
      } else if (x.bind && x.bind.key && (!x.bind.data || x.bind.data.length == 0)) {
        // 写入远程
        if (!x.bind.data) x.bind.data = [];
        if (x.bind.remote) {
@@ -839,8 +597,8 @@
        } else if (this.loadKey) {
          keys.push(x.bind.key);
          x.bind.valueType = x.type;
          if (x.edit&&x.edit.type) {
            x.bind.editType=x.edit.type
          if (x.edit && x.edit.type) {
            x.bind.editType = x.edit.type
          }
          columnBind.push(x.bind);
        }
@@ -857,24 +615,24 @@
                item.value = item.key;
              });
            }
            const arrType=['cascader','treeSelect'];
            const arrType = ['cascader', 'treeSelect'];
            columnBind.forEach((c) => {
            if ((arrType.indexOf(c.valueType)!=-1||arrType.indexOf(c.editType)!=-1)) {
                this.columns.forEach(col=>{
                    if (col.bind&&col.bind.key==c.key) {
                        col.bind.orginData=JSON.parse(JSON.stringify(x.data));
                    }
              if ((arrType.indexOf(c.valueType) != -1 || arrType.indexOf(c.editType) != -1)) {
                this.columns.forEach(col => {
                  if (col.bind && col.bind.key == c.key) {
                    col.bind.orginData = JSON.parse(JSON.stringify(x.data));
                  }
                })
                x.data = this.base.convertTree(x.data, (node, data, isRoot) => {
                    if (!node.inited) {
                      node.inited = true;
                      node.label = node.value;
                      node.value = node.key+'';
                    }
                  if (!node.inited) {
                    node.inited = true;
                    node.label = node.value;
                    node.value = node.key + '';
                  }
                });
              }
              // 转换数据源的类型与列的类型一致(2020.04.04)
            else  if (c.key == x.dicNo && (c.valueType == "int" || c.valueType == "sbyte")) {
              else if (c.key == x.dicNo && (c.valueType == "int" || c.valueType == "sbyte")) {
                x.data.forEach((d) => {
                  // 2020.09.01增加对数字类型的二次判断
                  if (!isNaN(d.key)) {
@@ -916,11 +674,11 @@
    }
  },
  methods: {
    initCellStyleColumns(){
      this.columns.forEach(x=>{
    initCellStyleColumns() {
      this.columns.forEach(x => {
        if (x.cellStyle) {
          this.cellStyleColumns[x.field] = x.cellStyle;
         }
        }
      })
    },
    watchRowSelectChange(newLen, oldLen) {
@@ -1130,7 +888,7 @@
      // }
      return;
    },
    toggleEdit(event) {},
    toggleEdit(event) { },
    setEditStatus(status) {
      // this.columns.forEach((x) => {
      //   if (x.hasOwnProperty("edit")) {
@@ -1175,13 +933,13 @@
            }
          } else {
            //多选或者级联编辑回写,2023.01.06
             if (Array.isArray(val)) {
              val = val.map(v=>{
                   return v*1
            if (Array.isArray(val)) {
              val = val.map(v => {
                return v * 1
              });
              row[column.field] = val;
            }
            else  if (typeof val == 'string' && val) {
            else if (typeof val == 'string' && val) {
              let _val = val * 1;
              if (_val + '' === val) {
                row[column.field] = _val;
@@ -1376,10 +1134,10 @@
      }
      this.rowData.push(row);
    },
    viewImg(row, column, url, $event,index) {
        $event.stopPropagation();
        const imgs=  this.getFilePath(row[column.field], column).map(x=>{return x.path});
        this.$refs.viewer.show(imgs,index);
    viewImg(row, column, url, $event, index) {
      $event.stopPropagation();
      const imgs = this.getFilePath(row[column.field], column).map(x => { return x.path });
      this.$refs.viewer.show(imgs, index);
      //this.base.previewImg(url);
      // window.open(row[column.field]);
    },
@@ -1444,7 +1202,7 @@
      }
      let param = {
        page: this.paginations.page,
        rows:this.paginationHide ? 1000: this.paginations.rows,
        rows: this.paginationHide ? 1000 : this.paginations.rows,
        sort: this.paginations.sort,
        order: this.paginations.order,
        wheres: [] // 查询条件,格式为[{ name: "字段", value: "xx" }]
@@ -1469,8 +1227,8 @@
        param.wheres = JSON.stringify(param.wheres);
      }
      this.loading = true;
      let url=param.url||this.url;
      param.url=undefined;
      let url = param.url || this.url;
      param.url = undefined;
      this.http.post(url, param).then(
        (data) => {
          //2021.06.04修复tree不刷新的问题
@@ -1479,7 +1237,7 @@
            this.rowData.splice(0);
          }
          this.loading = false;
          let rows=data.rows||[];
          let rows = data.rows || [];
          // 查询返回结果后处理
          // 2020.10.30增加查询后返回所有的查询信息
          this.$emit(
@@ -1492,9 +1250,9 @@
          );
          if (!status) return;
          this.GetTableDictionary(data.rows);
          if (this.rowParentField) {
            rows= this.base.convertTree(rows,null,this.rowKey,this.rowParentField);
            rows = this.base.convertTree(rows, null, this.rowKey, this.rowParentField);
          }
          this.rowData = rows;
          this.paginations.total = data.total;
@@ -1541,8 +1299,8 @@
          let sum = data.summary[col.field];
          //2024.01.07增加自定义合计格式化
          if (col.summaryFormatter) {
            sum = col.summaryFormatter(sum,col,data,this.summaryData)
          }else if (sum) {
            sum = col.summaryFormatter(sum, col, data, this.summaryData)
          } else if (sum) {
            sum =
              (sum * 1.0).toFixed(col.numberLength || 2).replace('.00', '') *
              1.0;
@@ -1553,7 +1311,7 @@
        }
      }
    },
    getInputChangeSummaries() {},
    getInputChangeSummaries() { },
    handleSizeChange(val) {
      this.paginations.size = val;
      this.paginations.rows = val;
@@ -1617,7 +1375,7 @@
        this.formatConfig[column.field].push(val);
        index = this.formatConfig[column.field].length - 1;
      }
      return this.colors[index]||'info';
      return this.colors[index] || 'info';
    },
    formatterDate(row, column) {
      return (row[column.field] || '').substr(0, 10);
@@ -1635,26 +1393,26 @@
      }
      if (column.edit && (column.edit.type == 'selectList'
         ||column.edit.type=='treeSelect'
         ||column.bind.type == "cascader"
         ||column.bind.type == "treeSelect")) {
        || column.edit.type == 'treeSelect'
        || column.bind.type == "cascader"
        || column.bind.type == "treeSelect")) {
        if (!Array.isArray(val)) {
          row[column.field] = (val+'').split(',');
          row[column.field] = (val + '').split(',');
        } else {
          val = val.join(',');
        }
        return this.getSelectFormatter(column, val);
      }
       // 编辑多选table显示
      // 编辑多选table显示
      //  if (
      //   column.bind.type == "selectList" ||
      //   column.bind.type == "checkbox" ||
      //   column.bind.type == "cascader" ||
      //   column.bind.type == "treeSelect"
      // ) {
       if (typeof val === 'string' && val.indexOf(',') != -1) {
          return this.getSelectFormatter(column, val);
       }
      if (typeof val === 'string' && val.indexOf(',') != -1) {
        return this.getSelectFormatter(column, val);
      }
      //}
      let source = column.bind.data.filter((x) => {
        // return x.key != "" && x.key == val;
@@ -1666,17 +1424,17 @@
    },
    getSelectFormatter(column, val) {
      // 编辑多选table显示
      let valArr = (val+"").split(",");
      let valArr = (val + "").split(",");
      for (let index = 0; index < valArr.length; index++) {
        ( column.bind.orginData&&column.bind.orginData.length
          ?column.bind.orginData
          :column.bind.data)
        .forEach((x) => {
          // 2020.06.06修复数据源为selectList时,key为数字0时不能转换文本的问题
          if (x.key !== "" && x.key !== undefined && x.key + "" == valArr[index] + "") {
            valArr[index] = x.label || x.value;
          }
        });
        (column.bind.orginData && column.bind.orginData.length
          ? column.bind.orginData
          : column.bind.data)
          .forEach((x) => {
            // 2020.06.06修复数据源为selectList时,key为数字0时不能转换文本的问题
            if (x.key !== "" && x.key !== undefined && x.key + "" == valArr[index] + "") {
              valArr[index] = x.label || x.value;
            }
          });
      }
      return valArr.join(",");
    },
@@ -1750,7 +1508,7 @@
      );
    },
    getDateFormat(column) {
      if(column.format){
      if (column.format) {
        return column.format;
      }
      if (column.edit.type == "month") {
@@ -1782,37 +1540,37 @@
    initColumnDisabled(row, column) {
      return column.getDisabled && column.getDisabled(row, column);
    },
    showUpload(row,column){
       this.fileInfo = (row[column.field] || '').split(",")
                    .filter(x => { return x })
                    .map(item => {
                       return { path: item, name: "" };
                    })
      this.currentRow=row;
      this.currentColumn=column;
      if (this.currentColumn.edit.autoUpload===undefined) {
        this.currentColumn.edit.autoUpload=true;
    showUpload(row, column) {
      this.fileInfo = (row[column.field] || '').split(",")
        .filter(x => { return x })
        .map(item => {
          return { path: item, name: "" };
        })
      this.currentRow = row;
      this.currentColumn = column;
      if (this.currentColumn.edit.autoUpload === undefined) {
        this.currentColumn.edit.autoUpload = true;
      }
      if (this.currentColumn.edit.multiple===undefined) {
        this.currentColumn.edit.multiple=false;
      if (this.currentColumn.edit.multiple === undefined) {
        this.currentColumn.edit.multiple = false;
      }
      if (this.currentColumn.edit.url===undefined) {
          this.uploadUrl='api/'+(this.url||'').replace('/api','api').split('/')[1]+'/upload'
      }else{
        this.uploadUrl=this.currentColumn.edit.url;
      if (this.currentColumn.edit.url === undefined) {
        this.uploadUrl = 'api/' + (this.url || '').replace('/api', 'api').split('/')[1] + '/upload'
      } else {
        this.uploadUrl = this.currentColumn.edit.url;
      }
      this.uploadModel=true;
      this.uploadModel = true;
    },
    uploadAfter(result, files) {
      this.currentColumn.uploadAfter&&this.currentColumn.uploadAfter(result,files);
      this.currentColumn.uploadAfter && this.currentColumn.uploadAfter(result, files);
      return true;
    },
    uploadBefore(files,params){
      this.currentColumn.uploadBefore&&this.currentColumn.uploadBefore(files,this.currentRow,params);
    uploadBefore(files, params) {
      this.currentColumn.uploadBefore && this.currentColumn.uploadBefore(files, this.currentRow, params);
      return true;
    },
    saveUpload(){
    saveUpload() {
      //生成保存后返回的路径
      let arr = this.fileInfo.map((x) => {
        if (x.path) {
@@ -1825,25 +1583,25 @@
      this.uploadModel = false;
      return true;
    },
    expandChange(row,expandedRows){ //   当用户对某一行展开或者关闭的时
      if (!this.defaultExpandAll&&!this.lazy) {
          if (expandedRows) {
             if(this.expandRowKeys.indexOf(row[this.rowKey])==-1){
              this.expandRowKeys.push(row[this.rowKey])
             }
          }else{
            let _index= this.expandRowKeys.findIndex(x=>{return x==row[this.rowKey]});
            if (_index!=-1) {
              this.expandRowKeys.splice(_index,1);
            }
    expandChange(row, expandedRows) { //   当用户对某一行展开或者关闭的时
      if (!this.defaultExpandAll && !this.lazy) {
        if (expandedRows) {
          if (this.expandRowKeys.indexOf(row[this.rowKey]) == -1) {
            this.expandRowKeys.push(row[this.rowKey])
          }
      }
        } else {
          let _index = this.expandRowKeys.findIndex(x => { return x == row[this.rowKey] });
          if (_index != -1) {
            this.expandRowKeys.splice(_index, 1);
          }
        }
      }
    },
    handleImageError($e){
      $e.target.src= this.defaultImg;
    handleImageError($e) {
      $e.target.src = this.defaultImg;
    },
    cellSpanMethod({row,column,rowIndex, columnIndex}){
      return this.spanMethod({row,column,rowIndex, columnIndex},this.url?this.rowData:this.tableData)
    cellSpanMethod({ row, column, rowIndex, columnIndex }) {
      return this.spanMethod({ row, column, rowIndex, columnIndex }, this.url ? this.rowData : this.tableData)
    }
  }
});
@@ -1851,6 +1609,7 @@
<style lang="less" scoped>
.vol-table {
  position: relative;
  .mask {
    opacity: 0.2;
    position: absolute;
@@ -1859,6 +1618,7 @@
    background: #d0d0d0;
    z-index: 100;
  }
  .message {
    text-align: center;
    color: #635c5c;
@@ -1878,12 +1638,15 @@
    border: 1px solid #a09e9e;
  }
}
.e-item {
  display: flex;
  > div:first-child {
  >div:first-child {
    flex: 1;
  }
}
.vol-table ::v-deep(.el-pager .number) {
  padding: 0 7px;
  border-radius: 5px;
@@ -1893,10 +1656,12 @@
  min-width: 28px;
  height: 27px;
}
.vol-table ::v-deep(.el-pager .number.active) {
  background: #ed4014;
  color: #fff;
}
.vol-table ::v-deep(.el-pagination .el-input__wrapper) {
  height: 27px;
}
@@ -1907,10 +1672,12 @@
  border-bottom: 1px solid;
  padding-bottom: 2px;
}
.vol-table .empty-tag {
  border: none;
  background: none;
}
.v-table ::v-deep(.el-date-editor .el-icon-date),
.v-table ::v-deep(.el-date-editor .el-icon-time) {
  width: 10px;
@@ -1935,6 +1702,7 @@
  border: 1px solid #eee;
  border-top: 0px;
}
/* .v-table ::v-deep(.el-input .el-input__inner) {
  padding: 0 7px;
} */
@@ -1949,11 +1717,13 @@
.v-table ::v-deep(.el-table__header th.is-sortable) {
  padding: 3px !important;
}
.vol-table.text-inline ::v-deep(.el-table__body .cell),
.vol-table.text-inline ::v-deep(.el-table__header-wrapper .cell) {
  word-break: inherit !important;
  white-space: nowrap !important;
}
/* .v-table  ::v-deep(.el-table__body td) {
  padding: 9px 0 !important;
} */
@@ -1965,6 +1735,7 @@
.vol-table ::v-deep(.el-table-column--selection .cell) {
  display: inline;
}
.vol-table.text-inline ::v-deep(.el-table th > .cell) {
  white-space: nowrap !important;
}
@@ -1976,6 +1747,7 @@
  width: 40px;
  object-fit: cover;
}
.vol-table .table-img:hover {
  cursor: pointer;
}
@@ -1983,9 +1755,11 @@
.vol-table ::v-deep(.cell) {
  padding: 2px 10px;
}
.vol-table ::v-deep(.cell .el-tag) {
  padding: 5px 9px;
}
.table-input {
  color: rgb(104, 103, 103);
  padding: 3px 10px;
@@ -1995,6 +1769,7 @@
  border-radius: 4px;
  border: 1px solid #dcdcdc;
}
.table-input:focus {
  outline: 1px solid #49a3fd;
}
@@ -2002,13 +1777,15 @@
.small-table ::v-deep(.el-pagination .el-input__wrapper) {
  height: 27px;
}
.small-table ::v-deep(.el-table__cell) {
  padding: 6px 0;
  font-size: 13px;
}
.small-table ::v-deep(.cell-tag) {
  padding: 0 5px !important;
  padding: 0 5px !important;
  height: 19px;
}
</style>