gaoshp
2024-06-13 fd7586c8d91473d2850af1e48b12f1a289e6b8d1
src/views/console/system/meta-object-type/index.vue
@@ -2,7 +2,7 @@
 * @Author: lzhe lzhe@example.com
 * @Date: 2024-03-26 10:28:33
 * @LastEditors: lzhe lzhe@example.com
 * @LastEditTime: 2024-05-13 12:15:04
 * @LastEditTime: 2024-05-14 16:22:28
 * @FilePath: /smart-web/src/views/master/person/main/index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@@ -10,96 +10,151 @@
   <div class="aposcope-main">
      <div class="aposcope-left">
         <div class="left-title">业务列表</div>
         <el-tree :data="tableData" row-key="id" :props="defalutProps" @node-click="handleNodeClick" ref="treeRef" default-expand-all :highlight-current="true" :expand-on-click-node="false" :default-checked-keys="treeCheck"/>
         <el-tree :data="tableData" node-key="id" :props="defalutProps" @node-click="handleNodeClick" ref="treeRef" default-expand-all :highlight-current="true" :expand-on-click-node="false"/>
      </div>
      <div class="aposcope-right">
         <div class="right-top">
            <div>
               <el-button type="primary" @click="addData">+ 添加规则</el-button>
               <el-button type="danger" plain @click="delData" disabled>删除</el-button>
            </div>
            <el-button @click="openVisible">开启规则分类</el-button>
         <div class="right-content">
            <div class="content-title"><span>*</span>所在物理表</div>
            <el-select v-model="metaForm.tableName" :disabled="isDis">
               <el-option v-for="item in tableNameList" :key="item.tableName" :label="item.tableName" :value="item.tableName"/>
            </el-select>
         </div>
         <div class="right-content" v-if="searchDataList.length == 0">
            <!-- <img src="./quesheng.bd026700.png" /> -->
            <div>
               <span>暂无数据</span>
               <!-- <span @click="addData">添加规则</span> -->
            </div>
         <div class="right-content">
            <div class="content-title"><span>*</span>字段1</div>
            <el-select v-model="metaForm.refCode" :disabled="isDis">
               <el-option v-for="item in refCodeList" :key="item.columnName" :label="item.columnName" :value="item.columnName"/>
            </el-select>
         </div>
         <el-table v-if="searchDataList.length != 0" ref="searchDataListRef" :data="searchDataList" border style="width: 100%;margin-top: 20px;" class="multipleTableRef" @selection-change="searchHandleSelectionChange">
            <el-table-column type="selection" width="55" />
            <el-table-column prop="moduleCode" label="接口模块"></el-table-column>
            <el-table-column prop="controllerCode" label="Controller"></el-table-column>
            <el-table-column prop="scopeName" label="action"></el-table-column>
            <el-table-column prop="httpMethod" label="Http方法"></el-table-column>
            <el-table-column prop="scopePath" label="api地址"></el-table-column>
         </el-table>
      </div>
      <el-drawer :title="'当前选中菜单路径'+drawerPath" v-model="drawer" :direction="direction" :before-close="handleClose" size="780" class="drawerClass">
         <el-form :inline="true" :model="drawerSearchData" abel-width="120px">
            <el-form-item label="接口模块">
               <el-select v-model="drawerSearchData.moduleCode" style="width: 100%">
                  <el-option v-for="item in aList" :key="item.id" :label="item.title" :value="item.id"/>
               </el-select>
            </el-form-item>
            <el-form-item label="接口Controller">
               <el-select v-model="drawerSearchData.controllerCode" style="width: 100%">
                  <el-option v-for="item in aList" :key="item.id" :label="item.title" :value="item.id"/>
               </el-select>
            </el-form-item>
            <el-form-item>
               <el-button type="primary" @click="drawerSearchclick">搜索</el-button>
            </el-form-item>
         </el-form>
         <div>
            <div class="dict-table">
               <el-table ref="multipleTableRef" :data="drawerTableData" border style="width: 100%" class="multipleTableRef" @selection-change="drawerHandleSelectionChange">
                  <el-table-column type="selection" width="55" />
                  <el-table-column prop="className" label="接口模块"></el-table-column>
                  <el-table-column prop="controllerCode" label="Controller"></el-table-column>
                  <el-table-column prop="name" label="action"></el-table-column>
                  <el-table-column prop="httpMethod" label="Http方法"></el-table-column>
                  <el-table-column prop="url" label="api地址"></el-table-column>
               </el-table>
            </div>
         <div class="right-content">
            <div class="content-title"><span>*</span>字段2</div>
            <el-select v-model="metaForm.refName" :disabled="isDis">
               <el-option v-for="item in refCodeList" :key="item.columnName" :label="item.columnName" :value="item.columnName"/>
            </el-select>
         </div>
         <div class="drawer-foot">
            <el-button type="primary" @click="drawerConfirm" disabled>添加</el-button>
            <el-button @click="closeDrawer">取消</el-button>
         <div class="right-content">
            <div class="content-title">编码字段</div>
            <el-select v-model="metaForm.code">
               <el-option v-for="item in refCodeList" :key="item.columnName" :label="item.columnName" :value="item.columnName"/>
            </el-select>
         </div>
      </el-drawer>
       <el-dialog title="规则分类" v-model="visible" :width="600" @closed="closeVisible('closed')">
           <el-form :model="classificationForm" :rules="classificationRules" ref="dialogForm" label-width="120px"
               label-position="center">
               <el-row>
                   <el-col :span="12">
                       <el-form-item label="分类字段" prop="classify">
                           <el-select v-model="classificationForm.classify" style="width: 100%" placeholder="请选择">
                        <el-option v-for="item in aList" :key="item.id" :label="item.title" :value="item.id"/>
         <div class="right-content">
            <div class="content-title">参数设置</div>
            <el-button type="primary" @click="addParameter" :disabled="isAdd">添加参数</el-button>
         </div>
         <el-table ref="searchDataListRef" :data="searchDataList" border style="width: 100%;margin-top: 20px;" class="multipleTableRef">
            <el-table-column prop="fcode" label="字段编码">
               <template #default="scope">
                  <div v-if="scope.row.isEdit">
                     <span class="important-star">*</span>
                     <el-select v-model="tableForm.fcode" style="width: 90%;">
                        <el-option v-for="item in refCodeList" :key="item.columnName" :label="item.columnName" :value="item.columnName"/>
                     </el-select>
                       </el-form-item>
                   </el-col>
                   <el-col :span="12">
                       <el-form-item label="分类字典">
                           <el-input v-model="classificationForm.dictionary" placeholder="分类字典" clearable></el-input>
                       </el-form-item>
                   </el-col>
               </el-row>
           </el-form>
           <template #footer>
               <el-button @click="visible = false">取消</el-button>
               <el-button type="primary" :loading="isSaveing" @click="classificationSubmit">确定</el-button>
           </template>
       </el-dialog>
                  </div>
                  <div v-else>{{scope.row.fcode}}</div>
               </template>
            </el-table-column>
            <el-table-column prop="fname" label="字段标题">
               <template #default="scope">
                  <div v-if="scope.row.isEdit">
                     <span class="important-star">*</span>
                     <el-input v-model="tableForm.fname" style="width: 90%;"></el-input>
                  </div>
                  <div v-else>{{scope.row.fname}}</div>
               </template>
            </el-table-column>
            <el-table-column prop="field" label="实体属性">
               <template #default="scope">
                  <div v-if="scope.row.isEdit">
                     <span class="important-star">*</span>
                     <el-input v-model="tableForm.field" style="width: 90%;"></el-input>
                  </div>
                  <div v-else>{{scope.row.field}}</div>
               </template>
            </el-table-column>
            <el-table-column prop="elementType" label="元素类型">
               <template #default="scope">
                  <div v-if="scope.row.isEdit">
                     <span class="important-star">*</span>
                     <el-select v-model="tableForm.elementType" @change="elementTypeNameChange" style="width: 90%;">
                        <el-option v-for="item in dictionaryType" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey"/>
                     </el-select>
                  </div>
                  <div v-else>{{scope.row.elementTypeName}}</div>
               </template>
            </el-table-column>
            <el-table-column prop="enumType" label="枚举类型">
               <template #default="scope">
                  <el-select v-if="scope.row.isEdit" v-model="tableForm.enumType" :disabled="tableForm.elementType!='4'" @change = enumTypeChange>
                     <el-option v-for="item in dictList" :key="item.id" :label="item.code" :value="item.id"/>
                  </el-select>
                  <div v-else>{{scope.row.enumTypeZn}}</div>
               </template>
            </el-table-column>
            <el-table-column prop="seq" label="字段顺序">
               <template #default="scope">
                  <el-input-number v-if="scope.row.isEdit" scope.row.isEdit v-model="tableForm.seq" :min="0" :max="99" style="width:100%;"/>
                  <div v-else>{{scope.row.seq}}</div>
               </template>
            </el-table-column>
            <el-table-column prop="refObjectTypeId" label="引用关系">
               <template #default="scope">
                  <el-tree-select v-if="scope.row.isEdit" node-key="id" :props="defalutProps" v-model="tableForm.refObjectTypeId" :data="tableData" :render-after-expand="false" :disabled="tableForm.elementType!='5'" @node-click="handleNodeClick1"/>
                  <div v-else>{{scope.row.refObjectTypeIdZn}}</div>
               </template>
            </el-table-column>
            <el-table-column label="操作">
               <template #default="scope">
                  <div v-if="scope.row.isEdit">
                     <el-button size="small" type="primary" @click="comfirmTable">确定</el-button>
                     <el-button size="small" @click="cancelTable">取消</el-button>
                  </div>
                  <div v-else>
                     <!-- <el-icon class="operationIcon" @click="editTable(scope.$index)"><Edit /></el-icon> -->
                     <el-icon class="operationIcon" @click="deleteTable(scope.$index)"><Delete /></el-icon>
                  </div>
               </template>
            </el-table-column>
         </el-table>
         <div class="saveBtn">
            <el-button type="primary" @click="saveBtn" :disabled="isAdd">保存</el-button>
         </div>
      </div>
   </div>
</template>
<script>
   import * as ElementPlusIconsVue from '@element-plus/icons-vue'
   let icons = []
   for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
      icons.push(key)
   }
   export default {
      name: "apiscope",
      name: "metaObject",
      data(){
         return {
            treeCheck: [],
            dictList: [],  //枚举类型
            elementTypeValue: "",
            detailobj: {},
            testList: [],
            tableForm: {
               fcode: "",
               fname: "",
               field: "",
               elementType: "",
               enumType: "",
               seq: 0,
               refObjectTypeId: ""
            },
            inputValue: "",
            isAdd: false,
            isDis: true,
            tableNameList: [],
            refCodeList: [],
            metaForm: {
               tableName: "",
               refCode: "",
               refName: "",
               code: ""
            },
            classificationRules: {
               classify: [
                  { required: true, message: "请选择分类字段" }
@@ -110,42 +165,158 @@
               dictionary: ""
            },
            isSaveing: false,
            visible: false,
            drawerPath: "",
            searchData: {
               size: "15",
               current: "1"
            },
            searchDataList: [],  //右侧数据list
            aList: [],
            drawerSearchData: {
               moduleCode: "",
               controllerCode: "",
               menuId: "",
               size: "-1"
            },
            direction: "rtl",
            drawer: false,
            defalutProps: {
               label: 'dictValue',
                 children: 'children',
               isLeaf: 'hasChildren'
            },
            parentId: "0",
            tableData: [],
            searchSelection: []
            firstChild: [],   //一级菜单
            dictKey: "",
            dictionaryType: []  //字典类型
         }
      },
      created(){
         
      },
      mounted(){
         this.getMenuList();
         this.getDictionary();  //字典类型
         this.getDict(); //枚举类型
      },
      components: {
       },
         ...ElementPlusIconsVue
      },
      methods: {
         getDict() {  //枚举类型
            this.$HTTP.get("/api/blade-system/dict/list").then(res=> {  //物理表
               if(res.code == 200) {
                  this.dictList = res.data;
               }
            })
         },
         editTable(index) {
            this.isAdd = true;
            var obj = Object.assign({},this.searchDataList[index],{isEdit: true});
            this.searchDataList.splice(index,1,obj);
         },
         deleteTable(index) {
            this.searchDataList.splice(index,1);
         },
         enumTypeChange(val) {  //枚举类型
            this.dictList.forEach(item=> {
               if(item.id == val) {
                  this.tableForm.enumTypeZn = item.code;
               }
            })
         },
         elementTypeNameChange(val) {  //元素类型
            this.dictionaryType.forEach(item=> {
               if(item.dictKey == val) {
                  this.elementTypeValue = item.dictValue;
               }
            })
            this.tableForm.enumType = "";
            this.tableForm.refObjectTypeId = "";
         },
         saveBtn() {
            var obj = Object.assign(this.detailobj,this.metaForm);  //detailobj物理数据,metaForm基础数据
            obj.fields = this.searchDataList;
            this.$HTTP.post("/api/blade-system/meta-object-type/submit",obj).then(res=> {
               if(res.code == 200) {
                  this.$message.success("保存成功");
               }
            })
         },
         comfirmTable() {
            this.cancelTable();
            this.tableForm.refObjectTypeIdZn = this.tableForm.dictKey;
            this.tableForm.elementTypeName = this.elementTypeValue;
            this.tableForm.enumType = this.tableForm.enumTypeZn;
            this.tableForm.id = null;
            this.tableForm.objectId = this.detailobj.objectId;
            this.searchDataList.unshift(this.tableForm);
         },
         cancelTable() {
            this.searchDataList.splice(0,1);
            this.isAdd = false;
         },
         addParameter() {
            this.tableForm = {
               fcode: "",
               fname: "",
               field: "",
               elementType: "",
               enumType: "",
               seq: 0,
               refObjectTypeId: ""
            }
            this.isAdd = true;
            var obj = Object.assign({},this.tableForm,{isEdit: true})
            obj.id = null;
            this.searchDataList.unshift(obj);
         },
         getDictionary() {  //字典类型
            this.$HTTP.get("/api/blade-system/dict/dictionary?code=element_type").then(res=> {  //物理表
               if(res.code == 200) {
                  this.dictionaryType = res.data;
                  this.getMenuList();
               }
            })
         },
         getList() {
            this.$HTTP.get(`/api/blade-system/bascoderule/count?type=${this.dictKey}`).then(res=> {  //是否可选
               if(res.code == 200) {
                  if(res.data == 1) {
                     this.isDis = true;
                  }else {
                     this.isDis = false;
                  }
               }
            })
            this.$HTTP.get("/api/blade-system/meta-object-type/tableDetail").then(res=> {  //物理表
               if(res.code == 200) {
                  this.tableNameList = res.data;
                  this.gettableName();  //获取字段
               }
            })
            this.getSearchDataList(); //表格数据
         },
         gettableName() {
            this.$HTTP.get(`/api/blade-system/meta-object-type/detail?fId=${this.dictKey}`).then(res=> {  //物理表数据
               if(res.code == 200) {
                  this.tableNameList.forEach(item=> {
                     if(res.data.tableName == item.tableName) {
                        this.refCodeList = item.tableColumns;
                     }
                  })
                  this.metaForm.tableName = res.data.tableName;
                  this.metaForm.refCode = res.data.refCode;
                  this.metaForm.refName = res.data.refName;
                  this.metaForm.code = res.data.code;
                  this.detailobj = res.data;
                  this.detailobj.objectId = res.data.fid;
               }
            })
         },
         getSearchDataList() {
            this.$HTTP.get(`/api/blade-system/meta-object-type-field/list?objectId=${this.dictKey}`).then(res=> {  //表格数据
               if(res.code == 200) {
                  this.searchDataList = res.data;
                  res.data.forEach(item=> {
                     item.enumTypeZn = item.enumType;  //枚举类型
                     item.refObjectTypeIdZn = item.refObjectTypeId;  //引用关系
                  })
                  this.dictionaryType.forEach(item=> {  //元素类型
                     this.searchDataList.forEach(item1=> {
                        if(item1.elementType == item.dictKey) {
                           item1.elementTypeName = item.dictValue;
                        }
                     })
                  })
               }
            })
         },
         closeVisible(flag) {
            if(flag == "closed") {
               this.classificationForm = {
@@ -155,104 +326,67 @@
               this.$refs.dialogForm.resetFields();
            };
         },
         classificationSubmit() {
            this.$refs.dialogForm.validate(async (valid) => {
               if (valid) {
                  this.isSaveing = false;
                  // this.$HTTP.post("/api/blade-system/data-scope/submit",obj).then(res=> {
                  //    this.isSaveing = false;
                  //    if(res.code == 200) {
                  //       this.$emit('success', this.addDictForm, this.mode);
                  //       this.visible = false;
                  //       this.$message.success("操作成功");
                  //    }else {
                  //       this.$alert(res.message, "提示", {type: 'error'});
                  //    }
                  // })
               }else{
                  return false;
               }
            })
         handleNodeClick1(data) {
            if(this.firstChild.includes(data.id)) {  //一级菜单返回
               this.$nextTick(()=> {
                  this.tableForm.refObjectTypeId = "";
               })
               return;
            };
            this.tableForm.refObjectTypeIdZn = data.dictValue;
            this.tableForm.dictKey = data.dictKey;
         },
         openVisible() {
            this.visible = true;
         },
         closeDrawer() {
            this.drawer = false;
         },
         drawerConfirm() {
            this.drawer = false;
         },
         searchHandleSelectionChange(selection) {
            this.searchSelection = selection;
         },
         drawerHandleSelectionChange() {
         },
         drawerSearchclick() {
            this.drawerSearchData.menuId = this.searchData.menuId;
            var obj = {};
            for(var key in this.drawerSearchData) {
               if(this.drawerSearchData[key]) {
                  obj[key] = this.drawerSearchData[key];
               }
            }
            this.$HTTP.get("/api/blade-system/resource-definition/page",obj).then(res=> {
               if(res.code == 200) {
                  this.drawerTableData = res.data.records;
               }
            })
         },
         handleClose(done) {
              done();
          },
         handleNodeClick(data) {
            if(!this.firstChild.includes(data.id)) {
               this.dictKey = data.dictKey;
               this.getList();  //所在物理表、是否可选
               this.isAdd = false;
            }
            // this.drawerPath = data.name;
            // console.log(data,data.name,222)
            // this.searchData.menuId = data.id;
            // this.$HTTP.get("/api/blade-system/api-scope/list",this.searchData).then(res=> {
            //    if(res.code == 200) {
            //       this.searchDataList = res.data.records;
            //    }
            // })
         },
         extractLastLevelIds(array) {  //递归获取children最后一级的id的数组
            let ids = [];
            for (let i = 0; i < array.length; i++) {
               const obj = array[i];
               if (obj.children) {
                  // 递归调用以提取更深层级的children中的id
                  ids = ids.concat(this.extractLastLevelIds(obj.children));
               } else {
                  // 如果没有children属性,则假定当前对象是最后一级
                  if (obj.id) {
                     ids.push(obj);
                  }
               }
            }
            return ids;
         },
         getMenuList() {
            this.$HTTP.get("/api/blade-system/dict/dictionary-tree?code=code_rule_for_biz_objects").then(res=> {
               if(res.code == 200) {
                  this.tableData = res.data;
                  // this.treeCheck = idarr;  //获取选中数据
                  var menuGrantList = res.data.filter(item=> { //过滤掉没有children的
                     return item.children;
                  });
                  var lastId = this.extractLastLevelIds(menuGrantList[0].children);  //获取最后一级id
                  this.firstChild = res.data.map(item=> {
                     return item.id;
                  })
                  this.$nextTick(()=> {
                     this.dictKey = lastId[0].dictKey;
                     this.$refs.treeRef.setCurrentKey(lastId[0].id);  //设置选中数据
                     this.getList();  //所在物理表、是否可选
                  })
               }
            })
         },
         addData() {
            // this.drawerSearchclick();
            // this.drawer = true;
         },
         delData() {
            if(this.searchSelection.length == 0) {
               this.$message({
                   message: '请选择至少一条数据',
                   type: 'warning'
                 });
                 return;
            }
            var selStr = "";
            this.searchSelection.map(item=> {
               selStr += item.id + ","
            })
            selStr = selStr.replace(/,$/, '');
            var that = this;
            // this.$HTTP.post("/api/blade-system/data-scope/remove?ids="+selStr).then(res=> {
            //    if(res.code == 200) {
            //       that.$message.success("操作成功");
            //       that.drawerSearchclick();
            //    }
            // })
         }
      }
   }
</script>
<style scoped>
.aposcope-main {
   display: flex;
@@ -282,31 +416,26 @@
   margin-bottom: 12px;
}
.right-content {
   text-align: center;
   margin-bottom: 12px;
}
.right-content img {
   width: 350px;
   height: 350px;
.content-title {
   margin-bottom: 12px;
}
.right-content > div {
   font-size: 14px;;
.content-title span {
   margin-right: 4px;
   color: red;
}
.right-content > div span:nth-child(2) {
   margin-left: 8px;
   color: #409eff;
.operationIcon {
   font-size: 16px;
   margin-right:4px;
   cursor: pointer;
}
/deep/ .drawerClass {
   padding: 8px;
}
.datascope-drawer-btn {
   margin-bottom: 8px;
}
.drawer-foot {
.saveBtn {
   margin-top: 20px;
   text-align: right;
}
.right-top {
   display: flex;
   justify-content: space-between;
.important-star {
   margin-right: 4px;
   color: red;
}
</style>