Преглед изворни кода

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_adminUI

ct пре 1 месец
родитељ
комит
d7c5924a86

+ 7 - 7
src/api/hisStore/shippingTemplates.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询运费模板列表
 export function listShippingTemplates(query) {
   return request({
-    url: '/store/store/shippingTemplates/list',
+    url: '/store/shippingTemplates/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listShippingTemplates(query) {
 // 查询运费模板详细
 export function getShippingTemplates(shippingId) {
   return request({
-    url: '/store/store/shippingTemplates/' + shippingId,
+    url: '/store/shippingTemplates/' + shippingId,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getShippingTemplates(shippingId) {
 // 新增运费模板
 export function addShippingTemplates(data) {
   return request({
-    url: '/store/store/shippingTemplates',
+    url: '/store/shippingTemplates',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addShippingTemplates(data) {
 // 修改运费模板
 export function updateShippingTemplates(data) {
   return request({
-    url: '/store/store/shippingTemplates',
+    url: '/store/shippingTemplates',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateShippingTemplates(data) {
 // 删除运费模板
 export function delShippingTemplates(shippingId) {
   return request({
-    url: '/store/store/shippingTemplates/' + shippingId,
+    url: '/store/shippingTemplates/' + shippingId,
     method: 'delete'
   })
 }
@@ -46,14 +46,14 @@ export function delShippingTemplates(shippingId) {
 // 导出运费模板
 export function exportShippingTemplates(query) {
   return request({
-    url: '/store/store/shippingTemplates/export',
+    url: '/store/shippingTemplates/export',
     method: 'get',
     params: query
   })
 }
 export function getAllShippingTemplates() {
   return request({
-    url: '/store/store/shippingTemplates/getAllList',
+    url: '/store/shippingTemplates/getAllList',
     method: 'get'
   })
 }

+ 11 - 11
src/api/hisStore/storeProduct.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询商品列表
 export function listStoreProduct(query) {
   return request({
-    url: '/store/store/storeProduct/list',
+    url: '/store/storeProduct/list',
     method: 'get',
     params: query
   })
@@ -11,7 +11,7 @@ export function listStoreProduct(query) {
 
 export function batchModify(param) {
   return request({
-    url: '/store/store/storeProduct/batchModify',
+    url: '/store/storeProduct/batchModify',
     method: 'post',
     data: param
   })
@@ -20,7 +20,7 @@ export function batchModify(param) {
 // 查询商品详细
 export function getStoreProduct(productId) {
   return request({
-    url: '/store/store/storeProduct/' + productId,
+    url: '/store/storeProduct/' + productId,
     method: 'get'
   })
 }
@@ -28,7 +28,7 @@ export function getStoreProduct(productId) {
 
 export function addOrEdit(data) {
   return request({
-    url: '/store/store/storeProduct/addOrEdit',
+    url: '/store/storeProduct/addOrEdit',
     method: 'post',
     data: data
   })
@@ -36,7 +36,7 @@ export function addOrEdit(data) {
 
 export function importTemplate() {
   return request({
-    url: '/store/store/storeProduct/importTemplate',
+    url: '/store/storeProduct/importTemplate',
     method: 'get'
   })
 }
@@ -45,7 +45,7 @@ export function importTemplate() {
 // 删除商品
 export function delStoreProduct(productId) {
   return request({
-    url: '/store/store/storeProduct/' + productId,
+    url: '/store/storeProduct/' + productId,
     method: 'delete'
   })
 }
@@ -53,7 +53,7 @@ export function delStoreProduct(productId) {
 // 导出商品
 export function exportStoreProduct(query) {
   return request({
-    url: '/store/store/storeProduct/export',
+    url: '/store/storeProduct/export',
     method: 'get',
     params: query
   })
@@ -61,7 +61,7 @@ export function exportStoreProduct(query) {
 
 export function genFormatAttr(productId,json) {
   return request({
-    url: '/store/store/storeProduct/genFormatAttr/'+productId,
+    url: '/store/storeProduct/genFormatAttr/'+productId,
     method: 'post',
     data: json
   })
@@ -70,7 +70,7 @@ export function genFormatAttr(productId,json) {
 
 export function getStoreProductAttrValueList(query) {
   return request({
-    url: '/store/store/storeProduct/getStoreProductAttrValueList',
+    url: '/store/storeProduct/getStoreProductAttrValueList',
     method: 'get',
     params: query
   })
@@ -79,7 +79,7 @@ export function getStoreProductAttrValueList(query) {
 
 export function getStoreTuiProductAttrValueList(query) {
   return request({
-    url: '/store/store/storeProduct/getStoreTuiProductAttrValueList',
+    url: '/store/storeProduct/getStoreTuiProductAttrValueList',
     method: 'get',
     params: query
   })
@@ -87,7 +87,7 @@ export function getStoreTuiProductAttrValueList(query) {
 
 export function productBySearCh(query) {
   return request({
-    url: '/store/store/storeProduct/listBySearch',
+    url: '/store/storeProduct/listBySearch',
     method: 'get',
     params: query
   })

+ 7 - 7
src/api/hisStore/storeProductCategory.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询商品分类列表
 export function listStoreProductCategory(query) {
   return request({
-    url: '/store/store/storeProductCategory/list',
+    url: '/store/storeProductCategory/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreProductCategory(query) {
 // 查询商品分类详细
 export function getStoreProductCategory(cateId) {
   return request({
-    url: '/store/store/storeProductCategory/' + cateId,
+    url: '/store/storeProductCategory/' + cateId,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getStoreProductCategory(cateId) {
 // 新增商品分类
 export function addStoreProductCategory(data) {
   return request({
-    url: '/store/store/storeProductCategory',
+    url: '/store/storeProductCategory',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addStoreProductCategory(data) {
 // 修改商品分类
 export function updateStoreProductCategory(data) {
   return request({
-    url: '/store/store/storeProductCategory',
+    url: '/store/storeProductCategory',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateStoreProductCategory(data) {
 // 删除商品分类
 export function delStoreProductCategory(cateId) {
   return request({
-    url: '/store/store/storeProductCategory/' + cateId,
+    url: '/store/storeProductCategory/' + cateId,
     method: 'delete'
   })
 }
@@ -46,14 +46,14 @@ export function delStoreProductCategory(cateId) {
 // 导出商品分类
 export function exportStoreProductCategory(query) {
   return request({
-    url: '/store/store/storeProductCategory/export',
+    url: '/store/storeProductCategory/export',
     method: 'get',
     params: query
   })
 }
 export function getAllStoreProductCategory() {
   return request({
-    url: '/store/store/storeProductCategory/getAllList' ,
+    url: '/store/storeProductCategory/getAllList' ,
     method: 'get'
   })
 }

+ 7 - 7
src/api/hisStore/storeProductRule.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询商品规则值(规格)列表
 export function listStoreProductRule(query) {
   return request({
-    url: '/store/store/storeProductRule/list',
+    url: '/store/storeProductRule/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listStoreProductRule(query) {
 // 查询商品规则值(规格)详细
 export function getStoreProductRule(id) {
   return request({
-    url: '/store/store/storeProductRule/' + id,
+    url: '/store/storeProductRule/' + id,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getStoreProductRule(id) {
 // 新增商品规则值(规格)
 export function addStoreProductRule(data) {
   return request({
-    url: '/store/store/storeProductRule',
+    url: '/store/storeProductRule',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addStoreProductRule(data) {
 // 修改商品规则值(规格)
 export function updateStoreProductRule(data) {
   return request({
-    url: '/store/store/storeProductRule',
+    url: '/store/storeProductRule',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateStoreProductRule(data) {
 // 删除商品规则值(规格)
 export function delStoreProductRule(id) {
   return request({
-    url: '/store/store/storeProductRule/' + id,
+    url: '/store/storeProductRule/' + id,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delStoreProductRule(id) {
 // 导出商品规则值(规格)
 export function exportStoreProductRule(query) {
   return request({
-    url: '/store/store/storeProductRule/export',
+    url: '/store/storeProductRule/export',
     method: 'get',
     params: query
   })
@@ -55,7 +55,7 @@ export function exportStoreProductRule(query) {
 
 export function getAllStoreProductRule() {
   return request({
-    url: '/store/store/storeProductRule/getAllList',
+    url: '/store/storeProductRule/getAllList',
     method: 'get'
   })
 }

+ 61 - 0
src/api/medical/indicator.js

@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+// 查询医疗指标分页列表
+export function listIndicator(query) {
+  return request({
+    url: '/admin/medical/indicator/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询所有启用的指标
+export function listAllEnabled() {
+  return request({
+    url: '/admin/medical/indicator/listEnabled',
+    method: 'get'
+  })
+}
+
+// 根据分类查询指标
+export function listByCategory(category) {
+  return request({
+    url: '/admin/medical/indicator/listByCategory',
+    method: 'get',
+    params: { category }
+  })
+}
+
+// 查询医疗指标详细
+export function getIndicator(indicatorId) {
+  return request({
+    url: '/admin/medical/indicator/' + indicatorId,
+    method: 'get'
+  })
+}
+
+// 新增医疗指标
+export function addIndicator(data) {
+  return request({
+    url: '/admin/medical/indicator/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改医疗指标
+export function updateIndicator(data) {
+  return request({
+    url: '/admin/medical/indicator/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除医疗指标
+export function delIndicator(indicatorId) {
+  return request({
+    url: '/admin/medical/indicator/' + indicatorId,
+    method: 'delete'
+  })
+}

+ 64 - 0
src/api/medical/report.js

@@ -0,0 +1,64 @@
+import request from '@/utils/request'
+
+// 查询体检报告分页列表
+export function listReport(query) {
+  return request({
+    url: '/admin/medical/report/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询体检报告详细
+export function getReport(reportId) {
+  return request({
+    url: '/admin/medical/report/' + reportId,
+    method: 'get'
+  })
+}
+
+// 根据用户ID查询体检报告列表
+export function listReportByUser(userId) {
+  return request({
+    url: '/admin/medical/report/listByUser/' + userId,
+    method: 'get'
+  })
+}
+
+// 根据用户ID和体检日期查询体检报告
+export function getReportByUserAndDate(userId, examDate) {
+  return request({
+    url: '/admin/medical/report/getByUserAndDate',
+    method: 'get',
+    params: {
+      userId: userId,
+      examDate: examDate
+    }
+  })
+}
+
+// 新增体检报告
+export function addReport(data) {
+  return request({
+    url: '/admin/medical/report/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改体检报告
+export function updateReport(data) {
+  return request({
+    url: '/admin/medical/report/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除体检报告
+export function delReport(reportId) {
+  return request({
+    url: '/admin/medical/report/' + reportId,
+    method: 'delete'
+  })
+}

+ 69 - 0
src/api/medical/reportIndicator.js

@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 查询报告指标检查结果列表
+export function listResult(query) {
+  return request({
+    url: '/admin/medical/result/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询报告指标检查结果详细
+export function getResult(resultId) {
+  return request({
+    url: '/admin/medical/result/' + resultId,
+    method: 'get'
+  })
+}
+
+// 根据报告ID查询所有指标结果
+export function listByReportId(reportId) {
+  return request({
+    url: '/admin/medical/result/listByReport/' + reportId,
+    method: 'get'
+  })
+}
+
+// 根据指标ID查询所有结果
+export function listByIndicatorId(indicatorId) {
+  return request({
+    url: '/admin/medical/result/listByIndicator/' + indicatorId,
+    method: 'get'
+  })
+}
+
+// 新增报告指标检查结果
+export function addResult(data) {
+  return request({
+    url: '/admin/medical/result/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 批量新增报告指标检查结果
+export function batchAddResult(data) {
+  return request({
+    url: '/admin/medical/result/batchAdd',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改报告指标检查结果
+export function updateResult(data) {
+  return request({
+    url: '/admin/medical/result/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除报告指标检查结果
+export function delResult(resultId) {
+  return request({
+    url: '/admin/medical/result/' + resultId,
+    method: 'delete'
+  })
+}

+ 61 - 0
src/api/medical/unit.js

@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+// 查询所有计量单位
+export function listAllUnit() {
+  return request({
+    url: '/admin/medical/unit/listAll',
+    method: 'get'
+  })
+}
+
+// 分页查询计量单位列表
+export function listUnit(query) {
+  return request({
+    url: '/admin/medical/unit/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 根据单位类型查询计量单位
+export function listUnitByType(unitType) {
+  return request({
+    url: '/admin/medical/unit/listByType',
+    method: 'get',
+    params: { unitType }
+  })
+}
+
+// 查询计量单位详细
+export function getUnit(unitId) {
+  return request({
+    url: '/admin/medical/unit/' + unitId,
+    method: 'get'
+  })
+}
+
+// 新增计量单位
+export function addUnit(data) {
+  return request({
+    url: '/admin/medical/unit/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改计量单位
+export function updateUnit(data) {
+  return request({
+    url: '/admin/medical/unit/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除计量单位
+export function delUnit(unitId) {
+  return request({
+    url: '/admin/medical/unit/' + unitId,
+    method: 'delete'
+  })
+}

+ 3 - 3
src/views/course/coursePlaySourceConfig/index.vue

@@ -338,7 +338,7 @@ export default {
     handleAdd() {
       this.reset()
       this.open = true
-      this.title = "添加点播配置"
+      this.title = "添加小程序配置"
     },
     handleUpdate(row) {
       this.reset()
@@ -349,12 +349,12 @@ export default {
           type: response.data.type.toString()
         }
         this.open = true
-        this.title = "修改点播配置"
+        this.title = "修改小程序配置"
       })
     },
     handleDelete(row) {
       const id = row.id || this.ids
-      this.$confirm('是否确认删除点播配置编号为"' + id + '"的数据项?', "警告", {
+      this.$confirm('是否确认删除小程序配置编号为"' + id + '"的数据项?', "警告", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning"

+ 22 - 1
src/views/his/company/index.vue

@@ -282,7 +282,22 @@
 <!--                              end: '24:00'-->
 <!--                            }"></el-time-select>-->
 <!--      </el-form-item>-->
-        <el-form-item label="服务号点播配置" prop="courseMaAppId">
+      <el-form-item label="自定义小程序" prop="customMiniAppId">
+        <el-select
+          v-model="form.customMiniAppId"
+          placeholder="请选择自定义小程序"
+          clearable
+          size="small"
+        >
+          <el-option
+            v-for="item in customAppList"
+            :key="item.appId"
+            :label="item.appName"
+            :value="item.appId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="服务号点播配置" prop="courseMaAppId">
           <el-select
             v-model="form.courseMaAppId"
             placeholder="请选择服务号"
@@ -469,6 +484,7 @@ export default {
       // 表单参数
       form: {
         restartTime: '13:10',
+        customMiniAppId:null,
         courseMaAppId: null,
         courseMiniAppId: null,
         miniAppMaster: [],
@@ -542,6 +558,7 @@ export default {
      },
       maAppList: [],
       miniAppList: [],
+      customAppList: [],
     };
   },
   created() {
@@ -733,6 +750,7 @@ export default {
     getAppList() {
       this.maAppList = []
       this.miniAppList = []
+      this.customAppList = []
       const key = "courseMa.config"
       getConfigByKey(key).then(response => {
         const {code,data} = response
@@ -746,6 +764,9 @@ export default {
             this.miniAppList = appList.filter(v => v.type === '1').map(v => {
               return { appId: v.appid, appName: v.name }
             })
+            this.customAppList = appList.filter(v => v.type === '3').map(v => {
+              return { appId: v.appid, appName: v.name }
+            })
           }
         }
       })

+ 6 - 6
src/views/hisStore/storeProduct/index.vue

@@ -5,8 +5,8 @@
       <el-form-item label="商品分类" prop="cateId">
          <treeselect  v-model="queryParams.cateId"  style="width:205.4px" :options="categoryOptions" :normalizer="normalizer" placeholder="请选择分类" />
       </el-form-item>
-      
-      <el-form-item label="所属店铺" prop="storeId" >
+
+<!--      <el-form-item label="所属店铺" prop="storeId" >
        <el-select v-model="queryParams.storeId"  placeholder="所属店铺" clearable size="small" filterable>
           <el-option
             v-for="dict in storeOptions"
@@ -15,7 +15,7 @@
             :value="dict.storeId"
           />
         </el-select>
-      </el-form-item>
+      </el-form-item>-->
       <el-form-item label="商品名称" prop="productName">
         <el-input
           v-model="queryParams.productName"
@@ -380,7 +380,7 @@
                     <single-img v-model="scope.row.image" type="image" :num="1" :width="60" :height="60" />
                   </template>
                 </el-table-column>
-                
+
                 <el-table-column prop="storeId" label="所属店铺" align="center" width="120">
                   <template slot-scope="scope">
                     <el-tag prop="storeId" v-for="(item, index) in storeOptions"    v-if="scope.row.storeId==item.storeId">{{item.storeName}}</el-tag>
@@ -954,7 +954,7 @@ export default {
     });
     this.getTreeselect();
     this.getList();
-    this.getStoreList();
+    // this.getStoreList();
   },
   methods: {
     cancel1(){
@@ -1504,7 +1504,7 @@ export default {
         } else {
           this.form.isShowDetails = null
         }
-        
+
         if(this.form.tuiCateId!=null){
           this.form.tuiCateId = response.data.tuiCateId.toString();
         }

+ 328 - 0
src/views/medical/indicator/index.vue

@@ -0,0 +1,328 @@
+<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="指标名称" prop="indicatorName">
+        <el-input
+          v-model="queryParams.indicatorName"
+          placeholder="请输入指标名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="分类" prop="category">
+        <el-select v-model="queryParams.category" placeholder="请选择分类" clearable>
+          <el-option
+            v-for="dict in categoryOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </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-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['medical:indicator:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['medical:indicator:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['medical:indicator:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="indicatorList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="指标ID" align="center" prop="indicatorId" />
+      <el-table-column label="指标名称" align="center" prop="indicatorName" />
+      <el-table-column label="指标代码" align="center" prop="indicatorCode" />
+      <el-table-column label="分类" align="center" prop="category">
+        <template slot-scope="scope">
+          <dict-tag :options="categoryOptions" :value="scope.row.category"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="单位" align="center" prop="unit" />
+      <el-table-column label="正常范围" align="center" prop="normalRange" />
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['medical:indicator:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['medical:indicator:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改医疗指标对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="指标名称" prop="indicatorName">
+          <el-input v-model="form.indicatorName" placeholder="请输入指标名称" />
+        </el-form-item>
+        <el-form-item label="指标代码" prop="indicatorCode">
+          <el-input v-model="form.indicatorCode" placeholder="请输入指标代码" />
+        </el-form-item>
+        <el-form-item label="分类" prop="category">
+          <el-select v-model="form.category" placeholder="请选择分类">
+            <el-option
+              v-for="dict in categoryOptions"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="单位" prop="unit">
+          <el-input v-model="form.unit" placeholder="请输入单位" />
+        </el-form-item>
+        <el-form-item label="正常范围" prop="normalRange">
+          <el-input v-model="form.normalRange" placeholder="请输入正常范围" />
+        </el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input v-model="form.description" type="textarea" placeholder="请输入描述" />
+        </el-form-item>
+        <el-form-item label="状态" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in statusOptions"
+              :key="dict.value"
+              :label="dict.value"
+            >{{dict.label}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listIndicator, getIndicator, delIndicator, addIndicator, updateIndicator } from "@/api/medical/indicator";
+
+export default {
+  name: "Indicator",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 医疗指标表格数据
+      indicatorList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 分类字典
+      categoryOptions: [],
+      // 状态字典
+      statusOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        indicatorName: null,
+        category: null,
+        status: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        indicatorName: [
+          { required: true, message: "指标名称不能为空", trigger: "blur" }
+        ],
+        indicatorCode: [
+          { required: true, message: "指标代码不能为空", trigger: "blur" }
+        ],
+        category: [
+          { required: true, message: "分类不能为空", trigger: "change" }
+        ],
+        status: [
+          { required: true, message: "状态不能为空", trigger: "change" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getDicts("indicator_category").then(response => {
+      this.categoryOptions = response.data;
+    });
+    this.getDicts("indicator_status").then(response => {
+      this.statusOptions = response.data;
+    });
+  },
+  methods: {
+    /** 查询医疗指标列表 */
+    getList() {
+      this.loading = true;
+      listIndicator(this.queryParams).then(response => {
+        this.indicatorList = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        indicatorId: null,
+        indicatorName: null,
+        indicatorCode: null,
+        category: null,
+        unit: null,
+        normalRange: null,
+        description: null,
+        status: "1"
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.indicatorId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加医疗指标";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const indicatorId = row.indicatorId || this.ids
+      getIndicator(indicatorId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改医疗指标";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.indicatorId != null) {
+            updateIndicator(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addIndicator(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const indicatorIds = row.indicatorId || this.ids;
+      this.$confirm('是否确认删除医疗指标编号为"' + indicatorIds + '"的数据项?').then(function() {
+        return delIndicator(indicatorIds);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    }
+  }
+};
+</script>

+ 845 - 0
src/views/medical/report/index.vue

@@ -0,0 +1,845 @@
+<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="用户ID" prop="userId">
+        <el-input
+          v-model="queryParams.userId"
+          placeholder="请输入用户ID"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="体检日期" prop="examDate">
+        <el-date-picker clearable
+                        v-model="queryParams.examDate"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="请选择体检日期">
+        </el-date-picker>
+      </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-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['medical:report:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['medical:report:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['medical:report:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="reportList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="报告ID" align="center" prop="reportId" />
+      <el-table-column label="用户" align="center" prop="userName" />
+      <el-table-column label="销售" align="center" prop="companyUserName" />
+      <el-table-column label="体检日期" align="center" prop="examDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.examDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="身高(cm)" align="center" prop="height" />
+      <el-table-column label="体重(kg)" align="center" prop="weight" />
+      <el-table-column label="BMI" align="center" prop="bmi" />
+      <el-table-column label="血压" align="center" prop="bloodPressure" />
+      <el-table-column label="心率" align="center" prop="heartRate" />
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['medical:report:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['medical:report:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改体检报告对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
+      <el-tabs v-model="activeTab">
+        <el-tab-pane label="身体信息" name="bodyInfo">
+          <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="用户ID" prop="userId">
+                  <el-input v-model="form.userId" placeholder="请输入用户ID" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="用户名" prop="userName">
+                  <el-input v-model="form.userName" placeholder="请输入用户名" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="销售ID" prop="companyUserId">
+                  <el-input v-model="form.companyUserId" placeholder="请输入销售ID" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="销售名称" prop="companyUserName">
+                  <el-input v-model="form.companyUserName" placeholder="请输入销售名称" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="体检日期" prop="examDate">
+                  <el-date-picker clearable
+                                  v-model="form.examDate"
+                                  type="date"
+                                  value-format="yyyy-MM-dd"
+                                  placeholder="请选择体检日期">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="身高(cm)" prop="height">
+                  <el-input v-model="form.height" placeholder="请输入身高" @input="calculateBMI" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="体重(kg)" prop="weight">
+                  <el-input v-model="form.weight" placeholder="请输入体重" @input="calculateBMI" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="BMI指数" prop="bmi">
+                  <el-input v-model="form.bmi" placeholder="BMI自动计算" disabled />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="腰围(cm)" prop="waistCircumference">
+                  <el-input v-model="form.waistCircumference" placeholder="请输入腰围" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="胸围(cm)" prop="chestCircumference">
+                  <el-input v-model="form.chestCircumference" placeholder="请输入胸围" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="血压" prop="bloodPressure">
+                  <el-input v-model="form.bloodPressure" placeholder="请输入血压" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="心率" prop="heartRate">
+                  <el-input v-model="form.heartRate" placeholder="请输入心率" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-tab-pane>
+
+        <el-tab-pane label="指标检查" name="indicators">
+          <div class="indicator-toolbar" style="margin-bottom: 15px;">
+            <el-input
+              placeholder="搜索指标"
+              v-model="indicatorSearch"
+              style="width: 200px; margin-right: 10px;"
+              class="filter-item"
+              @keyup.enter.native="searchIndicators"
+            >
+              <el-button slot="append" icon="el-icon-search" @click="searchIndicators"></el-button>
+            </el-input>
+            <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddIndicator">添加指标</el-button>
+          </div>
+          <el-table :data="indicatorList" style="width: 100%">
+            <el-table-column prop="indicatorName" label="指标名称" />
+            <el-table-column prop="testValue" label="检测值" />
+            <el-table-column prop="refRange" label="参考范围" />
+            <el-table-column label="结果评价" align="center">
+              <template slot-scope="scope">
+                <el-tag v-if="scope.row.isAbnormal === 0" type="success">正常</el-tag>
+                <el-tag v-else-if="scope.row.abnormalType === '偏高'" type="danger">偏高</el-tag>
+                <el-tag v-else-if="scope.row.abnormalType === '偏低'" type="warning">偏低</el-tag>
+                <el-tag v-else-if="scope.row.isAbnormal === 1" type="danger">异常</el-tag>
+                <span v-else>-</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="150">
+              <template slot-scope="scope">
+                <el-button type="text" size="small" @click="viewIndicatorDetail(scope.row)">查看详情</el-button>
+                <el-button type="text" size="small" @click="editIndicator(scope.row)">编辑</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+
+        <el-tab-pane label="查体" name="examination">
+          <el-form :model="form" label-width="120px">
+            <el-form-item label="一般情况" prop="generalCondition">
+              <el-input v-model="form.generalCondition" type="textarea" rows="2" placeholder="请输入一般情况"></el-input>
+            </el-form-item>
+            <el-form-item label="皮肤粘膜" prop="skinAndMucosa">
+              <el-input v-model="form.skinAndMucosa" type="textarea" rows="2" placeholder="请输入皮肤粘膜情况"></el-input>
+            </el-form-item>
+            <el-form-item label="淋巴结" prop="lymphNodes">
+              <el-input v-model="form.lymphNodes" type="textarea" rows="2" placeholder="请输入淋巴结情况"></el-input>
+            </el-form-item>
+            <el-form-item label="头颈" prop="head">
+              <el-input v-model="form.head" type="textarea" rows="2" placeholder="请输入头颈检查情况"></el-input>
+            </el-form-item>
+            <el-form-item label="颈部" prop="neck">
+              <el-input v-model="form.neck" type="textarea" rows="2" placeholder="请输入颈部情况"></el-input>
+            </el-form-item>
+            <el-form-item label="胸部" prop="chest">
+              <el-input v-model="form.chest" type="textarea" rows="2" placeholder="请输入胸部情况"></el-input>
+            </el-form-item>
+            <el-form-item label="心脏" prop="heart">
+              <el-input v-model="form.heart" type="textarea" rows="2" placeholder="请输入心脏情况"></el-input>
+            </el-form-item>
+            <el-form-item label="肺部" prop="lungs">
+              <el-input v-model="form.lungs" type="textarea" rows="2" placeholder="请输入肺部情况"></el-input>
+            </el-form-item>
+            <el-form-item label="腹部" prop="abdomen">
+              <el-input v-model="form.abdomen" type="textarea" rows="2" placeholder="请输入腹部情况"></el-input>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+
+        <el-tab-pane label="肝脏功能" name="liverFunction">
+          <el-table :data="liverFunctionList" style="width: 100%">
+            <el-table-column prop="indicatorName" label="检测项目" />
+            <el-table-column prop="testValue" label="检测值" />
+            <el-table-column prop="refRange" label="参考范围" />
+            <el-table-column label="结果评价" align="center">
+              <template slot-scope="scope">
+                <el-tag v-if="scope.row.isAbnormal === 0" type="success">正常</el-tag>
+                <el-tag v-else-if="scope.row.abnormalType === '偏高'" type="danger">偏高</el-tag>
+                <el-tag v-else-if="scope.row.abnormalType === '偏低'" type="warning">偏低</el-tag>
+                <el-tag v-else-if="scope.row.isAbnormal === 1" type="danger">异常</el-tag>
+                <span v-else>-</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="100">
+              <template slot-scope="scope">
+                <el-button type="text" size="small" @click="editIndicator(scope.row)">编辑</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 指标详情对话框 -->
+    <el-dialog title="指标详情" :visible.sync="indicatorDetailVisible" width="600px" append-to-body>
+      <el-descriptions :column="1" border>
+        <el-descriptions-item label="指标名称">{{ currentIndicator.indicatorName }}</el-descriptions-item>
+        <el-descriptions-item label="检测值">{{ currentIndicator.testValue || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="参考范围">{{ currentIndicator.refRange }}</el-descriptions-item>
+        <el-descriptions-item label="结果评价">
+          <el-tag v-if="currentIndicator.isAbnormal === 0" type="success">正常</el-tag>
+          <el-tag v-else-if="currentIndicator.abnormalType === '偏高'" type="danger">偏高</el-tag>
+          <el-tag v-else-if="currentIndicator.abnormalType === '偏低'" type="warning">偏低</el-tag>
+          <el-tag v-else-if="currentIndicator.isAbnormal === 1" type="danger">异常</el-tag>
+          <span v-else>-</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="备注说明">{{ currentIndicator.remarks || '-' }}</el-descriptions-item>
+      </el-descriptions>
+    </el-dialog>
+
+    <!-- 添加指标对话框 -->
+    <el-dialog title="添加指标" :visible.sync="indicatorSelectVisible" width="600px" append-to-body>
+      <div class="search-container" style="margin-bottom: 15px;">
+        <el-input
+          placeholder="搜索指标库"
+          v-model="indicatorLibrarySearch"
+          style="width: 250px; margin-right: 10px;"
+          @keyup.enter.native="searchIndicatorLibrary"
+        >
+          <el-button slot="append" icon="el-icon-search" @click="searchIndicatorLibrary"></el-button>
+        </el-input>
+        <el-select v-model="indicatorCategory" placeholder="选择分类" style="width: 150px;">
+          <el-option
+            v-for="item in indicatorCategoryOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value">
+          </el-option>
+        </el-select>
+      </div>
+
+      <el-table
+        :data="indicatorLibrary"
+        style="width: 100%"
+        height="350px"
+        @selection-change="handleIndicatorSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="indicatorName" label="指标名称" />
+        <el-table-column prop="indicatorCategory" label="分类" />
+        <el-table-column label="参考范围" align="center">
+          <template slot-scope="scope">
+            {{ formatReferenceRange(scope.row) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="description" label="描述" />
+      </el-table>
+
+      <div style="margin-top: 15px;">
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="currentPage"
+          :page-sizes="[10, 20, 50, 100]"
+          :page-size="pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="totalIndicators">
+        </el-pagination>
+      </div>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="addSelectedIndicators">添加所选指标</el-button>
+        <el-button @click="indicatorSelectVisible = false">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 编辑指标结果对话框 -->
+    <el-dialog title="编辑指标结果" :visible.sync="indicatorResultDialogVisible" width="500px" append-to-body>
+      <el-form ref="indicatorResultForm" :model="indicatorResultForm" :rules="indicatorResultRules" label-width="100px">
+        <el-form-item label="指标名称">
+          <span>{{ indicatorResultForm.indicatorName }}</span>
+        </el-form-item>
+        <el-form-item label="参考范围">
+          <span>{{ indicatorResultForm.referenceRange }}</span>
+        </el-form-item>
+        <el-form-item label="检查数值" prop="testValue">
+          <el-input v-model="indicatorResultForm.testValue" placeholder="请输入检查数值" />
+        </el-form-item>
+        <el-form-item label="检查结果" prop="testResult">
+          <el-input v-model="indicatorResultForm.testResult" placeholder="请输入检查结果(文本)" />
+        </el-form-item>
+        <el-form-item label="是否异常">
+          <el-radio-group v-model="indicatorResultForm.isAbnormal">
+            <el-radio :label="0">正常</el-radio>
+            <el-radio :label="1">异常</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="异常类型" v-if="indicatorResultForm.isAbnormal === 1" prop="abnormalType">
+          <el-select v-model="indicatorResultForm.abnormalType" placeholder="请选择异常类型">
+            <el-option label="偏高" value="偏高" />
+            <el-option label="偏低" value="偏低" />
+            <el-option label="其他" value="其他" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注说明" prop="remarks">
+          <el-input v-model="indicatorResultForm.remarks" type="textarea" rows="3" placeholder="请输入备注说明" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitIndicatorResult">确 定</el-button>
+        <el-button @click="indicatorResultDialogVisible = false">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listReport, getReport, delReport, addReport, updateReport } from "@/api/medical/report";
+import { parseTime } from "@/utils/common";
+
+export default {
+  name: "Report",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 体检报告表格数据
+      reportList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 当前激活的tab页
+      activeTab: 'bodyInfo',
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        examDate: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        userId: [
+          { required: true, message: "用户ID不能为空", trigger: "blur" }
+        ],
+        examDate: [
+          { required: true, message: "体检日期不能为空", trigger: "blur" }
+        ]
+      },
+      // 指标搜索
+      indicatorSearch: '',
+      // 指标列表
+      indicatorList: [],
+      // 肝功能列表
+      liverFunctionList: [],
+      // 指标详情对话框可见性
+      indicatorDetailVisible: false,
+      // 当前查看的指标
+      currentIndicator: {},
+      // 指标选择对话框可见性
+      indicatorSelectVisible: false,
+      // 指标库搜索
+      indicatorLibrarySearch: '',
+      // 指标分类
+      indicatorCategory: '',
+      // 指标分类选项
+      indicatorCategoryOptions: [
+        { value: '', label: '全部' },
+        { value: '肝脏', label: '肝脏' },
+        { value: '血常规', label: '血常规' },
+        { value: '尿常规', label: '尿常规' },
+        { value: '心脏', label: '心脏' },
+        { value: '肾功能', label: '肾功能' },
+        { value: '血脂', label: '血脂' },
+        { value: '其他', label: '其他' }
+      ],
+      // 指标库数据
+      indicatorLibrary: [],
+      // 选中的指标
+      selectedIndicators: [],
+      // 分页
+      currentPage: 1,
+      pageSize: 10,
+      totalIndicators: 0,
+      // 指标结果对话框可见性
+      indicatorResultDialogVisible: false,
+      // 指标结果表单
+      indicatorResultForm: {
+        resultId: null,
+        indicatorName: '',
+        referenceRange: '',
+        testValue: '',
+        testResult: '',
+        isAbnormal: 0,
+        abnormalType: '',
+        remarks: ''
+      },
+      // 指标结果表单校验规则
+      indicatorResultRules: {
+        testValue: [
+          { required: true, message: "检查数值不能为空", trigger: "blur" }
+        ],
+        testResult: [
+          { required: true, message: "检查结果不能为空", trigger: "blur" }
+        ],
+        abnormalType: [
+          { required: true, message: "异常类型不能为空", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    parseTime,
+    /** 查询体检报告列表 */
+    getList() {
+      this.loading = true;
+      listReport(this.queryParams).then(response => {
+        this.reportList = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        reportId: null,
+        userId: null,
+        userName: null,
+        companyUserId: null,
+        companyUserName: null,
+        examDate: null,
+        height: null,
+        weight: null,
+        bmi: null,
+        waistCircumference: null,
+        chestCircumference: null,
+        bloodPressure: null,
+        heartRate: null,
+        generalCondition: null,
+        skinAndMucosa: null,
+        lymphNodes: null,
+        head: null,
+        neck: null,
+        chest: null,
+        heart: null,
+        lungs: null,
+        abdomen: null,
+        examResult: null,
+        doctorAdvice: null
+      };
+      this.resetForm("form");
+      // 重置指标列表
+      this.indicatorList = [];
+      this.liverFunctionList = [];
+      // 重置当前tab
+      this.activeTab = 'bodyInfo';
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.reportId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加体检报告";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const reportId = row.reportId || this.ids
+      getReport(reportId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改体检报告";
+        // 获取指标数据
+        this.loadIndicators(reportId);
+        // 获取肝功能数据
+        this.loadLiverFunction(reportId);
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.reportId != null) {
+            updateReport(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addReport(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const reportIds = row.reportId || this.ids;
+      this.$confirm('是否确认删除体检报告编号为"' + reportIds + '"的数据项?').then(function() {
+        return delReport(reportIds);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    },
+
+    // 自动计算BMI
+    calculateBMI() {
+      if (this.form.height && this.form.weight) {
+        const height = parseFloat(this.form.height) / 100; // 转换为米
+        const weight = parseFloat(this.form.weight);
+        if (height > 0 && weight > 0) {
+          this.form.bmi = (weight / (height * height)).toFixed(2);
+        }
+      }
+    },
+
+    // 加载指标数据
+    loadIndicators(reportId) {
+      // 调用API从后端获取报告相关的指标检查结果
+      import('@/api/medical/reportIndicator').then(module => {
+        const { listByReportId } = module;
+        listByReportId(reportId).then(response => {
+          // 过滤出非肝功能相关的指标
+          this.indicatorList = response.data.filter(item => item.category !== '肝脏' && item.indicatorCategory !== '肝脏');
+        });
+      }).catch(error => {
+        console.error("加载指标数据失败", error);
+        this.$message.error("加载指标数据失败");
+      });
+    },
+
+    // 加载肝功能数据
+    loadLiverFunction(reportId) {
+      // 调用API从后端获取报告相关的肝功能检查结果
+      import('@/api/medical/reportIndicator').then(module => {
+        const { listByReportId } = module;
+        listByReportId(reportId).then(response => {
+          // 过滤出肝功能相关的指标
+          this.liverFunctionList = response.data.filter(item => item.category === '肝脏' || item.indicatorCategory === '肝脏');
+        });
+      }).catch(error => {
+        console.error("加载肝功能数据失败", error);
+        this.$message.error("加载肝功能数据失败");
+      });
+    },
+
+    // 搜索指标
+    searchIndicators() {
+      if (!this.indicatorSearch) {
+        // 如果搜索框为空,重新加载所有指标
+        this.loadIndicators(this.form.reportId);
+        return;
+      }
+
+      // 根据搜索条件过滤指标
+      const keyword = this.indicatorSearch.toLowerCase();
+      this.indicatorList = this.indicatorList.filter(item => {
+        return (item.indicatorName && item.indicatorName.toLowerCase().includes(keyword)) ||
+               (item.testValue && String(item.testValue).toLowerCase().includes(keyword)) ||
+               (item.testResult && item.testResult.toLowerCase().includes(keyword));
+      });
+    },
+
+    // 查看指标详情
+    viewIndicatorDetail(indicator) {
+      this.currentIndicator = indicator;
+      this.indicatorDetailVisible = true;
+    },
+
+    // 添加指标
+    handleAddIndicator() {
+      if (!this.form.reportId) {
+        this.$message.warning("请先保存体检报告,再添加指标");
+        return;
+      }
+
+      // 加载指标库数据
+      this.searchIndicatorLibrary();
+      this.indicatorSelectVisible = true;
+    },
+
+    // 搜索指标库
+    searchIndicatorLibrary() {
+      // 构建查询参数
+      const query = {
+        pageNum: this.currentPage,
+        pageSize: this.pageSize,
+        indicatorName: this.indicatorLibrarySearch || undefined,
+        indicatorCategory: this.indicatorCategory || undefined
+      };
+
+      // 调用API查询指标库
+      import('@/api/medical/indicator').then(module => {
+        const { listIndicator } = module;
+        listIndicator(query).then(response => {
+          this.indicatorLibrary = response.data.list;
+          this.totalIndicators = response.data.total;
+        });
+      }).catch(error => {
+        console.error("搜索指标库失败", error);
+        this.$message.error("搜索指标库失败");
+      });
+    },
+
+    // 分页大小变化
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.searchIndicatorLibrary();
+    },
+
+    // 分页页码变化
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.searchIndicatorLibrary();
+    },
+
+    // 指标选择变化
+    handleIndicatorSelectionChange(selection) {
+      this.selectedIndicators = selection;
+    },
+
+    // 添加选中的指标
+    addSelectedIndicators() {
+      if (this.selectedIndicators.length === 0) {
+        this.$message.warning("请至少选择一个指标");
+        return;
+      }
+
+      // 准备批量添加的数据
+      const batchData = this.selectedIndicators.map(item => ({
+        reportId: this.form.reportId,
+        indicatorId: item.indicatorId,
+        testValue: null,
+        testResult: null,
+        isAbnormal: 0,
+        abnormalType: null,
+        remarks: null
+      }));
+
+      // 调用API批量添加指标结果
+      import('@/api/medical/reportIndicator').then(module => {
+        const { batchAddResult } = module;
+        batchAddResult(batchData).then(() => {
+          this.$message.success("添加指标成功");
+          this.indicatorSelectVisible = false;
+          // 重新加载指标数据
+          this.loadIndicators(this.form.reportId);
+          // 重新加载肝功能数据
+          this.loadLiverFunction(this.form.reportId);
+        });
+      }).catch(error => {
+        console.error("添加指标失败", error);
+        this.$message.error("添加指标失败");
+      });
+    },
+
+    // 格式化参考范围
+    formatReferenceRange(indicator) {
+      if (indicator.referenceText) {
+        return indicator.referenceText;
+      } else if (indicator.referenceMin !== null && indicator.referenceMax !== null) {
+        return `${indicator.referenceMin}-${indicator.referenceMax}`;
+      } else if (indicator.referenceMin !== null) {
+        return `>${indicator.referenceMin}`;
+      } else if (indicator.referenceMax !== null) {
+        return `<${indicator.referenceMax}`;
+      }
+      return '无参考范围';
+    },
+
+    // 编辑指标结果
+    editIndicator(indicator) {
+      this.indicatorResultForm = {
+        resultId: indicator.resultId,
+        indicatorName: indicator.indicatorName || indicator.name,
+        referenceRange: indicator.refRange || '',
+        testValue: indicator.testValue || '',
+        testResult: indicator.testResult || '',
+        isAbnormal: indicator.isAbnormal || 0,
+        abnormalType: indicator.abnormalType || '',
+        remarks: indicator.remarks || ''
+      };
+      this.indicatorResultDialogVisible = true;
+    },
+
+    // 提交指标结果
+    submitIndicatorResult() {
+      this.$refs.indicatorResultForm.validate(valid => {
+        if (valid) {
+          // 调用API更新指标结果
+          import('@/api/medical/reportIndicator').then(module => {
+            const { updateResult } = module;
+            const data = {
+              resultId: this.indicatorResultForm.resultId,
+              testValue: this.indicatorResultForm.testValue,
+              testResult: this.indicatorResultForm.testResult,
+              isAbnormal: this.indicatorResultForm.isAbnormal,
+              abnormalType: this.indicatorResultForm.abnormalType,
+              remarks: this.indicatorResultForm.remarks
+            };
+
+            updateResult(data).then(() => {
+              this.$message.success("更新指标结果成功");
+              this.indicatorResultDialogVisible = false;
+              // 重新加载指标数据
+              this.loadIndicators(this.form.reportId);
+              // 重新加载肝功能数据
+              this.loadLiverFunction(this.form.reportId);
+            });
+          }).catch(error => {
+            console.error("更新指标结果失败", error);
+            this.$message.error("更新指标结果失败");
+          });
+        }
+      });
+    }
+  }
+};
+</script>

+ 468 - 0
src/views/medical/reportIndicator/index.vue

@@ -0,0 +1,468 @@
+<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="报告ID" prop="reportId">
+        <el-input
+          v-model="queryParams.reportId"
+          placeholder="请输入报告ID"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="指标ID" prop="indicatorId">
+        <el-input
+          v-model="queryParams.indicatorId"
+          placeholder="请输入指标ID"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </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-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['medical:result:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleBatchAdd"
+          v-hasPermi="['medical:result:add']"
+        >批量新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="resultList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="结果ID" align="center" prop="resultId" />
+      <el-table-column label="报告ID" align="center" prop="reportId" />
+      <el-table-column label="指标ID" align="center" prop="indicatorId" />
+      <el-table-column label="指标名称" align="center" prop="indicatorName" />
+      <el-table-column label="检查结果" align="center" prop="resultValue" />
+      <el-table-column label="参考范围" align="center" prop="referenceRange" />
+      <el-table-column label="单位" align="center" prop="unit" />
+      <el-table-column label="异常标识" align="center" prop="abnormalFlag">
+        <template slot-scope="scope">
+          <dict-tag :options="abnormalFlagOptions" :value="scope.row.abnormalFlag"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+            v-hasPermi="['medical:result:query']"
+          >详情</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['medical:result:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['medical:result:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改报告指标检查结果对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="报告ID" prop="reportId">
+          <el-input v-model="form.reportId" placeholder="请输入报告ID" />
+        </el-form-item>
+        <el-form-item label="指标ID" prop="indicatorId">
+          <el-input v-model="form.indicatorId" placeholder="请输入指标ID" />
+        </el-form-item>
+        <el-form-item label="指标名称" prop="indicatorName">
+          <el-input v-model="form.indicatorName" placeholder="请输入指标名称" />
+        </el-form-item>
+        <el-form-item label="检查结果" prop="resultValue">
+          <el-input v-model="form.resultValue" placeholder="请输入检查结果" />
+        </el-form-item>
+        <el-form-item label="参考范围" prop="referenceRange">
+          <el-input v-model="form.referenceRange" placeholder="请输入参考范围" />
+        </el-form-item>
+        <el-form-item label="单位" prop="unit">
+          <el-input v-model="form.unit" placeholder="请输入单位" />
+        </el-form-item>
+        <el-form-item label="异常标识" prop="abnormalFlag">
+          <el-select v-model="form.abnormalFlag" placeholder="请选择异常标识">
+            <el-option
+              v-for="dict in abnormalFlagOptions"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 批量新增对话框 -->
+    <el-dialog title="批量新增检查结果" :visible.sync="batchOpen" width="800px" append-to-body>
+      <el-form ref="batchForm" :model="batchForm" label-width="80px">
+        <el-form-item label="报告ID" prop="reportId">
+          <el-input v-model="batchForm.reportId" placeholder="请输入报告ID" />
+        </el-form-item>
+        <el-button type="primary" size="mini" @click="addBatchRow">添加行</el-button>
+        <el-table :data="batchForm.results" style="margin-top: 10px;">
+          <el-table-column label="指标ID" width="100">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.indicatorId" size="mini" />
+            </template>
+          </el-table-column>
+          <el-table-column label="指标名称" width="120">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.indicatorName" size="mini" />
+            </template>
+          </el-table-column>
+          <el-table-column label="检查结果" width="100">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.resultValue" size="mini" />
+            </template>
+          </el-table-column>
+          <el-table-column label="参考范围" width="120">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.referenceRange" size="mini" />
+            </template>
+          </el-table-column>
+          <el-table-column label="单位" width="80">
+            <template slot-scope="scope">
+              <el-input v-model="scope.row.unit" size="mini" />
+            </template>
+          </el-table-column>
+          <el-table-column label="异常标识" width="100">
+            <template slot-scope="scope">
+              <el-select v-model="scope.row.abnormalFlag" size="mini">
+                <el-option
+                  v-for="dict in abnormalFlagOptions"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" width="80">
+            <template slot-scope="scope">
+              <el-button type="text" size="mini" @click="removeBatchRow(scope.$index)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitBatchForm">确 定</el-button>
+        <el-button @click="cancelBatch">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 详情对话框 -->
+    <el-dialog title="检查结果详情" :visible.sync="detailOpen" width="500px" append-to-body>
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="结果ID">{{ detailData.resultId }}</el-descriptions-item>
+        <el-descriptions-item label="报告ID">{{ detailData.reportId }}</el-descriptions-item>
+        <el-descriptions-item label="指标ID">{{ detailData.indicatorId }}</el-descriptions-item>
+        <el-descriptions-item label="指标名称">{{ detailData.indicatorName }}</el-descriptions-item>
+        <el-descriptions-item label="检查结果">{{ detailData.resultValue }}</el-descriptions-item>
+        <el-descriptions-item label="参考范围">{{ detailData.referenceRange }}</el-descriptions-item>
+        <el-descriptions-item label="单位">{{ detailData.unit }}</el-descriptions-item>
+        <el-descriptions-item label="异常标识">
+          <dict-tag :options="abnormalFlagOptions" :value="detailData.abnormalFlag"/>
+        </el-descriptions-item>
+        <el-descriptions-item label="创建时间" :span="2">
+          {{ parseTime(detailData.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
+        </el-descriptions-item>
+        <el-descriptions-item label="备注" :span="2">{{ detailData.remark }}</el-descriptions-item>
+      </el-descriptions>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="detailOpen = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listResult, getResult, delResult, addResult, updateResult, batchAddResult, listByReportId, listByIndicatorId } from "@/api/medical/reportIndicator";
+
+export default {
+  name: "Result",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 报告指标检查结果表格数据
+      resultList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 是否显示批量新增弹出层
+      batchOpen: false,
+      // 是否显示详情弹出层
+      detailOpen: false,
+      // 详情数据
+      detailData: {},
+      // 异常标识字典
+      abnormalFlagOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        reportId: null,
+        indicatorId: null,
+      },
+      // 表单参数
+      form: {},
+      // 批量表单参数
+      batchForm: {
+        reportId: null,
+        results: []        },
+      // 表单校验规则
+      rules: {
+        reportId: [{ required: true, message: '请输入报告ID', trigger: 'blur' }],
+        indicatorId: [{ required: true, message: '请输入指标ID', trigger: 'blur' }],
+        indicatorName: [{ required: true, message: '请输入指标名称', trigger: 'blur' }],
+        resultValue: [{ required: true, message: '请输入检查结果', trigger: 'blur' }],
+        referenceRange: [{ required: true, message: '请输入参考范围', trigger: 'blur' }],
+        unit: [{ required: true, message: '请输入单位', trigger: 'blur' }],
+        abnormalFlag: [{ required: true, message: '请选择异常标识', trigger: 'change' }],
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.loadDictData();
+  },
+  methods: {
+    // 加载异常标识字典数据
+    loadDictData() {
+      // 这里模拟加载字典数据,实际可以根据项目字典接口替换
+      this.abnormalFlagOptions = [
+        { label: '正常', value: '0' },
+        { label: '异常', value: '1' }
+      ];
+    },
+    // 查询列表
+    getList() {
+      this.loading = true;
+      listResult(this.queryParams).then((res) => {
+        if (res && res.data) {
+          this.resultList = res.data.list;
+          this.total = res.data.total;
+        }
+        this.loading = false;
+      }).catch(() => {
+        this.loading = false;
+      });
+    },
+    // 重置搜索条件
+    resetQuery() {
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        reportId: null,
+        indicatorId: null,
+      };
+      this.getList();
+    },
+    // 处理查询按钮点击
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    // 选择项变化
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.resultId);
+      this.single = this.ids.length !== 1;
+      this.multiple = this.ids.length === 0;
+    },
+    // 打开新增弹窗
+    handleAdd() {
+      this.title = "新增检查结果";
+      this.form = {};
+      this.open = true;
+      this.$nextTick(() => {
+        if (this.$refs.form) {
+          this.$refs.form.resetFields();
+        }
+      });
+    },
+    // 打开批量新增弹窗
+    handleBatchAdd() {
+      this.batchForm = {
+        reportId: null,
+        results: []
+      };
+      this.batchOpen = true;
+    },
+    // 添加批量新增表格行
+    addBatchRow() {
+      this.batchForm.results.push({
+        indicatorId: '',
+        indicatorName: '',
+        resultValue: '',
+        referenceRange: '',
+        unit: '',
+        abnormalFlag: '0'
+      });
+    },
+    // 删除批量新增表格行
+    removeBatchRow(index) {
+      this.batchForm.results.splice(index, 1);
+    },
+    // 取消批量新增
+    cancelBatch() {
+      this.batchOpen = false;
+    },
+    // 提交批量新增表单
+    submitBatchForm() {
+      if (!this.batchForm.reportId) {
+        this.$message.error('请输入报告ID');
+        return;
+      }
+      if (this.batchForm.results.length === 0) {
+        this.$message.error('请添加检查结果行');
+        return;
+      }
+      // 给每个结果设置报告ID
+      this.batchForm.results.forEach(item => {
+        item.reportId = this.batchForm.reportId;
+      });
+      batchAddResult(this.batchForm.results).then(res => {
+        if (res.code === 200) {
+          this.$message.success(res.msg || '批量新增成功');
+          this.batchOpen = false;
+          this.getList();
+        } else {
+          this.$message.error(res.msg || '批量新增失败');
+        }
+      });
+    },
+    // 提交新增或修改表单
+    submitForm() {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          if (this.form.resultId) {
+            updateResult(this.form).then(res => {
+              if (res.code === 200) {
+                this.$message.success(res.msg || '更新成功');
+                this.open = false;
+                this.getList();
+              } else {
+                this.$message.error(res.msg || '更新失败');
+              }
+            });
+          } else {
+            addResult(this.form).then(res => {
+              if (res.code === 200) {
+                this.$message.success(res.msg || '新增成功');
+                this.open = false;
+                this.getList();
+              } else {
+                this.$message.error(res.msg || '新增失败');
+              }
+            });
+          }
+        }
+      });
+    },
+    // 取消新增或修改
+    cancel() {
+      this.open = false;
+    },
+    // 查看详情
+    handleDetail(row) {
+      getResult(row.resultId).then(res => {
+        if (res.code === 200) {
+          this.detailData = res.data;
+          this.detailOpen = true;
+        } else {
+          this.$message.error(res.msg || '获取详情失败');
+        }
+      });
+    },
+    // 修改
+    handleUpdate(row) {
+      this.title = "修改检查结果";
+      this.form = Object.assign({}, row);
+      this.open = true;
+      this.$nextTick(() => {
+        if (this.$refs.form) {
+          this.$refs.form.clearValidate();
+        }
+      });
+    },
+    // 删除
+    handleDelete(row) {
+      this.$confirm('确定删除该检查结果吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        delResult(row.resultId).then(res => {
+          if (res.code === 200) {
+            this.$message.success(res.msg || '删除成功');
+            this.getList();
+          } else {
+            this.$message.error(res.msg || '删除失败');
+          }
+        });
+      }).catch(() => {});
+    }
+  }
+};
+</script>

+ 300 - 0
src/views/medical/unit/index.vue

@@ -0,0 +1,300 @@
+<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="单位名称" prop="unitName">
+        <el-input
+          v-model="queryParams.unitName"
+          placeholder="请输入单位名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="单位类型" prop="unitType">
+        <el-select v-model="queryParams.unitType" placeholder="请选择单位类型" clearable>
+          <el-option
+            v-for="dict in unitTypeOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </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-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['medical:unit:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['medical:unit:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['medical:unit:remove']"
+        >删除</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="unitList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="单位ID" align="center" prop="unitId" />
+      <el-table-column label="单位名称" align="center" prop="unitName" />
+      <el-table-column label="单位符号" align="center" prop="unitSymbol" />
+      <el-table-column label="单位类型" align="center" prop="unitType">
+        <template slot-scope="scope">
+          <dict-tag :options="unitTypeOptions" :value="scope.row.unitType"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['medical:unit:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['medical:unit:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改计量单位对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="单位名称" prop="unitName">
+          <el-input v-model="form.unitName" placeholder="请输入单位名称" />
+        </el-form-item>
+        <el-form-item label="单位类型" prop="unitType">
+          <el-select v-model="form.unitType" placeholder="请选择单位类型">
+            <el-option
+              v-for="dict in unitTypeOptions"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="单位符号" prop="unitSymbol">
+          <el-input v-model="form.unitSymbol" placeholder="请输入单位符号" />
+        </el-form-item>
+        <el-form-item label="备注" prop="description">
+          <el-input v-model="form.description" type="textarea" placeholder="请输入备注" />
+        </el-form-item>
+        <el-form-item label="状态" prop="status">
+          <el-select v-model="form.status" placeholder="请选择状态">
+            <el-option
+              v-for="dict in statusOptions"
+              :key="dict.value"
+              :label="dict.label"
+              :value="parseInt(dict.value)"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listUnit, getUnit, addUnit, updateUnit, delUnit } from "@/api/medical/unit";
+
+export default {
+  name: "Unit",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 计量单位表格数据
+      unitList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 单位类型字典
+      unitTypeOptions: [],
+      // 状态字典
+      statusOptions: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        unitName: null,
+        unitType: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        unitName: [
+          { required: true, message: "单位名称不能为空", trigger: "blur" }
+        ],
+        unitType: [
+          { required: true, message: "单位类型不能为空", trigger: "change" }
+        ],
+        status: [
+          { required: true, message: "状态不能为空", trigger: "change" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getDicts("unit_type").then(response => {
+      this.unitTypeOptions = response.data;
+    });
+    this.getDicts("sys_normal_disable").then(response => {
+      this.statusOptions = response.data;
+    });
+  },
+  methods: {
+    /** 查询计量单位列表 */
+    getList() {
+      this.loading = true;
+      listUnit(this.queryParams).then(response => {
+        this.unitList = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        unitId: null,
+        unitName: null,
+        unitType: null,
+        unitSymbol: null,
+        description: null,
+        status: 1
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.unitId);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加计量单位";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const unitId = row.unitId || this.ids[0];
+      getUnit(unitId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改计量单位";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.unitId != null) {
+            updateUnit(this.form).then(response => {
+              this.$message.success("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addUnit(this.form).then(response => {
+              this.$message.success("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const unitIds = row.unitId || this.ids;
+      this.$confirm('是否确认删除计量单位编号为"' + unitIds + '"的数据项?').then(function() {
+        return delUnit(unitIds);
+      }).then(() => {
+        this.getList();
+        this.$message.success("删除成功");
+      }).catch(() => {});
+    }
+  }
+};
+</script>

+ 3 - 2
src/views/system/config/config.vue

@@ -1304,16 +1304,17 @@
                  :disabled="!scope.row.editing">
                  <el-option label="小程序" value="1"></el-option>
                  <el-option label="服务号" value="2"></el-option>
+                 <el-option label="自定义" value="3"></el-option>
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="小程序原始ID" align="center" prop="username">
-             <template slot-scope="scope" v-if="scope.row.type == 1">
+             <template slot-scope="scope" v-if="scope.row.type == 1 || scope.row.type == 3 ">
                <el-input v-model="scope.row.username" placeholder="请输入原始ID" :disabled="!scope.row.editing" />
              </template>
            </el-table-column>
            <el-table-column label="小程序图标" align="center" prop="log">
-             <template slot-scope="scope" v-if="scope.row.type == 1">
+             <template slot-scope="scope" v-if="scope.row.type == 1 || scope.row.type == 3 ">
                <el-image v-if="!scope.row.editing && scope.row.log" :src="scope.row.log" :preview-src-list="[scope.row.log]" />
                <image-upload v-if="scope.row.editing" v-model="scope.row.log" :file-type='["png", "jpg", "jpeg"]' :limit="1"/>
              </template>