瀏覽代碼

封装ux-grid表格

002390 1 年之前
父節點
當前提交
1147d720e7

+ 119 - 0
src/components/super-ux-table/freeze.vue

@@ -0,0 +1,119 @@
+<template>
+  <el-button size="mini" @click="drawer = true">
+    {{ number ? `冻结列 :${number}` : "冻结列" }}
+    <el-drawer
+      :modal="false"
+      :visible.sync="drawer"
+      size="20%"
+      title="冻结列"
+      append-to-body
+    >
+      <el-input
+        v-model="key"
+        size="mini"
+        placeholder="请输入列名称"
+        style="width: 100%; padding: 0 16px 16px"
+      >
+      </el-input>
+      <el-row :gutter="20" style="margin: 0">
+        <el-draggable
+          v-model="columns"
+          :group="{ item: 'key' }"
+          @end="$emit('freeze')"
+        >
+          <el-col
+            v-for="({ item }, index) in searchColumns"
+            :key="index"
+            :span="24"
+            style="
+              display: flex;
+              justify-content: space-between;
+              padding: 12px 16px;
+            "
+          >
+            <span
+              style="
+                font-size: 13px;
+                flex: 1;
+                cursor: move;
+                padding: 0 12px 0 0;
+                text-overflow: ellipsis;
+                overflow: hidden;
+                word-break: break-all;
+                white-space: nowrap;
+              "
+            >
+              <i
+                class="el-icon-mouse"
+                style="color: #72767b; margin: 0 6px 0 0"
+              ></i>
+              <i
+                class="el-icon-user"
+                style="color: #72767b; margin: 0 6px 0 0"
+              ></i>
+              {{ item.title }}
+            </span>
+            <div>
+              <el-switch
+                v-model="item.fixed"
+                size="mini"
+                @change="$emit('freeze')"
+              ></el-switch>
+            </div>
+          </el-col>
+        </el-draggable>
+      </el-row>
+    </el-drawer>
+  </el-button>
+</template>
+
+<script>
+export default {
+  name: "",
+  components: {
+    ElDraggable: () => import("@/components/draggable/index.vue"),
+  },
+  props: {
+    value: {
+      type: Array,
+      require: true,
+    },
+  },
+  data() {
+    return {
+      drawer: false,
+      key: "",
+    };
+  },
+  computed: {
+    columns: {
+      get() {
+        return this.$props.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+    searchColumns: {
+      get() {
+        return this.columns.filter(
+          ({ item }) => item.title.indexOf(this.key) > -1
+        );
+      },
+      set(value) {},
+    },
+    number: {
+      get() {
+        return this.columns.filter(({ item }) => item.fixed).length;
+      },
+      set(value) {},
+    },
+  },
+  watch: {},
+  methods: {},
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

+ 151 - 0
src/components/super-ux-table/hide.vue

@@ -0,0 +1,151 @@
+<template>
+  <el-button size="mini" @click="drawer = true">
+    {{ number ? `隐藏列 :${number}` : "隐藏列" }}
+    <el-drawer
+      :show-close="false"
+      :visible.sync="drawer"
+      size="22%"
+      title="隐藏列"
+      append-to-body
+    >
+      <template slot="title">
+        <span>隐藏列</span>
+        <!-- <el-button type="primary" size="mini" @click="useSubmit('superForm')">
+          确 认
+        </el-button>
+        <el-button size="mini" @click="drawer = false"> 取 消 </el-button> -->
+      </template>
+      <el-input
+        v-model="key"
+        size="mini"
+        placeholder="请输入列名称"
+        style="width: 100%; padding: 0 16px 16px"
+      >
+      </el-input>
+      <el-row :gutter="20" style="margin: 0; display: flex">
+        <el-draggable
+          v-model="columns"
+          :group="{ item: 'key' }"
+          @change="onDraggableChange"
+        >
+          <el-col
+            v-for="({ item }, index) in searchColumns"
+            :key="index"
+            :span="24"
+            style="
+              display: flex;
+              justify-content: space-between;
+              padding: 12px 16px;
+            "
+          >
+            <span
+              style="
+                height: 20px;
+                line-height: 20px;
+                font-size: 13px;
+                flex: 1;
+                cursor: move;
+                padding: 0 12px 0 0;
+                text-overflow: ellipsis;
+                overflow: hidden;
+                word-break: break-all;
+                white-space: nowrap;
+              "
+            >
+              <i
+                class="el-icon-mouse"
+                style="color: #72767b; margin: 0 6px 0 0"
+              ></i>
+              <i
+                class="el-icon-user"
+                style="color: #72767b; margin: 0 6px 0 0"
+              ></i>
+              {{ item.title }}
+            </span>
+            <el-switch
+              v-model="item.hidden"
+              size="mini"
+              @change="onDraggableChange"
+            ></el-switch>
+          </el-col>
+        </el-draggable>
+        <!-- <div @click.stop>
+          <div
+            v-for="({ item }, index) in searchColumns"
+            :key="index"
+            style="padding: 12px 16px"
+          >
+            <el-switch
+              v-model="item.hidden"
+              size="mini"
+              @change="onDraggableChange"
+            ></el-switch>
+          </div>
+        </div> -->
+      </el-row>
+    </el-drawer>
+  </el-button>
+</template>
+
+<script>
+import deepCopy from "@gby/deep-copy";
+export default {
+  name: "",
+  components: {
+    ElDraggable: () => import("@/components/draggable/index.vue"),
+  },
+  props: {
+    value: {
+      type: Array,
+      require: true,
+    },
+  },
+  data() {
+    return {
+      drawer: false,
+      key: "",
+    };
+  },
+  computed: {
+    columns: {
+      get() {
+        return this.$props.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+    searchColumns: {
+      get() {
+        return this.columns.filter(
+          ({ item }) => item.title.indexOf(this.key) > -1
+        );
+      },
+      set(value) {},
+    },
+    number: {
+      get() {
+        return this.columns.filter(({ item }) => !item.hidden).length;
+      },
+      set(value) {},
+    },
+  },
+  watch: {},
+  methods: {
+    onClone(prop) {
+      return deepCopy(prop);
+    },
+    onDraggableChange() {
+      event.stopPropagation(); 
+      this.$emit("change", this.columns);
+    },
+    useSubmit(){
+      this.drawer = false;
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

+ 573 - 0
src/components/super-ux-table/index.vue

@@ -0,0 +1,573 @@
+<script>
+export default {
+  name: "SuperUxTable",
+  props: {
+    // 数据
+    value: {
+      type: [Array],
+      require: true,
+    },
+    // 字典
+    dict: {
+      type: [Object],
+      require: true,
+    },
+    // 分页
+    page: {
+      type: [Object],
+      require: false,
+    },
+    // 模板
+    columns: {
+      type: [Array],
+      require: true,
+    },
+    // 是否显示序号
+    index: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否显示单选
+    radio: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否显示多选
+    checkbox: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否显示分页
+    pagination: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否列操作
+    convenitentOperation: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否禁止选择
+    selectable: {
+      type: Function,
+      default: () => {},
+    },
+    //
+    storageKey: {
+      type: String,
+    },
+    showSummary:{
+      type:Boolean,
+      default:false,
+    },
+    height:{
+      type:[String,Number],
+      default:()=>'auto',
+    }
+
+  },
+  components: {
+    ElDictTag: () => import("@/components/DictTag/index.vue"),
+    ElDraggable: () => import("@/components/draggable/index.vue"),
+    ElFilePreview: () => import("@/components/file-preview/index.vue"),
+    ElComputedInput: () => import("@/components/computed-input/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    ElPopoverMultipleSelectV2: () =>
+      import("@/components/popover-select-v2/multiple.vue"),
+    ElComputedInputV2: () => import("@/components/computed-input-v2/index.vue"),
+    ElPopoverTreeSelect: () =>
+      import("@/components/popover-tree-select/index.vue"),
+    ButtonHide: () => import("./hide.vue"),
+    ButtonFreeze: () => import("./freeze.vue"),
+    IconHide: () => import("./once/hide.vue"),
+    IconSort: () => import("./once/sort.vue"),
+    IconFreeze: () => import("./once/freeze.vue"),
+    IconFilter: () => import("./once/filters.vue"),
+  },
+  data() {
+    const { columns, storageKey } = this.$props;
+    const localColumns = localStorage.getItem(storageKey);
+    const innerColumns =
+      storageKey && localColumns
+        ? JSON.parse(localColumns)
+        : columns.map(({ item, attr }) => ({
+            attr,
+            item: { hidden: true, ...item },
+          }));
+    return {
+      innerColumns: innerColumns,
+      rowKey: "id",
+      // 选择
+      selectData: [],
+      selectState: false,
+      // 过滤
+      filterData: [],
+      filterState: false,
+      count: 0,
+    };
+  },
+  computed: {
+    innerValue: {
+      get() {
+        if (this.filterState) {
+          return this.filterData;
+        } else if (this.selectState) {
+          return this.selectData;
+        } else {
+          return this.$props.value;
+        }
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+    showColumns: {
+      get() {
+        return this.innerColumns.filter(({ item }) => item.hidden);
+      },
+      set() {},
+    },
+    filterRules: {
+      get() {
+        return Object.fromEntries(
+          this.innerColumns
+            .filter(({ item }) => item.filter && !!item.filter.length)
+            .map(({ item }) => [item.key, item.filter])
+        );
+      },
+      set() {},
+    },
+    // height:{
+    //   get(){
+    //     return 100% - 
+    //   },
+    //   set(){},
+    // }
+  },
+  watch: {
+    filterRules: {
+      handler: function (newValue) {
+        function multiFilter(array, filters) {
+          const filterKeys = Object.keys(filters);
+          // filters all elements passing the criteria
+          return array.filter((item) => {
+            // dynamically validate all filter criteria
+            return filterKeys.every((key) => {
+              //ignore when the filter is empty Anne
+              if (!filters[key].length) return true;
+              return !!~filters[key].indexOf(item[key]);
+            });
+          });
+        }
+        this.filterState = JSON.stringify(newValue) !== "{}";
+        this.filterData = multiFilter(this.$props.value, newValue);
+      },
+    },
+    value:{
+      handler: function (newValue) {
+        if(this.value.length > 0){
+          this.$refs.superUxTable && this.$refs.superUxTable.clearSelection();
+        }
+      },
+      immediate: true,
+      deep:true
+    }
+  },
+  methods: {
+    //
+    onSelectionChange(value) {
+      this.selectData = value;
+      this.$emit("row-select", this.selectData);
+    },
+    //
+    onRowClick(row, column, event) {
+      const { radio, checkbox } = this.$props;
+      // 单选
+      if (radio) {
+        this.$emit("row-select", [row]);
+      }
+      // 多选
+      if (checkbox) {
+        this.$refs.superUxTable.toggleRowSelection(
+          this.innerValue.find((item) => item.id === row.id)
+        );
+      }
+    },
+    // 宽度
+    onWidth(newProp, oldProp, column) {
+      console.log(column,'column');
+      this.innerColumns = this.innerColumns.map(({ item, attr }) => ({
+        attr,
+        item: {
+          ...item,
+          width: item.key === column.property ? newProp : item.width,
+        },
+      }));
+      if (this.$props.storageKey) {
+        localStorage.setItem(
+          this.$props.storageKey,
+          JSON.stringify(this.innerColumns)
+        );
+      }
+    },
+    // 隐藏
+    onHide(prop) {
+      this.$nextTick(() => {
+        this.$refs.superUxTable.doLayout();
+        if (this.$props.storageKey) {
+          localStorage.setItem(
+            this.$props.storageKey,
+            JSON.stringify(this.innerColumns)
+          );
+        }
+      });
+    },
+    // 排序
+    onSort(prop) {
+      const { key, sort } = prop;
+      this.$nextTick(() => {
+        this.$refs.superUxTable.sort(key, sort);
+        this.$refs.superUxTable.doLayout();
+        if (this.$props.storageKey) {
+          localStorage.setItem(
+            this.$props.storageKey,
+            JSON.stringify(this.innerColumns)
+          );
+        }
+      });
+    },
+    // 冻结
+    onFreeze() {
+      this.$nextTick(() => {
+        this.$refs.superUxTable.doLayout();
+
+        if (this.$props.storageKey) {
+          localStorage.setItem(
+            this.$props.storageKey,
+            JSON.stringify(this.innerColumns)
+          );
+        }
+        this.count++;
+      });
+     
+    },
+    // 过滤
+    onFilter() {
+      this.$nextTick(() => {
+        this.$refs.superUxTable.doLayout();
+        if (this.$props.storageKey) {
+          localStorage.setItem(
+            this.$props.storageKey,
+            JSON.stringify(this.innerColumns)
+          );
+        }
+      });
+    },
+    onFilters(value) {
+      const {
+        item: { key },
+        attr: { dictName },
+      } = value;
+      let dataList = [];
+      const dict = this.dict.type[dictName];
+      dataList = Array.from(
+        new Set(this.innerValue.map((item) => item[key]).filter((item) => item))
+      ).map((item) => ({
+        text: dictName
+          ? (dict.find((dictItem) => dictItem.value == item) || {}).label
+          : item,
+        value: item,
+      }));
+      return dataList;
+    },
+    // 继承el-table的Method
+    extendMethod() {
+      const refMethod = Object.entries(this.$refs["superUxTable"]);
+      for (const [key, value] of refMethod) {
+        if (!(key.includes("$") || key.includes("_"))) {
+          this[key] = value;
+        }
+      }
+    },
+    getSummaries({ columns, data }){
+      
+      const means = [] // 合计
+      columns.forEach((column, columnIndex) => {
+          if (columnIndex === 0) {
+              means.push('合计')
+          } else {
+              const values = data.map(item => Number(item[column.property]));
+              
+              let sumColumn = this.showColumns.filter(({item,attr}) => attr.isSummary && item.key === column.property);
+
+              // 合计
+              // if (!values.every(value => isNaN(value))) {
+              if (sumColumn.length) {
+                  means[columnIndex] = values.reduce((prev, curr) => {
+                      const value = Number(curr);
+                      if (!isNaN(value)) {
+                          return prev + curr;
+                      } else {
+                          return prev;
+                      }
+                  }, 0);
+                  means[columnIndex] = means[columnIndex].toFixed(2); 
+              } else {
+                  means[columnIndex] = '';
+              }
+            }
+      })
+      // sums[index] = sums[index] && sums[index].toFixed(2); // 保留2位小数,解决小数合计列
+      return [means]
+			
+    },
+  },
+  created() {},
+  mounted() {
+    this.extendMethod();
+  },
+  updated() {
+    this.$nextTick(()=>{
+      this.$refs.superUxTable.doLayout();
+    })
+  },
+  destroyed() {},
+};
+</script>
+
+<template>
+  <div class="el-super-ux-table" :key="count">
+    <ux-grid
+      border
+      row-key
+      use-virtual
+      keep-source
+      show-overflow
+      beautify-table
+      :height="height"
+      ref="superUxTable"
+      v-bind="$attrs"
+      v-on="$listeners"
+      :data="innerValue"
+      :show-summary="showSummary"
+      :summary-method="getSummaries"
+      :highlight-current-row="radio"
+      @row-click="onRowClick"
+      @selection-change="onSelectionChange"
+      :header-row-style="{
+      color: '#515a6e' ,
+    }"
+      style="flex: 1"
+    >
+      <!-- 多选 -->
+      <ux-table-column
+        v-if="checkbox"
+        fixed="left"
+        width="60"
+        align="center"
+        type="checkbox"
+        resizable
+        reserve-selection
+        :column-key="rowKey"
+      >
+      </ux-table-column>
+      <!-- 序号 -->
+      <ux-table-column
+        v-if="index"
+        fixed="left"
+        width="50"
+        title="序号"
+        type="index"
+        align="center"
+        class="is-index"
+        resizable
+      >
+      </ux-table-column>
+      <ux-table-column
+        v-for="({ item, attr }, index) in showColumns"
+        :key="item.key + index"
+        :field="item.key"
+        :title="item.title"
+        :fixed="item.fixed ? 'left' :undefined"
+        :width="item.width || 200"
+        resizable
+        show-overflow
+      >
+        <template slot="header" slot-scope="scope">
+          <template>
+            <span v-if="item.require" style="color: #ff4949">*</span>
+            <span
+              :style="{
+                color:
+                  item.sort ||
+                  item.fixed ||
+                  (item.filter && !!item.filter.length)
+                    ? '#1890ff'
+                    : '',
+              }"
+            >
+              {{ item.title }}
+            </span>
+            <template>
+              <icon-sort
+                v-if="item.sortabled"
+                v-model="item.sort"
+                @sort="onSort(item)"
+              ></icon-sort>
+              <icon-freeze
+                v-if="item.fixedabled"
+                v-model="item.fixed"
+                @freeze="onFreeze"
+              ></icon-freeze>
+              <icon-filter
+                v-if="item.filterabled"
+                v-model="item.filter"
+                :filters="onFilters({ item, attr })"
+                @filter="onFilter"
+              ></icon-filter>
+              <icon-hide
+                v-if="item.hiddenabled"
+                v-model="item.hidden"
+                @hide="onHide"
+              ></icon-hide>
+            </template>
+          </template>
+        </template>
+        <template slot-scope="scope">
+          <slot :name="item.key" v-bind="scope" :item="item" :attr="attr">
+            <template v-if="attr.is">
+              <component
+                v-if="attr.is === 'el-dict-tag'"
+                v-bind="attr"
+                :size="$attrs.size"
+                :value="scope.row[item.key]"
+                :options="dict.type[attr.dictName]"
+              ></component>
+              <component
+                v-else-if="attr.is === 'el-popover-select-v2'"
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :title="item.title"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+              >
+              </component>
+              <component
+                v-else-if="attr.is === 'el-popover-multiple-select-v2'"
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :title="item.title"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+              >
+              </component>
+              <component
+                v-else-if="attr.is === 'el-select'"
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :size="$attrs.size"
+              >
+                <template>
+                  <el-option
+                    v-for="item in dict.type[attr.dictName]"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </template>
+              </component>
+              <component
+                v-else
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :size="$attrs.size"
+                style="width: 100%"
+              >
+              </component
+            ></template>
+            <template v-else>
+              <component v-if="attr.formatter" is="span">{{
+                attr.formatter(scope.row)
+              }}</component>
+              <component v-else is="span">{{
+                scope.row[item.key] || "--"
+              }}</component>
+            </template>
+          </slot>
+        </template>
+      </ux-table-column>
+      <slot></slot>
+    <!-- </el-table> -->
+    </ux-grid>
+    <div
+      style="
+        height: 50px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+      "
+      :style="{
+        height: checkbox || pagination ? '50px' : '0px',
+      }"
+    >
+      <div class="mr-4">
+        <template v-if="convenitentOperation">
+          <button-hide v-model="innerColumns" @change="onHide"></button-hide>
+        </template>
+      </div>
+      <pagination
+        v-if="pagination"
+        v-show="!selectState"
+        :total="page.total"
+        :page.sync="page.pageNum"
+        :limit.sync="page.pageSize"
+        @pagination="$emit('pagination', { ...$event })"
+        style="height: 32px; padding: 0 !important; flex: 1; overflow-x: auto"
+      />
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.el-super-ux-table {
+  position: relative;
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  overflow: auto;
+}
+::v-deep.el-super-ux-table .elx-cell {
+  word-break: keep-all;
+  white-space: nowrap;
+  .icon-sort {
+    display: none;
+  }
+  &:hover .icon-sort {
+    display: inline-block;
+  }
+  .icon-freeze {
+    display: none;
+  }
+  &:hover .icon-freeze {
+    display: inline-block;
+  }
+  .icon-filter {
+    display: none;
+  }
+  &:hover .icon-filter {
+    display: inline-block;
+  }
+  .icon-hide {
+    display: none;
+  }
+  &:hover .icon-hide {
+    display: inline-block;
+  }
+}
+
+::v-deep.uxbeautifyTableClass .elx-header--column .elx-resizable.is--line:before{
+  height: 100%;
+  background-color: #dfe6ec;
+}
+</style>

+ 145 - 0
src/components/super-ux-table/once/filters.vue

@@ -0,0 +1,145 @@
+<template>
+  <el-popover
+    v-if="innerValue !== false || filterData.length"
+    :visible-arrow="false"
+    width="auto"
+    trigger="click"
+    placement="bottom"
+    popper-class="p-0"
+    class="icon-filter"
+    v-model="visible"
+    :style="{
+      color: innerValue && innerValue.length ? '#1890ff' : '',
+      display: innerValue && innerValue.length ? 'inline-block' : '',
+    }"
+  >
+    <template>
+      <el-checkbox-group
+        v-model="selectData"
+        class="pt-3 px-3"
+        @change="onCheck"
+        style="max-height: 300px; overflow-y: auto"
+      >
+        <el-checkbox
+          v-for="item in filterData"
+          :key="item.value"
+          :label="item.value"
+          class="mr-0 mb-3"
+          style="display: block"
+        >
+          {{ item.text }}
+        </el-checkbox>
+      </el-checkbox-group>
+      <el-divider class="m-0"></el-divider>
+      <div
+        class="p-3"
+        style="min-width: 175px; display: flex; justify-content: space-between"
+      >
+        <el-checkbox
+          v-model="checkAll"
+          :indeterminate="indeterminate"
+          @change="onCheckAll"
+        >
+          全选
+        </el-checkbox>
+        <div>
+          <el-button type="text" class="p-0" @click="onReset">重置</el-button>
+          <el-button type="text" class="p-0" @click="onFilter">筛选</el-button>
+        </div>
+      </div>
+    </template>
+    <i
+      slot="reference"
+      class="el-icon-search pl-1"
+      style="cursor: pointer; font-weight: 600; transition: 500ms"
+      @click="onOpen"
+    ></i>
+  </el-popover>
+</template>
+
+<script>
+export default {
+  name: "IconFilter",
+  components: {},
+  data() {
+    return {
+      disabled: false,
+      selectData: [],
+      visible:false,
+    };
+  },
+  props: {
+    value: {
+      type: [Array, Boolean],
+      require: true,
+    },
+    filters: {
+      type: Array,
+      require: true,
+    },
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.$props.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+    filterData: {
+      get() {
+        return this.$props.filters;
+      },
+      set() {},
+    },
+    indeterminate: {
+      get() {
+        const count = this.filterData.length;
+        const selectCount = this.selectData.length;
+        return selectCount > 0 && selectCount < count;
+      },
+      set() {},
+    },
+    checkAll: {
+      get() {
+        const count = this.filterData.length;
+        const selectCount = this.selectData.length;
+        return count === selectCount;
+      },
+      set() {},
+    },
+  },
+  watch: {},
+  methods: {
+    // 打开
+    onOpen() {
+      this.disabled = !this.disabled;
+    },
+    // 选中
+    onCheck() {
+      // const count = this.filterData.length;
+      // const selectCount = this.selectData.length;
+      // this.checkAll = count === selectCount;
+    },
+    // 全选
+    onCheckAll(value) {
+      this.selectData = value ? this.filterData.map((item) => item.value) : [];
+    },
+    // 重置
+    onReset() {
+      this.selectData = [];
+      this.innerValue = this.selectData;
+    },
+    // 筛选
+    onFilter() {
+      this.innerValue = this.selectData;
+      this.visible = false;
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

+ 66 - 0
src/components/super-ux-table/once/freeze.vue

@@ -0,0 +1,66 @@
+<template>
+  <span
+    class="icon-freeze"
+    :style="{
+      color: innerValue ? '#1890ff' : '',
+      display: innerValue ? 'inline-block' : '',
+    }"
+  >
+    <i
+      v-if="innerValue"
+      class="el-icon-lock pl-1"
+      style="
+        color: #1890ff;
+        cursor: pointer;
+        font-weight: 600;
+        transition: 500ms;
+      "
+      @click="onFreeze"
+    ></i>
+    <i
+      v-else
+      class="el-icon-unlock pl-1"
+      style="cursor: pointer; font-weight: 600; transition: 500ms"
+      @click="onFreeze"
+    ></i>
+  </span>
+</template>
+
+<script>
+export default {
+  name: "IconFreeze",
+  components: {},
+  data() {
+    return {};
+  },
+  props: {
+    value: {
+      type: Boolean,
+      require: true,
+    },
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.$props.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+
+      },
+    },
+  },
+  watch: {},
+  methods: {
+    async onFreeze() {
+      this.innerValue = !this.innerValue;
+      await this.$emit("freeze");
+    },
+  },
+  created() {
+  },
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

+ 45 - 0
src/components/super-ux-table/once/hide.vue

@@ -0,0 +1,45 @@
+<template>
+  <i
+    v-if="innerValue"
+    class="el-icon-circle-close pl-1 icon-hide"
+    style="cursor: pointer; font-weight: 600; transition: 500ms"
+    @click="onHide"
+  ></i>
+</template>
+
+<script>
+export default {
+  name: "IconHide",
+  components: {},
+  props: {
+    value: {
+      type: Boolean,
+      require: true,
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.$props.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+  },
+  watch: {},
+  methods: {
+    onHide() {
+      this.innerValue = !this.innerValue;
+      this.$emit("hide");
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

+ 64 - 0
src/components/super-ux-table/once/sort.vue

@@ -0,0 +1,64 @@
+<template>
+  <span
+    class="icon-sort"
+    :style="{
+      color: innerValue ? '#1890ff' : '',
+      display: innerValue ? 'inline-block' : '',
+    }"
+  >
+    <i
+      v-if="innerValue === 'descending'"
+      class="el-icon-bottom pl-1"
+      style="
+        color: #1890ff;
+        cursor: pointer;
+        font-weight: 600;
+        transition: 500ms;
+      "
+      @click="onSort(null)"
+    ></i>
+    <i
+      v-else
+      class="el-icon-top pl-1"
+      style="cursor: pointer; font-weight: 600; transition: 500ms"
+      @click="onSort('descending')"
+    ></i>
+  </span>
+</template>
+
+<script>
+export default {
+  name: "IconSort",
+  components: {},
+  data() {
+    return {};
+  },
+  props: {
+    value: {
+      type: String,
+      require: true,
+    },
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.$props.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+  },
+  watch: {},
+  methods: {
+    onSort(value) {
+      this.innerValue = value;
+      this.$emit("sort");
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

文件差異過大導致無法顯示
+ 481 - 474
src/views/material/requisition/add/columns.js


+ 16 - 7
src/views/purchase/apply/index.vue

@@ -16,6 +16,7 @@
       DeleButton: () => import("./delete/index.vue"),
       SubmButton: () => import("./submit/index.vue"),
       ElSuperTable: () => import("@/components/super-table/index.vue"),
+      ElSuperUxTable: () => import("@/components/super-ux-table/index.vue"),
       ElSuperSearch: () => import("@/components/super-search/index.vue"),
     },
     data() {
@@ -48,7 +49,14 @@
         TableColumns: TableColumns,
       };
     },
-    computed: {},
+    computed: {
+      tableHeight:{
+        get(){
+          return window.innerHeight - 220;
+        },
+        set(){},
+      }
+    },
     created() {
       this.params.priceCode = this.$route.query.billCode
       this.useQuery(this.params, this.page);
@@ -272,12 +280,13 @@
         <el-button size="mini" @click="importMb">导 入</el-button>
       </el-button-group>
     </el-row>
-    <el-super-table
+    <el-super-ux-table
       v-model="tableData"
       :size="size"
       :dict="dict"
       :page="page"
       :columns="TableColumns"
+      :height="tableHeight"
       index
       checkbox
       pagination
@@ -287,17 +296,17 @@
       @row-select="useSelect"
       @pagination="useQuery(params, page)"
     >
-      <el-table-column
+      <ux-table-column
         fixed="right"
-        label="操作"
+        title="操作"
         align="center"
         width="100"
         >
         <template slot-scope="scope">
           <el-button type="text" size="mini" v-if="scope.row.status == '1' && scope.row.flowId" @click="reback(scope.row)">收回</el-button>
         </template>
-      </el-table-column>
-    </el-super-table>
+      </ux-table-column>
+    </el-super-ux-table>
     <!-- 文件导入对话框 -->
     <el-dialog title="文件导入" :visible.sync="upload.open" width="400px">
       <el-upload
@@ -327,7 +336,7 @@
         <el-button size="mini" type="primary" @click="submitFileForm">确 定</el-button>
         <el-button size="mini" @click="upload.open = false">取 消</el-button>
       </div>
-    </el-dialog>
+    </el-dialog> 
   </el-card>
 </template>
 <style scoped lang="scss">

+ 225 - 2
src/views/purchase/purchase-order/column.js

@@ -1,5 +1,210 @@
+import Cookies from "js-cookie";
 
-export const TableColumns = [
+// 集采中心
+const PurColumns = [
+  { 
+    item:{ 
+      key: "puOrgName", title: "采购组织", inputType: "Input",},
+    attr:{
+      isHidden:true,
+      width:150, 
+    },
+  },
+  {
+    item:{ 
+      key: "billType",
+      title: "订单类型",
+      width:150, 
+    },
+    attr:{
+      isHidden:true,
+      is: "el-dict-tag",
+      dictName: "sys_order_type",
+    },
+  },
+  { 
+    item:{
+      key: "code", 
+      title: "订单编号", 
+      inputType: "Input",
+      width:150, 
+    },
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{key: "supplierName", title: "供应商", inputType: "Input",},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "createByName", title: "制单人" ,width:100,},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "createTime", title: "制单日期" ,width:100,},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{key: "qty", title: "总数量",width:80,},
+    attr:{
+      isHidden:true,
+      isSummary:true,
+    },
+  },
+  { 
+    item:{
+      key: "money", 
+      title: "价税合计",
+      width:80,
+      // 
+    },
+    attr:{
+      isHidden:true,
+      isSummary:true,
+    },
+  },
+  {
+    item:{
+      key: "status",
+      title: "单据状态",
+      width:80,
+    },
+    attr:{
+      is: "el-dict-tag",
+      dictName: "documents_status",
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "warehouseName", title: "WMS入库仓库" ,},
+    attr:{
+      isHidden:true,
+    },
+    width:100,
+  }, //WMS入库仓库名称
+  { 
+    item:{
+      key: "rebateMoney", 
+      title: "订单使用返利金额" ,
+      width:100,
+      // 
+    },
+    attr:{
+      isHidden:true,
+      isSummary:true,
+    },
+  },
+  { 
+    item:{key: "deductionMoney", title: "订单抵扣余款金额" ,},
+    attr:{
+      isHidden:true,
+      isSummary:true,
+     
+    },
+    width:100,
+  },
+  { 
+    item:{ key: "remark", title: "备注" ,},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "address", title: "收货地址" ,},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{key: "paymentAgreementName", title: "付款协议",width:100, },
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "applyPaymentMoney", title: "累计付款申请金额", width:100, },
+    attr:{
+      isHidden:true,
+      isSummary:true,
+     
+    },
+  },
+  { 
+    item:{ key: "paymentMoney", title: "累计付款金额" ,},
+    attr:{
+      isHidden:true,
+      isSummary:true,
+    },
+    width:100,
+  },
+  { 
+    item:{ key: "invoiceMoney", title: "发票金额" ,},
+    attr:{
+      isHidden:true,
+      isSummary:true,
+    },
+    width:100,
+  },
+  {
+    item:{ 
+      key: "isClose",
+      title: "最终关闭",
+      width:80,
+    },
+    attr:{
+      is: "el-checkbox",
+      'true-label':"Y",
+      'false-label':"N",
+      disabled:true,
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "approverName", title: "审批人" ,width:100,},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "approverFinishTime", title: "审批时间",width:100, },
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    // 更新人
+    item:{ key: "updateByName", title: "最后修改人" ,width:100,},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "updateTime", title: "最后修改时间",},
+    attr:{
+      isHidden:true,
+    },
+  },
+  { 
+    item:{ key: "originalMoney", title: "原始金额",},
+    attr:{
+      isHidden:true,
+      isSummary:true,
+    },
+  },
+].map(({ item, attr }) => ({
+  attr,
+  item: { ...item, hidden: true, fixed: false },
+}));
+
+// 事业发展部
+const CauseColumns = [
   { 
     item:{ 
       key: "puOrgName", title: "采购组织", inputType: "Input",},
@@ -489,7 +694,7 @@ export const TableColumns = [
   item: { ...item, hidden: true, fixed: false },
 }));
 
-export const TabColumns = [
+const CommonTabColumns = [
 
 
   {
@@ -1410,3 +1615,21 @@ export const SearchColumns = [
   item: { ...item, hidden: true, span: item.span || 6 },
 }));
 
+export const judgeColumns = () =>{
+
+  // let Columns =  _.cloneDeep(PurColumns);
+  // let TabColumns =  _.cloneDeep(CommonTabColumns);
+
+  // let roles =  Cookies.get('roles').split(',');
+  // let role = roles.find(item => item === "syfz-purchaseorder") || "procurementManager";
+
+  // if(role === "syfz-purchaseorder"){
+    // 事业发展部
+    let Columns =  _.cloneDeep(CauseColumns);
+    let TabColumns =  _.cloneDeep(CommonTabColumns);
+  // }
+
+  return { Columns,TabColumns }
+
+}
+

+ 21 - 14
src/views/purchase/purchase-order/index.vue

@@ -1,6 +1,7 @@
 <!-- 采购订单修订—— 列表 -->
 <script>
-import { TableColumns, SearchColumns, TabColumns, SelectColumns } from "./column";
+// import { TableColumns, SearchColumns, TabColumns, SelectColumns } from "./column";
+import { judgeColumns, SearchColumns, } from "./column";
 import orderApi from "@/api/business/purchase/purchase-order";
 import {
   initPage,
@@ -9,7 +10,9 @@ import {
 } from "@/utils/init/index.js";
 import {  initDicts } from "@/utils/init.js";
 
-const allColumns = [...TableColumns, ...SearchColumns];
+const {Columns,TabColumns} = judgeColumns();
+
+const allColumns = [...Columns, ...SearchColumns];
 
 TabColumns.forEach(column =>{
   allColumns.push(...column.tableColumns)
@@ -26,6 +29,7 @@ export default {
     EditDrawer: () => import('./edit/index.vue'),
     PurchaseReturnDrawer: () => import('./purchaseReturn/index.vue'),
     ElSuperTable: () => import("@/components/super-table/index.vue"),
+    ElSuperUxTable: () => import("@/components/super-ux-table/index.vue"),
     ElSuperSearch: () => import("@/components/super-search/index.vue"),
     Retrieve: () => import("@/components/Retrieve/index.vue"),
     ZpButton: () => import("./zhuan-pai/index.vue"),
@@ -38,7 +42,8 @@ export default {
       page: { pageNum: 1, pageSize: 10, total: 0 },
       searchColumns: SearchColumns,
       params: initParams(SearchColumns),
-      tableColumns: TableColumns,
+      // tableColumns: TableColumns,
+      tableColumns: Columns,
       tableData: [],
       tabColumns: initTabColumns(),
       tabName: "puOrderItemList",
@@ -683,7 +688,7 @@ export default {
 
     <el-super-search
       v-model="params"
-      :size="'mini'"
+      :size="size"
       :dict="dict"
       :columns="searchColumns"
       @reset="handleResetList"
@@ -737,20 +742,21 @@ export default {
         class="purchaseTable"
         v-model="tableData"
         ref="purchaseTable"
-        :dict="dict"
-        :columns="tableColumns"
-        :selectable="setSelectable"
         index
         checkbox
         pagination
         showSummary
         :page="page"
+        :size="size"
+        :dict="dict"
         convenitentOperation
-        @pagination="fetchList(params, page)"
-        @row-dblclick="handleOpenSeeDrawer" 
+        @select="handleSelect"
+        :columns="tableColumns"
+        :selectable="setSelectable"
         @row-click="handleDetailsData" 
+        @row-dblclick="handleOpenSeeDrawer" 
+        @pagination="fetchList(params, page)"
         @selection-change="handleSelectionChange"
-        @select="handleSelect"
       >
         
         <el-table-column fixed="right" label="操作" width="120">
@@ -758,7 +764,7 @@ export default {
               <el-button 
                 v-if="judgeIsOption('revise',scope.row)"
                 type="text" 
-                size="small" 
+                :size="size" 
                 @click.stop="handleOpenEditDrawer(scope.row)"
                 v-hasPermi="['material:order:edit']">
               修订
@@ -766,7 +772,7 @@ export default {
               <el-button 
                 v-if="judgeIsOption('edit',scope.row)"
                 type="text" 
-                size="small" 
+                :size="size" 
                 @click.stop="handleOpenEditDrawer(scope.row)"
                 v-hasPermi="['material:order:edit']">
               编辑
@@ -775,7 +781,7 @@ export default {
               <el-button 
                 v-if="judgeIsOption('del',scope.row)" 
                 type="text" 
-                size="small" 
+                :size="size" 
                 @click.stop="handleDeleteList(scope.row)"
                 v-hasPermi="['material:order:remove']"
               >删除</el-button>
@@ -808,7 +814,7 @@ export default {
     <div style="position: relative; padding-top: 10px;" v-loading="tabLoading">
       <el-row style="position: absolute; top: 30px; right: 20px;z-index: 10;">
         <el-button 
-          size="mini" 
+        :size="size"
           @click="handleLineReturn"
           :disabled="judgeIsLineReturn()"
         >行退回</el-button>
@@ -838,6 +844,7 @@ export default {
               :checkbox="setTabSelectable()"
               convenitentOperation
               showSummary
+              :size="size"
               @select="handleTabSelect"
               @selection-change="handleTabSelectionChange"
             >

部分文件因文件數量過多而無法顯示