1
z8018
2025-06-10 e46aa927d231af83724683c7286d9db503e24cf7
ÏîÄ¿´úÂë/WCS/WIDESEAWCS_Client/src/components/basic/VolTable.vue
@@ -45,12 +45,7 @@
        :selectable="selectable"
        width="55"
      ></el-table-column>
      <el-table-column
        v-if="columnIndex"
        type="index"
        :fixed="fixed"
        width="55"
      ></el-table-column>
      <el-table-column v-if="columnIndex" type="index" :fixed="fixed" width="55"></el-table-column>
      <!-- 2020.10.10移除table第一行强制排序 -->
      <el-table-column
@@ -66,11 +61,8 @@
        :show-overflow-tooltip="true"
      >
        <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">
@@ -111,15 +103,13 @@
                  )
                "
              ></div>
              <div v-else-if="column.bind">
                {{ formatter(scopeChildren.row, columnChildren, true) }}
              </div>
              <span v-else-if="column.type == 'date'">{{
              <div v-else-if="column.bind">{{ formatter(scopeChildren.row, columnChildren, true) }}</div>
              <span v-else-if="column.type == 'date'">
                {{
                formatterDate(scopeChildren.row, columnChildren)
              }}</span>
              <template v-else>
                {{ scopeChildren.row[columnChildren.field] }}
              </template>
                }}
              </span>
              <template v-else>{{ scopeChildren.row[columnChildren.field] }}</template>
            </template>
          </el-table-column>
          <!-- 2020.06.18增加render渲染自定义内容 -->
@@ -174,8 +164,7 @@
                )"
                :key="fIndex"
                @click="dowloadFile(file)"
                >{{ file.name }}</a
              >
              >{{ file.name }}</a>
            </div>
          </template>
          <div
@@ -206,8 +195,7 @@
                  :disabledDate="(val) => getDateOptions(val, column)"
                  :value-format="getDateFormat(column)"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-date-picker>
                ></el-date-picker>
                <el-time-picker
                  clearable
                  size="default"
@@ -223,8 +211,7 @@
                  :placeholder="column.placeholder || column.title"
                  :value-format="column.format || 'HH:mm:ss'"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-time-picker>
                ></el-time-picker>
                <el-switch
                  v-else-if="column.edit.type == 'switch'"
                  v-model="scope.row[column.field]"
@@ -250,8 +237,7 @@
                      : 0
                  "
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-switch>
                ></el-switch>
                <template
                  v-else-if="
                    ['select', 'selectList'].indexOf(column.edit.type) != -1
@@ -273,9 +259,7 @@
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
                    <template #default="{ item }">
                      {{ item.label }}
                    </template>
                    <template #default="{ item }">{{ item.label }}</template>
                  </el-select-v2>
                  <el-select
@@ -304,8 +288,7 @@
                      :disabled="item.disabled"
                      :label="item.value"
                      :value="item.key"
                      >{{ item.value }}
                    </el-option>
                    >{{ item.value }}</el-option>
                  </el-select>
                </template>
                <el-input
@@ -314,8 +297,7 @@
                  :placeholder="column.placeholder || column.title"
                  v-model="scope.row[column.field]"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-input>
                ></el-input>
                <input
                  class="table-input"
                  v-else-if="!column.summary && !column.onKeyPress"
@@ -333,10 +315,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"
@@ -379,11 +358,12 @@
              )"
              :key="fIndex"
              @click="dowloadFile(file)"
              >{{ file.name }}</a
            >
            <span v-else-if="column.type == 'date'">{{
            >{{ file.name }}</a>
            <span v-else-if="column.type == 'date'">
              {{
              formatterDate(scope.row, column)
            }}</span>
              }}
            </span>
            <div
              v-else-if="column.formatter"
              @click="formatterClick(scope.row, column, $event)"
@@ -394,15 +374,11 @@
              v-else-if="column.bind && (column.normal || column.edit)"
              @click="formatterClick(scope.row, column, $event)"
              :style="column.getStyle && column.getStyle(scope.row, column)"
            >
              {{ formatter(scope.row, column, true) }}
            </div>
            >{{ formatter(scope.row, column, true) }}</div>
            <div
              v-else-if="column.click && !column.bind"
              @click="formatterClick(scope.row, column)"
            >
              {{ scope.row[column.field] }}
            </div>
            >{{ scope.row[column.field] }}</div>
            <div
              @click="
                () => {
@@ -416,11 +392,12 @@
                :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) }}</el-tag>
              <template v-else>
                {{
                formatter(scope.row, column, true)
              }}</template>
                }}
              </template>
            </div>
            <span v-else>{{ formatter(scope.row, column, true) }}</span>
@@ -445,14 +422,7 @@
    </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
@@ -474,12 +444,8 @@
    </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
        >
        <el-button type="default" size="small" @click="uploadModel = false">关闭</el-button>
        <el-button type="primary" size="small" @click="saveUpload">保存</el-button>
      </div>
    </template>
  </VolBox>
@@ -496,157 +462,157 @@
    "tableData.length": {
      handler(newLen, oldLen) {
        this.watchRowSelectChange(newLen, oldLen);
      },
      }
    },
    "rowData.length": {
      handler(newLen, oldLen) {
        this.watchRowSelectChange(newLen, oldLen);
      },
    },
      }
    }
  },
  components: {
    "table-render": VolTableRender,
    VolUpload: defineAsyncComponent(() =>
      import("@/components/basic/VolUpload.vue")
    ),
    VolBox: defineAsyncComponent(() => import("@/components/basic/VolBox.vue")),
    VolBox: defineAsyncComponent(() => import("@/components/basic/VolBox.vue"))
  },
  props: {
    rowKey: {
      // æ ‘形结构的主键字段,如果设置值默认会开启树形table;注意rowKey字段的值必须是唯一(2021.05.02)
      typeof: String,
      default: undefined,
      default: undefined
    },
    loadTreeChildren: {
      // æ ‘形结构加载子节点
      type: Function,
      default: (tree, treeNode, resolve) => {
        return resolve([]);
      },
      }
    },
    textInline: {
      // è¡¨æ ¼å†…容超出后是否换行显示(2020.01.16)
      type: Boolean,
      default: true,
      default: true
    },
    tableData: {
      // è¡¨æ•°æ®æº,配置了url就不用传这个参数了
      type: Array,
      default: () => {
        return [];
      },
      }
    },
    columns: {
      type: Array,
      default: [],
      default: []
    },
    height: {
      type: Number,
      default: 0,
      default: 0
    },
    maxHeight: {
      type: Number,
      default: 0,
      default: 0
    },
    linkView: {
      type: Function,
      default: function () {
      default: function() {
        return 1;
      },
      }
    },
    pagination: {
      type: Object,
      default: function () {
      default: function() {
        return { total: 0, size: 30, sortName: "" };
      },
      }
    },
    url: {
      type: String,
      default: "",
      default: ""
    },
    paginationHide: {
      type: Boolean,
      default: true,
      default: true
    },
    color: {
      type: Boolean,
      default: true,
      default: true
    },
    index: {
      // æ˜¯å¦åˆ›å»ºç´¢å¼•号,如果需要表格编辑功能,这里需要设置为true
      type: Boolean,
      default: false,
      default: false
    },
    allowEmpty: {
      // è¡¨æ ¼æ•°æ®ä¸ºç©ºæ—¶æ˜¯å¦é»˜è®¤ä¸º--
      type: Boolean,
      default: true,
      default: true
    },
    defaultLoadPage: {
      // ä¼ å…¥äº†url,是否默认加载表格数据
      type: Boolean,
      default: true,
      default: true
    },
    loadKey: {
      // æ˜¯å¦è‡ªåŠ¨ä»ŽåŽå°åŠ è½½æ•°æ®æº
      type: Boolean,
      default: true,
      default: true
    },
    single: {
      type: Boolean, // æ˜¯å¦å•选
      default: false,
      default: false
    },
    doubleEdit: {
      type: Boolean, // æ˜¯å¦åŒå‡»å¯ç”¨ç¼–辑功能
      default: true,
      default: true
    },
    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;
      },
      }
    },
    ck: {
      // æ˜¯å¦æ˜¾ç¤ºcheckbox
      type: Boolean,
      default: true,
      default: true
    },
    columnIndex: {
      // æ˜¯å¦æ˜¾ç¤ºè¡Œå·(2020..11.1)
      type: Boolean,
      default: true,
      default: true
    },
    highlightCurrentRow: {
      //增加选中行高亮显示(2022.10.07)
      type: Boolean,
      default: true,
      default: true
    },
    select2Count: {
      //超出数量显示select2组件
      type: Number,
      default: 500,
      default: 500
    },
    selectable: {
      type: Function,
      default: (row, index) => {
        return true;
      },
    },
      }
    }
  },
  data() {
    return {
@@ -670,7 +636,7 @@
      rule: {
        phone: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
        decimal: /(^[\-0-9][0-9]*(.[0-9]+)?)$/,
        number: /(^[\-0-9][0-9]*([0-9]+)?)$/,
        number: /(^[\-0-9][0-9]*([0-9]+)?)$/
      },
      columnNames: [],
      rowData: [],
@@ -684,7 +650,7 @@
        size: 30, // é»˜è®¤åˆ†é¡µå¤§å°
        Wheres: [],
        page: 1,
        rows: 30,
        rows: 30
      },
      errorFiled: "",
      edit: { columnIndex: -1, rowIndex: -1 }, // å½“前双击编辑的行与列坐标
@@ -705,7 +671,7 @@
      currentColumn: [],
      fileInfo: [],
      uploadUrl: "",
      uploadModel: false,
      uploadModel: false
    };
  },
  created() {
@@ -723,12 +689,12 @@
    // }
    this.realHeight = this.getHeight();
    this.realMaxHeight = this.getMaxHeight();
    this.fxRight = this.columns.some((x) => {
    this.fxRight = this.columns.some(x => {
      return x.fixed == "right";
    });
    //2021.09.21移除强制固定行号与checkbox列
    if (
      this.columns.some((x) => {
      this.columns.some(x => {
        return x.fixed && x.fixed != "right";
      })
    ) {
@@ -782,33 +748,31 @@
      }
    });
    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;
@@ -817,10 +781,10 @@
    if (this.pagination.size) {
      this.paginations.rows = this.pagination.size;
    }
    this.enableEdit = this.columns.some((x) => {
    this.enableEdit = this.columns.some(x => {
      return x.hasOwnProperty("edit");
    });
    let keyColumn = this.columns.find((x) => {
    let keyColumn = this.columns.find(x => {
      return x.isKey;
    });
    if (keyColumn) {
@@ -836,7 +800,7 @@
        }
        return !x.hidden;
      });
    },
    }
  },
  methods: {
    watchRowSelectChange(newLen, oldLen) {
@@ -904,7 +868,7 @@
        if (row.elementIndex == this.edit.rowIndex) {
          // ç‚¹å‡»çš„单元格如果不可以编辑,直接结束编辑
          // 2020.10.12修复结束编辑时,element table高版本属性获取不到的问题
          let _col = this.columns.find((x) => {
          let _col = this.columns.find(x => {
            return x.field == ((event && event.property) || column.property);
          });
          if (_col && (!_col.edit || _col.readonly)) {
@@ -930,7 +894,7 @@
        file.path,
        file.name,
        {
          Authorization: this.$store.getters.getToken(),
          Authorization: this.$store.getters.getToken()
        },
        this.http.ipAddress
      );
@@ -947,10 +911,10 @@
      if (column.base64 && pathSring.indexOf("data") != -1) {
        filePath = ("," + pathSring)
          .split(",data")
          .filter((x) => {
          .filter(x => {
            return x;
          })
          .map((m) => {
          .map(m => {
            return "data" + m;
          });
      } else {
@@ -966,14 +930,14 @@
            name: "",
            path:
              (file.indexOf("data") == -1 ? "data:image/png;base64," : "") +
              file,
              file
          });
        } else if (file.indexOf(".") != -1) {
          let splitFile = file.split("/");
          if (splitFile.length > 0) {
            fileInfo.push({
              name: splitFile[splitFile.length - 1],
              path: this.base.isUrl(file) ? file : this.http.ipAddress + file,
              path: this.base.isUrl(file) ? file : this.http.ipAddress + file
            });
          }
        }
@@ -1063,7 +1027,7 @@
      if (this.edit.rowIndex != -1) {
        return;
      }
      let _row = this.columns.find((x) => x.field == column.property);
      let _row = this.columns.find(x => x.field == column.property);
      if (_row) {
        if (_row.readonly) {
          return;
@@ -1080,10 +1044,10 @@
      _errMsg = "";
      // ç¼–辑前
      this.columns
        .filter((x) => {
        .filter(x => {
          return x.bind && x.bind.data && x.bind.data.length;
        })
        .forEach((column) => {
        .forEach(column => {
          let val = row[column.field];
          if (typeof column.bind.data[0].key == "string") {
            if (typeof val == "number") {
@@ -1267,7 +1231,7 @@
      if (!row) {
        row = {};
      }
      this.columns.forEach((x) => {
      this.columns.forEach(x => {
        // 2022.05.06 æ·»åŠ è¡Œæ—¶ï¼Œå¦‚æžœåˆ—æœ‰ç¼–è¾‘å±žæ€§ï¼Œè®¾ç½®å¼€å¯ç¼–è¾‘(避免关闭编辑后,无法再次启用编辑)??
        //x.readonly = false;
        if (!row.hasOwnProperty(x.field)) {
@@ -1302,7 +1266,7 @@
        // åªæœ‰è®¾ç½®äº†å±žæ€§index才有索引行
        return [];
      }
      let indexArr = this.selectRows.map((x) => {
      let indexArr = this.selectRows.map(x => {
        return x.elementIndex;
      });
      return indexArr || [];
@@ -1316,7 +1280,7 @@
        //  column.bind.data.splice(0);
        let key = column.bind.key;
        let data = [];
        rows.forEach((row) => {
        rows.forEach(row => {
          if (row[column.field] || row[column.field] == "0") {
            if (data.indexOf(row[column.field]) == -1) {
              data.push(row[column.field]);
@@ -1331,9 +1295,9 @@
      // ha= Object.assign([], ha, hb)
      this.http
        .post("/api/Sys_Dictionary/GetTableDictionary", remoteInfo)
        .then((dic) => {
          dic.forEach((x) => {
            this.remoteColumns.forEach((column) => {
        .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);
@@ -1354,7 +1318,7 @@
        rows: this.paginations.rows,
        sort: this.paginations.sort,
        order: this.paginations.order,
        wheres: [], // æŸ¥è¯¢æ¡ä»¶ï¼Œæ ¼å¼ä¸º[{ name: "字段", value: "xx" }]
        wheres: [] // æŸ¥è¯¢æ¡ä»¶ï¼Œæ ¼å¼ä¸º[{ name: "字段", value: "xx" }]
      };
      let status = true;
      // åˆå¹¶æŸ¥è¯¢ä¿¡æ¯(包查询分页、排序、查询条件等)
@@ -1367,7 +1331,7 @@
          callBack(true);
        })
      */
      this.$emit("loadBefore", param, (result) => {
      this.$emit("loadBefore", param, result => {
        status = result;
      });
      if (!status) return;
@@ -1377,7 +1341,7 @@
      }
      this.loading = true;
      this.http.post(this.url, param).then(
        (data) => {
        data => {
          //2021.06.04修复tree不刷新的问题
          if (this.rowKey) {
            this.randomTableKey++;
@@ -1389,7 +1353,7 @@
          this.$emit(
            "loadAfter",
            data.rows || [],
            (result) => {
            result => {
              status = result;
            },
            data
@@ -1404,7 +1368,7 @@
          //   this.$refs.table.doLayout();
          // });
        },
        (error) => {
        error => {
          this.loading = false;
          // this.$Message.error(error || "网络异常");
        }
@@ -1422,9 +1386,9 @@
        this.summaryData.push("");
      }
      this.columns.forEach((col) => {
      this.columns.forEach(col => {
        if (col.children && col.children.length) {
          col.children.forEach((item) => {
          col.children.forEach(item => {
            this.getColumnSummaries(item, data);
          });
        } else {
@@ -1533,7 +1497,9 @@
      if (
        column.edit &&
        (column.edit.type == "selectList" || column.edit.type == "treeSelect")
        (column.edit.type == "selectList" ||
          column.edit.type == "selectlist" ||
          column.edit.type == "treeSelect")
      ) {
        if (!Array.isArray(val)) {
          row[column.field] = val.split(",");
@@ -1545,6 +1511,7 @@
      // ç¼–辑多选table显示
      if (
        column.bind.type == "selectList" ||
        column.bind.type == "selectlist" ||
        column.bind.type == "checkbox" ||
        column.bind.type == "treeSelect"
      ) {
@@ -1552,7 +1519,7 @@
        return this.getSelectFormatter(column, val + "");
        //  }
      }
      let source = column.bind.data.filter((x) => {
      let source = column.bind.data.filter(x => {
        // return x.key != "" && x.key == val;
        // 2020.06.06修复单独使用table组件时,key为数字0时转换成文本失败的问题
        return x.key !== "" && x.key !== undefined && x.key + "" === val + "";
@@ -1567,7 +1534,7 @@
        (column.bind.orginData && column.bind.orginData.length
          ? column.bind.orginData
          : column.bind.data
        ).forEach((x) => {
        ).forEach(x => {
          // 2020.06.06修复数据源为selectList时,key为数字0时不能转换文本的问题
          if (
            x.key !== "" &&
@@ -1669,7 +1636,7 @@
      if (!children) {
        return [];
      }
      return children.filter((x) => {
      return children.filter(x => {
        return !x.hidden;
      });
    },
@@ -1679,10 +1646,10 @@
    showUpload(row, column) {
      this.fileInfo = (row[column.field] || "")
        .split(",")
        .filter((x) => {
        .filter(x => {
          return x;
        })
        .map((item) => {
        .map(item => {
          return { path: item, name: "" };
        });
      this.currentRow = row;
@@ -1711,7 +1678,7 @@
    },
    saveUpload() {
      //生成保存后返回的路径
      let arr = this.fileInfo.map((x) => {
      let arr = this.fileInfo.map(x => {
        if (x.path) {
          return x.path;
        }
@@ -1721,8 +1688,8 @@
      this.currentRow[this.currentColumn.field] = arr.join(",");
      this.uploadModel = false;
      return true;
    },
  },
    }
  }
});
</script>
<style lang="less" scoped>