Преглед на файлове

解读报告和样本统计

cynthia-qin преди 2 седмици
родител
ревизия
c8388f9687

+ 3 - 2
package.json

@@ -28,7 +28,7 @@
     "axios": "0.28.1",
     "clipboard": "2.0.8",
     "core-js": "3.37.1",
-    "echarts": "5.4.0",
+    "echarts": "^5.4.0",
     "element-ui": "2.15.14",
     "file-saver": "2.0.5",
     "fuse.js": "6.4.3",
@@ -46,7 +46,8 @@
     "vue-cropper": "0.5.5",
     "vue-router": "3.4.9",
     "vuedraggable": "2.24.3",
-    "vuex": "3.6.0"
+    "vuex": "3.6.0",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "4.4.6",

+ 12 - 0
src/api/data/dataBase.js

@@ -42,3 +42,15 @@ export function delDataBase(id) {
     method: 'delete'
   })
 }
+
+// 导入病原体管理
+export function importDataBase(data) {
+  return request({
+    url: '/data/dataBase/importData',
+    method: 'post',
+    data: data,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
+  })
+}

+ 8 - 0
src/api/sample/sampleExperiment.js

@@ -42,3 +42,11 @@ export function delSampleExperiment(id) {
     method: 'delete'
   })
 }
+
+// 拉取为解读报告
+export function pullSampleExperiment(id) {
+  return request({
+    url: '/sample/sampleExperiment/readData/' + id,
+    method: 'put'
+  })
+}

+ 8 - 0
src/api/sample/sampleInfo.js

@@ -42,3 +42,11 @@ export function delSampleInfo(id) {
     method: 'delete'
   })
 }
+
+// 获取样本类型下拉列表
+export function getSampleTypeSelect() {
+  return request({
+    url: '/sample/sampleType/getAll',
+    method: 'get'
+  })
+}

+ 2 - 0
src/api/sample/sampleType.js

@@ -42,3 +42,5 @@ export function delSampleType(id) {
     method: 'delete'
   })
 }
+
+

+ 14 - 0
src/router/index.js

@@ -87,6 +87,20 @@ export const constantRoutes = [
 
 // 动态路由,基于用户权限动态去加载
 export const dynamicRoutes = [
+    {
+    path: '/read/sampleExperiment-filter',
+    component: Layout,
+    hidden: true,
+    permissions: ['sample:sampleExperiment:edit'],
+    children: [
+      {
+        path: 'report/:reportId(\\d+)',
+        component: () => import('@/views/sample/sampleExperiment/filterReport'),
+        name: 'FilterReport',
+        meta: { title: '过滤报告', activeMenu: '/read/sampleExperiment' }
+      }
+    ]
+  },
   {
     path: '/system/user-auth',
     component: Layout,

+ 83 - 26
src/views/data/dataBase/byt.vue

@@ -9,14 +9,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="参考基因组类型" prop="refseqCategory">
+      <!-- <el-form-item label="参考基因组类型" prop="refseqCategory">
         <el-input
           v-model="queryParams.refseqCategory"
           placeholder="请输入参考基因组类型"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="分类号" prop="taxid">
         <el-input
           v-model="queryParams.taxid"
@@ -41,15 +41,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="亚种名称" prop="infraspecificName">
+      <!-- <el-form-item label="亚种名称" prop="infraspecificName">
         <el-input
           v-model="queryParams.infraspecificName"
           placeholder="请输入亚种名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="分类类型" prop="isolate">
+      </el-form-item> -->
+      <!-- <el-form-item label="分类类型" prop="isolate">
         <el-input
           v-model="queryParams.isolate"
           placeholder="请输入分类类型"
@@ -64,32 +64,32 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="基因组级别" prop="genomeRep">
+      </el-form-item> -->
+      <!-- <el-form-item label="基因组级别" prop="genomeRep">
         <el-input
           v-model="queryParams.genomeRep"
           placeholder="请输入基因组级别"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="seq_rel_date" prop="seqRelDate">
+      </el-form-item> -->
+      <!-- <el-form-item label="seq_rel_date" prop="seqRelDate">
         <el-date-picker clearable
           v-model="queryParams.seqRelDate"
           type="date"
           value-format="yyyy-MM-dd"
           placeholder="请选择seq_rel_date">
         </el-date-picker>
-      </el-form-item>
-      <el-form-item label="ASM编号" prop="asmName">
+      </el-form-item> -->
+      <!-- <el-form-item label="ASM编号" prop="asmName">
         <el-input
           v-model="queryParams.asmName"
           placeholder="请输入ASM编号"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="gbrs_paired_asm" prop="gbrsPairedAsm">
+      </el-form-item> -->
+      <!-- <el-form-item label="gbrs_paired_asm" prop="gbrsPairedAsm">
         <el-input
           v-model="queryParams.gbrsPairedAsm"
           placeholder="请输入gbrs_paired_asm"
@@ -104,7 +104,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="来源地址" prop="ftpPath">
         <el-input
           v-model="queryParams.ftpPath"
@@ -113,14 +113,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
+      <!-- <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
         <el-input
           v-model="queryParams.excludedFromRefseq"
           placeholder="请输入excluded_from_refseq"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="病源类型" prop="group">
         <el-input
           v-model="queryParams.group"
@@ -129,7 +129,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="基因组大小" prop="genomeSize">
+      <!-- <el-form-item label="基因组大小" prop="genomeSize">
         <el-input
           v-model="queryParams.genomeSize"
           placeholder="请输入基因组大小"
@@ -200,7 +200,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="中文名" prop="nameCn">
         <el-input
           v-model="queryParams.nameCn"
@@ -225,15 +225,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="文件路径" prop="filePath">
+      <!-- <el-form-item label="文件路径" prop="filePath">
         <el-input
           v-model="queryParams.filePath"
           placeholder="请输入文件路径"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="点突变耐药基因" prop="dtpnyjy">
+      </el-form-item> -->
+      <!-- <el-form-item label="点突变耐药基因" prop="dtpnyjy">
         <el-input
           v-model="queryParams.dtpnyjy"
           placeholder="请输入点突变耐药基因"
@@ -280,7 +280,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -304,6 +304,7 @@
           plain
           icon="el-icon-upload"
           size="mini"
+          @click="$refs.upload_file.click()"
         >导入</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -353,7 +354,7 @@
       <el-table-column label="毒力基因" align="center" prop="dljy" />
       <el-table-column label="毒力基因说明" align="center" prop="dljyExpress" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -365,7 +366,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -498,11 +499,15 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+    <!-- 上传文件  -->
+     <input hidden type="file" ref="upload_file" accept=".xls,.xlsx" class="upload_file" @change="readExcel($event)" />
+
   </div>
 </template>
 
 <script>
-import { listDataBase, getDataBase, delDataBase, addDataBase, updateDataBase } from "@/api/data/dataBase"
+import { listDataBase, getDataBase, delDataBase, addDataBase, updateDataBase,importDataBase } from "@/api/data/dataBase"
+import * as XLSX from "xlsx"
 
 export default {
   name: "DataBase",
@@ -572,13 +577,65 @@ export default {
       form: {},
       // 表单校验
       rules: {
-      }
+      },
+      upload_file: "",
+      lists: [],
     }
   },
   created() {
     this.getList()
   },
   methods: {
+    // 读取Excel文件
+    readExcel(e) {
+      console.log("读取Excel文件", e);
+      console.log("读取Excel文件11", XLSX);
+  // 读取表格文件
+  let that = this;
+  const files = e.target.files;
+  if (files.length <= 0) {
+    return false;
+  } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
+    this.$message({
+      message: "上传格式不正确,请上传xls或者xlsx格式",
+      type: "warning",
+    });
+    return false;
+  } else {
+    this.uploadFile(files[0]);
+    // 更新获取文件名
+    // that.upload_file = files[0].name;
+  }
+  // const fileReader = new FileReader();
+  // fileReader.onload = (ev) => {
+  //   try {
+  //     const data = ev.target.result;
+  //     const workbook = XLSX.read(data, {
+  //       type: "binary",
+  //     });
+  //     const wsname = workbook.SheetNames[0]; //取第一张表
+  //     console.log(XLSX);
+  //     console.log(wsname);
+  //     console.log(workbook);
+  //     const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
+  //     that.lists = [];
+  //     console.log(ws);
+  //   } catch (e) {
+  //     return false;
+  //   }
+  // };
+  // fileReader.readAsBinaryString(files[0]);
+},
+uploadFile(file) {
+  console.log("上传文件", file);
+  // 创建FormData对象
+const formData = new FormData(); // 创建FormData对象
+formData.append('file', file); // 将文件添加到FormData对象中,
+importDataBase(formData).then(response => {
+  this.$modal.msgSuccess("导入成功")
+  this.getList()
+})
+},
     /** 查询病原体管理列表 */
     getList() {
       this.loading = true

+ 42 - 13
src/views/data/dataBase/dljy.vue

@@ -9,14 +9,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="参考基因组类型" prop="refseqCategory">
+      <!-- <el-form-item label="参考基因组类型" prop="refseqCategory">
         <el-input
           v-model="queryParams.refseqCategory"
           placeholder="请输入参考基因组类型"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="分类号" prop="taxid">
         <el-input
           v-model="queryParams.taxid"
@@ -41,15 +41,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="亚种名称" prop="infraspecificName">
+      <!-- <el-form-item label="亚种名称" prop="infraspecificName">
         <el-input
           v-model="queryParams.infraspecificName"
           placeholder="请输入亚种名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="分类类型" prop="isolate">
+      </el-form-item> -->
+      <!-- <el-form-item label="分类类型" prop="isolate">
         <el-input
           v-model="queryParams.isolate"
           placeholder="请输入分类类型"
@@ -104,7 +104,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="来源地址" prop="ftpPath">
         <el-input
           v-model="queryParams.ftpPath"
@@ -113,7 +113,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
+      <!-- <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
         <el-input
           v-model="queryParams.excludedFromRefseq"
           placeholder="请输入excluded_from_refseq"
@@ -200,7 +200,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="中文名" prop="nameCn">
         <el-input
           v-model="queryParams.nameCn"
@@ -225,7 +225,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="文件路径" prop="filePath">
+      <!-- <el-form-item label="文件路径" prop="filePath">
         <el-input
           v-model="queryParams.filePath"
           placeholder="请输入文件路径"
@@ -280,7 +280,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -304,6 +304,7 @@
           plain
           icon="el-icon-upload"
           size="mini"
+          @click="$refs.upload_file.click()"
         >导入</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -353,7 +354,7 @@
       <el-table-column label="毒力基因" align="center" prop="dljy" />
       <el-table-column label="毒力基因说明" align="center" prop="dljyExpress" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -365,7 +366,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -498,11 +499,13 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+    <!-- 上传文件  -->
+     <input hidden type="file" ref="upload_file" accept=".xls,.xlsx" class="upload_file" @change="readExcel($event)" />
   </div>
 </template>
 
 <script>
-import { listDataBase, getDataBase, delDataBase, addDataBase, updateDataBase } from "@/api/data/dataBase"
+import { listDataBase, getDataBase, delDataBase, addDataBase, updateDataBase,importDataBase } from "@/api/data/dataBase"
 
 export default {
   name: "DataBase",
@@ -580,6 +583,32 @@ export default {
     this.getList()
   },
   methods: {
+        // 读取Excel文件
+    readExcel(e) {
+  // 读取表格文件
+  const files = e.target.files;
+  if (files.length <= 0) {
+    return false;
+  } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
+    this.$message({
+      message: "上传格式不正确,请上传xls或者xlsx格式",
+      type: "warning",
+    });
+    return false;
+  } else {
+    this.uploadFile(files[0]);
+  }
+},
+uploadFile(file) {
+  console.log("上传文件", file);
+  // 创建FormData对象
+const formData = new FormData(); // 创建FormData对象
+formData.append('file', file); // 将文件添加到FormData对象中,
+importDataBase(formData).then(response => {
+  this.$modal.msgSuccess("导入成功")
+  this.getList()
+})
+},
     /** 查询病原体管理列表 */
     getList() {
       this.loading = true

+ 46 - 14
src/views/data/dataBase/dtbnyjy.vue

@@ -9,14 +9,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="参考基因组类型" prop="refseqCategory">
+      <!-- <el-form-item label="参考基因组类型" prop="refseqCategory">
         <el-input
           v-model="queryParams.refseqCategory"
           placeholder="请输入参考基因组类型"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="分类号" prop="taxid">
         <el-input
           v-model="queryParams.taxid"
@@ -25,14 +25,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="种分类号" prop="speciesTaxid">
+      <!-- <el-form-item label="种分类号" prop="speciesTaxid">
         <el-input
           v-model="queryParams.speciesTaxid"
           placeholder="请输入种分类号"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="生物名称" prop="organismName">
         <el-input
           v-model="queryParams.organismName"
@@ -41,15 +41,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="亚种名称" prop="infraspecificName">
+      <!-- <el-form-item label="亚种名称" prop="infraspecificName">
         <el-input
           v-model="queryParams.infraspecificName"
           placeholder="请输入亚种名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="分类类型" prop="isolate">
+      </el-form-item> -->
+      <!-- <el-form-item label="分类类型" prop="isolate">
         <el-input
           v-model="queryParams.isolate"
           placeholder="请输入分类类型"
@@ -104,7 +104,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="来源地址" prop="ftpPath">
         <el-input
           v-model="queryParams.ftpPath"
@@ -113,7 +113,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
+      <!-- <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
         <el-input
           v-model="queryParams.excludedFromRefseq"
           placeholder="请输入excluded_from_refseq"
@@ -200,7 +200,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="中文名" prop="nameCn">
         <el-input
           v-model="queryParams.nameCn"
@@ -225,7 +225,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="文件路径" prop="filePath">
+      <!-- <el-form-item label="文件路径" prop="filePath">
         <el-input
           v-model="queryParams.filePath"
           placeholder="请输入文件路径"
@@ -280,7 +280,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -304,6 +304,7 @@
           plain
           icon="el-icon-upload"
           size="mini"
+          @click="$refs.upload_file.click()"
         >导入</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -353,7 +354,7 @@
       <el-table-column label="毒力基因" align="center" prop="dljy" />
       <el-table-column label="毒力基因说明" align="center" prop="dljyExpress" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -365,7 +366,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -498,6 +499,8 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+    <!-- 上传文件  -->
+     <input hidden type="file" ref="upload_file" accept=".xls,.xlsx" class="upload_file" @change="readExcel($event)" />
   </div>
 </template>
 
@@ -580,6 +583,35 @@ export default {
     this.getList()
   },
   methods: {
+        // 读取Excel文件
+    readExcel(e) {
+      console.log("读取Excel文件", e);
+      console.log("读取Excel文件11", XLSX);
+  // 读取表格文件
+  let that = this;
+  const files = e.target.files;
+  if (files.length <= 0) {
+    return false;
+  } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
+    this.$message({
+      message: "上传格式不正确,请上传xls或者xlsx格式",
+      type: "warning",
+    });
+    return false;
+  } else {
+    this.uploadFile(files[0]);
+  }
+},
+uploadFile(file) {
+  console.log("上传文件", file);
+  // 创建FormData对象
+const formData = new FormData(); // 创建FormData对象
+formData.append('file', file); // 将文件添加到FormData对象中,
+importDataBase(formData).then(response => {
+  this.$modal.msgSuccess("导入成功")
+  this.getList()
+})
+},
     /** 查询病原体管理列表 */
     getList() {
       this.loading = true

+ 46 - 14
src/views/data/dataBase/nyjy.vue

@@ -9,14 +9,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="参考基因组类型" prop="refseqCategory">
+      <!-- <el-form-item label="参考基因组类型" prop="refseqCategory">
         <el-input
           v-model="queryParams.refseqCategory"
           placeholder="请输入参考基因组类型"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="分类号" prop="taxid">
         <el-input
           v-model="queryParams.taxid"
@@ -25,14 +25,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="种分类号" prop="speciesTaxid">
+      <!-- <el-form-item label="种分类号" prop="speciesTaxid">
         <el-input
           v-model="queryParams.speciesTaxid"
           placeholder="请输入种分类号"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="生物名称" prop="organismName">
         <el-input
           v-model="queryParams.organismName"
@@ -41,7 +41,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="亚种名称" prop="infraspecificName">
+      <!-- <el-form-item label="亚种名称" prop="infraspecificName">
         <el-input
           v-model="queryParams.infraspecificName"
           placeholder="请输入亚种名称"
@@ -104,7 +104,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="来源地址" prop="ftpPath">
         <el-input
           v-model="queryParams.ftpPath"
@@ -113,15 +113,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
+      <!-- <el-form-item label="excluded_from_refseq" prop="excludedFromRefseq">
         <el-input
           v-model="queryParams.excludedFromRefseq"
           placeholder="请输入excluded_from_refseq"
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
-      <el-form-item label="病源类型" prop="group">
+      </el-form-item> -->
+      <!-- <el-form-item label="病源类型" prop="group">
         <el-input
           v-model="queryParams.group"
           placeholder="请输入病源类型"
@@ -200,7 +200,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="中文名" prop="nameCn">
         <el-input
           v-model="queryParams.nameCn"
@@ -225,7 +225,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="文件路径" prop="filePath">
+      <!-- <el-form-item label="文件路径" prop="filePath">
         <el-input
           v-model="queryParams.filePath"
           placeholder="请输入文件路径"
@@ -280,7 +280,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -304,6 +304,7 @@
           plain
           icon="el-icon-upload"
           size="mini"
+          @click="$refs.upload_file.click()"
         >导入</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -353,7 +354,7 @@
       <el-table-column label="毒力基因" align="center" prop="dljy" />
       <el-table-column label="毒力基因说明" align="center" prop="dljyExpress" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -365,7 +366,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -498,6 +499,8 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+    <!-- 上传文件  -->
+     <input hidden type="file" ref="upload_file" accept=".xls,.xlsx" class="upload_file" @change="readExcel($event)" />
   </div>
 </template>
 
@@ -580,6 +583,35 @@ export default {
     this.getList()
   },
   methods: {
+        // 读取Excel文件
+    readExcel(e) {
+      console.log("读取Excel文件", e);
+      console.log("读取Excel文件11", XLSX);
+  // 读取表格文件
+  let that = this;
+  const files = e.target.files;
+  if (files.length <= 0) {
+    return false;
+  } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
+    this.$message({
+      message: "上传格式不正确,请上传xls或者xlsx格式",
+      type: "warning",
+    });
+    return false;
+  } else {
+    this.uploadFile(files[0]);
+  }
+},
+uploadFile(file) {
+  console.log("上传文件", file);
+  // 创建FormData对象
+const formData = new FormData(); // 创建FormData对象
+formData.append('file', file); // 将文件添加到FormData对象中,
+importDataBase(formData).then(response => {
+  this.$modal.msgSuccess("导入成功")
+  this.getList()
+})
+},
     /** 查询病原体管理列表 */
     getList() {
       this.loading = true

+ 187 - 0
src/views/sample/sampleExperiment/filterReport.vue

@@ -0,0 +1,187 @@
+<template>
+  <div class="filter-report">
+    <!-- 患者基本信息 -->
+    <el-card class="patient-info" shadow="hover">
+      <div>
+        <span>姓名:{{ patient.name }}</span>
+        <span style="margin-left: 20px;">性别:{{ patient.gender }}</span>
+        <span style="margin-left: 20px;">年龄:{{ patient.age }}</span>
+      </div>
+    </el-card>
+
+    <el-tabs v-model="activeTab">
+      <el-tab-pane label="病原体解读" name="pathogen">
+        <div class="tab-content">
+          <!-- 全部数据选择 -->
+          <el-card class="all-data" shadow="hover">
+            <div style="margin-bottom: 10px;">
+              <el-checkbox
+                v-model="selectAll"
+                @change="handleSelectAll"
+              >全选</el-checkbox>
+              <el-button
+                type="primary"
+                @click="handleFilter"
+                style="margin-left: 20px;"
+              >过滤</el-button>
+            </div>
+            <el-table
+              :data="availableData"
+              border
+              style="width: 100%"
+              @selection-change="handleSelectionChange"
+              ref="dataTable"
+            >
+              <el-table-column
+                type="selection"
+                width="55"
+              ></el-table-column>
+              <el-table-column
+                prop="id"
+                label="ID"
+                width="80"
+              ></el-table-column>
+              <el-table-column
+                prop="name"
+                label="数据名称"
+              ></el-table-column>
+              <el-table-column
+                prop="value"
+                label="数值"
+              ></el-table-column>
+            </el-table>
+          </el-card>
+
+          <!-- 过滤数据展示 -->
+          <el-card class="filtered-data" shadow="hover" style="margin-top: 20px;">
+            <div slot="header">
+              <span>已选数据(过滤数据)</span>
+            </div>
+            <el-table
+              :data="filteredData"
+              border
+              style="width: 100%"
+            >
+              <el-table-column
+                prop="id"
+                label="ID"
+                width="80"
+              ></el-table-column>
+              <el-table-column
+                prop="name"
+                label="数据名称"
+              ></el-table-column>
+              <el-table-column
+                prop="value"
+                label="数值"
+              ></el-table-column>
+              <el-table-column
+                label="操作"
+                width="100"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    type="text"
+                    size="small"
+                    @click="removeFiltered(scope.row)"
+                  >移除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-card>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="耐药基因解读" name="resistance">
+        <div class="tab-content">
+          <!-- 这里可以添加耐药基因解读相关内容 -->
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="毒力基因解读" name="virulence">
+        <div class="tab-content">
+          <!-- 这里可以添加毒力基因解读相关内容 -->
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="点突变基因解读" name="mutation">
+        <div class="tab-content">
+          <!-- 这里可以添加点突变基因解读相关内容 -->
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="基本信息" name="basicInfo">
+        <div class="tab-content">
+          <!-- 可添加其他基本信息内容 -->
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'FilterReport',
+  data() {
+    return {
+      activeTab: 'pathogen',
+      patient: {
+        name: '张三',
+        gender: '男',
+        age: 35
+      },
+      allData: [
+        { id: 1, name: '血压', value: '120/80' },
+        { id: 2, name: '血糖', value: '5.6' },
+        { id: 3, name: '心率', value: '72' },
+        { id: 4, name: '体温', value: '36.5' }
+      ],
+      tempSelectedRows: [],
+      selectedRows: [],
+      selectAll: false
+    }
+  },
+  computed: {
+    filteredData() {
+      return this.selectedRows;
+    },
+    availableData() {
+      return this.allData.filter(item => !this.selectedRows.some(selected => selected.id === item.id));
+    }
+  },
+  methods: {
+    handleSelectionChange(val) {
+      this.tempSelectedRows = val;
+      this.selectAll = val.length === this.availableData.length;
+    },
+    handleSelectAll(val) {
+      if (val) {
+        this.$refs.dataTable.clearSelection();
+        this.availableData.forEach(row => {
+          this.$refs.dataTable.toggleRowSelection(row, true);
+        });
+      } else {
+        this.$refs.dataTable.clearSelection();
+      }
+    },
+    handleFilter() {
+      this.selectedRows = [...this.selectedRows, ...this.tempSelectedRows];
+      this.tempSelectedRows = [];
+      this.$refs.dataTable.clearSelection();
+      this.selectAll = false;
+    },
+    removeFiltered(row) {
+      this.selectedRows = this.selectedRows.filter(item => item.id !== row.id);
+    }
+  }
+}
+</script>
+
+<style scoped>
+.filter-report {
+  padding: 20px;
+}
+.patient-info span {
+  font-size: 16px;
+  font-weight: 500;
+}
+.tab-content {
+  padding: 20px;
+}
+</style>

+ 40 - 4
src/views/sample/sampleExperiment/index.vue

@@ -27,7 +27,7 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="解读或作废时间" prop="dealTime">
+      <el-form-item label="解读或作废时间" prop="dealTime" label-width="120px">
         <el-date-picker clearable
           v-model="queryParams.dealTime"
           type="date"
@@ -106,6 +106,29 @@
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
+          v-if="scope.row.status !== 1"
+            size="mini"
+            type="text"
+            @click="handleDelete(scope.row)"
+          >查看报告</el-button>
+          <el-button
+           v-if="scope.row.status !== 1"
+            size="mini"
+            type="text"
+            @click="handleDelete(scope.row)"
+          >重新生成</el-button>
+          <el-button
+           v-if="scope.row.status === 1"
+            size="mini"
+            type="text"
+            @click="handlePull(scope.row)"
+          >生成报告</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleFilter(scope.row)"
+          >过滤</el-button>
+          <!-- <el-button
             size="mini"
             type="text"
             icon="el-icon-edit"
@@ -118,11 +141,11 @@
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
             v-hasPermi="['sample:sampleExperiment:remove']"
-          >删除</el-button>
+          >删除</el-button> -->
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -171,7 +194,7 @@
 </template>
 
 <script>
-import { listSampleExperiment, getSampleExperiment, delSampleExperiment, addSampleExperiment, updateSampleExperiment } from "@/api/sample/sampleExperiment"
+import { listSampleExperiment, getSampleExperiment, delSampleExperiment, addSampleExperiment, updateSampleExperiment,pullSampleExperiment } from "@/api/sample/sampleExperiment"
 
 export default {
   name: "SampleExperiment",
@@ -301,6 +324,19 @@ export default {
         }
       })
     },
+    // 生成报告按钮操作
+    handlePull(row) {
+      const ids = row.id
+      pullSampleExperiment(ids).then(() => {
+        this.$modal.msgSuccess("生成报告成功")
+        this.getList()
+      }).catch(() => {})
+    },
+    // 过滤按钮操作
+    handleFilter(row) {
+      const id = row.id
+      this.$router.push("/read/sampleExperiment-filter/report/" + id)
+    },
     /** 删除按钮操作 */
     handleDelete(row) {
       const ids = row.id || this.ids

+ 4 - 4
src/views/sample/sampleHospital/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
       <el-form-item label="医院名称" prop="name">
         <el-input
           v-model="queryParams.name"
@@ -29,7 +29,7 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="中国行政区域编号" prop="cnAreanId">
+      <el-form-item label="中国行政区域编号" prop="cnAreanId" label-width="130px">
         <el-input
           v-model="queryParams.cnAreanId"
           placeholder="请输入中国行政区域编号"
@@ -37,7 +37,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="中国行政区域组合名称" prop="cnAreaname">
+      <el-form-item label="中国行政区域组合名称" prop="cnAreaname" label-width="160px">
         <el-input
           v-model="queryParams.cnAreaname"
           placeholder="请输入中国行政区域组合名称"
@@ -142,7 +142,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"

+ 181 - 80
src/views/sample/sampleInfo/index.vue

@@ -1,6 +1,13 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+      label-width="100px"
+    >
       <el-form-item label="样品编号" prop="sampleCode">
         <el-input
           v-model="queryParams.sampleCode"
@@ -26,12 +33,24 @@
         />
       </el-form-item>
       <el-form-item label="样本类型" prop="sampleTypeId">
-        <el-input
+        <!-- <el-input
           v-model="queryParams.sampleTypeId"
           placeholder="请输入样本类型"
           clearable
           @keyup.enter.native="handleQuery"
-        />
+        /> -->
+        <el-select
+          v-model="queryParams.sampleTypeId"
+          placeholder="请选择样本类型"
+        >
+          <el-option
+            v-for="item in options"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
       </el-form-item>
       <el-form-item label="送检医院编号" prop="sampleHospitalId">
         <el-input
@@ -58,8 +77,16 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
       </el-form-item>
     </el-form>
 
@@ -72,7 +99,8 @@
           size="mini"
           @click="handleAdd"
           v-hasPermi="['sample:sampleInfo:add']"
-        >新增</el-button>
+          >新增</el-button
+        >
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -83,7 +111,8 @@
           :disabled="single"
           @click="handleUpdate"
           v-hasPermi="['sample:sampleInfo:edit']"
-        >修改</el-button>
+          >修改</el-button
+        >
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -94,7 +123,8 @@
           :disabled="multiple"
           @click="handleDelete"
           v-hasPermi="['sample:sampleInfo:remove']"
-        >删除</el-button>
+          >删除</el-button
+        >
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -104,23 +134,43 @@
           size="mini"
           @click="handleExport"
           v-hasPermi="['sample:sampleInfo:export']"
-        >导出</el-button>
+          >导出</el-button
+        >
       </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
     </el-row>
 
-    <el-table v-loading="loading" :data="sampleInfoList" @selection-change="handleSelectionChange">
+    <el-table
+      v-loading="loading"
+      :data="sampleInfoList"
+      @selection-change="handleSelectionChange"
+    >
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="编号" align="center" prop="id" />
       <el-table-column label="样品编号" align="center" prop="sampleCode" />
       <el-table-column label="患者编号" align="center" prop="patientId" />
       <el-table-column label="患者电话" align="center" prop="patientPhone" />
       <el-table-column label="样本类型" align="center" prop="sampleTypeId" />
-      <el-table-column label="送检医院编号" align="center" prop="sampleHospitalId" />
-      <el-table-column label="送检科室编号" align="center" prop="sampleDeptId" />
+      <el-table-column
+        label="送检医院编号"
+        align="center"
+        prop="sampleHospitalId"
+      />
+      <el-table-column
+        label="送检科室编号"
+        align="center"
+        prop="sampleDeptId"
+      />
       <el-table-column label="医生名字" align="center" prop="doctorName" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -128,20 +178,22 @@
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['sample:sampleInfo:edit']"
-          >修改</el-button>
+            >修改</el-button
+          >
           <el-button
             size="mini"
             type="text"
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
             v-hasPermi="['sample:sampleInfo:remove']"
-          >删除</el-button>
+            >删除</el-button
+          >
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
-      v-show="total>0"
+      v-show="total > 0"
       :total="total"
       :page.sync="queryParams.pageNum"
       :limit.sync="queryParams.pageSize"
@@ -161,19 +213,43 @@
           <el-input v-model="form.patientPhone" placeholder="请输入患者电话" />
         </el-form-item>
         <el-form-item label="样本类型" prop="sampleTypeId">
-          <el-input v-model="form.sampleTypeId" placeholder="请输入样本类型" />
+          <!-- <el-input v-model="form.sampleTypeId" placeholder="请输入样本类型" /> -->
+
+          <el-select
+            v-model="queryParams.sampleTypeId"
+            placeholder="请选择样本类型"
+            style="width: 100%;"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
         </el-form-item>
         <el-form-item label="送检医院编号" prop="sampleHospitalId">
-          <el-input v-model="form.sampleHospitalId" placeholder="请输入送检医院编号" />
+          <el-input
+            v-model="form.sampleHospitalId"
+            placeholder="请输入送检医院编号"
+          />
         </el-form-item>
         <el-form-item label="送检科室编号" prop="sampleDeptId">
-          <el-input v-model="form.sampleDeptId" placeholder="请输入送检科室编号" />
+          <el-input
+            v-model="form.sampleDeptId"
+            placeholder="请输入送检科室编号"
+          />
         </el-form-item>
         <el-form-item label="医生名字" prop="doctorName">
           <el-input v-model="form.doctorName" placeholder="请输入医生名字" />
         </el-form-item>
         <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+          <el-input
+            v-model="form.remark"
+            type="textarea"
+            placeholder="请输入内容"
+          />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -185,7 +261,14 @@
 </template>
 
 <script>
-import { listSampleInfo, getSampleInfo, delSampleInfo, addSampleInfo, updateSampleInfo } from "@/api/sample/sampleInfo"
+import {
+  listSampleInfo,
+  getSampleInfo,
+  delSampleInfo,
+  addSampleInfo,
+  updateSampleInfo,
+  getSampleTypeSelect,
+} from "@/api/sample/sampleInfo";
 
 export default {
   name: "SampleInfo",
@@ -224,27 +307,37 @@ export default {
       // 表单参数
       form: {},
       // 表单校验
-      rules: {
-      }
-    }
+      rules: {},
+      options: [],
+    };
   },
   created() {
-    this.getList()
+    this.getList();
+    this.getSampleTypeOptions();
   },
   methods: {
     /** 查询样品管理列表 */
     getList() {
-      this.loading = true
-      listSampleInfo(this.queryParams).then(response => {
-        this.sampleInfoList = response.rows
-        this.total = response.total
-        this.loading = false
-      })
+      this.loading = true;
+      listSampleInfo(this.queryParams).then((response) => {
+        this.sampleInfoList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 获取样本类型选项
+    getSampleTypeOptions() {
+      getSampleTypeSelect().then((response) => {
+        this.options = response.data.map((item) => ({
+          value: item.id,
+          label: item.name,
+        }));
+      });
     },
     // 取消按钮
     cancel() {
-      this.open = false
-      this.reset()
+      this.open = false;
+      this.reset();
     },
     // 表单重置
     reset() {
@@ -261,78 +354,86 @@ export default {
         createTime: null,
         updateBy: null,
         updateTime: null,
-        remark: null
-      }
-      this.resetForm("form")
+        remark: null,
+      };
+      this.resetForm("form");
     },
     /** 搜索按钮操作 */
     handleQuery() {
-      this.queryParams.pageNum = 1
-      this.getList()
+      this.queryParams.pageNum = 1;
+      this.getList();
     },
     /** 重置按钮操作 */
     resetQuery() {
-      this.resetForm("queryForm")
-      this.handleQuery()
+      this.resetForm("queryForm");
+      this.handleQuery();
     },
     // 多选框选中数据
     handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
+      this.ids = selection.map((item) => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
     },
     /** 新增按钮操作 */
     handleAdd() {
-      this.reset()
-      this.open = true
-      this.title = "添加样品管理"
+      this.reset();
+      this.open = true;
+      this.title = "添加样品管理";
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
-      this.reset()
-      const id = row.id || this.ids
-      getSampleInfo(id).then(response => {
-        this.form = response.data
-        this.open = true
-        this.title = "修改样品管理"
-      })
+      this.reset();
+      const id = row.id || this.ids;
+      getSampleInfo(id).then((response) => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改样品管理";
+      });
     },
     /** 提交按钮 */
     submitForm() {
-      this.$refs["form"].validate(valid => {
+      this.$refs["form"].validate((valid) => {
         if (valid) {
           if (this.form.id != null) {
-            updateSampleInfo(this.form).then(response => {
-              this.$modal.msgSuccess("修改成功")
-              this.open = false
-              this.getList()
-            })
+            updateSampleInfo(this.form).then((response) => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
           } else {
-            addSampleInfo(this.form).then(response => {
-              this.$modal.msgSuccess("新增成功")
-              this.open = false
-              this.getList()
-            })
+            addSampleInfo(this.form).then((response) => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
           }
         }
-      })
+      });
     },
     /** 删除按钮操作 */
     handleDelete(row) {
-      const ids = row.id || this.ids
-      this.$modal.confirm('是否确认删除样品管理编号为"' + ids + '"的数据项?').then(function() {
-        return delSampleInfo(ids)
-      }).then(() => {
-        this.getList()
-        this.$modal.msgSuccess("删除成功")
-      }).catch(() => {})
+      const ids = row.id || this.ids;
+      this.$modal
+        .confirm('是否确认删除样品管理编号为"' + ids + '"的数据项?')
+        .then(function () {
+          return delSampleInfo(ids);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+        .catch(() => {});
     },
     /** 导出按钮操作 */
     handleExport() {
-      this.download('sample/sampleInfo/export', {
-        ...this.queryParams
-      }, `sampleInfo_${new Date().getTime()}.xlsx`)
-    }
-  }
-}
+      this.download(
+        "sample/sampleInfo/export",
+        {
+          ...this.queryParams,
+        },
+        `sampleInfo_${new Date().getTime()}.xlsx`
+      );
+    },
+  },
+};
 </script>

+ 6 - 5
src/views/sample/samplePatient/index.vue

@@ -17,7 +17,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="出生年份(换算年龄)" prop="birth">
+      <!-- <el-form-item label="出生年份(换算年龄)" prop="birth">
         <el-input
           v-model="queryParams.birth"
           placeholder="请输入出生年份(换算年龄)"
@@ -522,7 +522,7 @@
           clearable
           @keyup.enter.native="handleQuery"
         />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -648,7 +648,7 @@
       <el-table-column label="死亡距发病时间" align="center" prop="returnLg90death" />
       <el-table-column label="目前存活" align="center" prop="returnLive" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center"  fixed="right" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -667,7 +667,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
       v-show="total>0"
       :total="total"
@@ -686,7 +686,8 @@
           <el-input v-model="form.name" placeholder="请输入姓名" />
         </el-form-item>
         <el-form-item label="出生年份(换算年龄)" prop="birth">
-          <el-input v-model="form.birth" placeholder="请输入出生年份(换算年龄)" />
+          <!-- <el-input v-model="form.birth" placeholder="请输入出生年份(换算年龄)" /> -->
+          <el-date-picker type="date" placeholder="请选择出生年份(换算年龄)" v-model="form.birth" style="width: 100%;"></el-date-picker>
         </el-form-item>
         <el-form-item label="性别" prop="sex">
           <el-select v-model="form.sex" placeholder="请选择性别">

+ 214 - 0
src/views/statistics/sample-statistics/index.vue

@@ -0,0 +1,214 @@
+<template>
+  <div class="sample-statistics">
+    <!-- Top: Statistics & Time Filter -->
+    <el-row :gutter="20" class="top-bar">
+      <el-col :span="12">
+        <div class="stat-box">
+          <div class="stat-title">样本统计</div>
+          <!-- <div class="stat-value">{{ totalSamples }}</div> -->
+        </div>
+      </el-col>
+      <el-col :span="12" class="filter-col">
+        <el-select v-model="selectedRange" placeholder="选择时间范围" @change="onRangeChange" size="small">
+          <el-option label="24小时" value="24h"></el-option>
+          <el-option label="三天" value="3d"></el-option>
+          <el-option label="五天" value="5d"></el-option>
+          <el-option label="七天" value="7d"></el-option>
+        </el-select>
+      </el-col>
+    </el-row>
+
+    <!-- Middle: Line Chart -->
+    <div class="chart-section">
+      <div ref="lineChart" class="line-chart"></div>
+    </div>
+
+    <!-- Bottom: Pie Charts -->
+    <el-row :gutter="20" class="pie-row">
+      <el-col :span="12">
+        <div class="pie-title">样本类型占比</div>
+        <div ref="typePieChart" class="pie-chart"></div>
+      </el-col>
+      <el-col :span="12">
+        <div class="pie-title">检出物占比</div>
+        <div ref="detectedPieChart" class="pie-chart"></div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+export default {
+  name: 'SampleStatistics',
+  data() {
+    return {
+      selectedRange: '24h',
+      totalSamples: 1234,
+      lineChart: null,
+      typePieChart: null,
+      detectedPieChart: null,
+      lineData: [],
+      typePieData: [],
+      detectedPieData: [],
+    }
+  },
+  mounted() {
+    this.initCharts()
+    this.fetchData()
+  },
+  methods: {
+    onRangeChange() {
+      this.fetchData()
+    },
+    fetchData() {
+      // 模拟数据,根据selectedRange更新
+      const now = new Date()
+      let days = 1
+      if (this.selectedRange === '3d') days = 3
+      if (this.selectedRange === '5d') days = 5
+      if (this.selectedRange === '7d') days = 7
+
+      // 生成日期
+      const xData = []
+      const analysisData = []
+      const adoptionData = []
+      for (let i = days - 1; i >= 0; i--) {
+        const d = new Date(now)
+        d.setDate(now.getDate() - i)
+        xData.push(`${d.getMonth() + 1}-${d.getDate()}`)
+        analysisData.push(Math.floor(Math.random() * 100 + 100))
+        adoptionData.push(Math.floor(Math.random() * 80 + 50))
+      }
+      this.lineData = { xData, analysisData, adoptionData }
+
+      // 饼图数据
+      this.typePieData = [
+        { value: 335, name: '血液' },
+        { value: 310, name: '尿液' },
+        { value: 234, name: '唾液' },
+        { value: 135, name: '其他' }
+      ]
+      this.detectedPieData = [
+        { value: 400, name: '物质A' },
+        { value: 335, name: '物质B' },
+        { value: 310, name: '物质C' },
+        { value: 234, name: '其他' }
+      ]
+      this.totalSamples = analysisData.reduce((a, b) => a + b, 0)
+      this.updateCharts()
+    },
+    initCharts() {
+      this.lineChart = echarts.init(this.$refs.lineChart)
+      this.typePieChart = echarts.init(this.$refs.typePieChart)
+      this.detectedPieChart = echarts.init(this.$refs.detectedPieChart)
+    },
+    updateCharts() {
+      // 折线图
+      this.lineChart.setOption({
+        tooltip: { trigger: 'axis' },
+        legend: { data: ['数据分析量', '收养量'] },
+        xAxis: { type: 'category', data: this.lineData.xData },
+        yAxis: { type: 'value', name: '数量' },
+        series: [
+          {
+            name: '数据分析量',
+            type: 'line',
+            smooth: true,
+            data: this.lineData.analysisData
+          },
+          {
+            name: '收养量',
+            type: 'line',
+            smooth: true,
+            data: this.lineData.adoptionData
+          }
+        ]
+      })
+      // 样本类型饼图
+      this.typePieChart.setOption({
+        tooltip: { trigger: 'item' },
+        legend: { bottom: 0 },
+        series: [
+          {
+            name: '样本类型',
+            type: 'pie',
+            radius: '60%',
+            data: this.typePieData,
+            emphasis: {
+              itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' }
+            }
+          }
+        ]
+      })
+      // 检出物饼图
+      this.detectedPieChart.setOption({
+        tooltip: { trigger: 'item' },
+        legend: { bottom: 0 },
+        series: [
+          {
+            name: '检出物',
+            type: 'pie',
+            radius: '60%',
+            data: this.detectedPieData,
+            emphasis: {
+              itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' }
+            }
+          }
+        ]
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.sample-statistics {
+  padding: 24px;
+  background: #fff;
+}
+.top-bar {
+  margin-bottom: 24px;
+  align-items: center;
+}
+.stat-box {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  height: 60px;
+}
+.stat-title {
+  font-size: 16px;
+  color: #888;
+}
+.stat-value {
+  font-size: 28px;
+  font-weight: bold;
+  color: #409EFF;
+}
+.filter-col {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+}
+.chart-section {
+  margin-bottom: 24px;
+}
+.line-chart {
+  width: 100%;
+  height: 320px;
+}
+.pie-row {
+  margin-top: 12px;
+}
+.pie-chart {
+  width: 100%;
+  height: 260px;
+}
+.pie-title {
+  text-align: center;
+  font-size: 16px;
+  margin-bottom: 8px;
+  color: #333;
+}
+</style>

+ 22 - 8
src/views/system/role/index.vue

@@ -10,7 +10,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      
+
       <el-form-item label="状态" prop="status">
         <el-select
           v-model="queryParams.status"
@@ -167,14 +167,13 @@
         <el-form-item label="菜单权限">
           <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
           <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
-          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
+          <!-- <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox> -->
           <el-tree
             class="tree-border"
             :data="menuOptions"
             show-checkbox
             ref="menu"
             node-key="id"
-            :check-strictly="!form.menuCheckStrictly"
             empty-text="加载中,请稍候"
             :props="defaultProps"
           ></el-tree>
@@ -195,7 +194,7 @@
         <el-form-item label="角色名称">
           <el-input v-model="form.roleName" :disabled="true" />
         </el-form-item>
-        
+
         <el-form-item label="权限范围">
           <el-select v-model="form.dataScope" @change="dataScopeSelectChange">
             <el-option
@@ -209,7 +208,7 @@
         <el-form-item label="数据权限" v-show="form.dataScope == 2">
           <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
           <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
-          <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
+          <!-- <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox> -->
           <el-tree
             class="tree-border"
             :data="deptOptions"
@@ -217,7 +216,6 @@
             default-expand-all
             ref="dept"
             node-key="id"
-            :check-strictly="!form.deptCheckStrictly"
             empty-text="加载中,请稍候"
             :props="defaultProps"
           ></el-tree>
@@ -463,7 +461,23 @@ export default {
       if (type == 'menu') {
         this.$refs.menu.setCheckedNodes(value ? this.menuOptions: [])
       } else if (type == 'dept') {
-        this.$refs.dept.setCheckedNodes(value ? this.deptOptions: [])
+        console.log(this.getAllCheckedNode(this.deptOptions),'deptOptions')
+        let allChecked = this.getAllCheckedNode(this.deptOptions)
+        this.$refs.dept.setCheckedKeys(value ? allChecked : [])
+
+        }
+
+    },
+    getAllCheckedNode(arr) {
+      let checkedList = []
+      if(arr.length) {
+        arr.forEach(item => {
+          checkedList.push(item.id)
+          if (item.children && item.children.length) {
+            checkedList = checkedList.concat(this.getAllCheckedNode(item.children))
+          }
+        })
+        return checkedList
       }
     },
     // 树权限(父子联动)
@@ -579,4 +593,4 @@ export default {
     }
   }
 }
-</script>
+</script>

+ 1 - 1
vue.config.js

@@ -10,7 +10,7 @@ const CompressionPlugin = require('compression-webpack-plugin')
 const name = process.env.VUE_APP_TITLE || '传染病溯源预测系统' // 网页标题
 
 // const baseUrl = '/' // 后端接口
-const baseUrl = 'http://localhost:8081' // 后端接口
+const baseUrl = 'http://173.18.12.205:8081/' // 后端接口
 
 const port = process.env.port || process.env.npm_config_port || 80 // 端口