zhaoke 2 ani în urmă
părinte
comite
f736692715
1 a modificat fișierele cu 346 adăugiri și 1 ștergeri
  1. 346 1
      src/components/table/index.vue

+ 346 - 1
src/components/table/index.vue

@@ -1,9 +1,354 @@
 <template>
-  <div class="table"></div>
+  <div class="tableTmp">
+    <div class="tableTmp-add flex">
+      <div class="manageTitle">{{pageTitle}}</div>
+      <el-button size="default" @click="handleAdd" plain>新增</el-button>
+    </div>
+    <div class="tableTmp-content t24">
+      <el-table height="100%" v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" v-el-table-infinite-scroll="load" :data="filteredTableData" stripe :border="true" style="width: 100%">
+        <el-table-column v-for="(item, index) in tableColsCopy" :sortable="item.needSort ? true : false" :key="index" :prop="item.columnName" :label="item.columnLabel" :show-overflow-tooltip="showOverflowTooltip">
+          <template #header>
+            <span class="colTips">
+              <el-tooltip :content="item.columnDescribe" placement="top">
+                <span>{{ item.columnLabel }}</span>
+              </el-tooltip>
+            </span>
+            <span v-if="item.needFilters">
+              <el-popover placement="bottom" trigger="click">
+                <template #reference>
+                  <el-icon>
+                    <ArrowDownBold />
+                  </el-icon>
+                </template>
+                <el-form>
+                  <el-form-item :label="item.columnLabel">
+                    <el-select v-model="filterValues[item.columnName]" size="small" placeholder="筛选" default-first-option filterable clearable>
+                      <el-option v-for="(option, optionIndex) in tableDataFilters[item.columnName]" :key="option.value + optionIndex" :value="option.value" :label="option.text" />
+                    </el-select>
+                  </el-form-item>
+                </el-form>
+              </el-popover>
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column fixed="right" label="操作" :width="fixedWidth">
+          <template #default="scope">
+            <el-button type="primary" @click="handleEdit(scope.row)" size="small">编辑</el-button>
+            <el-button type="danger" @click="handleRemove(scope.row)" size="small">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!--新增/编辑-->
+    <Dialog :flag="editFlag" width="650px" :msgTitle="editTitle" @submitForm="submitForm(ruleFormRef)" @resetForm="resetForm(ruleFormRef)" :show-flag="true">
+      <el-form ref="ruleFormRef" :model="tableForm" :label-width="labelWidth" class="demo-ruleForm">
+        <el-row :gutter="20">
+          <el-col v-for="(item, index) in tableColsCopy" :key="index" :span="rows">
+            <el-form-item :label="item.columnLabel">
+              <template v-if="item.listqueryTemplateID || item.listqueryTemplateID == 0">
+                <el-select class="input-shadow" size="default" filterable default-first-option style="width: 100%" v-model="tableForm[item.columnName]" placeholder="请选择" clearable @clear="tableForm[item.columnName] = ''">
+                  <el-option v-for="citem in tableOptions[item.columnName]" :key="citem.v ? citem.v : citem.planDepartureApt" :label="citem.k ? citem.k : citem.planDepartureApt" :value="citem.setlabel === 'positionDescribe' ? citem.v : citem.v != undefined ? citem.v : citem.planDepartureApt">
+                  </el-option>
+                </el-select>
+              </template>
+              <template v-else-if="item.dataType == 'longtext'">
+                <el-input size="default" :rows="1" type="textarea" v-model="tableForm[item.columnName]"></el-input>
+              </template>
+              <template v-else-if="item.dataType == 'datetime'">
+                <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="tableForm[item.columnName]" :rows="1" type="datetime" placeholder="选择日期时间">
+                </el-date-picker>
+              </template>
+              <template v-else-if="item.dataType == 'number'">
+                <el-input size="default" v-model.number="tableForm[item.columnName]" onkeyup="value=value.replace(/[^1-9]/g,'')"></el-input>
+              </template>
+              <template v-else>
+                <el-input size="default" v-model="tableForm[item.columnName]"></el-input>
+              </template>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </Dialog>
+    <!---删除-->
+    <Dialog type="del" :flag="delFlag" msgTitle="删除" :delName="delTitle" @delRest="delRest" @delRemove="delRemove" />
+  </div>
 </template>
 
 <script setup lang="ts">
+import { ref, onBeforeMount, computed } from "vue";
+import * as _ from "lodash";
+import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";
+import { Query, GeneralDataReception } from "@/api/webApi";
+import { ElMessage, FormInstance, FormRules } from "element-plus";
+import Dialog from "@/components/dialog/index.vue";
+const props = defineProps({
+  tableId: {
+    type: Number,
+    default: 0,
+  },
+  dataContent: {
+    type: Array,
+    default: () => [],
+  },
+  fixedWidth: {
+    type: String || Number,
+    default: "150px",
+  },
+  // 不换行,溢出隐藏
+  showOverflowTooltip: {
+    type: Boolean,
+    default: false,
+  },
+  //弹框-表单文字宽度
+  labelWidth: {
+    type: String,
+    default: "80px",
+  },
+  //弹框表单-行数
+  rows: {
+    type: Number,
+    default: 12,
+  },
+});
+const page = ref<number>(0); //分页参数
+const { dataContent, showOverflowTooltip, fixedWidth, labelWidth, rows } =
+  props;
+const ruleFormRef = ref<FormInstance>();
+const loading = ref(false);
+const noMore = ref(false);
+const queryId = ref<any>(null);
+const serviceId = ref<any>(null);
+const tableData = ref<any>([]);
+const tableCols = ref<any>([]);
+const tableDataCopy = ref<any>([]);
+const tableColsCopy = ref<any>([]); //表头数据缓存
+const tableForm = ref<any>({}); //弹框新增/编辑数据
+const filterValues = ref<any>({}); //表头-下拉-选中数据
+const tableDataFilters = ref<any>({}); //表头-下拉数据
+const tableGroups = ref<any>([]); //表格分组数据
+const pageTitle = ref<any>("");
+const rowTitle = ref("");
+const delTitle = ref("");
+const delFlag = ref(false);
+const editTitle = ref("编辑");
+const editType = ref("add");
+const editFlag = ref(false);
+const delObj = ref<any>({});
+const tableOptions = ref<any>({}); //弹框-下来数据缓存
+//获取表格数据
+const getQuery = async (id) => {
+  try {
+    loading.value = true;
+    const { code, returnData } = await Query({
+      id,
+      needPage: ++page.value,
+      dataContent,
+    });
+    if (code == 0) {
+      if (returnData.listValues.length === 0) {
+        page.value--;
+        noMore.value = true;
+        loading.value = false;
+      }
+      const titleColumn = returnData.columnSet.find(
+        (item) => item.needShow === 1
+      );
+      if (titleColumn) {
+        rowTitle.value = titleColumn.columnName;
+      }
+      tableData.value.push(...returnData.listValues);
+      tableCols.value = returnData.columnSet;
+      serviceId.value = returnData.submitID;
+      setTimeout(() => {
+        initTableData();
+      }, 100);
+    } else {
+      page.value--;
+      loading.value = false;
+    }
+  } catch (error) {
+    page.value--;
+    loading.value = false;
+  }
+};
+
+//初始化表格
+const initTableData = () => {
+  tableColsCopy.value = tableCols.value.filter((item) => item.needShow);
+  tableDataCopy.value = _.cloneDeep(tableData.value);
+  const datas = _.cloneDeep(tableColsCopy.value);
+  datas.forEach(async (item) => {
+    tableDataFilters.value[item.columnName] = [];
+    if (item.needGroup) {
+      tableGroups.value.push(item.columnName);
+    }
+  });
+  setTableFilters(tableData.value, tableDataFilters.value);
+};
+
+// 表格添加过滤条件
+const setTableFilters = (tableData, filters) => {
+  const tempSets = {};
+  Object.keys(filters).forEach((key) => {
+    tempSets[key] = new Set();
+  });
+  tableData.forEach((item) => {
+    Object.keys(tempSets).forEach((key) => {
+      (item[key] ?? "") !== "" && tempSets[key].add(String(item[key]));
+    });
+  });
+  Object.keys(tempSets).forEach((key) => {
+    filters[key] = _.orderBy(
+      [...tempSets[key]].map((value) => ({
+        text: value,
+        value,
+      })),
+      (o) => o.value
+    );
+  });
+};
+
+//表格数据滚动加载
+const load = () => {
+  if (noMore.value) {
+    return;
+  }
+  getQuery(queryId.value);
+};
+
+//重置表格
+const resetTable = () => {
+  page.value = 0;
+  noMore.value = false;
+  tableData.value = [];
+};
+
+//表格筛选下拉
+const itemFilters = computed(() => (item) => {
+  if (item.needFilters) {
+    const datas = <any>[];
+    const table = _.cloneDeep(tableData.value);
+    const key = item.columnName;
+    table.forEach((citem) => {
+      datas.push({
+        text: citem[key],
+        value: citem[key],
+      });
+    });
+    return datas;
+  } else {
+    return [];
+  }
+});
+
+//表格筛选
+const filterHandler = (value: string, row, column: TableColumnCtx<any>) => {
+  const property = column["property"];
+  return row[property] === value;
+};
+//表格数据新增弹框
+const handleAdd = () => {
+  editFlag.value = true;
+  editType.value = "add";
+  tableForm.value = {};
+};
+//表格数据编辑弹框
+const handleEdit = (row) => {
+  editFlag.value = true;
+  editType.value = "edit";
+  tableForm.value = _.cloneDeep(row);
+};
+//表格数据删除弹框
+const handleRemove = (row) => {
+  delFlag.value = true;
+  delObj.value = _.cloneDeep(row);
+  delTitle.value = row[rowTitle.value];
+};
+//删除-取消
+const delRest = () => {
+  delFlag.value = false;
+};
+//删除-确定
+const delRemove = () => {
+  dataChange(3, delObj.value);
+  delFlag.value = false;
+};
+//新增/编辑确定
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  await formEl.validate((valid, fields) => {
+    if (valid) {
+      if (editType.value == "add") {
+        dataChange(1, tableForm.value);
+      } else {
+        dataChange(2, tableForm.value);
+      }
+      editFlag.value = false;
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+//新增/编辑取消
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  editFlag.value = false;
+};
+//增删改
+const dataChange = async (event, data) => {
+  data.event = event;
+  const { code, message } = await GeneralDataReception({
+    serviceId: serviceId.value,
+    dataContent: JSON.stringify(data),
+  });
+  if (code == 0) {
+    getQuery(queryId.value);
+    ElMessage.success(message);
+  } else {
+    ElMessage.error(message);
+  }
+};
+//设置表头-下拉-选中数据
+const filteredTableData = computed(() => {
+  return tableData.value.filter((item) => {
+    let flag = true;
+    Object.entries(filterValues.value).forEach(([key, value]) => {
+      if (value !== "" && item[key] !== value) {
+        flag = false;
+      }
+    });
+    return flag;
+  });
+});
+//获取表格id
+onBeforeMount(() => {
+  const route = useRoute();
+  const { qid, title } = route.meta;
+  pageTitle.value = title;
+  if (qid) {
+    queryId.value = qid;
+  }
+});
 </script>
 
 <style lang="scss" scoped>
+.tableTmp {
+  height: 100%;
+  &-content {
+    height: calc(100% - 56px);
+    :deep .el-table {
+      .colTips {
+        color: #333;
+        font-size: 14px;
+      }
+      .is-first-column {
+        .cell {
+          color: #333;
+          font-size: 14px;
+        }
+      }
+    }
+  }
+}
 </style>