|
@@ -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>
|