wangting
2025-01-08 354cad3d3ab22ba147169beb6a0f6f51b9bab3a8
Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/formDefine/index.vue
@@ -4,19 +4,19 @@
    <el-aside>
      <basic-container>
        <div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
          <!-- 左侧树         -->
          <div style="height:  calc(100vh - 280px);">
          <!-- 左侧树 -->
          <div style="height:  calc(100vh - 220px);">
            <div style="margin-bottom: 10px;display: flex;justify-content: center">
              <el-radio v-model="treeRadio" label="0">业务类型树</el-radio>
              <el-radio v-model="treeRadio" label="1">链接类型树</el-radio>
              <el-radio v-model="treeRadio" label="0" @input="TreeRadioChange">业务类型树</el-radio>
              <el-radio v-model="treeRadio" label="1" @input="TreeRadioChange">链接类型树</el-radio>
            </div>
            <avue-tree :data="treeData" :option="treeOption" @node-click="nodeClick">
          <span slot-scope="{ node, data }" class="el-tree-node__label">
           <span style="font-size: 15px">
              <i class="el-icon-s-promotion"></i>
                {{ (node || {}).label }}
            </span>
          </span>
            <avue-tree v-loading="treeLoading" :data="treeData" :option="treeOption" @node-click="nodeClick">
              <span slot-scope="{ node, data }" class="el-tree-node__label">
               <span>
                  <icon-show :name="data.icon"></icon-show>
                    {{ (node || {}).label }}
                </span>
              </span>
            </avue-tree>
          </div>
        </div>
@@ -25,81 +25,613 @@
    <el-main>
      <basic-container>
        <div v-if="!tableStatus" style="display: flex;justify-content: left;margin-top: 15px">
          <el-button v-if="permissionList.addBtn" class="button-custom-icon" plain size="small" type="primary"
                     @click="addClickHandler">
            <icon-show :name="permissionList.addBtn.source"></icon-show>
            增加
          </el-button>
          <el-button v-if="permissionList.delBtn" class="button-custom-icon" plain size="small" type="danger"
                     @click="deleteClickHandler">
            <icon-show :name="permissionList.delBtn.source"></icon-show>
            删除
          </el-button>
          <el-button v-if="permissionList.cloneBtn" class="button-custom-icon" plain size="small" type="primary"
                     @click="copyClickHandler">
            <icon-show :name="permissionList.cloneBtn.source"></icon-show>
            克隆
          </el-button>
          <el-button v-if="permissionList.importBtn" class="button-custom-icon" plain size="small" type="primary"
                     @click="upLoadClickHandler">
            <icon-show :name="permissionList.importBtn.source"></icon-show>
            导入
          </el-button>
          <el-button v-if="permissionList.exportBtn" class="button-custom-icon" plain size="small" type="primary"
                     @click="exportClickHandler">
            <icon-show :name="permissionList.exportBtn.source"></icon-show>
            导出
          </el-button>
        </div>
        <avue-crud
          v-if="!tableStatus"
          ref="crud"
          :data="data"
          :option="option">
          :option="option"
          :page.sync="page"
          @size-change="sizeChange"
          @current-change="currentChange"
          @selection-change="selectChangeHandler"
          @row-click="rowClickHandler">
          <template slot="menuLeft">
            <div style="display: flex; align-items: center;">
               <span style="display: inline-block; margin-right: 10px;">
                <el-radio v-model="tableRadio" label="0">表单</el-radio>
                <el-radio v-model="tableRadio" label="1">表格<span style="color: red;">(先导入表单,再导入表格!)</span></el-radio>
                <el-radio v-model="tableRadio" label="0" @input="tableRadioChange">表单</el-radio>
                <el-radio v-model="tableRadio" label="1" @input="tableRadioChange">表格<span style="color: red;">(先导入表单,再导入表格!)</span></el-radio>
               </span>
              <span style="display: flex;align-items: center; margin-right: 10px;">
                <p style="display: flex; flex-shrink: 0;font-size: 14px">名称:</p>
                <el-input v-model="input" placeholder="请输入内容" size="mini"></el-input>
              </span>
              <span style="display: flex; align-items: center;">
                <p
                  style="display: flex; align-items: center; margin: 0 10px 0 0;flex-shrink: 0;font-size: 14px">克隆目标:</p>
                <el-input v-model="input" placeholder="请输入内容" size="mini" style="margin-right: 10px;"></el-input>
                <el-button plain size="mini" type="success">克隆目标</el-button>
                <el-input v-model="topName" placeholder="请输入内容" size="mini" style="margin-right: 10px;"></el-input>
                <el-button plain size="mini" type="success" @click="nameSearchHandler">查询</el-button>
              </span>
            </div>
          </template>
          <template slot="menu" slot-scope="scope">
            <el-button icon="el-icon-edit" size="small" type="text" @click="editBtnClick(scope.row)">编辑
            <el-button v-if="permissionList.editBtn" size="small" type="text" @click="editBtnClick(scope.row)">
              <icon-show :name="permissionList.editBtn.source"></icon-show>
              编辑
            </el-button>
            <el-button icon="el-icon-delete" size="small" type="text" @click="rowDeleteHandler(scope.row)">删除
            <el-button v-if="permissionList.delBtn" size="small" type="text" @click="rowDeleteHandler(scope.row)">
              <icon-show :name="permissionList.delBtn.source"></icon-show>
              删除
            </el-button>
          </template>
        </avue-crud>
        <div style="display: flex;justify-content: center;margin-top: 15px">
          <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">增加</el-button>
          <el-button icon="el-icon-delete" plain size="small" type="danger">删除</el-button>
          <el-button icon="el-icon-document-add" plain size="small" type="primary">克隆</el-button>
          <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="upLoadHandler">导入</el-button>
          <el-button icon="el-icon-download" plain size="small" type="primary" @click="downLoadHandler">导出</el-button>
        </div>
      </basic-container>
    </el-main>
    <form-dialog ref="formDialog"></form-dialog>
    <table-dialog ref="tableDialog"></table-dialog>
    <form-dialog ref="formDialog" :TreeNodeRow="this.nodeRow" :editRow="editRow" :treeRadio="treeRadio"
                 @updataTable="getRightPortalVIDatas"></form-dialog>
    <table-dialog ref="tableDialog" :TreeNodeRow="this.nodeRow" :treeRadio="treeRadio"
                  @updataTable="getRightPortalVIDatas"></table-dialog>
    <!-- 导入 -->
    <upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="导入"
                 @updata="getRightPortalVIDatas"></upload-file>
    <el-dialog
      v-dialogDrag
      :visible.sync="cloneVisible"
      append-to-body="true"
      class="avue-dialog"
      title="克隆"
      width="50%">
      <basic-container>
        <div ref="TreeBox" style="height: calc(100vh - 294px);!important;">
          <!-- 左侧树 -->
          <div style="height:  calc(100vh - 370px);">
            <div style="margin-bottom: 10px;display: flex;justify-content: center">
              <el-radio v-model="cloneTreeRadio" label="0" @input="cloneTreeRadioChange">业务类型树</el-radio>
              <el-radio v-model="cloneTreeRadio" label="1" @input="cloneTreeRadioChange">链接类型树</el-radio>
            </div>
            <avue-tree ref="cloneTree" v-loading="cloneTreeLoading" :data="cloneTreeData" :option="treeOption"
                       @node-click="cloneTreeNodeClick">
              <span slot-scope="{ node, data }" class="el-tree-node__label">
               <span>
                 <icon-show :name="data.icon"></icon-show>
                    {{ (node || {}).label }}
                </span>
              </span>
            </avue-tree>
          </div>
        </div>
      </basic-container>
      <span slot="footer" class="dialog-footer">
         <el-button @click="cloneVisible = false">取 消</el-button>
         <el-button type="primary" @click="cloneSaveHandler">确 定</el-button>
        </span>
    </el-dialog>
  </el-container>
</template>
<script>
import basicOption from "@/util/basic-option";
import FormDialog from "@/views/modelingMenu/ui/formDefine/components/formDialog";
import TableDialog from "@/views/modelingMenu/ui/formDefine/components/tableDialog"
import TableDialog from "@/views/modelingMenu/ui/formDefine/components/tableDialog";
import {gridPortalVIDatas, getPortalVIById, deleteByIds, exportExcel, clone} from "@/api/UI/formDefine/api";
import {getBizTypes} from "@/api/modeling/businessType/api";
import {gridLink} from "@/api/modeling/linkType/api";
import func from "@/util/func";
import {mapGetters} from "vuex";
export default {
  name: "index",
  components: {FormDialog, TableDialog},
  data() {
    return {
      cloneTreeNode: {},
      cloneTreeRadio: '0',
      cloneTreeData: [],
      cloneTreeLoading: false,
      cloneVisible: false,
      tipList: [
        "导入业务类型名称不可为空",
        "导入名称不可为空且名称只能为英文字母",
        "上传的文件为压缩文件,且压缩格式仅能为zip格式"
      ],
      upFileType: ['zip'],
      fileUrl: 'api/portalVIController/importData',
      lastIndex: null,
      selectList: [],
      topName: '',
      page: {
        currentPage: 1,
        pageSize: 10,
        total: 0,
        pageSizes: [10, 30, 50, 100],
      },
      nodeRow: {},
      treeLoading: false,
      option: {
        ...basicOption,
        addBtn: false,
        editBtn: false,
        delBtn: false
        delBtn: false,
        calcHeight: -60,
        column: [
          {
            label: '业务名称',
            prop: 'typeName',
          },
          {
            label: '名称',
            prop: 'viName',
            sortable: true,
          },
          {
            label: '类型',
            prop: 'viTypeText',
          },
        ]
      },
      data: [],
      tableRadio: "",
      treeRadio: "0",
      treeData: [],
      treeOption: {
        addBtn: false
      }
        addBtn: false,
        props: {
          label: 'id',
          value: 'id',
          children: 'children'
        }
      },
      dbClickList: [],
      defaultData: [], // 用于查询恢复原始值,
      editRow: {},
    }
  },
  created() {
    this.getTreeList();
  },
  computed: {
    ...mapGetters(["permission"]),
    permissionList() {
      return {
        addBtn: this.vaildData(this.permission[this.$route.query.id].ADD, false),
        delBtn: this.vaildData(this.permission[this.$route.query.id].DELETE, false),
        editBtn: this.vaildData(this.permission[this.$route.query.id].EDIT, false),
        exportBtn: this.vaildData(this.permission[this.$route.query.id].EXPORT, false),
        importBtn: this.vaildData(this.permission[this.$route.query.id].IMPORT, false),
        cloneBtn: this.vaildData(this.permission[this.$route.query.id].CLONE, false),
      };
    },
    tableStatus() {
      return func.isEmptyObject(this.nodeRow);
    }
  },
  methods: {
    // 右侧新增
    addClickHandler() {
      if (!this.tableRadio) {
        this.$message.error('请在表格上方选择新增类型');
        return;
      }
      if (this.tableRadio === "0") {
        this.editRow.id = "";
        this.$refs.formDialog.visible = true;
        this.$refs.formDialog.getTreeList();
      } else {
        this.$refs.tableDialog.visible = true;
        this.$refs.tableDialog.getDbList(); // 双击操作下拉接口
        this.$refs.tableDialog.getSearchSelectList(); // 选择表单下拉接口
        this.$refs.tableDialog.getFormSelect(); // 查询模板下拉接口
      }
    },
      this.tableRadio === "0" ? this.$refs.formDialog.visible = true : this.$refs.tableDialog.visible = true;
    // 初始化树请求
    getTreeList() {
      this.treeLoading = true;
      getBizTypes().then(res => {
        const data = res.data.data.map(item => {
          this.processChildren(item); // 处理每个节点
          item.attributes.id = item.attributes.id;
          item.attributes.icon = item.attributes.imageName;
          return item.attributes; // 返回处理后的 attributes
        });
        this.treeData = data;
        this.treeLoading = false;
      }).catch(error => {
        this.treeLoading = false;
      });
    },
    // 左侧业务类型切换
    TreeRadioChange(val) {
      this.treeLoading = true;
      this.resetTable();
      if (val === "0") {
        getBizTypes().then(res => {
          const data = res.data.data.map(item => {
            this.processChildren(item); // 处理每个节点
            item.attributes.id = item.attributes.id;
            item.attributes.icon = item.attributes.imageName;
            return item.attributes; // 返回处理后的 attributes
          });
          this.treeData = data;
          this.treeLoading = false;
        });
      } else {
        gridLink().then(res => {
          const data = res.data.data.map(item => {
            item.id = item.name;
            return item;
          });
          this.treeData = data;
          this.treeLoading = false;
        })
      }
    },
    // 处理树形结构
    processChildren(item) {
      if (item.children && item.children.length > 0) {
        item.attributes.children = item.children.map(child => {
          child.attributes.id = child.attributes.id;
          child.attributes.icon = child.attributes.imageName;
          this.processChildren(child); // 递归处理每个子节点
          return child.attributes; // 只返回子节点的 attributes
        });
      }
    },
    // 左侧树点击
    nodeClick(row) {
      this.tableRadio = null;
      this.nodeRow = row;
      this.getRightPortalVIDatas(row);
    },
    // 重置表格展示信息 和 表格表单选项
    resetTable() {
      this.data = [];
      this.tableRadio = null;
    },
    // 右侧 表格 表单 信息查询
    getRightPortalVIDatas() {
      const params = {
        'conditionMap[typeName]': this.treeRadio === '0' ? this.nodeRow.id : this.nodeRow.name,
        'conditionMap[viType]': this.tableRadio === '0' ? 'Form' : this.tableRadio === '1' ? 'Table' : '',
        'conditionMap[viTypeFlag]': this.treeRadio === '0' ? 'BtmType' : this.treeRadio === '1' ? 'LinkType' : '',
      }
      gridPortalVIDatas(this.page.currentPage, this.page.pageSize, params).then(res => {
        if (res.data.code === 200) {
          const data = res.data.data;
          this.data = data;
          this.defaultData = data;
          this.page.total = res.data.total;
        }
      })
    },
    sizeChange(val) {
      this.page.pageSize = val;
      this.getRightPortalVIDatas();
    },
    // 页码
    currentChange(val) {
      this.page.currentPage = val;
      this.getRightPortalVIDatas();
    },
    // 表格 表单切换
    tableRadioChange() {
      this.getRightPortalVIDatas();
    },
    // 编辑按钮
    editBtnClick(row) {
      // 表格
      if (row.viType === 0) {
        const params = {
          id: row.id,
          viType: row.viType
        };
        getPortalVIById(params).then(res => {
          if (res.data.code === 200) {
            const data = res.data.obj.prm;
            const prmItem = data.prmItemList[0] || {}; // 取出第一个元素并提供默认值
            // 获取初始化表格里需要的默认数据
            this.$refs.tableDialog.getFormSelectList();
            // 更新表单
            this.$refs.tableDialog.form = {
              ...prmItem,
              itemFieldWidthList: prmItem.itemFieldWidthList.map(item => {
                return {
                  ...item,
                  $cellEdit: true,
                }
              }),
              viName: res.data.obj.viName,
              itemQtName: res.data.obj.prm.formQtName,
              editNodeId: row.id,
              itemOutFieldList: (prmItem.itemOutFieldList || []),
              itemSearchFieldList: (prmItem.itemSearchFieldList || []).map(item => ({id: item})),
              itemKeyFieldList: (prmItem.itemKeyFieldList || []),
              searchNumber: '1',
              itemFileWidthSelect: (prmItem.itemFieldWidthList && prmItem.itemFieldWidthList.length > 0) ? prmItem.itemFieldWidthList[0].key : '',
              itemWidth: (prmItem.itemFieldWidthList && prmItem.itemFieldWidthList.length > 0) ? prmItem.itemFieldWidthList[0].value : '250'
            };
            // 处理图片宽高
            const [width = '0', height = '0'] = (prmItem.itemImgWH || '0,0').split(',');
            this.$refs.tableDialog.itemImgWidth = width;
            this.$refs.tableDialog.itemImgHeight = height;
            // 显示对话框
            this.$refs.tableDialog.visible = true;
          }
        });
      } else {
        const params = {
          id: row.id,
          viType: row.viType
        };
        this.editRow = row;
        getPortalVIById(params).then(res => {
          if (res.data.code === 200) {
            const data = res.data.obj.prm.prmItemList;
            const updatedData = data.map(item => {
              const {itemField, ...rest} = item;
              return {
                text: itemField,
                ...rest
              };
            });
            this.$refs.formDialog.formList = updatedData;
            this.$refs.formDialog.getTreeList();
            this.$refs.formDialog.topForm.viName = res.data.obj.viName;
            this.$refs.formDialog.topForm.itemQtName = res.data.obj.prm.formQtName;
            this.$refs.formDialog.topForm.columnNumber = this.getValueBasedOnInput(res.data.obj.prm.showCols);
            this.$refs.formDialog.topForm.showColumn = res.data.obj.prm.showCols;
            this.$refs.formDialog.visible = true;
          }
        })
      }
    },
    // 根据传入每行列数 来判断el-col :span是多少
    getValueBasedOnInput(val) {
      const n = JSON.parse(val ? val : '3');
      switch (n) {
        case 1:
          return 24;
        case 2:
          return 12;
        case 3:
          return 8;
        case 4:
          return 6;
        case 5:
          return 4;
        case 6:
          return 4;
        case 7:
        case 8:
          return 3;
        case 9:
          return 2;
        default:
          return n > 10 ? 1 : 8; // 默认给8
      }
    },
    // 名称查询
    nameSearchHandler() {
      if (!this.topName) {
        this.getRightPortalVIDatas();
        return;
      }
      const list = this.defaultData.filter(item => item.viName.includes(this.topName.trim()));
      this.data = list;
      this.page.total = this.data.length;
    },
    // 删除按钮
    deleteClickHandler() {
      if (this.selectList.length <= 0) {
        this.$message.error('请至少选择一条数据');
        return;
      }
      const params = {
        ids: this.selectList.map(item => item.id).join(',')
      }
      deleteByIds(params).then(res => {
        if (res.data.code === 200) {
          this.$message.success('删除成功');
          this.getRightPortalVIDatas();
        }
      })
    },
    rowDeleteHandler(row) {
      deleteByIds({ids: row.id}).then(res => {
        if (res.data.code === 200) {
          this.$message.success('删除成功');
          this.getRightPortalVIDatas();
        }
      })
    },
    // 多选
    selectChangeHandler(row) {
      this.selectList = row;
    },
    // 行点击
    rowClickHandler(row) {
      func.rowClickHandler(
        row,
        this.$refs.crud,
        this.lastIndex,
        (newIndex) => {
          this.lastIndex = newIndex;
        },
        () => {
          this.selectList = [row];
        }
      );
    },
    // 导出
    exportClickHandler() {
      if (this.selectList.length <= 0) {
        this.$message.error('请至少选择一条数据');
        return;
      }
      const params = {
        ids: this.selectList.map(item => item.id).join(',')
      }
      exportExcel(params).then(res => {
        func.downloadFileByBlobHandler(res);
        this.$message.success('导出成功');
      });
    },
    // 导入
    upLoadClickHandler() {
      this.$refs.upload.visible = true;
    },
    // 克隆
    copyClickHandler() {
      if (this.selectList.length <= 0) {
        this.$message.error('请至少选择一条数据');
        return;
      }
      if (this.selectList.length > 1) {
        this.$message.error('只能选择一条数据');
        return;
      }
      this.cloneVisible = true;
      this.cloneTreeLoading = true;
      getBizTypes().then(res => {
        const data = res.data.data.map(item => {
          this.processChildren(item); // 处理每个节点
          item.attributes.id = item.attributes.id;
          return item.attributes; // 返回处理后的 attributes
        });
        this.cloneTreeData = data;
        this.cloneTreeLoading = false;
      }).catch(error => {
        this.cloneTreeLoading = false;
      });
    },
    // 克隆树点击
    cloneTreeNodeClick(row) {
      this.cloneTreeNode = row;
    },
    // 克隆树类型切换
    cloneTreeRadioChange(val) {
      this.cloneTreeLoading = true;
      if (val === "0") {
        getBizTypes().then(res => {
          const data = res.data.data.map(item => {
            this.processChildren(item); // 处理每个节点
            item.attributes.id = item.attributes.id;
            return item.attributes; // 返回处理后的 attributes
          });
          this.cloneTreeData = data;
          this.cloneTreeLoading = false;
        });
      } else {
        gridLink().then(res => {
          const data = res.data.data.map(item => {
            item.id = item.name;
            return item;
          });
          this.cloneTreeData = data;
          this.cloneTreeLoading = false;
        })
      }
    },
    // 查询表格数据详情
    searchDetail() {
      return new Promise((resolve, reject) => {
        const params = {
          id: this.selectList[0].id,
          viType: this.selectList[0].viType
        };
        getPortalVIById(params).then(res => {
          const obj = res.data.obj;
          resolve(obj);
        }).catch(error => {
          reject(error);
        });
      });
    },
    // 克隆保存
    async cloneSaveHandler() {
      if (func.isEmptyObject(this.cloneTreeNode)) {
        this.$message.error('请选择一条数据进行克隆');
        return;
      }
      const obj = await this.searchDetail();
      this.$prompt('请输入克隆文件名称', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      }).then(({value}) => {
        const params = {
          clonePortalVIDTOList: [
            {
              viName: value,
              typeName: this.cloneTreeRadio === '0' ? this.cloneTreeNode.id : this.cloneTreeNode.name,
              typeFlag: this.cloneTreeRadio,
              oldPortalVIDTO: {...obj}
            }
          ],
        }
        clone(params).then(res => {
          if (res.data.code === 200) {
            this.$message.success('克隆成功');
            this.cloneVisible = false;
          }
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '取消输入'
        });
      });
    }
  }
}
@@ -139,7 +671,6 @@
.headerCon > .el-button:nth-child(7) {
  margin-left: 0;
}
.smallBtn {
  width: 82px;