Forráskód Böngészése

样本管理 自定义查询 下拉弹框

gongyb 4 éve
szülő
commit
b1fe7d4778

+ 943 - 23
src/dashoo.cn/frontend_animal/src/components/samples/samplesearchdialog.vue

@@ -1,3 +1,4 @@
+<!--
 <template>
   <el-dialog title="样本自定义搜索"
              :visible.sync="samplesearchdialogVisable"
@@ -6,7 +7,7 @@
              :close-on-click-modal="false">
     <el-row class="inputrow">
       <el-col :span="4">
-        <!-- <el-row> -->
+        &lt;!&ndash; <el-row> &ndash;&gt;
         <el-tabs type="border-card">
           <el-tab-pane label="基础字段"
                        style="height:calc(100vh - 370px)">
@@ -30,7 +31,7 @@
             </div>
           </el-tab-pane>
         </el-tabs>
-        <!-- </el-row> -->
+        &lt;!&ndash; </el-row> &ndash;&gt;
 
       </el-col>
       <el-col :span="16">
@@ -81,7 +82,7 @@
                              :label="item.label"
                              :value="item.value"></el-option>
                 </el-select>
-                <!--1. 基础字段是str类型 或者 2.是扩展字段但是不是日期类型 , -->
+                &lt;!&ndash;1. 基础字段是str类型 或者 2.是扩展字段但是不是日期类型 , &ndash;&gt;
                 <el-select v-if="acquritype(scope.row)=='str'||(scope.row.kuoz==='true'&&scope.row.FieldType!==4)"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in stroptions"
@@ -89,7 +90,7 @@
                              :label="item.label"
                              :value="item.value"></el-option>
                 </el-select>
-                <!--如果基础字段是date类型,或者扩展字段并且是日期类型,那么就选用日期类型的表达式-->
+                &lt;!&ndash;如果基础字段是date类型,或者扩展字段并且是日期类型,那么就选用日期类型的表达式&ndash;&gt;
                 <el-select v-else-if="acquritype(scope.row)=='str'||(scope.row.kuoz==='true'&&scope.row.FieldType===4)"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in dateoptions"
@@ -97,15 +98,15 @@
                              :label="item.label"
                              :value="item.value"></el-option>
                 </el-select>
-                <!-- <el-select v-else-if="scope.row.TagIcon==='date'"
+                &lt;!&ndash; <el-select v-else-if="scope.row.TagIcon==='date'"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in dateoptions"
                              :key="item.value"
                              :label="item.label"
                              :value="item.value"></el-option>
-                </el-select> -->
+                </el-select> &ndash;&gt;
 
-                <!--如果基础字段是int类型,选用int表达式-->
+                &lt;!&ndash;如果基础字段是int类型,选用int表达式&ndash;&gt;
                 <el-select v-else-if="acquritype(scope.row)=='int'"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in intoptions"
@@ -113,7 +114,7 @@
                              :label="item.label"
                              :value="item.value"></el-option>
                 </el-select>
-                <!--如果基础字段是cascader类型-->
+                &lt;!&ndash;如果基础字段是cascader类型&ndash;&gt;
                 <el-select v-else-if="acquritype(scope.row)=='cascader'"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in dateoptions"
@@ -121,7 +122,7 @@
                              :label="item.label"
                              :value="item.value"></el-option>
                 </el-select>
-                <!--如果基础字段是date类型,选用日期表达式-->
+                &lt;!&ndash;如果基础字段是date类型,选用日期表达式&ndash;&gt;
                 <el-select v-else-if="acquritype(scope.row)=='date'"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in dateoptions"
@@ -137,7 +138,7 @@
                              align="center"
                              show-overflow-tooltip>
               <template slot-scope="scope">
-                <!--这个v-if 程序中不会走进来,是日期类型between and 的条件,不要删除-->
+                &lt;!&ndash;这个v-if 程序中不会走进来,是日期类型between and 的条件,不要删除&ndash;&gt;
                 <el-date-picker v-model="scope.row.Value"
                                 type="daterange"
                                 v-if="acquritype(scope.row)==='date'&&scope.row.Operate==='between'"
@@ -146,18 +147,18 @@
                                 end-placeholder="结束日期"
                                 value-format="yyyy-MM-dd"
                                 style="width:100%"></el-date-picker>
-                <!--如果基础字段是date类型,或者扩展字段的字段类型是日期类型-->
+                &lt;!&ndash;如果基础字段是date类型,或者扩展字段的字段类型是日期类型&ndash;&gt;
                 <el-date-picker v-model="scope.row.Value"
                                 v-else-if="acquritype(scope.row)==='date'||scope.row.FieldType===4"
                                 type="date"
                                 value-format="yyyy-MM-dd"
                                 :clearable="true"></el-date-picker>
-                <!--如果基础字段是str类型,就正常展示input-->
-                <!-- <el-input v-model="scope.row.Value"
+                &lt;!&ndash;如果基础字段是str类型,就正常展示input&ndash;&gt;
+                &lt;!&ndash; <el-input v-model="scope.row.Value"
                           placeholder="请输入内容"
-                          v-else-if="acquritype(scope.row)==='str'||acquritype(scope.row)==='int'"></el-input> -->
+                          v-else-if="acquritype(scope.row)==='str'||acquritype(scope.row)==='int'"></el-input> &ndash;&gt;
 
-                <!--如果基础字段是cascader类型,就正常展示cascader-->
+                &lt;!&ndash;如果基础字段是cascader类型,就正常展示cascader&ndash;&gt;
 
                 <el-cascader :options="orgtreelist"
                              v-if="acquritypeN(scope.row)=='cascader'"
@@ -167,13 +168,13 @@
                              placeholder="请选择"
                              clearable
                              @change="changecascader"></el-cascader>
-                <!-- <el-select v-if="acquritypeN(scope.row)=='select'"
+                &lt;!&ndash; <el-select v-if="acquritypeN(scope.row)=='select'"
                            v-model="scope.row.Operate">
                   <el-option v-for="item in intoptions"
                              :key="item.value"
                              :label="item.label"
                              :value="item.value"></el-option>
-                </el-select> -->
+                </el-select> &ndash;&gt;
                 <el-date-picker v-model="scope.row.Value"
                                 v-else-if="acquritypeN(scope.row)==='date'"
                                 type="date"
@@ -501,7 +502,7 @@ export default {
       this.getSampleSourceTypeExpand()
       this.getAllSearchTab()
       // this.resetForm()
-      // console.log("ddddd自定义搜索---currentSearchTemplateName", this.currentSearchTemplateName)
+      // console.log("ddddd自定义搜索-&#45;&#45;currentSearchTemplateName", this.currentSearchTemplateName)
     },
     removeCustomCondition (row) {
       if (this.searchTableData !== undefined && this.searchTableData != null && this.searchTableData.length > 0) {
@@ -722,7 +723,7 @@ export default {
 
       for (var m = 0; m < this.searchTableData.length; m++) {
         if (this.searchTableData[m].Operate === 'between' && this.searchTableData[m].Value instanceof Array && this.searchTableData[m].Value.length === 2) {
-          this.searchTableData[m].Value = this.searchTableData[m].Value[0] + '--' + this.searchTableData[m].Value[1]
+          this.searchTableData[m].Value = this.searchTableData[m].Value[0] + '&#45;&#45;' + this.searchTableData[m].Value[1]
         }
         if (typeof this.searchTableData[m].Value === 'object') {
           console.log(this.searchTableData[m].Value, '1111')
@@ -738,7 +739,7 @@ export default {
       // // 这里再循环一遍是为了,让日期范围回填到table中,暂时没有想到好的办法,勿喷
       // for (var j = 0; j < this.searchTableData.length; j++) {
       //   if (this.searchTableData[j].Operate === 'between') {
-      //     this.searchTableData[j].Value = this.searchTableData[j].Value.split('--')
+      //     this.searchTableData[j].Value = this.searchTableData[j].Value.split('&#45;&#45;')
       //   }
       // }
       // console.log(this.searchTableData, '22222222222222222222')
@@ -750,7 +751,7 @@ export default {
       //       for (let j = 0; j < searchValue.length; j++) {
       //         arr.push(this.formatDateTime(searchValue[j]))
       //       }
-      //       s = arr.join('--')
+      //       s = arr.join('&#45;&#45;')
       //     } else {
       //       s = searchValue[searchValue.length - 1]
       //     }
@@ -759,7 +760,7 @@ export default {
       // console.log(template, 'BBBBBBBBB')
 
       // 保存确定
-      service.postRequest('dashoo.biobank.bee-0.1', 'Sample', 'putSearchTemplate', {templeteName: this.currentSearchTemplateName, currentSearchId: this.currentSearchId, template: template, type: 'sample'})
+      service.postRequest('dashoo.biobank.bee-0.1', 'SampleRelated', 'SaveSearchTemplate', {name: this.currentSearchTemplateName, currentSearchId: this.currentSearchId, template: template, type: 'Sample'})
       // putSearchTemplate(this.currentSearchTemplateName, this.currentSearchId, template, 'sample')
         .then(res => {
           if (res.info.code === 0) {
@@ -809,7 +810,7 @@ export default {
         //   })
         // })
         if (ele['Operate'] === 'between') {
-          ele['Value'] = ele['Value'].split('--')
+          ele['Value'] = ele['Value'].split('&#45;&#45;')
         }
         if (ele.TagIcon == 'cascader') {
           ele.Value = ele.Value.split('/')
@@ -883,3 +884,922 @@ export default {
   }
 }
 </style>
+-->
+
+
+
+
+
+<template>
+  <el-dialog title="样本自定义搜索"
+             :visible.sync="samplesearchdialogVisable"
+             width="90%"
+             :before-close="beforeClose"
+             :close-on-click-modal="false">
+    <el-row class="inputrow">
+      <el-col :span="4">
+        <!-- <el-row> -->
+        <el-tabs type="border-card">
+          <el-tab-pane label="基础字段"
+                       style="height:calc(100vh - 370px)">
+            <div :style="{'width':'100%','height':tableHeight-60+'px','overflow':'auto'}">
+              <el-tree :data="data1"
+                       @node-click="handleNodeClick"></el-tree>
+            </div>
+          </el-tab-pane>
+          <el-tab-pane label="扩展字段"
+                       style="height:calc(100vh - 370px)">
+            <div :style="{'width':'100%','height':tableHeight-60+'px','overflow':'auto'}">
+              <el-tree :data="data"
+                       @node-click="handleNodeClicKuoZhan"></el-tree>
+            </div>
+
+          </el-tab-pane>
+          <el-tab-pane label="样本来源基础字段"
+                       style="height:calc(100vh - 370px)">
+            <div :style="{'width':'100%','height':tableHeight-60+'px','overflow':'auto'}">
+              <el-tree :data="data2"
+                       @node-click="handleNodeClick"></el-tree>
+            </div>
+          </el-tab-pane>
+          <el-tab-pane label="样本来源扩展字段"
+                       style="height:calc(100vh - 370px)">
+            <div :style="{'width':'100%','height':tableHeight-60+'px','overflow':'auto'}">
+              <el-tree :data="data3"
+                       @node-click="handleNodeClicKuoZhan"></el-tree>
+            </div>
+
+          </el-tab-pane>
+          <!--          <el-tab-pane label="样本来源"-->
+          <!--                       style="height:calc(100vh - 370px)">-->
+          <!--            <div :style="{'width':'100%','height':tableHeight-60+'px','overflow':'auto'}">-->
+          <!--              <el-tree :data="data2"-->
+          <!--                       @node-click="handleNodeClicSource"></el-tree>-->
+          <!--            </div>-->
+          <!--          </el-tab-pane>-->
+        </el-tabs>
+        <!-- </el-row> -->
+
+      </el-col>
+      <el-col :span="18">
+        <el-row style="margin-bottom:20px">
+          <el-col :span="24">
+            <el-card>
+              <el-tag v-for="tag in searchTemplates"
+                      :id="tag.id"
+                      :key="tag.name"
+                      closable
+                      class="reporttag reportselect"
+                      @click="clickmodeltypetag(tag.name, tag.id)"
+                      @close="removeSearchTab(tag.id,tag.name)">
+                <i class="el-icon-caret-right"
+                   v-if="tag.name === currentSearchTemplateName"></i>
+                {{tag.name}}
+              </el-tag>
+            </el-card>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-card>
+              <el-form inline
+                       label-width="120px">
+                <el-row>
+                  <el-col>
+                    <el-button size="mini"
+                               type="primary"
+                               style="margin-top:10px;"
+                               @click="resetcustomcondition()">新增方案</el-button>
+                    <el-button size="mini"
+                               type="primary"
+                               style="margin-top:10px;"
+                               @click="saveSearchTemplate()">保存</el-button>
+                    <el-form-item label="自定义搜索名称">
+                      <el-input v-model="currentSearchTemplateName"
+                                @change="customsearchnamechange()"
+                                size="mini"
+                                style="width:200px"
+                                placeholder="请输入自定义名称"></el-input>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
+
+              <el-table :data="searchTableData"
+                        size="mini"
+                        border
+                        style="width: 100%;margin-top:-60px"
+                        height="calc(100vh - 360px)">
+                <el-table-column prop="Name"
+                                 label="字段"
+                                 align="center"
+                                 show-overflow-tooltip>
+                </el-table-column>
+                <el-table-column prop="Operate"
+                                 label="表达式"
+                                 align="center"
+                                 width="200px"
+                                 show-overflow-tooltip>
+                  <template slot-scope="scope">
+                    <el-select v-if="scope.row.TagIcon==='date'"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in dateoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                    <!--1. 基础字段是str类型 或者 2.是扩展字段但是不是日期类型 , -->
+                    <el-select v-if="acquritype(scope.row)=='str'||(scope.row.kuoz==='true'&&scope.row.FieldType!==4)"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in stroptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                    <!--如果基础字段是date类型,或者扩展字段并且是日期类型,那么就选用日期类型的表达式-->
+                    <el-select v-else-if="acquritype(scope.row)=='str'||(scope.row.kuoz==='true'&&scope.row.FieldType===4)"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in dateoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                    <!-- <el-select v-else-if="scope.row.TagIcon==='date'"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in dateoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select> -->
+
+                    <!--如果基础字段是int类型,选用int表达式-->
+                    <el-select v-else-if="acquritype(scope.row)=='int'"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in intoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                    <!--如果基础字段是cascader类型-->
+                    <el-select v-else-if="acquritype(scope.row)=='cascader'"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in dateoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                    <!--如果基础字段是date类型,选用日期表达式-->
+                    <el-select v-else-if="acquritype(scope.row)=='date'"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in dateoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="Value"
+                                 label="值"
+                                 width="250"
+                                 align="center"
+                                 show-overflow-tooltip>
+                  <template slot-scope="scope">
+                    <!--这个v-if 程序中不会走进来,是日期类型between and 的条件,不要删除-->
+                    <el-date-picker v-model="scope.row.Value"
+                                    type="daterange"
+                                    v-if="acquritype(scope.row)==='date'&&scope.row.Operate==='between'"
+                                    range-separator="至"
+                                    start-placeholder="开始日期"
+                                    end-placeholder="结束日期"
+                                    value-format="yyyy-MM-dd"
+                                    style="width:100%"></el-date-picker>
+                    <!--如果基础字段是date类型,或者扩展字段的字段类型是日期类型-->
+                    <el-date-picker v-model="scope.row.Value"
+                                    v-else-if="acquritype(scope.row)==='date'||scope.row.FieldType===4"
+                                    type="date"
+                                    value-format="yyyy-MM-dd"
+                                    :clearable="true"></el-date-picker>
+                    <!--如果基础字段是str类型,就正常展示input-->
+                    <!-- <el-input v-model="scope.row.Value"
+                              placeholder="请输入内容"
+                              v-else-if="acquritype(scope.row)==='str'||acquritype(scope.row)==='int'"></el-input> -->
+
+                    <!--如果基础字段是cascader类型,就正常展示cascader-->
+
+                    <el-cascader :options="orgtreelist"
+                                 v-if="acquritypeN(scope.row)=='cascader'"
+                                 :props="orgtreeprops"
+                                 change-on-select
+                                 v-model="scope.row.Value"
+                                 placeholder="请选择"
+                                 clearable
+                                 @change="changecascader"></el-cascader>
+                    <!-- <el-select v-if="acquritypeN(scope.row)=='select'"
+                               v-model="scope.row.Operate">
+                      <el-option v-for="item in intoptions"
+                                 :key="item.value"
+                                 :label="item.label"
+                                 :value="item.value"></el-option>
+                    </el-select> -->
+                    <el-date-picker v-model="scope.row.Value"
+                                    v-else-if="acquritypeN(scope.row)==='date'"
+                                    type="date"
+                                    value-format="yyyy-MM-dd"
+                                    :clearable="true"></el-date-picker>
+                    <el-input v-model="scope.row.Value"
+                              placeholder="请输入内容"
+                              v-else="acquritypeN(scope.row)=='input'"></el-input>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="Guanxi"
+                                 label="逻辑关系"
+                                 align="center"
+                                 show-overflow-tooltip>
+                  <template slot-scope="scope">
+                    <el-select v-model="scope.row.Guanxi"
+                               v-if="scope.$index + 1 != searchTableData.length">
+                      <el-option v-for="item in orAndData"
+                                 :key="item.value"
+                                 :label="item.name"
+                                 :value="item.value"></el-option>
+                    </el-select>
+                  </template>
+                </el-table-column>
+                <el-table-column label="操作"
+                                 align="center"
+                                 show-overflow-tooltip>
+                  <template slot-scope="scope">
+                    <el-button @click="removeCustomCondition(scope.row)"
+                               title="移除"
+                               type="danger"
+                               icon="el-icon-close"
+                               class="dashoo_button_2"
+                               circle
+                               size="small"></el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-card>
+          </el-col>
+        </el-row>
+      </el-col>
+
+    </el-row>
+  </el-dialog>
+</template>
+
+<script>
+import service from '../../utils/micro_request'
+export default {
+  name: 'customsearchdialog',
+
+  created () {
+  },
+  computed: {
+
+  },
+  // watch: {
+  //   visible (val) {
+  //     this.selfVisible = val
+  //   }
+
+  // },
+  data () {
+    return {
+      tableHeight: window.innerHeight - 230,
+      samplesearchdialogVisable: false,
+      orAnd: 'and',
+      orgtreelist: [],
+      orgtreeprops: {
+        value: 'label',
+        label: 'label',
+        children: 'children'
+      },
+      orAndData: [{
+        name: '并且',
+        value: 'and'
+      },
+      {
+        name: '或者',
+        value: 'or'
+      }
+      ],
+      cascaderType: '',
+      selectType: '',
+      inputType: '',
+      selfVisible: this.visible, // 避免vue双向绑定警告
+      searchTableData: [],
+      searchTemplates: [],
+      currentSearchId: 0, // 当前自定义搜索模板的ID
+      currentSearchTemplateName: '', // 当前搜索名称
+      // 字符表达式选择
+      stroptions: [{
+        value: '=',
+        label: '等于'
+      },
+      {
+        value: '!=',
+        label: '不等于'
+      }, {
+        value: 'like',
+        label: '包含'
+      }
+      ],
+      // 数值类型表达式选择
+      intoptions: [{
+        value: '=',
+        label: '等于'
+      }, {
+        value: '>',
+        label: '大于'
+      }, {
+        value: '<',
+        label: '小于'
+      }, {
+        value: '>=',
+        label: '大于等于'
+      }, {
+        value: '!=',
+        label: '不等于'
+      }, {
+        value: '<=',
+        label: '小于等于'
+      }],
+      dateoptions: [{
+        value: '=',
+        label: '等于'
+      }, {
+        value: '>',
+        label: '大于'
+      }, {
+        value: '<',
+        label: '小于'
+      }, {
+        value: '>=',
+        label: '大于等于'
+      }, {
+        value: '!=',
+        label: '不等于'
+      }, {
+        value: '<=',
+        label: '小于等于'
+      }],
+      options: [{
+        value: '=',
+        label: '等于'
+      }, {
+        value: '>',
+        label: '大于'
+      }, {
+        value: '<',
+        label: '小于'
+      }, {
+        value: '>=',
+        label: '大于等于'
+      }, {
+        value: '!=',
+        label: '不等于'
+      }, {
+        value: '<=',
+        label: '小于等于'
+      }, {
+        value: 'like',
+        label: '包含'
+      }],
+      data1: [{
+        value: 'BarCode',
+        label: '样本唯一码',
+        type: 'str'
+      }, {
+        value: 'SampleCode',
+        label: '样本编码',
+        type: 'str'
+      }, {
+        value: 'SourceName',
+        label: '样本来源',
+        type: 'str'
+      }, {
+        value: 'Name',
+        label: '名称',
+        type: 'str'
+      }, {
+        value: 'SampleTypeName',
+        label: '样本类型',
+        type: 'str'
+      }, {
+        value: 'Capacity',
+        label: '可用容量',
+        type: 'int'
+      },
+      {
+        value: 'ValidityDate',
+        label: '有效日期',
+        type: 'date'
+      }, {
+        value: 'ReceiveDate',
+        label: '接收日期',
+        type: 'date'
+      }, {
+        value: 'CreateBy',
+        label: '录入人',
+        type: 'str'
+      }, {
+        value: 'PositionInfo',
+        label: '存储位置',
+        type: 'date'
+      }
+      ],
+      data: [],
+      data2: [],
+      data3: []
+    }
+  },
+
+  // mounted () {
+  //   let _this = this
+  //   window.clickmodeltypetag = function (val, e) {
+  //     _this.clickmodeltypetag(val)
+  //   }
+  // },
+  methods: {
+    getOrgTreeList () {
+      service.postRequest('dashoo.biobank.bee-0.1', 'Sample', 'BasicSampleType')
+        .then(res => {
+          this.orgtreelist = utils.toolfun_gettreejson(res.data, 'id', 'parent_id', 'id,label')
+        })
+        .catch(err => {
+          console.error(err)
+        })
+    },
+    toolfun_gettreejson (rows, idFieldName, pidFieldName, fileds) { // 工具方法,将扁平数据转化成tree格式数据
+      function nodejsonexists (rows, ParentId) {
+        for (var i = 0; i < rows.length; i++) {
+          if (rows[i][idFieldName] === ParentId) {
+            return true
+          }
+        }
+        return false
+      }
+
+      let nodes = []
+      // get the top level nodes
+      for (let i = 0; i < rows.length; i++) {
+        let row = rows[i]
+        if (!nodejsonexists(rows, row[pidFieldName])) {
+          var data = {
+            id: row[idFieldName]
+          }
+          let arrFiled = fileds.split(',')
+          for (var j = 0; j < arrFiled.length; j++) {
+            if (arrFiled[j] !== idFieldName) {
+              data[arrFiled[j]] = row[arrFiled[j]]
+            }
+          }
+          nodes.push(data)
+        }
+      }
+      let toDo = []
+      for (let i = 0; i < nodes.length; i++) {
+        toDo.push(nodes[i])
+      }
+      while (toDo.length) {
+        let node = toDo.shift() // the parent node
+        // get the children nodes
+        for (let i = 0; i < rows.length; i++) {
+          let row = rows[i]
+          if (row[pidFieldName] === node.id) {
+            let child = {
+              id: row[idFieldName]
+            }
+            let arrFiled = fileds.split(',')
+            for (let j = 0; j < arrFiled.length; j++) {
+              if (arrFiled[j] !== idFieldName) {
+                child[arrFiled[j]] = row[arrFiled[j]]
+              }
+            }
+            if (node.children) {
+              node.children.push(child)
+            } else {
+              node.children = [child]
+            }
+            toDo.push(child)
+          }
+        }
+      }
+      return nodes
+    },
+    changecascader (e) {
+      this.cascaderName = e.join('/')
+    },
+    // 清除弹框的绑定值
+    resetForm () {
+      // 自定义弹框数据
+      this.currentSearchTemplateName = '',
+      this.currentSearchId = 0,
+      this.searchTableData = [],
+      this.searchTemplates = [],
+      this.searchTemplateName = ''
+    },
+    // 点击关闭时调用
+    closePopup () {
+      this.resetForm()
+      // this.resetcustomcondition()
+      this.samplesearchdialogVisable = false
+    },
+
+    creatpage () {
+      // 黏膜搜索
+      this.searchKuoZhanData()
+      this.getAllSearchTab()
+    },
+    removeCustomCondition (row) {
+      if (this.searchTableData !== undefined && this.searchTableData != null && this.searchTableData.length > 0) {
+        for (var i = 0; i < this.searchTableData.length; i++) {
+          if (row.Name === this.searchTableData[i].Name) {
+            this.searchTableData.splice(i, 1)
+          }
+        }
+      }
+      this.searchTableData = this.searchTableData
+    },
+    // 查询扩展字段
+    searchKuoZhanData () {
+      this.data = []
+      service.postRequest('dashoo.biobank.bee-0.1', 'SampleRelated', 'CustomizeSearch',{type: 'Sample'})
+        .then(res => {
+          var models = res.info.items
+          for (var i = 0; i < models.length; i++) {
+            var kuozhan = {
+              label: '',
+              children: []
+            }
+            if (i !== 0) {
+              // 和上一条数据是同一种类型,i-1>=0 数组下标不会越界
+              if (models[i].SampleTypeId === models[i - 1].SampleTypeId) {
+                this.data[this.data.length - 1].label = models[i].SampleTypeName
+                this.data[this.data.length - 1].children.push({ label: models[i].KuoZhanFieldName, sampleTypeId: models[i].SampleTypeId, FieldName: models[i].FieldName, FieldType: models[i].FieldType, TagIcon: models[i].TagIcon })
+              } else {
+                // 和上一条数据不是同一个样本类型
+                kuozhan.label = models[i].SampleTypeName
+                kuozhan.children.push({ label: models[i].KuoZhanFieldName, sampleTypeId: models[i].SampleTypeId, FieldName: models[i].FieldName, FieldType: models[i].FieldType, TagIcon: models[i].TagIcon })
+                // 不是同一种样本类型的时候需要增加一个元素
+                this.data.push(kuozhan)
+              }
+            } else {
+              // 第一次循环肯定要加入一个元素
+              kuozhan.label = models[i].SampleTypeName
+              kuozhan.children.push({ label: models[i].KuoZhanFieldName, sampleTypeId: models[i].SampleTypeId, FieldName: models[i].FieldName, FieldType: models[i].FieldType, TagIcon: models[i].TagIcon })
+              this.data.push(kuozhan)
+            }
+          }
+        })
+    },
+
+    // getSampleSourceTypeExpand () {
+    //   this.data2 = []
+    //   service.postRequest('dashoo.biobank.bee-0.1', 'SampleSource', 'SourceTypeExpand')
+    //     .then(res => {
+    //       var models = res
+    //       // cascader判断
+    //       for (var i = 0; i < models.length; i++) {
+    //         var kuozhan = {
+    //           label: '',
+    //           children: []
+    //         }
+    //         if (i !== 0) {
+    //           // 和上一条数据是同一种类型,i-1>=0 数组下标不会越界
+    //           if (models[i].SampleSourceId === models[i - 1].SampleSourceId) {
+    //             this.data2[this.data2.length - 1].label = models[i].SampleSourceTypeName
+    //             this.data2[this.data2.length - 1].children.push({ label: models[i].KuoZhanFieldName, SampleSourceId: models[i].SampleSourceId, FieldName: models[i].FieldName, FieldType: models[i].FieldType, TagIcon: models[i].TagIcon })
+    //           } else {
+    //             // 和上一条数据不是同一个样本类型
+    //             kuozhan.label = models[i].SampleSourceTypeName
+    //             kuozhan.children.push({ label: models[i].KuoZhanFieldName, SampleSourceId: models[i].SampleSourceId, FieldName: models[i].FieldName, FieldType: models[i].FieldType, TagIcon: models[i].TagIcon })
+    //             // 不是同一种样本类型的时候需要增加一个元素
+    //             this.data2.push(kuozhan)
+    //           }
+    //         } else {
+    //           // 第一次循环肯定要加入一个元素
+    //           kuozhan.label = models[i].SampleSourceTypeName
+    //           kuozhan.children.push({ label: models[i].KuoZhanFieldName, SampleSourceId: models[i].SampleSourceId, FieldName: models[i].FieldName, FieldType: models[i].FieldType, TagIcon: models[i].TagIcon })
+    //           this.data2.push(kuozhan)
+    //         }
+    //       }
+    //     })
+    // },
+
+    // 获取类型
+    acquritype (row) {
+      if (row.kuoz === 'false') {
+        for (var i = 0; i < this.data1.length; i++) {
+          if (this.data1[i].value === row.Field) {
+            return this.data1[i].type
+          }
+        }
+      }
+    },
+    getAllSearchTab () {
+      let _this = this
+      service.postRequest('dashoo.biobank.bee-0.1', 'SampleRelated', 'GetSearchTemplate', { type: 'Sample' })
+        // getSearchTemplate({ Type: 'sample' })
+        .then(res => {
+          console.log('searchTemplates', _this.searchTemplates)
+          if (res.data && res.data.length > 0) {
+            _this.searchTemplates = res.data.map(function (e) {
+              e.Fields = JSON.parse(e.template)
+              return e
+            })
+            console.log('searchTemplates', _this.searchTemplates)
+            console.log('_this.searchTemplates[0].name', _this.searchTemplates[0].name)
+            // //当前搜索模板的I
+
+            _this.currentSearchId = _this.searchTemplates[0].id
+            _this.currentSearchTemplateName = _this.searchTemplates[0].name
+            // console.log(_this.searchTemplates, 'searchTemplatessearchTemplatessearchTemplates')
+            // console.log(this.searchTemplates[0].Fields, "this.searchTemplates[0].Fields")
+            _this.searchTableData = this.getSearchTableData(this.searchTemplates[0].Fields)
+          } else {
+            // _this.$message({
+            //   type: 'warning',
+            //   message: res.data.message,
+            // })
+          }
+        })
+        .catch(err => {
+          // handle error
+          console.error(err)
+        })
+    },
+    beforeClose () {
+      this.$emit('close')
+      this.samplesearchdialogVisable = false
+    },
+    removeSearchTab (Id, targetName) {
+      let _this = this
+      _this.$confirm('确定删除该条搜索模板, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        service.postRequest('dashoo.biobank.bee-0.1', 'SampleRelated', 'DeleteSearchTemplate', {id: Id})
+          .then(res => {
+            if (res.info.code === 0) {
+              let tabs = _this.searchTemplates
+              let activeName = _this.currentSearchTemplateName
+              if (activeName === targetName) {
+                tabs.forEach((tab, index) => {
+                  if (tab.Name === targetName) {
+                    let nextTab = tabs[index + 1] || tabs[index - 1]
+                    if (nextTab) {
+                      activeName = nextTab.Name
+                      _this.searchTableData = this.getSearchTableData(nextTab.Fields)
+                    }
+                  }
+                })
+              }
+
+              this.$observer.$emit('handleSeach', true)
+              _this.currentSearchTemplateName = activeName
+              _this.searchTemplates = tabs.filter(tab => tab.Name !== targetName)
+            } else {
+              _this.$message({
+                type: 'warning',
+                message: res.info.message
+              })
+            }
+          })
+          .catch(err => {
+            // handle error
+            console.error(err)
+          })
+        this.searchTableData = []
+        this.currentSearchTemplateName = ''
+      })
+    },
+
+    saveAndSearchWithTemplate () {
+      let _this = this
+      this.saveSearchTemplate(function () {
+        _this.currentSearchTemplate = _this.currentSearchTemplateName
+        _this.searchWithTemplate(_this.currentSearchTemplateName)
+      })
+    },
+    searchWithTemplate () {
+
+    },
+    // 自定义搜索名称发生变化
+    customsearchnamechange () {
+
+    },
+    // 重置
+    resetcustomcondition () {
+      this.searchTableData = []
+      this.currentSearchTemplateName = ''
+      this.currentSearchId = 0
+      this.searchTemplateName = ''
+    },
+    // 保存自定义的搜索条件
+    // 对表达式和逻辑关系要进行健壮性的判断
+    saveSearchTemplate () {
+      let _this = this
+      if (!this.searchTableData.length > 0) {
+        this.$message({
+          type: 'warning',
+          message: '添加自定义查询条件'
+        })
+        return
+      }
+      if (this.currentSearchTemplateName === '') {
+        this.$message({
+          type: 'warning',
+          message: '请输入自定义搜索名称'
+        })
+        return
+      }
+      if (this.searchTableData && this.searchTableData.length > 0) {
+        for (var i = 0; i < this.searchTableData.length; i++) {
+          // 判断表达式
+          if (this.searchTableData[i].Operate === '' || this.searchTableData[i].Operate === undefined || this.searchTableData[i].Operate === null) {
+            this.$message({
+              type: 'warning',
+              message: '【' + this.searchTableData[i].Name + '】表达式为空,保存失败!'
+            })
+            return
+          }
+          // 再判断逻辑关系 ,最后一个表达式不需要判断逻辑关系
+          if ((i != this.searchTableData.length - 1) && (this.searchTableData[i].Guanxi === '' || this.searchTableData[i].Guanxi === undefined || this.searchTableData[i].Guanxi === null)) {
+            this.$message({
+              type: 'warning',
+              message: '【' + this.searchTableData[i].Name + '】逻辑关系为空,保存失败!'
+            })
+            return
+          }
+
+          this.searchTableData[i].OrAnd = this.searchTableData[i].Guanxi
+        }
+      }
+
+      for (var m = 0; m < this.searchTableData.length; m++) {
+        if (this.searchTableData[m].Operate === 'between' && this.searchTableData[m].Value instanceof Array && this.searchTableData[m].Value.length === 2) {
+          this.searchTableData[m].Value = this.searchTableData[m].Value[0] + '--' + this.searchTableData[m].Value[1]
+        }
+        if (typeof this.searchTableData[m].Value === 'object') {
+          console.log(this.searchTableData[m].Value, '1111')
+          this.searchTableData[m].Value = this.searchTableData[m].Value.join('/')
+          console.log(this.searchTableData[m].Value, '2222')
+        }
+      }
+
+      let template = JSON.stringify(this.searchTableData)
+      console.log(template, '333')
+
+      // debugger
+      // // 这里再循环一遍是为了,让日期范围回填到table中,暂时没有想到好的办法,勿喷
+      // for (var j = 0; j < this.searchTableData.length; j++) {
+      //   if (this.searchTableData[j].Operate === 'between') {
+      //     this.searchTableData[j].Value = this.searchTableData[j].Value.split('--')
+      //   }
+      // }
+      // console.log(this.searchTableData, '22222222222222222222')
+
+      //   let s = ''
+      //   if (searchValue instanceof Array && searchValue.length > 0) {
+      //     if (searchValue[0] instanceof Date) {
+      //       let arr = []
+      //       for (let j = 0; j < searchValue.length; j++) {
+      //         arr.push(this.formatDateTime(searchValue[j]))
+      //       }
+      //       s = arr.join('--')
+      //     } else {
+      //       s = searchValue[searchValue.length - 1]
+      //     }
+      //   } else {
+      //     s =
+      // console.log(template, 'BBBBBBBBB')
+
+      // 保存确定
+      service.postRequest('dashoo.biobank.bee-0.1', 'SampleRelated', 'SaveSearchTemplate', {id: this.currentSearchId, name: this.currentSearchTemplateName, template: template, type: 'Sample'})
+        // putSearchTemplate(this.currentSearchTemplateName, this.currentSearchId, template, 'sample')
+        .then(res => {
+          if (res.code === 0) {
+            _this.$message({
+              type: 'success',
+              message: res.msg
+            })
+            this.getAllSearchTab()
+            _this.closePopup()
+            this.$observer.$emit('handleSeach', true)
+          } else {
+            _this.$message({
+              type: 'warning',
+              message: res.msg
+            })
+          }
+        })
+        .catch(err => {
+          // handle error
+          console.error(err)
+        })
+      // _this.resetcustomcondition()
+    },
+    clickmodeltypetag (name, id) {
+      // this.currentSearchTemplateName = val.getAttribute('id')
+      this.currentSearchTemplateName = name
+      this.currentSearchTemplateId = id
+      for (let i = 0; i < this.searchTemplates.length; i++) {
+        if (this.searchTemplates[i].name === this.currentSearchTemplateName) {
+          this.currentSearchId = this.searchTemplates[i].id
+          this.searchTableData = this.getSearchTableData(this.searchTemplates[i].Fields)
+        }
+      }
+    },
+    getSearchTableData (searchFields) {
+      let data = searchFields.map(function (ele) {
+        // if (ele['OrAnd'] === 'or') {
+        //   ele['Guanxi'] = '或者'
+        // } else {
+        //   ele['Guanxi'] = '并且'
+        // }
+
+        // _this.searchTemplates.forEach((item) => {
+        //   item.Fields.forEach((it) => {
+        //     if (it.TagIcon == "cascader") {
+        //       it.Value = "[" + it.Value + "]"
+        //     }
+        //   })
+        // })
+        if (ele['Operate'] === 'between') {
+          ele['Value'] = ele['Value'].split('--')
+        }
+        if (ele.TagIcon == 'cascader') {
+          ele.Value = ele.Value.split('/')
+        }
+        return ele
+      })
+
+      return data || []
+    },
+
+    handleNodeClick (data) {
+      var converdata = {}
+      converdata.Name = data.label // 字段名称
+      converdata.Field = data.value // column
+      converdata.kuoz = 'false'
+      this.searchTableData.push(converdata)
+    },
+    handleNodeClicKuoZhan (data) {
+      // 样本类型下面的扩展字段是没有children的,所以可以用这种方式来判断
+      if (data.children === undefined || data.children.length === 0) {
+        var converdata = {}
+        converdata.Name = data.label // 字段名称
+        converdata.Field = data.FieldName // column
+        converdata.kuoz = 'true'
+        converdata.typecode = 'SampleType'
+        converdata.SampleTypeId = data.sampleTypeId
+        converdata.FieldType = data.FieldType
+        converdata.TagIcon = data.TagIcon
+        this.searchTableData.push(converdata)
+        console.log(this.searchTableData, data.TagIcon, 'datadatadatadatadatadatadatadata')
+        this.acquritypeN(data)
+      }
+    },
+    acquritypeN (row) {
+      for (var i = 0; i < this.searchTableData.length; i++) {
+        if (this.searchTableData[i].TagIcon === row.TagIcon) {
+          return this.searchTableData[i].TagIcon
+        }
+      }
+    }
+    // handleNodeClicSource (data2) {
+    //   // 样本类型下面的扩展字段是没有children的,所以可以用这种方式来判断
+    //   if (data2.children === undefined || data2.children.length === 0) {
+    //     var converdata = {}
+    //
+    //     converdata.TagIcon = data2.TagIcon
+    //     converdata.Name = data2.label // 字段名称
+    //     converdata.Field = data2.FieldName // column
+    //     converdata.kuoz = 'true'
+    //     converdata.typecode = 'SampleSource'
+    //     converdata.SampleTypeId = parseInt(data2.SampleSourceId)
+    //     converdata.FieldType = data2.FieldType
+    //     this.searchTableData.push(converdata)
+    //     console.log(this.searchTableData)
+    //     this.acquritypeN(data2)
+    //   }
+    // }
+
+  }
+}
+</script>
+<style lang="scss">
+.inputrow {
+  .el-date-editor.el-input,
+  .el-date-editor.el-input__inner {
+    margin-right: 30px;
+  }
+  .el-select {
+    width: 176px;
+    margin-right: 30px;
+  }
+}
+</style>

+ 45 - 9
src/dashoo.cn/frontend_animal/src/pages/samples/stored/index.vue

@@ -44,8 +44,12 @@
               <el-dropdown-menu slot="dropdown">
                 <el-dropdown-item command="search">高级查询</el-dropdown-item>
                 <el-dropdown-item command="clear">查询重置</el-dropdown-item>
-                <el-dropdown-item style="color:black;" v-for="item in searchTemplates" :key="item.Name"
-                  :command="item.Name">{{item.Name}}</el-dropdown-item>
+
+                <el-dropdown-item style="color:black;"
+                                  v-for="item in searchTemplates"
+                                  :key="item.name"
+                                  :command="item.name">{{item.name}}</el-dropdown-item>
+
                 <el-dropdown-item divided style="color:black;" command="编辑">自定义</el-dropdown-item>
               </el-dropdown-menu>
             </el-dropdown>
@@ -353,6 +357,7 @@
   import {
     mapGetters
   } from 'vuex'
+  import service from '../../../utils/micro_request'
 
   export default {
     name: 'sampleinput',
@@ -1124,7 +1129,7 @@
         this.initData()
       },
 
-      addSearchField () {
+      /* addSearchField () {
         let searchValue
         for (let k in this.searchValue) {
           if (typeof this.searchValue[k] === 'number') {
@@ -1176,9 +1181,9 @@
             break
           }
         }
-      },
+      }, */
 
-      deleteSearchField (v) {
+      /*      deleteSearchField (v) {
         if (v.Name) {
           for (let i = 0; i < this.searchTemplates.length; i++) {
             if (this.searchTemplates[i].Name == this.currentSearchTemplateName) {
@@ -1190,7 +1195,7 @@
             }
           }
         }
-      },
+      }, */
 
       getSearchTableData (searchFields) {
         let data = searchFields.map(function (ele) {
@@ -1223,7 +1228,7 @@
         return ''
       },
 
-      addSearchTab (name) {
+      /*  addSearchTab (name) {
         for (let i = 0; i < this.searchTemplates.length; i++) {
           if (this.searchTemplates[i].Name == name) {
             this.$message('名称已经存在')
@@ -1241,9 +1246,40 @@
             this.searchTableData = this.getSearchTableData(this.searchTemplates[i].Fields)
           }
         }
-      },
+      }, */
 
       getAllSearchTab () {
+        let _this = this
+        // getSearchTemplate({ Type: 'sample' })
+        service.postRequest('dashoo.biobank.bee-0.1', 'SampleRelated', 'GetSearchTemplate', {type: 'Sample'})
+          .then(res => {
+            console.log('res.data', res.data)
+            if (res.data && res.data.length > 0) {
+              _this.searchTemplates = res.data.map(function (e) {
+                e.Fields = JSON.parse(e.template)
+                return e
+              })
+              console.log('_this.searchTemplates', _this.searchTemplates)
+              // //当前搜索模板的I
+
+              _this.currentSearchId = _this.searchTemplates[0].id
+              _this.currentSearchTemplateName = _this.searchTemplates[0].name
+              // console.log(_this.searchTemplates, 'searchTemplatessearchTemplatessearchTemplates')
+              // console.log(this.searchTemplates[0].Fields, "this.searchTemplates[0].Fields")
+              _this.searchTableData = this.getSearchTableData(this.searchTemplates[0].Fields)
+            } else {
+              // _this.$message({
+              //   type: 'warning',
+              //   message: res.data.message,
+              // })
+            }
+          })
+          .catch(err => {
+            // handle error
+            console.error(err)
+          })
+      },
+      /* getAllSearchTab () {
         let _this = this
         this.$axios.get('/sampleinput/searchTemplate', {})
           .then(res => {
@@ -1265,7 +1301,7 @@
             // handle error
             console.error(err)
           })
-      },
+      }, */
 
       removeSearchTab (targetName) {
         let _this = this