소스 검색

报表优化

cynthia-qin 5 일 전
부모
커밋
5835013297
4개의 변경된 파일223개의 추가작업 그리고 27개의 파일을 삭제
  1. 8 0
      src/api/data/dataReportByt.js
  2. 7 0
      src/api/statistics/report.js
  3. 139 15
      src/views/data/dataReportByt/index.vue
  4. 69 12
      src/views/statistics/sample-statistics/index.vue

+ 8 - 0
src/api/data/dataReportByt.js

@@ -42,3 +42,11 @@ export function delDataReportByt(id) {
     method: 'delete'
   })
 }
+
+// 获取全世界区域编号
+export function getAllAreaData(id) {
+  return request({
+    url: `/system/area/getAreaByParentId/${id}`,
+    method: 'get'
+  })
+}

+ 7 - 0
src/api/statistics/report.js

@@ -89,3 +89,10 @@ export async function getConfigData(type, assemblyAccession, configId) {
     method: 'get',
   })
 }
+// 模糊搜索NCBI基因组序列编号
+export async function getAssemblyAccessionList(keyword) {
+  return request({
+    url: `/data/dataBase/loadTop20DataBase/${keyword}`,
+    method: 'get',
+  })
+}

+ 139 - 15
src/views/data/dataReportByt/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="NCBI基因组序列编号" prop="assemblyAccession">
+      <el-form-item label="NCBI基因组序列编号" prop="assemblyAccession" label-width="200">
         <el-input
           v-model="queryParams.assemblyAccession"
           placeholder="请输入NCBI基因组序列编号"
@@ -9,7 +9,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="病原体名称" prop="name">
+      <el-form-item label="病原体名称" prop="name" label-width="120">
         <el-input
           v-model="queryParams.name"
           placeholder="请输入病原体名称"
@@ -26,21 +26,32 @@
         </el-date-picker>
       </el-form-item>
       <el-form-item label="区域编号" prop="areaId">
-        <el-input
+       <el-cascader
           v-model="queryParams.areaId"
-          placeholder="请输入区域编号"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+          :options="areaOptions"
+          :props="{
+            value: 'areaId',
+            label: 'areaName',
+            children: 'children',
+            // checkStrictly: true,
+            emitPath: false,
+            expandTrigger: 'click',
+            checkDescendants: false,
+            clickTrigger: 'select'
+          }"
+          @change="handleAreaChange"
+          placeholder="请选择区域编号"
+        >
+      </el-cascader>
       </el-form-item>
-      <el-form-item label="区域名称" prop="areaName">
+      <!-- <el-form-item label="区域名称" prop="areaName">
         <el-input
           v-model="queryParams.areaName"
           placeholder="请输入区域名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="数量" prop="num">
         <el-input
           v-model="queryParams.num"
@@ -135,7 +146,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -162,11 +173,26 @@
           </el-date-picker>
         </el-form-item>
         <el-form-item label="区域编号" prop="areaId">
-          <el-input v-model="form.areaId" placeholder="请输入区域编号" />
+          <el-cascader
+            v-model="form.areaId"
+            :options="areaOptions"
+            :props="{
+              value: 'areaId',
+              label: 'areaName',
+              children: 'children',
+              // checkStrictly: true,
+              emitPath: false,
+              expandTrigger: 'click',
+              checkDescendants: false,
+              clickTrigger: 'select'
+            }"
+            @change="handleAreaChange"
+            placeholder="请选择区域编号"
+          />
         </el-form-item>
-        <el-form-item label="区域名称" prop="areaName">
+        <!-- <el-form-item label="区域名称" prop="areaName">
           <el-input v-model="form.areaName" placeholder="请输入区域名称" />
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label="数量" prop="num">
           <el-input v-model="form.num" placeholder="请输入数量" />
         </el-form-item>
@@ -183,7 +209,7 @@
 </template>
 
 <script>
-import { listDataReportByt, getDataReportByt, delDataReportByt, addDataReportByt, updateDataReportByt } from "@/api/data/dataReportByt"
+import { listDataReportByt, getDataReportByt, delDataReportByt, addDataReportByt, updateDataReportByt, getAllAreaData } from "@/api/data/dataReportByt"
 
 export default {
   name: "DataReportByt",
@@ -223,13 +249,111 @@ export default {
       form: {},
       // 表单校验
       rules: {
-      }
+      },
+      areaList:[],
+      // 级联选择器选项
+      areaOptions: [],
+      // 级联选择器加载状态
+      areaLoading: false,
     }
   },
   created() {
     this.getList()
+    this.getAllAreaList()
   },
   methods: {
+    // 查询所有区域编号
+    async getAllAreaList() {
+      try {
+        const res = await getAllAreaData(0)
+      // 并发请求每个父节点的子节点数据
+        const areaOptions = await Promise.all(
+          res.data.map(async (item) => {
+            const childRes = await getAllAreaData(item.areaId)
+            return {
+              areaId: item.areaId,
+              areaName: item.areaName,
+              // 根据子节点数据长度判断是否有子节点
+              children:[...childRes.data]
+            }
+          })
+        )
+        this.areaOptions = areaOptions
+        console.log('this.areaName',this.areaOptions)
+        // this.areaOptions = await this.getChildren(res.data)
+      } catch (error) {
+        console.error('获取区域数据失败:', error)
+      }
+    },
+    // // 递归获取子节点
+    // async getChildren(areas) {
+    //   const result = []
+    //   for (const area of areas) {
+    //     const childRes = await getAllAreaData(area.areaId)
+    //     const children = await this.getChildren(childRes.data)
+    //     result.push({
+    //       areaId: area.areaId,
+    //       areaName: area.areaName,
+    //       children: children.length > 0 ? children : null
+    //     })
+    //   }
+    //   return result
+    // },
+    /** 懒加载子节点 */
+    async loadAreaChildren(node, resolve) {
+      if (!node.data) return
+      if (node.parent) return resolve([])
+      console.log('node',node)
+      const parentId = node.data.areaId
+      try {
+        const res = await getAllAreaData(parentId)
+        const children = res.data.map(item => ({
+          areaId: item.areaId,
+          areaName: item.areaName,
+          // 子节点没有下级,设置为 false
+          hasChildren: false,
+          children:[]
+        }))
+        resolve(children)
+      } catch (error) {
+        console.error('获取子区域数据失败:', error)
+        resolve([])
+      }
+    },
+    /** 处理区域选择事件 */
+    handleAreaChange(value) {
+      const selectedNode = this.getAreaByValue([value])
+      console.log('selectedNode',selectedNode)
+      if (selectedNode) {
+        // 确保选择的是子节点
+        if (this.$refs.form) {
+          this.form.areaId = value
+          this.form.areaName = selectedNode.areaName
+        }
+        if (this.$refs.queryForm) {
+          this.queryParams.areaId = value
+          this.queryParams.areaName = selectedNode.areaName
+        }
+      }
+    },
+    /** 根据值获取区域信息 */
+    getAreaByValue(value) {
+      function findArea(options, value) {
+        for (const option of options) {
+          if (option.areaId === value[0]) {
+            return option
+          }
+          if (option.children) {
+            const result = findArea(option.children, value)
+            if (result) {
+              return result
+            }
+          }
+        }
+        return null
+      }
+      return findArea(this.areaOptions, value)
+    },
     /** 查询病原体历史统计列表 */
     getList() {
       this.loading = true

+ 69 - 12
src/views/statistics/sample-statistics/index.vue

@@ -4,8 +4,27 @@
     <el-row  :gutter="20" class="top-bar">
       <el-col :span="10">
        <div style="display: flex;align-items: center;">
-       <span style="display: block;"> 病原体注册号:</span>
-        <el-input style="flex: 1;" v-model="assemblyAccession" placeholder="请输入病原体注册号"></el-input>
+       <span style="display: block;"> NCBI基因组序列编号:</span>
+        <!-- <el-input style="flex: 1;" v-model="assemblyAccession" placeholder="请输入病原体注册号"></el-input> -->
+         <el-select
+                v-model="assemblyAccession"
+                filterable
+                remote
+                reserve-keyword
+                placeholder="请输入患者身份证号"
+                :remote-method="queryInfo"
+                :loading="loading"
+                @change="handleSelect"
+                style="flex:1"
+              >
+                <el-option
+                  v-for="item in Assoptions"
+                  :key="item.id"
+                  :label="item.asmName"
+                  :value="item.assemblyAccession"
+                >
+                </el-option>
+              </el-select>
        </div>
       </el-col>
       <el-col :span="3" class="filter-col">
@@ -50,7 +69,7 @@
 <script>
 import * as echarts from 'echarts';
 import * as Plotly from 'plotly.js-dist-min';
-import {getjcwzbInfo, getyblxtjInfo, getybtjInfo,getConfigList,getConfigData} from '@/api/statistics/report';
+import {getjcwzbInfo, getyblxtjInfo, getybtjInfo,getConfigList,getConfigData,getAssemblyAccessionList} from '@/api/statistics/report';
 export default {
   name: 'SampleStatistics',
   data() {
@@ -67,7 +86,10 @@ export default {
       value: [],
       options: [],
       dynamicChartContainers: [],
-      isGettingConfigList:false // 新增:标记是否正在获取配置列表
+      isGettingConfigList:false, // 新增:标记是否正在获取配置列表
+      loading:false,
+      Assoptions:[],
+      ASSTimer:null,
     }
   },
   mounted() {
@@ -90,6 +112,33 @@ export default {
     }
   },
   methods: {
+    // 搜索
+    queryInfo(queryString){
+        if (this.ASSTimer) {
+        clearTimeout(this.ASSTimer);
+      }
+      this.ASSTimer = setTimeout(() => {
+        if (queryString.length > 0){
+          this.loading = true
+          getAssemblyAccessionList(queryString).then(res => {
+            console.log('查询基因组序列编号',res)
+            if (res.data && res.data.length > 0) {
+              this.Assoptions = res.data
+
+            }
+             this.loading = false
+          }).finally(() => {
+            this.loading = false
+          })
+        }
+
+      }, 500);
+    },
+    handleSelect(){
+      if (this.assemblyAccession) {
+        this.fetchData();
+      }
+    },
     // 新增:判断两个数组是否相等的方法
     isArrayEqual(arr1, arr2) {
       if (arr1.length !== arr2.length) {
@@ -109,7 +158,7 @@ export default {
       this.isGettingConfigList = true; // 设置标记为正在获取
       const res = await getConfigList();
       this.options = res.data.map(item => ({
-        label: item.keyword,
+        label: item.title,
         value: item.id,
         ...item
       }));
@@ -129,10 +178,11 @@ export default {
             this.assemblyAccession,
             item
           );
+          console.log(optionItem,'optionItem.label')
           if (optionItem.isNum === 'Y') {
-            this.renderViolinChart(res.data, optionItem.label);
+            this.renderViolinChart(res.data, optionItem.keyword);
           } else {
-            this.renderLineChart(res.data, optionItem.label);
+            this.renderLineChart(res.data, optionItem.keyword);
           }
         }
       });
@@ -184,7 +234,7 @@ export default {
 
       const layout = {
         title: {
-          text: `提琴图 - ${label}`,
+          text: label,
           font: {
             size: 20,
             color: '#333'
@@ -267,8 +317,15 @@ export default {
       const xdsyxData = data.map(item => item.xdsyx);
 
       const option = {
+         // 添加 grid 配置项,设置底部边距
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '15%', // 增大底部边距,为 X 轴标签留出空间
+        containLabel: true
+      },
         title: {
-          text: `折线图 - ${label}`,
+          text: label,
           left: 'center',
           top: '3%',
           textStyle: {
@@ -443,7 +500,7 @@ export default {
           }
         },
         legend: {
-          data: ['阳性占比', '阳性率'],
+          data: ['阳性个例', '阳性率'],
           show: true,
           // 调整图例位置
           top: '5%'
@@ -471,7 +528,7 @@ export default {
         yAxis: [
           {
             type: 'value',
-            name: '阳性占比',
+            name: '阳性个例',
             position: 'left',
             axisLabel: {
               formatter: '{value}'
@@ -520,7 +577,7 @@ export default {
         ],
         series: [
           {
-            name: '阳性占比',
+            name: '阳性个例',
             type: 'bar',
             data: yxsData,
             // 更换柱状图颜色