Browse Source

架构的复制/报告的分组

zhuhao 1 year ago
parent
commit
ab7ea1cc21

+ 6 - 0
src/api/newApi/framework.js

@@ -37,4 +37,10 @@ export default {
   deleteTreeNode(data) {
     return axios.post('/xiaoshi/treeNode/deleteTreeNode', data)
   },
+  /**
+  * 复制架构节点
+  */
+  copyTreeNode(data) {
+    return axios.post('/xiaoshi/treeNode/copyTreeNode', data)
+  },
 }

+ 3 - 1
src/utils/model/index.js

@@ -16,6 +16,7 @@ import myCard from './card/index'
 import myImageViewer from './imageViewer/index'
 import myUpload from './upload/index'
 import myCascader from './Cascader/index'
+import myNodeCopy from './nodeCopy/index'
 
 var models = {
   myCustomSvg,
@@ -34,7 +35,8 @@ var models = {
   myCard,
   myImageViewer,
   myUpload,
-  myCascader
+  myCascader,
+  myNodeCopy,
 }
 export default {
   install(Vue) {

+ 144 - 0
src/utils/model/nodeCopy/index.vue

@@ -0,0 +1,144 @@
+<template>
+  <!-- 新增/编辑架构分类节点 -->
+  <div class="nodeCopy">
+    <el-dialog :title="title" :visible.sync="dialogVisible" :before-close="handleClose" width="700px"
+      :close-on-click-modal="false">
+      <div class="margin_bottom_10">
+        <span>是否包含子节点:</span>
+        <!-- display:flex;align-items:center; -->
+        <el-radio v-model="check" :label="false">是</el-radio>
+        <el-radio v-model="check" :label="true">否</el-radio>
+      </div>
+      <div class="margin_bottom_10">
+        <span>所属来源:</span>
+        <el-select v-model="fromValue" size="small" disabled placeholder="请选择">
+          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="margin_bottom_10" v-if="false">
+        <span>所属{{ options.filter(item => { return item.value == fromValue })[0].label }}:</span>
+        <span>{{ affiliation }}</span>
+      </div>
+      <div>
+        <span>树:</span>
+        <div v-if="treeData.length > 0" style="min-height:200px;max-height: 600px;overflow: auto;">
+          <el-tree :data="treeData" ref="tree" :props="props" show-checkbox node-key="id" :check-strictly="check" @check="handleCheck">
+          </el-tree>
+        </div>
+        <div v-else>
+          <div style="padding-left: 20px;">暂无数据</div>
+        </div>
+
+      </div>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取消</el-button>
+        <el-button type="primary" @click="submit">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    // 数据源
+    treeData: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    // 勾选父级是否连带勾选子级,true不连带,false连带
+    checkStrictly: {
+      type: Boolean,
+      default: false,
+    },
+    // 来源
+    source: {
+      type: String,
+      default: '1',
+    },
+    // 所属地,属于那个产品类别或产品等
+    affiliation: {
+      type: String,
+      default: '暂无说明'
+    }
+  },
+  data() {
+    return {
+      // 提示
+      title: '复制分类节点',
+      // 控制弹窗显示与隐藏
+      dialogVisible: false,
+      // 配置项,树节点的显示与层级
+      props: {
+        label: 'name',
+        children: 'child'
+      },
+      // 勾选父级是否连带勾选子级,true不连带,false连带
+      check: this.checkStrictly,
+      // 来源选项
+      options: [
+        { label: '产品类别', value: '1' },
+        { label: '产品', value: '2' },
+        { label: '技术分类', value: '3' },
+        { label: '自定义树', value: '4' },
+      ],
+      // 来源
+      fromValue: this.source,
+      // 存储选中的id
+      checkId: [],
+    }
+  },
+  mounted() {
+
+  },
+  methods: {
+    // 树节点的勾选
+    handleCheck(node, data) {
+      if (this.checkId && this.checkId.length > 0) {
+        let index = this.checkId.findIndex(item => {
+          return item == node.id
+        })
+        if (index != -1) {
+          this.checkId.splice(index, 1)
+        } else {
+          this.checkId.push(node.id)
+        }
+      } else {
+        this.checkId.push(node.id)
+      }
+    },
+    // 打开弹窗
+    open() {
+      this.dialogVisible = true
+    },
+    // 弹窗确定提交 
+    submit() {
+      let is = {
+        checked: this.checkId,
+        check:!this.check,
+      }
+      this.$emit('checkId', is)
+      this.handleClose()
+    },
+    // 关闭
+    handleClose() {
+      this.$refs.tree.setCheckedKeys([]);
+      this.checkId = []
+      this.dialogVisible = false
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.nodeCopy {
+  .margin_bottom_10{
+    margin-bottom:10px;
+  }
+  
+}
+</style>

+ 107 - 75
src/views/event/components/dialog/addEvent.vue

@@ -6,32 +6,27 @@
         <el-form :model="formData[0]" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
           <el-form-item label="事件名称" prop="name">
             <el-autocomplete class="inline-input" v-model="formData[0].name" value-key="name" v-SelectLazyLoading="load"
-              :fetch-suggestions="querySearchQuestion"
-              placeholder="请输入或选择事件" :trigger-on-focus="false"
+              :fetch-suggestions="querySearchQuestion" placeholder="请输入或选择事件" :trigger-on-focus="false"
               @select="handleSelectQuestion" @blur="blur($event, { $index: 0 })" style="width: 100%;">
             </el-autocomplete>
           </el-form-item>
-          <el-form-item label="所属客户" prop="clientId" v-if="userinfo.tenantType == 1" >
+          <el-form-item label="所属客户" prop="clientId" v-if="userinfo.tenantType == 1">
             <!-- <el-select v-model="formData[0].clientId" :disabled="(formData[0].id && !this.row) ? true : false" -->
-            <el-select ref="select" v-model="formData[0].clientId" clearable
-              style="width: 100%;" placeholder="请选择客户">
-              <el-option
-                v-for="item in clientList"
-                :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)">
+            <el-select ref="select" v-model="formData[0].clientId" clearable filterable remote style="width: 100%;"
+              placeholder="请选择客户" v-SelectLazyLoading="loadClient" :remote-method="remoteMethod" :loading="client.loading">
+              <el-option v-for="item in clientList" :key="parseInt(item.id)" :label="item.name"
+                :value="parseInt(item.id)">
               </el-option>
             </el-select>
           </el-form-item>
           <el-form-item label="事件日期" prop="eventDate">
-            <el-date-picker
-              style="width: 100%" v-model="formData[0].eventDate"
-              type="date" value-format="yyyy-MM-dd" placeholder="请选择事件日期"
-              >
+            <el-date-picker style="width: 100%" v-model="formData[0].eventDate" type="date" value-format="yyyy-MM-dd"
+              placeholder="请选择事件日期">
             </el-date-picker>
           </el-form-item>
           <el-form-item label="事件场景" prop="scenarioId">
             <!-- <el-select v-model="formData[0].applicationScenarios[0]" :disabled="(formData[0].id && !this.row) ? true : false" -->
-            <el-select ref="select2" v-model="formData[0].scenarioId" 
-              style="width: 100%;" placeholder="请选择事件场景">
+            <el-select ref="select2" v-model="formData[0].scenarioId" style="width: 100%;" placeholder="请选择事件场景">
               <el-option
                 v-for="item in commonData.ENTERPRISE_APPLICATION_SCENARIO ? commonData.ENTERPRISE_APPLICATION_SCENARIO : []"
                 :key="parseInt(item.value)" :label="item.label" :value="parseInt(item.value)">
@@ -39,11 +34,12 @@
             </el-select>
           </el-form-item>
           <el-form-item label="文件上传">
-            <myUpload :file-list="handleConcat(formData[0].systemFileList)" @on-change="onchange" @on-remove="onRemove" style="height: 180px;"></myUpload>
+            <myUpload :file-list="handleConcat(formData[0].systemFileList)" @on-change="onchange" @on-remove="onRemove"
+              style="height: 180px;"></myUpload>
           </el-form-item>
           <el-form-item label="事件描述" prop="description">
-            <el-input type="textarea" :rows="2" v-model="formData[0].description" autocomplete="off" placeholder="请输入事件描述"
-              ></el-input>
+            <el-input type="textarea" :rows="2" v-model="formData[0].description" autocomplete="off"
+              placeholder="请输入事件描述"></el-input>
           </el-form-item>
         </el-form>
       </div>
@@ -60,9 +56,9 @@
             </template>
             <template slot-scope="scope">
               <div>
-                <el-autocomplete class="inline-input" v-model="scope.row.name"
-                  :fetch-suggestions="querySearchQuestion" placeholder="请输入或选择事件" :trigger-on-focus="false"
-                  @select="handleSelectQuestion" @blur="blur($event, scope)" style="width: 100%;">
+                <el-autocomplete class="inline-input" v-model="scope.row.name" :fetch-suggestions="querySearchQuestion"
+                  placeholder="请输入或选择事件" :trigger-on-focus="false" @select="handleSelectQuestion"
+                  @blur="blur($event, scope)" style="width: 100%;">
                 </el-autocomplete>
               </div>
             </template>
@@ -70,19 +66,18 @@
           <el-table-column prop="eventDate" label="事件时间" align="center">
             <template slot-scope="scope">
               <div>
-                <el-date-picker style="width: 100%" v-model="scope.row.eventDate"
-                  type="datetime" value-format="yyyy-MM-dd" placeholder="选择事件日期时间">
+                <el-date-picker style="width: 100%" v-model="scope.row.eventDate" type="datetime"
+                  value-format="yyyy-MM-dd" placeholder="选择事件日期时间">
                 </el-date-picker>
               </div>
             </template>
           </el-table-column>
-          
+
           <el-table-column prop="applicationScenarios" label="事件场景" align="center">
             <template slot-scope="scope">
               <div>
                 <!-- multiple -->
-                <el-select v-model="scope.row.scenarioId"
-                  style="width: 100%;" placeholder="请选择事件场景">
+                <el-select v-model="scope.row.scenarioId" style="width: 100%;" placeholder="请选择事件场景">
                   <el-option
                     v-for="item in commonData.ENTERPRISE_APPLICATION_SCENARIO ? commonData.ENTERPRISE_APPLICATION_SCENARIO : []"
                     :key="parseInt(item.value)" :label="item.label" :value="parseInt(item.value)">
@@ -116,7 +111,8 @@
       <div slot="footer" class="dialog-footer">
         <el-button size="small" @click="handleClose()" style="width:100px">取消</el-button>
         <el-button size="small" @click="resetForm()" style="width:100px">重置</el-button>
-        <el-button type="primary" @click="submitForm1()" size="small" :loading="loading" style="width:100px">确定</el-button>
+        <el-button type="primary" @click="submitForm1()" size="small" :loading="loading"
+          style="width:100px">确定</el-button>
       </div>
     </el-dialog>
 
@@ -129,7 +125,7 @@ export default {
   props: [],
   data() {
     return {
-      loading:false,
+      loading: false,
       //弹窗标题
       title: '',
       //弹窗状态
@@ -147,30 +143,39 @@ export default {
       ],
       //检验规则
       rules: {
-        name: [ { required: true, message: '请输入事件名称', trigger: 'blur' },],
-        scenarioId: [ { required: true, message: '请选择事件场景', trigger: 'change' },],
+        name: [{ required: true, message: '请输入事件名称', trigger: 'blur' },],
+        scenarioId: [{ required: true, message: '请选择事件场景', trigger: 'change' },],
       },
       //应用场景数据
       commonData: {},
       //弹窗类型
       type: 1,
-      questionNameArr:{
+      questionNameArr: {
         queryParams: {
           current: 1,
-          size:10,
+          size: 10,
         },
-        eventInput:'',
-        data:[]
+        eventInput: '',
+        data: []
       },
-      
+
       //客户集合
       clientList: [],
+      // 客户懒加载所需
+      client: {
+        queryParams: {
+          current: 1,
+          size: 10,
+        },
+        isLazy: true,
+        loading:false,
+      },
       // 文件数组
-      files:[],
+      files: [],
     }
   },
   watch: {},
-  computed:{
+  computed: {
     ...mapGetters(["userinfo"]),
   },
   async mounted() {
@@ -186,43 +191,70 @@ export default {
         })
         this.formData[0].systemFileList.splice(a, 1)
       } else {
-        let a=this.files.findIndex(item => {
+        let a = this.files.findIndex(item => {
           return item.size == file.size
         })
         this.files.splice(a, 1)
       }
-      
+
     },
     // 自定义组件文件监听
     onchange(file, fileList) {
-      if (this.files && this.files.length>0) {
-        let a=this.files.findIndex(item => {
+      if (this.files && this.files.length > 0) {
+        let a = this.files.findIndex(item => {
           return item.size == file.size
         })
         if (a != -1) {
           this.$message.error(`${file.raw.name}文件重复`)
-          this.files.splice(a,1,file.raw)
+          this.files.splice(a, 1, file.raw)
         } else {
           this.files.push(file.raw)
         }
       } else {
         this.files.push(file.raw)
       }
-      
+
     },
     // 合并已上传的文件和未上传的文件
     handleConcat(arr) {
       let files = (arr || []).concat(this.files)
       return files
     },
+    loadClient() {
+      if(this.client.queryParams.current * this.client.queryParams.size>=this.client.queryParams.total){
+        return false
+      }
+      this.client.queryParams.current +=1
+      this.getAdminClientList()
+    },
+    remoteMethod(query) {
+      // this.client.isLazy = true
+      // if (query !== '') {
+      //   this.client.loading = true;
+      //   this.client.queryParams = {
+      //     current: 1,
+      //     size: 10,
+      //     searchQuery: `name=${query}`
+      //   }
+      //   this.$api.getAdminClientList(this.client.queryParams).then(response => {
+      //     if (response.code == 200) {
+      //       this.client.loading = false;
+      //       this.clientList = response.data.records
+      //     }
+      //   }).catch(error => {
+      //     this.client.loading = false;
+      //   })
+      // } else {
+      //   this.client.queryParams.name = null
+      //   this.clientList = [];
+      //   this.getAdminClientList()
+      // }
+    },
     //获取客户信息
     getAdminClientList() {
-      let params = {
-        current: 1,
-        size:9999
-      }
-      this.$api.getAdminClientList(params).then(response => {
-        this.clientList = response.data.records
+      this.$api.getAdminClientList(this.client.queryParams).then(response => {
+        this.clientList.push(...response.data.records)
+        this.client.queryParams.total = response.data.total
       }).catch(error => {
 
       })
@@ -236,9 +268,9 @@ export default {
         this.$set(this.formData, 0, data)
       } else {
         if (this.type == 1) {
-          this.title='新增事件'
+          this.title = '新增事件'
         } else {
-          this.title='批量新增事件'
+          this.title = '批量新增事件'
         }
         this.formData = [
           {
@@ -259,7 +291,7 @@ export default {
         this.$refs.ruleForm.resetFields()
       }
       this.files = []
-      this.loading=false
+      this.loading = false
       this.dialogVisible = false
     },
     // 请求应用场景(是通过字典还是接口待定)
@@ -272,16 +304,16 @@ export default {
     submitForm1() {
       var list = []
       try {
-        if (this.type=='1') {//单个新增事件
-          list=this.formData
+        if (this.type == '1') {//单个新增事件
+          list = this.formData
         } else {//多个新增事件
           this.formData.forEach(item => {
             var a = false
             for (let key in item) {
               // if (key != 'scenarioId') {
-                if (item[key] != '' && item[key] != null) {
-                  a = true
-                }
+              if (item[key] != '' && item[key] != null) {
+                a = true
+              }
               // }else {
               //   if (item[key].length > 0) {
               //     a = true
@@ -315,12 +347,12 @@ export default {
     // 提交保存事件
     addFormData(val) {
       let lists = JSON.parse(JSON.stringify(val.list))
-     
-      if (this.type=='1') {//单个事件新增
+
+      if (this.type == '1') {//单个事件新增
         this.$refs.ruleForm.validate(valid => {
           if (valid) {
             this.addInterface(lists)
-          } 
+          }
         })
       } else {//多个事件新增
         this.addInterface(lists)
@@ -328,15 +360,15 @@ export default {
     },
     //提交保存、编辑事件接口
     addInterface(forms) {
-      this.loading=true
+      this.loading = true
       let formData = new FormData()
       if (this.files && this.files.length > 0) {
-        for (var i = 0; i < this.files.length; i++) { 
-          formData.append('files',this.files[i])//文件数据
+        for (var i = 0; i < this.files.length; i++) {
+          formData.append('files', this.files[i])//文件数据
         }
       }
-      if (forms[0].systemFileList && forms[0].systemFileList.length>0) {
-        forms[0].fileGuids=forms[0].systemFileList.map(item => {
+      if (forms[0].systemFileList && forms[0].systemFileList.length > 0) {
+        forms[0].fileGuids = forms[0].systemFileList.map(item => {
           return item.guid
         })
       }
@@ -344,23 +376,23 @@ export default {
       if (forms[0].id) {//编辑
         this.$api.updateEvent(formData).then(res => {
           if (res.code == 200) {
-            this.$emit('isSuccess','编辑成功')
+            this.$emit('isSuccess', '编辑成功')
             this.$message.success('事件编辑成功')
             this.handleClose()
           }
         }).catch(error => {
-          this.loading=false
+          this.loading = false
           this.$message.error(error.message)
         })
       } else {//新增
         this.$api.eventAddEvent(formData).then(res => {
           if (res.code == 200) {
-            this.$emit('isSuccess','新增成功')
+            this.$emit('isSuccess', '新增成功')
             this.$message.success('事件新增成功')
             this.handleClose()
           }
         }).catch(error => {
-          this.loading=false
+          this.loading = false
           this.$message.error(error.message)
         })
       }
@@ -408,22 +440,22 @@ export default {
 
     // 懒加载事件方法
     load() {
-      if(this.questionNameArr.queryParams.current * this.questionNameArr.queryParams.size>=this.questionNameArr.queryParams.total){
+      if (this.questionNameArr.queryParams.current * this.questionNameArr.queryParams.size >= this.questionNameArr.queryParams.total) {
         return false
       }
-      this.questionNameArr.queryParams.current ++
+      this.questionNameArr.queryParams.current++
       this.questionEventList()
     },
     // 查询事件
     async questionEventList() {
-      let searchValue={name:this.questionNameArr.eventInput}
+      let searchValue = { name: this.questionNameArr.eventInput }
       let params = {
         ...this.questionNameArr.queryParams,//分页信息
-        searchQuery:this.$commonJS.objectToString(searchValue)//输入的建议
+        searchQuery: this.$commonJS.objectToString(searchValue)//输入的建议
       }
       await this.$api.queryEvent(params).then(res => {
         if (res.code == 200) {
-          this.questionNameArr.data.push(...res.data.data) 
+          this.questionNameArr.data.push(...res.data.data)
           this.questionNameArr.queryParams.total = res.data.total
           this.questionNameArr.cb(this.questionNameArr.data);
         }
@@ -432,9 +464,9 @@ export default {
     //获取下拉建议事件数据
     async querySearchQuestion(queryString, cb) {
       this.questionNameArr.queryParams.current = 1
-      this.questionNameArr.eventInput=queryString
+      this.questionNameArr.eventInput = queryString
       this.questionNameArr.data = []
-      this.questionNameArr.cb=cb
+      this.questionNameArr.cb = cb
       await this.questionEventList()
     },
 

+ 1 - 1
src/views/product/components/dialog/addEditProduct.vue

@@ -127,7 +127,7 @@ export default {
       productCategoryList:[],
       //产品类别分页信息
       queryParams:{
-        size:3,
+        size:10,
         current:1
       },
       //是否懒加载

+ 3 - 3
src/views/product/components/dialog/classifyNode.vue

@@ -76,7 +76,7 @@ export default {
   methods: {
     // 打开弹窗,data有值是编辑,productName是产品名称,newData有值是树节点上的新增
     open(data, row, newData) {
-      console.log(data, newData,row);
+      // console.log(data, newData,row);
       this.$set(this,'row',row)
       if (data) {
           this.options=this.treeDataPath
@@ -129,7 +129,7 @@ export default {
                 this.$message.success('更新成功')
                 this.handleClose()
               }
-            }).cath(err => {
+            }).catch(err => {
               this.$message.error(err.message)
             })
           } else {//新增
@@ -139,7 +139,7 @@ export default {
                 this.$message.success('新增成功')
                 this.handleClose()
               } 
-            }).cath(err => {
+            }).catch(err => {
               this.$message.error(err.message)
             })
           }

+ 58 - 9
src/views/product/components/framework/viewIndex.vue

@@ -17,8 +17,8 @@
           <div style="display:flex;margin-bottom:10px;">
             <el-input v-model="productName" size="small" placeholder="请输入名称" style="margin-right:10px;"></el-input>
             <el-button type="primary" size="small" @click="handleQuery">查询</el-button>
-            <!-- <el-button type="primary" size="small" @click="handleAppend">新增分类节点</el-button> -->
-            <el-dropdown split-button type="primary" size="small" @click="handleAppend">
+            <el-button v-if="typesOf=='1'" type="primary" size="small" @click="handleAppend">新增分类节点</el-button>
+            <el-dropdown v-else split-button type="primary" size="small" @click="handleAppend">
               <span>新增分类节点</span>
               <el-dropdown-menu slot="dropdown">
                 <el-dropdown-item @click.native="handleCopy">复制分类架构节点</el-dropdown-item>
@@ -80,8 +80,10 @@
 
     <classifyNode ref="classifyNode" :treeDataPath="treeDataPath" @isSuccess="handleSuccess"></classifyNode>
     <myImageViewer v-if="showImg" :on-close="closeViewer" :src="imgSrc"></myImageViewer>
+    <myNodeCopy v-if="typesOf=='2'" ref="nodeCopy" :treeData="categoryTreeData" source="1" :checkStrictly="true" @checkId="handleChecked"></myNodeCopy>
+    
   </div>
-</template>
+</template> 
 
 <script>
 import frameworkTable from './view/table.vue'
@@ -93,7 +95,7 @@ export default {
   },
   components: {
     frameworkTable,
-    classifyNode
+    classifyNode,
   },
   data() {
     return {
@@ -132,7 +134,11 @@ export default {
       //展示图片
       showImg:false,
       //图片地址
-      imgSrc:'',
+      imgSrc: '',
+      // 类别分类架构的数据
+      categoryTreeData: [],
+      // 当前节点的id
+      nodeId:null,
     }
   },
   mounted() {
@@ -143,6 +149,11 @@ export default {
     this.getTableList()
     // 请求架构路径
     this.getPath()
+    // 请求类别的分类架构,用于复制类别架构至产品
+    if (this.typesOf == '2') {
+      this.getCategory()
+    }
+    
   },
   methods: {
     //获取排序字段// 子组件table排序
@@ -230,7 +241,7 @@ export default {
         this.$api.deleteTreeNode(params).then(res => {
           if (res.code == 200) {
             this.getList()
-            this.parentId = 0
+            this.parentId = '0'
             this.getTableList()
             this.$message.success('删除该当前分类节点及所属子级分类节点成功!');
           }
@@ -280,7 +291,9 @@ export default {
     },
     // 树节点上复制分类架构
     copy(data, node) {
-      
+      this.nodeId=data.id
+      // console.log(data,node);
+      this.$refs.nodeCopy.open()
     },
     // 树节点点击事件
     handleNodeClick(data, node) {
@@ -292,8 +305,44 @@ export default {
     },
     // 按钮复制分类架构
     handleCopy() {
-      
+      this.nodeId=null
+      this.$refs.nodeCopy.open()
     },
+    // 选中需要复制的类别架构的节点
+    handleChecked(val) {
+      let params = {
+        fromNodeIds: val.checked,//选中需要复制的数据
+        fromType: 1,//类型:1产品类别,2产品,3技术分类,4自定义树
+        fromTypeId:this.row.categoryId,//类别id
+        toType: 2,//类型:1产品类别,2产品,3技术分类,4自定义树
+        toTypeId: this.row.id,//产品或类别id
+        toNodeId: this.nodeId,//放到哪一个节点下面
+        ifCopyChild:val.check,//是否有子节点  
+      }
+      this.$api.copyTreeNode(params).then(res => {
+        if (res.code == 200) {
+          this.nodeId=null
+          this.$message.success('类别分类架构节点复制成功')
+          this.getList()
+          this.getTableList()
+        }
+      })
+    },
+    // 请求类别架构的数据,用于复制分类架构
+    getCategory() {
+      let params = {
+        type: 1,//类型:1产品类别,2产品,3技术分类,4自定义树
+        typeId: this.row.categoryId,//产品类别id
+      }
+      this.$api.queryTreeNodeTree(params).then(res => {
+        if (res.code == 200) {
+          this.categoryTreeData = res.data.data
+        }
+      }).catch(err => {
+        this.$message.error(err.message)
+      })
+    },
+
     // 请求数据(tree)
     async getList() {
       let params = {
@@ -322,7 +371,7 @@ export default {
         } else if (item == 'typeId') {
           label = this.row.id
         } else {
-          label = this.parentId
+          label = this.parentId?this.parentId:'0'
         }
         let obj = {
           searchValue: {

+ 80 - 82
src/views/report/components/dialog/addAndEditReport.vue

@@ -58,7 +58,7 @@
             <el-form-item label="负责人" prop="personId">
               <el-select style="width:100%" v-model="form.personId" placeholder="请选择负责人" filterable remote
                 :popper-append-to-body="false" :remote-method="remoteMethodPerson" v-SelectLazyLoading="lazyLoadingPerson"
-                :loading="loading">
+                :loading="personObj.loading">
                 <el-option v-for="item in personnelList" :key="item.id" :label="item.personnelName"
                   :value="item.id"></el-option>
               </el-select>
@@ -72,7 +72,7 @@
                 <el-form-item label="委托方" prop="clientId" v-if="userinfo.tenantType == 1">
                   <el-select style="width:100%" v-model="form.clientId" placeholder="请选择委托方" filterable remote
                     :popper-append-to-body="false" :remote-method="remoteMethodClient"
-                    v-SelectLazyLoading="lazyLoadingClient" :loading="loading">
+                    v-SelectLazyLoading="lazyLoadingClient" :loading="clientObj.loading">
                     <el-option v-for="item in clientList" :key="item.id" :label="item.name" :value="item.id"></el-option>
                   </el-select>
                 </el-form-item>
@@ -147,7 +147,7 @@
           </div>
         </template>
         <el-form-item :label="(!form.id && form.status == 3) ? '上传报告文档' : '上传附件'">
-          <myUpload :file-list="handleConcat(form[0].systemFileList)" @on-change="onChange" @on-remove="onRemove"
+          <myUpload :file-list="handleConcat(form.systemFileList)" @on-change="onChange" @on-remove="onRemove"
             @on-preview="onPreview" style="height: 180px;"></myUpload>
         </el-form-item>
         <el-form-item label="备注" prop="remark">
@@ -191,7 +191,8 @@
 
     <!-- 无效应对报告下一步所打开弹窗 -->
     <el-dialog :visible.sync="showEvidenceAndRequest" width="1000px" :close-on-click-modal="false">
-      <evidenceAndRequest ref="evidence" :examine="true" :reportId="reportId" @show="showEvidenceAndRequest = false"></evidenceAndRequest>
+      <evidenceAndRequest ref="evidence" :examine="true" :reportId="reportId" @show="showEvidenceAndRequest = false">
+      </evidenceAndRequest>
     </el-dialog>
 
   </div>
@@ -284,12 +285,26 @@ export default {
         "4": "TORT_COPY",
         "5": "AVOID_COPY",
       },
-      queryParams: {
-        current: 1,
-        size: 10,
+      // 客户懒加载obj
+      clientObj: {
+        queryParams: {
+          current: 1,
+          size: 10,
+        },
+        loading: false,
+        //是否懒加载
+        isLazy: true,
+      },
+      // 人员懒加载obj
+      personObj: {
+        queryParams: {
+          current: 1,
+          size: 10,
+        },
+        loading: false,
+        //是否懒加载
+        isLazy: true,
       },
-      //是否懒加载
-      isLazy: true,
       matterType: null,
       /*审核弹窗所需变量start*/
       showTask: false,
@@ -298,7 +313,7 @@ export default {
       isEndTime: true,
       isEndTimes: null,
       // 任务表单校验
-      TaskForm: {
+      TaskRules: {
         taskName: [{ required: true, message: '请输入任务名称', trigger: 'blur' },],
         personnelId: [{ required: true, message: '请选择审核人', trigger: 'change' },],
         endTime: [{ required: true, validator: isTime, trigger: 'change' }],
@@ -308,7 +323,7 @@ export default {
       // 报告id
       reportId: null,
       // 控制弹窗的关闭
-      showEvidenceAndRequest:false,
+      showEvidenceAndRequest: false,
       /*无效应对报告下一步弹窗所需变量end*/
     };
   },
@@ -353,49 +368,39 @@ export default {
     },
     // 人员列表远程搜索
     remoteMethodPerson(query) {
-      this.isLazy = true
-      if (query !== '') {
-        this.loading = true;
-        let params = {
-          ...this.queryParams,//分页信息
-          searchQuery: `name=${query}`,
-        }
-        this.$api.AllPersonnelList(params).then(response => {
-          if (response.code == 200) {
-            this.loading = false;
-            this.personnelList = response.data.data
-          }
-        }).catch(error => {
-          this.loading = false;
-        })
-      } else {
-        this.personnelList = [];
-        this.getProductCategory()
-      }
+      // this.personObj.isLazy = true
+      // if (query !== '') {
+      //   this.personObj.loading = true;
+      //   let params = {
+      //     ...this.personObj.queryParams,//分页信息
+      //     searchQuery: `name=${query}`,
+      //   }
+      //   this.$api.AllPersonnelList(params).then(response => {
+      //     if (response.code == 200) {
+      //       this.personObj.loading = false;
+      //       this.personnelList = response.data.data
+      //     }
+      //   }).catch(error => {
+      //     this.personObj.loading = false;
+      //   })
+      // } else {
+      //   this.personnelList = [];
+      //   this.getProductCategory()
+      // }
     },
     // 获取所有人员列表懒加载
     lazyLoadingPerson() {
-      if (!this.isLazy) {
+      if (this.personObj.queryParams.current * this.personObj.queryParams.size >= this.personObj.queryParams.total) {
         return false
       }
-      this.queryParams.current++;
-      this.getAllPersonnelList();
+      this.personObj.queryParams.current += 1
+      this.getAllPersonnelList()
     },
     //获取所有人员列表(修改不要一次性获取,可以使用懒加载加远程搜索 )
     getAllPersonnelList() {
-      if (!this.isLazy) {
-        return false
-      }
-      let params = {
-        ...this.queryParams,//分页信息
-      }
-      this.$api.AllPersonnelList(params).then(response => {
-        if (response.code == 200) {
-          if (response.data.data && response.data.data.length == 0) {
-            this.isLazy = false
-          }
-          this.personnelList = [...this.personnelList, ...response.data.data];
-        }
+      this.$api.getAdminClientList(this.personObj.queryParams).then(response => {
+        this.personnelList.push(...response.data.records)
+        this.personObj.queryParams.total = response.data.total
       }).catch(error => {
         this.personnelList = []
         this.$message.error(error.message)
@@ -403,49 +408,39 @@ export default {
     },
     // 客户列表远程搜索
     remoteMethodClient(query) {
-      this.isLazy = true
-      if (query !== '') {
-        this.loading = true;
-        let params = {
-          ...this.queryParams,//分页信息
-          searchQuery: `name=${query}`,
-        }
-        this.$api.AllClientList(params).then(response => {
-          if (response.code == 200) {
-            this.loading = false;
-            this.clientList = response.data.data
-          }
-        }).catch(error => {
-          this.loading = false;
-        })
-      } else {
-        this.clientList = [];
-        this.getAllClientList()
-      }
+      // this.clientObj.isLazy = true
+      // if (query !== '') {
+      //   this.clientObj.loading = true;
+      //   let params = {
+      //     ...this.clientObj.queryParams,//分页信息
+      //     searchQuery: `name=${query}`,
+      //   }
+      //   this.$api.AllClientList(params).then(response => {
+      //     if (response.code == 200) {
+      //       this.clientObj.loading = false;
+      //       this.clientList = response.data.data
+      //     }
+      //   }).catch(error => {
+      //     this.clientObj.loading = false;
+      //   })
+      // } else {
+      //   this.clientList = [];
+      //   this.getAllClientList()
+      // }
     },
     // 获取所有客户列表懒加载
     lazyLoadingClient() {
-      if (!this.isLazy) {
+      if (this.clientObj.queryParams.current * this.clientObj.queryParams.size >= this.clientObj.queryParams.total) {
         return false
       }
-      this.queryParams.current++;
-      this.getAllClientList();
+      this.clientObj.queryParams.current += 1
+      this.getAllClientList()
     },
     //获取所有客户列表(修改不要一次性获取,可以使用懒加载加远程搜索 )
     getAllClientList() {
-      if (!this.isLazy) {
-        return false
-      }
-      let params = {
-        ...this.queryParams,//分页信息
-      }
-      this.$api.AllClientList(params).then(response => {
-        if (response.code == 200) {
-          if (response.data.data && response.data.data.length == 0) {
-            this.isLazy = false
-          }
-          this.clientList = [...this.clientList, ...response.data.data];
-        }
+      this.$api.getAdminClientList(this.clientObj.queryParams).then(response => {
+        this.clientList.push(...response.data.records)
+        this.clientObj.queryParams.total = response.data.total
       }).catch(error => {
         this.clientList = []
         this.$message.error(error.message)
@@ -453,6 +448,9 @@ export default {
     },
     //获取所有部门列表
     getAllDepartmentList() {
+      let params = {
+        
+      }
       this.$api.AllDepartmentList(params).then(res => {
         if (res.code == 200) {
           this.departmentList = res.data
@@ -617,7 +615,7 @@ export default {
       if (this.form.type == 7 && val) {
         this.showEvidenceAndRequest = true
         this.$s.setSession('params', {})
-        this.reportId=val
+        this.reportId = val
       }
       this.$refs.reportForm.resetFields()
       this.form = {}

+ 62 - 11
src/views/report/components/index.vue

@@ -7,9 +7,16 @@
           </mySearch>
         </div>
         <div style="display:flex;">
+          <div v-if="[2].indexOf(isOperate) == -1" class="margin-right_10">
+            <span>分组查询:</span>
+            <el-select v-model="groupingValue" size="small" @change="changeGrouping" clearable style="width: 120px">
+              <el-option v-for="item in groupingOption" :key="item.value" :label="item.name" :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
           <el-button-group style="display:flex;justify-content:flex-start" v-if="[2].indexOf(isOperate) == -1">
             <el-button v-for="item in viewTypes" :key="item.component" size="small"
-              :type="viewType == item.component ? 'primary' : ''" @click="onChange2(item.component)">{{ item.name
+              :type="viewType == item.component ? 'primary' : ''" @click="onChange(item.component)">{{ item.name
               }}</el-button>
           </el-button-group>
           <el-dropdown size="small" style="margin-right:20px" v-if="$permission('/pcs/report/add')">
@@ -28,7 +35,8 @@
       </el-header>
       <el-main id="patent-list-container" class="main" v-loading="loading">
         <component :is="viewType" v-bind="$attrs" v-on="$listeners" :isOperate="isOperate" :tableData="dataList"
-          :state="state" :group="group" :queryParams="queryParams" @option="handleOption" @sort="handleSort"
+          :state="state" :queryParams="queryParams" @option="handleOption" @sort="handleSort" :groupBy='groupingValue'
+            :groupingOption="groupingOption" :commonData="commonData" :searchOption="searchOption"
           @getRow="checkDetails" @params="getParams"></component>
       </el-main>
       <el-footer class="pagination" v-if="viewType != 'visual'">
@@ -46,13 +54,15 @@
 import Table from './view/table.vue'
 import Card from './view/card.vue'
 import visual from './view/visual.vue'
+import mergeTable from './view/mergeTable.vue'
 import CreateReport from './dialog/addAndEditReport.vue'
 export default {
   components: {
     Table,
     Card,
     visual,
-    CreateReport
+    CreateReport,
+    mergeTable,
   },
   props: {
     isOperate: ''
@@ -110,6 +120,10 @@ export default {
       searchOption: {
         name: localStorage.searchContent
       },
+      //分组的值
+      groupingValue: '',
+      //分组
+      groupingOption: [],
       //分页信息
       queryParams: {
         current: 1,
@@ -126,12 +140,12 @@ export default {
           "orderType": 1
         }
       ],
-      //分组
-      group: '',
       //加载
       loading: false,
       //报告数据集合
       dataList: [],
+      // 报告分组数据集合
+      commonData:[],
       //获取报告类型、报告状态、核心结论
       reportSearch: {},
     };
@@ -251,6 +265,26 @@ export default {
         this.$message.error(error.message)
       })
     },
+    // 获取分组数据
+    getGrouping() {
+      this.commonData = [{}]
+      return
+      let params = {
+        ...this.queryParams,//分页信息
+        orderDTOList:this.sort,//排序
+        groupBy:this.groupingValue,//分组信息
+      }
+      this.$api.query(params).then(res => {
+        if (res.code == 200) {
+          this.commonData = res.data
+          this.total = res.total
+        }
+      }).catch(error => {
+        this.commonData = []
+        this.total = 0
+        this.$message.error(error.message)
+      })
+    },
     //排序
     handleSort({ column, prop, order }) {
       this.sort = []//如需要多个字段排序,则不需要清空
@@ -285,7 +319,7 @@ export default {
       this.getList()
     },
     //切换视图
-    onChange2(type) {
+    onChange(type) {
       this.viewType = type
       if (type == 'visual') {
         this.$nextTick(() => {
@@ -294,7 +328,9 @@ export default {
         return false
       }
       this.queryParams.size = this.viewType === 'Table' ? 10 : 12
-      this.onChange()
+      this.groupingValue = ''
+      this.queryParams.current = 1
+      this.getList()
     },
     //展示报告可视化
     reportVisual() {
@@ -304,10 +340,24 @@ export default {
         }
       })
     },
-    //切换视图后查询报告数据
-    onChange() {
+    //切换分组值
+    changeGrouping(val) {
+      if (val!='') {
+        this.viewSelected='mergeTable'
+      } else {
+        this.viewSelected='Table'
+      }
       this.queryParams.current = 1
-      this.getList()
+      this.groupingValue=val
+      this.isGrouping()
+    },
+    // 区分是否为分组
+    isGrouping() {
+      if (this.groupingValue != '') {//分组
+        this.getGrouping()
+      } else {//不分组
+        this.getList()
+      }
     },
     //打开创建报告弹窗
     handleAnalyse(id) {
@@ -456,7 +506,8 @@ export default {
       var a = JSON.parse(JSON.stringify(this.searchOption))
       this.searchOption = a
       this.viewType = 'Table'
-      this.onChange()
+      this.queryParams.current = 1
+      this.getList()
     },
     //创建报告子组件返回值
     isGetList(val) {

+ 136 - 0
src/views/report/components/view/mergeTable.vue

@@ -0,0 +1,136 @@
+<template>
+  <div>
+    <el-table :data="commonData" border header-row-class-name="custom-table-header" @expand-change="expandChange"  @sort-change="sortChange">
+      <el-table-column type="expand">
+        <template slot-scope="props">
+          <div style="padding: 10px;height: 340px;">
+            <Table  :column="column" :tableData="props.row.data"  @option="handleOption" :row="{row:props.row,groupBy:groupBy,searchOption:searchOption,}" v-bind="$attrs" v-on="$listeners"/>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column v-for="column in groupingOption.filter(item=> {return item.value == groupBy})" :key="column.value" :label="column.name" :prop="column.value" sortable="custom"
+        show-overflow-tooltip>
+        <template slot-scope="scope">
+          <div>
+            {{ scope.row.name?scope.row.name:'--' }}
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+  
+<script>
+import Table from "./table";
+
+export default {
+  props: {
+    // 检索条件
+    searchOption: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+    // 分组的栏位
+    groupingOption: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    // 分组的值
+    groupBy:String,
+    commonData: Array,
+    column: {//显示栏位管理数组
+      type: Array,
+      default: () => {
+        return [
+          {
+            ifGroup: false,
+            ifSearch: true,
+            name: "事件名称",
+            type: "String",
+            value: "name",
+          },
+          {
+            name: "创建人",
+            type: "String",
+            value: "createName",
+            ifSearch: true,
+            ifGroup: false
+          },
+          {
+            name: "创建时间",
+            type: "DateTime",
+            value: "createTime",
+            ifSearch: true,
+            ifGroup: true
+          },
+          {
+            name: "发生时间",
+            type: "DateTime",
+            value: "eventDate",
+            ifSearch: true,
+            ifGroup: true
+          },
+          {
+            name: "描述",
+            type: "String",
+            value: "description",
+            ifSearch: true,
+            ifGroup: false
+          },
+          {
+            name: "应用场景",
+            type: "Integer",
+            value: "scenarioId",
+            ifSearch: true,
+            ifGroup: true
+          }
+        ]
+      }
+    }
+  },
+  mixins: [],
+  components: {
+    Table
+  },
+  data() {
+    return {
+      // columnList: [],
+      tableData: [],
+      showData: [],
+      expandList: [],
+
+      sort:[
+        {
+          "orderBy": "createTime",
+          "orderType": 1
+        }
+      ],
+    }
+  },
+  watch: {
+  },
+  mounted() {
+    
+  },
+  methods: {
+    // 排序
+    sortChange({ column, prop, order }) {
+      let str='1'
+      this.$emit('on-sort',{ column, prop, order ,str})
+    },
+    //操作列事件
+    handleOption(data) {
+      this.$emit('option', data)
+    },
+    //打开展开行获取数据并保存起来
+    expandChange(row, expandedRows) {
+      row.data = []
+    }
+  }
+}
+</script>
+