leiqunqing
2026-02-06 15b3879cd259108e7ebb755fe02c190f28f1e20c
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/components/basic/VolTable.vue
@@ -143,21 +143,13 @@
          >
            <div style="display: flex; align-items: center" @click.stop>
              <i
                style="
                  padding: 3px;
                  margin-right: 10px;
                  color: #8f9293;
                  cursor: pointer;
                "
                style="padding: 3px; margin-right: 10px; color: #8f9293; cursor: pointer"
                @click="showUpload(scope.row, column)"
                class="el-icon-upload"
              ></i>
              <img
                v-show="column.edit.type == 'img'"
                v-for="(file, imgIndex) in getFilePath(
                  scope.row[column.field],
                  column
                )"
                v-for="(file, imgIndex) in getFilePath(scope.row[column.field], column)"
                :key="imgIndex"
                :onerror="defaultImg"
                @click="viewImg(scope.row, column, file.path, $event)"
@@ -168,10 +160,7 @@
                style="margin-right: 8px"
                v-show="column.edit.type != 'img'"
                class="t-file"
                v-for="(file, fIndex) in getFilePath(
                  scope.row[column.field],
                  column
                )"
                v-for="(file, fIndex) in getFilePath(scope.row[column.field], column)"
                :key="fIndex"
                @click="dowloadFile(file)"
                >{{ file.name }}</a
@@ -197,8 +186,7 @@
                  v-model="scope.row[column.field]"
                  @change="
                    (val) => {
                      column.onChange &&
                        column.onChange(scope.row, column, val);
                      column.onChange && column.onChange(scope.row, column, val);
                    }
                  "
                  :type="column.edit.type"
@@ -216,8 +204,7 @@
                  v-model="scope.row[column.field]"
                  @change="
                    (val) => {
                      column.onChange &&
                        column.onChange(scope.row, column, val);
                      column.onChange && column.onChange(scope.row, column, val);
                    }
                  "
                  :placeholder="column.placeholder || column.title"
@@ -253,9 +240,7 @@
                >
                </el-switch>
                <template
                  v-else-if="
                    ['select', 'selectList'].indexOf(column.edit.type) != -1
                  "
                  v-else-if="['select', 'selectList'].indexOf(column.edit.type) != -1"
                >
                  <el-select-v2
                    style="width: 100%"
@@ -267,9 +252,7 @@
                    :placeholder="column.placeholder || column.title"
                    :autocomplete="column.autocomplete"
                    :options="column.bind.data"
                    @change="
                      column.onChange && column.onChange(scope.row, column)
                    "
                    @change="column.onChange && column.onChange(scope.row, column)"
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
@@ -284,16 +267,12 @@
                    v-else
                    v-model="scope.row[column.field]"
                    :filterable="
                      column.filter || column.bind.data.length > 10
                        ? true
                        : false
                      column.filter || column.bind.data.length > 10 ? true : false
                    "
                    :multiple="column.edit.type == 'select'"
                    :placeholder="column.placeholder || column.title"
                    :autocomplete="column.autocomplete"
                    @change="
                      column.onChange && column.onChange(scope.row, column)
                    "
                    @change="column.onChange && column.onChange(scope.row, column)"
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
@@ -333,10 +312,7 @@
                  :disabled="initColumnDisabled(scope.row, column)"
                ></el-input>
              </div>
              <div
                class="extra"
                v-if="column.extra && edit.rowIndex == scope.$index"
              >
              <div class="extra" v-if="column.extra && edit.rowIndex == scope.$index">
                <a
                  :style="column.extra.style"
                  style="text-decoration: none"
@@ -359,10 +335,7 @@
            ></a>
            <img
              v-else-if="column.type == 'img'"
              v-for="(file, imgIndex) in getFilePath(
                scope.row[column.field],
                column
              )"
              v-for="(file, imgIndex) in getFilePath(scope.row[column.field], column)"
              :key="imgIndex"
              :onerror="defaultImg"
              @click="viewImg(scope.row, column, file.path, $event)"
@@ -373,10 +346,7 @@
              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
              )"
              v-for="(file, fIndex) in getFilePath(scope.row[column.field], column)"
              :key="fIndex"
              @click="dowloadFile(file)"
              >{{ file.name }}</a
@@ -418,9 +388,7 @@
                :effect="column.effect"
                >{{ formatter(scope.row, column, true) }}</el-tag
              >
              <template v-else>{{
                formatter(scope.row, column, true)
              }}</template>
              <template v-else>{{ formatter(scope.row, column, true) }}</template>
            </div>
            <span v-else>{{ formatter(scope.row, column, true) }}</span>
@@ -463,9 +431,7 @@
        :max-file="currentColumn.edit.maxFile"
        :img="currentColumn.edit.type == 'img'"
        :excel="currentColumn.edit.type == 'excel'"
        :fileTypes="
          currentColumn.edit.fileTypes ? currentColumn.edit.fileTypes : []
        "
        :fileTypes="currentColumn.edit.fileTypes ? currentColumn.edit.fileTypes : []"
        :fileInfo="fileInfo"
        :upload-after="uploadAfter"
      >
@@ -477,9 +443,7 @@
        <el-button type="default" size="small" @click="uploadModel = false"
          >关闭</el-button
        >
        <el-button type="primary" size="small" @click="saveUpload"
          >保存</el-button
        >
        <el-button type="primary" size="small" @click="saveUpload">保存</el-button>
      </div>
    </template>
  </VolBox>
@@ -506,9 +470,7 @@
  },
  components: {
    "table-render": VolTableRender,
    VolUpload: defineAsyncComponent(() =>
      import("@/components/basic/VolUpload.vue")
    ),
    VolUpload: defineAsyncComponent(() => import("@/components/basic/VolUpload.vue")),
    VolBox: defineAsyncComponent(() => import("@/components/basic/VolBox.vue")),
  },
  props: {
@@ -642,7 +604,6 @@
      default: 500,
    },
    selectable: {
      type: Function,
      default: (row, index) => {
        return true;
@@ -783,33 +744,28 @@
      }
    });
    if (keys.length > 0) {
      this.http
        .post("/api/Sys_Dictionary/GetVueDictionary", keys)
        .then((dic) => {
          dic.forEach((x) => {
            if (x.data.length > this.select2Count) {
              x.data.forEach((item) => {
                item.label = item.value;
                item.value = item.key;
      this.http.post("/api/Sys_Dictionary/GetVueDictionary", keys).then((dic) => {
        dic.forEach((x) => {
          if (x.data.length > this.select2Count) {
            x.data.forEach((item) => {
              item.label = item.value;
              item.value = item.key;
            });
          }
          columnBind.forEach((c) => {
            // è½¬æ¢æ•°æ®æºçš„类型与列的类型一致(2020.04.04)
            if (c.key == x.dicNo && (c.valueTyoe == "int" || c.valueTyoe == "sbyte")) {
              x.data.forEach((d) => {
                // 2020.09.01增加对数字类型的二次判断
                if (!isNaN(d.key)) {
                  d.key = ~~d.key;
                }
              });
            }
            columnBind.forEach((c) => {
              // è½¬æ¢æ•°æ®æºçš„类型与列的类型一致(2020.04.04)
              if (
                c.key == x.dicNo &&
                (c.valueTyoe == "int" || c.valueTyoe == "sbyte")
              ) {
                x.data.forEach((d) => {
                  // 2020.09.01增加对数字类型的二次判断
                  if (!isNaN(d.key)) {
                    d.key = ~~d.key;
                  }
                });
              }
              if (c.key == x.dicNo) c.data.push(...x.data);
            });
            if (c.key == x.dicNo) c.data.push(...x.data);
          });
        });
      });
    }
    this.paginations.sort = this.pagination.sortName;
@@ -861,11 +817,7 @@
    },
    extraClick(row, column) {
      column.extra.click &&
        column.extra.click(
          row,
          column,
          this.url ? this.rowData : this.tableData
        );
        column.extra.click(row, column, this.url ? this.rowData : this.tableData);
    },
    headerClick(column, event) {
      if (this.clickEdit && this.edit.rowIndex != -1) {
@@ -885,74 +837,76 @@
    rowDbClick(row, column, event) {
      //2021.05.23增加双击行事件
      this.$emit("rowDbClick", { row, column, event });
    },rowClick(row, column, event) {
  // 2022.02.20增加点击时表格参数判断
  if (!column) {
    return;
  }
    },
    rowClick(row, column, event) {
      // 2022.02.20增加点击时表格参数判断
      if (!column) {
        return;
      }
  // ===== ä¼˜åŒ–:隔离复选框点击事件,避免冒泡干扰 å¼€å§‹ =====
  // åˆ¤æ–­ç‚¹å‡»ç›®æ ‡æ˜¯å¦æ˜¯å¤é€‰æ¡†ï¼ˆæˆ–复选框所在的单元格/图标)
  const targetEl = event.target;
  const isCheckbox = targetEl.classList.contains('el-checkbox__input') ||
                      targetEl.closest('.el-checkbox__input') ||
                      targetEl.closest('.el-table-column--selection');
  // å¦‚果点击的是复选框区域,直接返回,不执行行选中逻辑
  if (isCheckbox) {
    return;
  }
  // ===== ä¼˜åŒ–:隔离复选框点击事件 ç»“束 =====
      // ===== ä¼˜åŒ–:隔离复选框点击事件,避免冒泡干扰 å¼€å§‹ =====
      // åˆ¤æ–­ç‚¹å‡»ç›®æ ‡æ˜¯å¦æ˜¯å¤é€‰æ¡†ï¼ˆæˆ–复选框所在的单元格/图标)
      const targetEl = event.target;
      const isCheckbox =
        targetEl.classList.contains("el-checkbox__input") ||
        targetEl.closest(".el-checkbox__input") ||
        targetEl.closest(".el-table-column--selection");
      // å¦‚果点击的是复选框区域,直接返回,不执行行选中逻辑
      if (isCheckbox) {
        return;
      }
      // ===== ä¼˜åŒ–:隔离复选框点击事件 ç»“束 =====
  // ===== ä¼˜åŒ–:点击行选中/切换复选框 å¼€å§‹ =====
  // 1. åˆ¤æ–­æ˜¯å¦æ˜¾ç¤ºå¤é€‰æ¡†ï¼ˆck为true),不显示则无需处理
  // 2. ç¼–辑状态下不触发(避免干扰编辑功能)
  if (this.ck && this.edit.rowIndex === -1) {
    // 3. å•选场景(single为true):先清空所有选中项,再强制选中当前行(保持单选逻辑)
    if (this.single) {
      this.$refs.table.clearSelection(); // æ¸…空所有选中
      this.$refs.table.toggleRowSelection(row, true); // å•选场景强制选中当前行
    }
    // 4. å¤šé€‰åœºæ™¯ï¼ˆsingle为false):不传第二个参数,实现切换选中/取消状态
    else {
      this.$refs.table.toggleRowSelection(row); // åˆ‡æ¢çŠ¶æ€ï¼Œæ”¯æŒå–æ¶ˆé€‰ä¸­
    }
  }
  // ===== ä¼˜åŒ–:点击行选中/切换复选框 ç»“束 =====
  // æ­£åœ¨ç¼–辑时,禁止触发rowClick事件
  if (this.edit.rowIndex == -1) {
    this.$emit("rowClick", { row, column, event });
  }
  // ç‚¹å‡»è¡Œäº‹ä»¶(2020.11.07)
  if (!this.doubleEdit) {
    return;
  }
  // ç‚¹å‡»å…¶ä»–行时,如果点击的行与正在编辑的行相同,保持编辑状态
  if (this.clickEdit && this.edit.rowIndex != -1) {
    if (row.elementIndex == this.edit.rowIndex) {
      // ç‚¹å‡»çš„单元格如果不可以编辑,直接结束编辑
      // 2020.10.12修复结束编辑时,element table高版本属性获取不到的问题
      let _col = this.columns.find((x) => {
        return x.field == ((event && event.property) || column.property);
      });
      if (_col && (!_col.edit || _col.readonly)) {
        if (this.rowEndEdit(row, event)) {
          this.edit.rowIndex = -1;
      // ===== ä¼˜åŒ–:点击行选中/切换复选框 å¼€å§‹ =====
      // 1. åˆ¤æ–­æ˜¯å¦æ˜¾ç¤ºå¤é€‰æ¡†ï¼ˆck为true),不显示则无需处理
      // 2. ç¼–辑状态下不触发(避免干扰编辑功能)
      if (this.ck && this.edit.rowIndex === -1) {
        // 3. å•选场景(single为true):先清空所有选中项,再强制选中当前行(保持单选逻辑)
        if (this.single) {
          this.$refs.table.clearSelection(); // æ¸…空所有选中
          this.$refs.table.toggleRowSelection(row, true); // å•选场景强制选中当前行
        }
        // 4. å¤šé€‰åœºæ™¯ï¼ˆsingle为false):不传第二个参数,实现切换选中/取消状态
        else {
          this.$refs.table.toggleRowSelection(row); // åˆ‡æ¢çŠ¶æ€ï¼Œæ”¯æŒå–æ¶ˆé€‰ä¸­
        }
      }
      return;
    }
    if (this.rowEndEdit(row, event && event.property ? event : column)) {
      this.edit.rowIndex = -1;
    }
    //当正在编辑,且点击到其他行时,在原编辑的行结束编辑后,触发新行的rowClick事件
    //正在编辑时,禁止触发rowClick事件
    if (this.edit.rowIndex == -1) {
      this.$emit("rowClick", { row, column, event });
    }
  }
  this.rowBeginEdit(row, column);
},
      // ===== ä¼˜åŒ–:点击行选中/切换复选框 ç»“束 =====
      // æ­£åœ¨ç¼–辑时,禁止触发rowClick事件
      if (this.edit.rowIndex == -1) {
        this.$emit("rowClick", { row, column, event });
      }
      // ç‚¹å‡»è¡Œäº‹ä»¶(2020.11.07)
      if (!this.doubleEdit) {
        return;
      }
      // ç‚¹å‡»å…¶ä»–行时,如果点击的行与正在编辑的行相同,保持编辑状态
      if (this.clickEdit && this.edit.rowIndex != -1) {
        if (row.elementIndex == this.edit.rowIndex) {
          // ç‚¹å‡»çš„单元格如果不可以编辑,直接结束编辑
          // 2020.10.12修复结束编辑时,element table高版本属性获取不到的问题
          let _col = this.columns.find((x) => {
            return x.field == ((event && event.property) || column.property);
          });
          if (_col && (!_col.edit || _col.readonly)) {
            if (this.rowEndEdit(row, event)) {
              this.edit.rowIndex = -1;
            }
          }
          return;
        }
        if (this.rowEndEdit(row, event && event.property ? event : column)) {
          this.edit.rowIndex = -1;
        }
        //当正在编辑,且点击到其他行时,在原编辑的行结束编辑后,触发新行的rowClick事件
        //正在编辑时,禁止触发rowClick事件
        if (this.edit.rowIndex == -1) {
          this.$emit("rowClick", { row, column, event });
        }
      }
      this.rowBeginEdit(row, column);
    },
    //   //正在编辑时,禁止出发rowClick事件
    //   if (this.edit.rowIndex == -1) {
@@ -1028,9 +982,7 @@
        if (column.base64) {
          fileInfo.push({
            name: "",
            path:
              (file.indexOf("data") == -1 ? "data:image/png;base64," : "") +
              file,
            path: (file.indexOf("data") == -1 ? "data:image/png;base64," : "") + file,
          });
        } else if (file.indexOf(".") != -1) {
          let splitFile = file.split("/");
@@ -1200,9 +1152,7 @@
          this.edit.rowIndex = -1;
          return;
        }
        let row = (this.url ? this.rowData : this.tableData)[
          this.edit.rowIndex
        ];
        let row = (this.url ? this.rowData : this.tableData)[this.edit.rowIndex];
        for (let index = 0; index < this.columns.length; index++) {
          const _column = this.columns[index];
          if (_column.edit) {
@@ -1300,9 +1250,7 @@
      let data = this.url ? this.rowData : this.tableData;
      let indexArr = this.getSelectedIndex();
      if (indexArr.length == 0) {
        return this.$Message.error(
          "删除操作必须设置VolTable的属性index='true'"
        );
        return this.$Message.error("删除操作必须设置VolTable的属性index='true'");
      }
      // if (indexArr.length == 0 || !this.key) {
      //   return this.$message.error(
@@ -1393,19 +1341,17 @@
      }
      if (remoteInfo.length == 0) return;
      // ha= Object.assign([], ha, hb)
      this.http
        .post("/api/Sys_Dictionary/GetTableDictionary", remoteInfo)
        .then((dic) => {
          dic.forEach((x) => {
            this.remoteColumns.forEach((column) => {
              if (column.bind.key == x.key) {
                column.bind.data = Object.assign([], column.bind.data, x.data);
                // column.bind.data.push(...x.data);
              }
            });
      this.http.post("/api/Sys_Dictionary/GetTableDictionary", remoteInfo).then((dic) => {
        dic.forEach((x) => {
          this.remoteColumns.forEach((column) => {
            if (column.bind.key == x.key) {
              column.bind.data = Object.assign([], column.bind.data, x.data);
              // column.bind.data.push(...x.data);
            }
          });
          this.$emit("dicInited", dic);
        });
        this.$emit("dicInited", dic);
      });
    },
    load(query, isResetPage) {
      // isResetPage重置分页数据
@@ -1504,9 +1450,7 @@
        if (data.summary.hasOwnProperty(col.field)) {
          let sum = data.summary[col.field];
          if (sum) {
            sum =
              (sum * 1.0).toFixed(col.numberLength || 2).replace(".00", "") *
              1.0;
            sum = (sum * 1.0).toFixed(col.numberLength || 2).replace(".00", "") * 1.0;
          }
          this.summaryData.push(sum);
        } else {
@@ -1633,11 +1577,7 @@
          : column.bind.data
        ).forEach((x) => {
          // 2020.06.06修复数据源为selectList时,key为数字0时不能转换文本的问题
          if (
            x.key !== "" &&
            x.key !== undefined &&
            x.key + "" == valArr[index] + ""
          ) {
          if (x.key !== "" && x.key !== undefined && x.key + "" == valArr[index] + "") {
            valArr[index] = x.label || x.value;
          }
        });
@@ -1669,9 +1609,7 @@
        if (column.summary == "avg") {
          sum = sum / (this.rowData.length || this.tableData.length || 1);
        }
        sum =
          (sum * 1.0).toFixed(column.numberLength || 2).replace(".00", "") *
          1.0;
        sum = (sum * 1.0).toFixed(column.numberLength || 2).replace(".00", "") * 1.0;
      }
      this.summaryData[this.summaryIndex[column.field]] = sum;
    },
@@ -1696,8 +1634,7 @@
        return true;
      }
      return (
        date1.valueOf() <
        (typeof date2 == "number" ? date2 : new Date(date2).valueOf())
        date1.valueOf() < (typeof date2 == "number" ? date2 : new Date(date2).valueOf())
      );
    },
    getDateOptions(date, item) {
@@ -1709,9 +1646,7 @@
        //不设置时分秒,后面会自动加上 08:00
        item.min = item.min + " 00:00:000";
      }
      return (
        this.compareDate(date, item.min) || !this.compareDate(date, item.max)
      );
      return this.compareDate(date, item.min) || !this.compareDate(date, item.max);
    },
    getDateFormat(column) {
      //见https://day.js.org/docs/zh-CN/display/format
@@ -1761,17 +1696,14 @@
      if (this.currentColumn.edit.url === undefined) {
        this.uploadUrl =
          "api/" +
          (this.url || "").replace("/api", "api").split("/")[1] +
          "/upload";
          "api/" + (this.url || "").replace("/api", "api").split("/")[1] + "/upload";
      } else {
        this.uploadUrl = this.currentColumn.edit.url;
      }
      this.uploadModel = true;
    },
    uploadAfter(result, files) {
      this.currentColumn.uploadAfter &&
        this.currentColumn.uploadAfter(result, files);
      this.currentColumn.uploadAfter && this.currentColumn.uploadAfter(result, files);
      return true;
    },
    saveUpload() {