Jelajahi Sumber

木易华康-迁移润天腕表相关代码

Long 1 hari lalu
induk
melakukan
83d65b2eb8

+ 9 - 0
src/api/watch/common.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+import { status } from 'nprogress'
+
+const baseURL = process.env.VUE_APP_BASE_API
+// watch端 通用下载方法
+export function watchDownload(fileName) {
+    window.location.href = "/watch-api/watchCommon/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
+}
+

+ 121 - 5
src/api/watch/deviceInfo.js

@@ -9,7 +9,6 @@ export function listDeviceInfo(query) {
     params: query
   })
 }
-
 // 查询设备信息列表
 export function myDeviceInfo(query) {
   return request({
@@ -18,7 +17,6 @@ export function myDeviceInfo(query) {
     params: query
   })
 }
-
 // 查询设备信息详细
 export function getDeviceInfo(deviceId) {
   return request({
@@ -90,11 +88,11 @@ export function exportMy(query) {
 }
 
   // 查询用户信息
-export function getUser(deviceId) {
+export function getUser(data) {
   return request({
     url: '/watch-api/device/set/up/getUserInfo',
     method: 'get',
-    params: { deviceId } 
+    params:data
   })
 }
 
@@ -123,6 +121,14 @@ export function queryByDate(date,deviceId) {
   })
 }
 
+export function queryHrList(data) {
+  return request({
+    url: `/watch-api/watch/heart/rate/list`,
+    method: 'get',
+    params: data
+  })
+}
+
 //exportHeartDate导出
 export function exportHeartDate(date,deviceId) {
   return request({
@@ -168,6 +174,15 @@ export function queryGlucoseDate(date,deviceId) {
   })
 }
 
+// 根据时间获取血糖数据
+export function queryGlucoseList(data) {
+  return request({
+    url: `/watch-api/watch/blood/glucose/list`,
+    method: 'get',
+    params: data
+  })
+}
+
 // 根据时间获取房颤数据
 export function queryAfDate(date,deviceId) {
   return request({
@@ -186,6 +201,15 @@ export function queryPressure(date,deviceId) {
   })
 }
 
+// 根据时间获取血压数据
+export function queryPressureList(data) {
+  return request({
+    url: `/watch-api/watch/blood/pressure/list`,
+    method: 'get',
+    params:data
+  })
+}
+
 // 根据时间获取温度数据
 export function queryTemperature(date,deviceId) {
   return request({
@@ -213,6 +237,15 @@ export function querySpo2(date,deviceId) {
   })
 }
 
+// 根据时间获取血氧数据
+export function querySpo2List(data) {
+  return request({
+    url: `/watch-api/watch/spo2/data/list`,
+    method: 'get',
+    params: data
+  })
+}
+
 // 根据时间获取睡眠数据
 export function querySleep(date,deviceId) {
   return request({
@@ -222,6 +255,15 @@ export function querySleep(date,deviceId) {
   })
 }
 
+// 根据时间获取睡眠数据
+export function querySleepList(data) {
+  return request({
+    url: `/watch-api/watch/sleep/data/list`,
+    method: 'get',
+    params: data
+  })
+}
+
 // 获取预警数据
 export function queryAlarm(status) {
   return request({
@@ -288,6 +330,15 @@ export function queryUaData(data) {
   })
 }
 
+//获取尿酸数据
+export function queryUaList(data) {
+  return request({
+      url: '/watch-api/watch/third/ua/list',
+      method: 'get',
+      params:data
+  })
+}
+
 //获最新健康数据
 export function queryLastHealthData(data) {
   return request({
@@ -350,4 +401,69 @@ export function queryTemperaturePageByDate(data) {
       method: 'get',
       params:data
   })
-}
+}
+
+//查询某个时间段的温度数据 分页
+export function queryBOPageByDate(data) {
+  return request({
+      url: '/watch-api/watch/continuous/spo2/data/queryPageByDateAndDeviceId',
+      method: 'get',
+      params:data
+  })
+}
+
+//物联网 分页
+export function queryIotList(data) {
+  return request({
+      url: '/watch-api/watch/deviceInfo/query',
+      method: 'get',
+      params:data
+  })
+}
+
+//查询某个时间段的压力数据 分页
+export function queryFatiguePageByDate(data) {
+  return request({
+      url: '/watch-api/watch/fatigue/page',
+      method: 'get',
+      params:data
+  })
+}
+
+// 根据时间获取压力数据
+export function queryFatigue(date,deviceId) {
+  return request({
+    url: `/watch-api/watch/fatigue/queryByDateAndDeviceId`,
+    method: 'get',
+    params: { date,deviceId } 
+  })
+}
+
+
+//健康周报-步数,卡路里,睡眠等信息
+export function getUserHealthInfoByDeviceId(data) {
+  return request({
+      url: '/watch-api/watch/sport/data/getUserHealthInfoByDeviceId',
+      method: 'get',
+      params:data
+  })
+}
+
+//健康周报-步数,卡路里,睡眠等信息
+export function queryHealthReport(data) {
+  return request({
+      url: '/watch-api/device/queryHealthReport',
+      method: 'get',
+      params:data
+  })
+}
+
+//舌诊
+export function queryTongueList(data) {
+  return request({
+      url: '/watch-api/device/getHealthTongueList',
+      method: 'get',
+      params:data
+  })
+}
+

+ 1 - 1
src/components/DeviceInfo/AtrialFibrillation.vue

@@ -21,7 +21,7 @@
     </div>
     <div class="afib-diagnosis">
       <div class="afib-diagnosis-title">诊断结论:</div>
-      <div class="afib-diagnosis-note">{{conclusion||'没有房颤数据'}}</div>
+      <div class="afib-diagnosis-note">{{conclusion||'今日暂无数据,请选择其他日期'}}</div>
       <div class="afib-diagnosis-tips">
         注:非医疗诊断,供参考,请以医院确诊结论为准。
       </div>

+ 5 - 0
src/components/DeviceInfo/BloodSugar.vue

@@ -17,6 +17,11 @@
             </el-table-column>
             <el-table-column prop="bloodGlucose" align="center" label="测量结果">
             </el-table-column>
+            <template #empty>
+                <div>
+                    今日暂无数据,请选择其他日期
+                </div>
+            </template>
         </el-table>
 
     </div>

+ 8 - 3
src/components/DeviceInfo/Bloodoxygen.vue

@@ -22,6 +22,11 @@
             <el-table-column type="index" label="序号" align="center"/>
             <el-table-column label="时间" align="center" prop="time" />
             <el-table-column label="血氧" align="center" prop="avgBoxy" />
+            <template #empty>
+                <div>
+                    今日暂无数据,请选择其他日期
+                </div>
+            </template>
             </el-table>
             <pagination v-show="(total>0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
         </div>
@@ -87,9 +92,9 @@ export default {
                 xAxis: {
                     type: "time",
                     splitNumber: 6,
-                    axisLine: {
-                        show: false,
-                    },
+                    // axisLine: {
+                    //     show: false,
+                    // },
                     axisTick: {
                         show: false,
                     },

+ 5 - 0
src/components/DeviceInfo/Heartrate.vue

@@ -65,6 +65,11 @@
         <el-table-column label="最小心率" align="center" prop="minBpm" />
         <el-table-column label="状态" align="center" prop="status" :formatter="statusFormatter"/>
         <el-table-column label="时间" align="center" prop="createTime" />
+        <template #empty>
+            <div>
+                今日暂无数据,请选择其他日期
+            </div>
+        </template>
       </el-table>
       
     </div>

+ 9 - 4
src/components/DeviceInfo/Pressure.vue

@@ -24,8 +24,13 @@
                 <el-table-column label="sbp(mmgh)" align="center" prop="sbp" />
                 <el-table-column label="dbp(mmgh)" align="center" prop="dbp" />
                 <el-table-column label="hr(次/分)" align="center" prop="hr" />
+                <template #empty>
+                    <div>
+                        今日暂无数据,请选择其他日期
+                    </div>
+                </template>
             </el-table>
-            <pagination v-show="(dataListTotal > 0) && detailsType" :total="dataListTotal" :page.sync="tqueryParams.pageNum" :limit.sync="tqueryParams.pageSize" @pagination="getTableList"/>
+            <pagination v-show="(dataListTotal>0) && detailsType" :total="dataListTotal" :page.sync="tqueryParams.pageNum" :limit.sync="tqueryParams.pageSize" @pagination="getTableList"/>
         </div>
     </div>
 </template>
@@ -66,9 +71,9 @@ export default {
                     boundaryGap: false,
                     type: "time",
                     splitNumber: 6,
-                    axisLine: {
-                        show: false,
-                    },
+                    // axisLine: {
+                    //     show: false,
+                    // },
                     axisTick: {
                         show: false,
                     },

+ 291 - 0
src/components/DeviceInfo/PressureValue.vue

@@ -0,0 +1,291 @@
+<template>
+    <div>
+        <div class="box-header">
+            <div class="box-title boldtext">
+                压力 <span style="margin-left: 14px">{{ currentDate }}</span>
+            </div>
+            <div>
+                <!-- <el-button @click="exportData" size="small" style="margin-right: 20px"
+            >导出</el-button
+          > -->
+                <el-date-picker size="small" v-model="currentDatePicker" type="date" placeholder="选择日期"
+                    value-format="yyyy-MM-dd" @change="datePickerchange">
+                </el-date-picker>
+            </div>
+        </div>
+        <div v-show="!detailsType">
+            <div style="min-width: 841px; height: 320px; width: 100%;">
+                <div ref="heartrateChart" style="width: 100%; height: 100%;min-width: 783px;"></div>
+            </div>
+        </div>
+        <!-- 列表展示 -->
+        <div v-show="detailsType">
+            <el-table :data="dataList" style="width: 100%">
+                <el-table-column prop="createTime" label="时间" />
+                <el-table-column prop="pressure" label="压力值" />
+                <template #empty>
+                    <div>
+                        今日暂无数据,请选择其他日期
+                    </div>
+                </template>
+            </el-table>
+            <pagination v-show="(total > 0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
+        </div>
+        
+    </div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+import { queryFatiguePageByDate, queryFatigue} from "@/api/watch/deviceInfo";
+export default {
+    props: {
+        detailsType: { 
+            type: Boolean,
+            default: false
+        },
+        deviceId: {
+            type: String || Number,
+            default: "",
+        },
+    },
+    data() {
+        return {
+            total:0,
+            dataList:[],
+            queryParams:{
+                pageNum: 1,
+                pageSize: 10,
+                deviceId:"",
+                beginTime:"",
+                endTime:""
+            },
+            currentDate: this.parseTime(new Date(), "{y}-{m}-{d}"),
+            currentDatePicker: "",
+            exportLoading: false,
+            chart: null,
+            chartOptions: {
+                tooltip: {
+                    trigger: 'axis'
+                },
+                legend: {},
+                xAxis: {
+                    boundaryGap: false,
+                    type: "time",
+                    splitNumber: 6,
+                    axisTick: {
+                        show: false,
+                    },
+                    splitLine: {
+                        show: false,
+                    },
+                    axisLabel: {
+                        color: "#999999",
+                        margin: 20,
+                        // fontSize: 14,
+                        fontWeight: "bold",
+                        formatter: (value) => {
+                            return this.parseTime(value, "{h}:{i}");
+                        },
+                    }
+                },
+                yAxis: {
+                    type: 'value',
+                    max: 100, // 设置y轴最大值为100
+                    // splitLine: {
+                    //     show: false // 去掉y轴的横线
+                    // }
+                },
+                series: [
+                    {
+                        name: '压力值',
+                        type: 'line',
+                        data: [],
+                        smooth: true
+                    }
+                    
+                ]
+            }
+
+        }
+    },
+    methods: {
+        getDataPage(){
+            this.loading = true;
+            this.queryParams.deviceId = this.deviceId;
+            this.queryParams.beginTime = this.currentDate + " 00:00:00";
+            this.queryParams.endTime = this.currentDate + " 23:59:59";
+            queryFatiguePageByDate(this.queryParams)
+                .then((response) => {
+                if (response.data) {
+                    this.dataList = response.data.rows;
+                    this.total = response.data.total;
+                    this.loading = false;
+                } else {
+                    console.warn("分页数据返回为空或格式不正确:", response);
+                }
+                })
+                .catch((error) => {
+                console.error("获取分页数据失败:", error);
+                });
+        },
+        datePickerchange() {
+            this.currentDate = this.currentDatePicker || this.parseTime(new Date(), "{y}-{m}-{d}");
+            if(this.detailsType){
+                this.getDataPage();
+            } else{
+                this.getDetailsData();
+            }
+        },
+        initChart() {
+            const chartElement = this.$refs.heartrateChart;
+            const sportChartElement = this.$refs.sportHeartrate;
+            if (chartElement) {
+                this.chart = echarts.init(chartElement);
+                this.seChartOptions()
+            }
+            if (sportChartElement) {
+                this.sportChart = echarts.init(sportChartElement);
+                this.sportChart.setOption(this.sportChartOption);
+            }
+        },
+        seChartOptions() {
+            this.chartOptions.xAxis.min = this.currentDate + ' 00:00:00'
+            this.chartOptions.xAxis.max = this.currentDate + ' 23:59:59'
+            this.chart.setOption(this.chartOptions);
+        },
+        // 获取体温折线图
+        getDetailsData() {
+            queryFatigue(this.currentDate, this.deviceId)
+                .then((response) => {
+                    if (response && response.data) {
+                        // console.log("------------------" + JSON.stringify(response.data, null, 2))
+                        const data = response.data.map((item) => (
+                            {
+                                value: [
+                                    new Date(item.createTime).getTime(),
+                                    item.pressure,
+                                ],
+                            }));
+                     
+
+                        // 将数据分别赋值给不同的 series
+                        this.chartOptions.series[0].data = data;
+                        // 更新图表
+                        if (this.detailsType == false) {
+                            this.initChart();
+                        }
+                    } else {
+                        console.warn("数据返回为空或格式不正确:", response);
+                    }
+                })
+                .catch((error) => {
+                    console.error("获取数据失败:", error);
+                });
+        },
+       
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+@mixin u-flex($flexD, $alignI, $justifyC) {
+    display: flex;
+    flex-direction: $flexD;
+    align-items: $alignI;
+    justify-content: $justifyC;
+}
+
+.fz15 {
+    font-size: 15px !important;
+}
+
+.boldtext {
+    font-size: 16px;
+    color: #292929;
+    line-height: 30px;
+    font-weight: 700;
+}
+
+.box-header {
+    padding: 0 15px;
+    @include u-flex(row, center, space-between);
+    height: 50px;
+}
+
+.box-title {
+    color: #292929;
+    font-size: 16px;
+    font-family: PingFang SC-Medium;
+    padding-left: 10px;
+    border-left: 4px solid #2284ff;
+    line-height: 13px;
+}
+
+.heartrate-data {
+    @include u-flex(row, center, space-around);
+    margin-top: 30px;
+
+    &-item {
+        height: 60px;
+        width: 196px;
+        border-radius: 4px;
+        box-shadow: 0 0 10px rgba(1, 24, 54, 0.1);
+        overflow: hidden;
+        @include u-flex(row, center, flex-start);
+
+        img {
+            height: 41px;
+            width: 41px;
+        }
+    }
+
+    &-imgbox {
+        flex-shrink: 0;
+        height: 60px;
+        width: 60px;
+        @include u-flex(row, center, center);
+    }
+
+    &-right {
+        flex: 1;
+        text-align: center;
+        font-size: 13px;
+        color: #606165;
+        font-family: PingFang SC-Medium;
+        background: #fff;
+        height: 60px;
+    }
+
+    &-num {
+        font-size: 22px;
+        color: #2c2c3b;
+        line-height: 38px;
+    }
+}
+
+.heartrate-sport {
+    @include u-flex(row, flex-start, flex-start);
+    margin-top: 20px;
+
+    &-l {
+        width: 490px;
+        flex-shrink: 0;
+    }
+
+    &-r {
+        flex: 1;
+        max-width: 720px;
+    }
+
+    &-lechart {
+        width: 490px;
+        height: 300px;
+    }
+
+    &-rechart {
+        width: 100%;
+        @include u-flex(row, center, center);
+    }
+}
+</style>

+ 6 - 1
src/components/DeviceInfo/Pulse.vue

@@ -70,8 +70,13 @@
           <el-table-column type="index" label="序号" align="center"/>
           <el-table-column label="时间" align="center" prop="time" />
           <el-table-column label="脉搏" align="center" prop="pulseRate" />
+          <template #empty>
+              <div>
+                  今日暂无数据,请选择其他日期
+              </div>
+          </template>
         </el-table>
-        <pagination v-show="(dataListTotal > 0) && detailsType" :total="dataListTotal" :page.sync="tqueryParams.pageNum" :limit.sync="tqueryParams.pageSize" @pagination="getTableList"/>
+        <pagination v-show="(dataListTotal>0) && detailsType" :total="dataListTotal" :page.sync="tqueryParams.pageNum" :limit.sync="tqueryParams.pageSize" @pagination="getTableList"/>
       </div>
     </div>
   </template>

+ 1942 - 0
src/components/DeviceInfo/Report.vue

@@ -0,0 +1,1942 @@
+<template>
+    <div class="weekly-report no-scrollbar">
+      <div class="report-header">
+        <div class="report-title">
+          <img class="title-icon" src="@/assets/images/watchApi/title-icon.png" />
+          <span>周报</span>
+        </div>
+        <div class="date-selector">
+          <el-date-picker
+            :picker-options="{ firstDayOfWeek: 1 }"
+            v-model="selectedDate"
+            type="week"
+            format="yyyy 第 WW 周"
+            placeholder="选择周"
+            @change="handleDateChange"
+          ></el-date-picker>
+        </div>
+      </div>
+  
+      <el-card class="report-card">
+        <div class="progress-section">
+          <div class="progress-container">
+            <el-progress type="circle" :percentage="healthIndex" :width="120" color="#FF9F43"></el-progress>
+            <div class="progress-info">
+              <div class="progress-label">健康指数</div>
+            </div>
+            <div class="health-status">{{ healthStatus }}</div>
+            <div class="health-description">{{ healthDesc }}</div>
+          </div>
+          
+          <div class="health-metrics-container">
+            <div class="health-metrics-row">
+              <div class="metric-item">
+                <div class="metric-data">
+                  <div class="metric-value">{{ height }}<span class="metric-unit">cm</span></div>
+                  <div class="metric-label">身高</div>
+                </div>
+                <div class="metric-icon orange">
+                  <i class="el-icon-sort"></i>
+                </div>
+              </div>
+              <div class="metric-item">
+                <div class="metric-data">
+                  <div class="metric-value">{{ weight }}<span class="metric-unit">kg</span></div>
+                <div class="metric-label">体重</div>
+                </div>
+                <div class="metric-icon green">
+                  <i class="el-icon-top"></i>
+                </div>
+              </div>
+            </div>
+            
+            <div class="health-metrics-row">
+              <div class="metric-item">
+                <div class="metric-data">
+                  <div class="metric-value">{{ bmiStatus }}</div>
+                <div class="metric-label">BMI</div>
+                </div>
+                <div class="metric-icon blue">
+                  <i class="el-icon-plus"></i>
+                </div>
+              </div>
+              <div class="metric-item">
+                <div class="metric-data">
+                  <div class="metric-value">{{ caloriesData.value }}<span class="metric-unit">{{ caloriesData.unit }}</span></div>
+                  <div class="metric-label">{{ caloriesData.label }}</div>
+                </div>
+                <div class="metric-icon red">
+                  <i class="el-icon-hot-water"></i>
+                </div>
+              </div>
+            </div>
+            
+            <div class="health-metrics-row">
+              <div class="metric-item">
+                <div class="metric-data">
+                  <div class="metric-value">{{ stepsData.value }}<span class="metric-unit">{{ stepsData.unit }}</span></div>
+                  <div class="metric-label">{{ stepsData.label }}</div>
+                </div>
+                <div class="metric-icon orange">
+                  <i class="el-icon-s-promotion"></i>
+                </div>
+              </div>
+              <div class="metric-item">
+                <div class="metric-data">
+                  <div class="metric-value">{{ sleepCardData.status }}</div>
+                <div class="metric-label">{{ sleepCardData.label }}</div>
+                </div>
+                <div class="metric-icon purple">
+                  <i class="el-icon-moon"></i>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+  
+        <!-- 健康数据 (Health Data) Section -->
+        <div class="health-data-section">
+          <div class="section-title">健康数据</div>
+          
+          <!-- 血糖趋势 (Blood Sugar Trend) -->
+          <div class="trend-chart">
+            <div class="trend-title">血糖趋势</div>
+            <div class="trend-subtitle">单位: mmol/L</div>
+            <div class="line-chart-container" ref="bloodSugarChart"></div>
+            <div class="trend-advice">
+            </div>
+          </div>
+          
+          <!-- 尿酸趋势 (Uric Acid Trend) -->
+          <div class="trend-chart">
+            <div class="trend-title">尿酸趋势</div>
+            <div class="trend-subtitle">单位: μmol/L</div>
+            <div class="bar-chart-container" ref="uricAcidChart"></div>
+            <div class="legend">
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #4CD964;"></span>
+                <span>150~416μmol/L</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #FFCC00;"></span>
+                <span>&lt;150μmol/L</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #FF6B6B;"></span>
+                <span>&gt;416μmol/L</span>
+              </div>
+            </div>
+          </div>
+
+           <div class="trend-chart">
+            <div class="trend-title">血压趋势</div>
+            <div class="trend-subtitle">单位: mmgh</div>
+            <div class="line-chart-container" ref="bloodPressureChart"></div>
+          </div>
+
+           <div class="trend-chart">
+            <div class="trend-title">心率趋势</div>
+            <div class="trend-subtitle">单位: 次/分</div>
+            <div class="line-chart-container" ref="heartRateChart"></div>
+          </div>
+
+           <div class="trend-chart">
+            <div class="trend-title">血氧趋势</div>
+            <div class="trend-subtitle"></div>
+            <div class="line-chart-container" ref="bloodOxygenChart"></div>
+            <div class="legend">
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #4CD964;"></span>
+                <span>&lt;90%</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #FFCC00;"></span>
+                <span>&lt;95%</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #FF6B6B;"></span>
+                <span>其他</span>
+              </div>
+            </div>
+          </div>
+
+           <div class="trend-chart">
+            <div class="trend-title">睡眠趋势</div>
+            <div class="trend-subtitle"></div>
+            <div class="line-chart-container" ref="sleepChart"></div>
+            <div class="legend">
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #8C37E6;"></span>
+                <span>深睡</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #D138CF;"></span>
+                <span>浅睡</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #F88082;"></span>
+                <span>快速眼动</span>
+              </div>
+              <div class="legend-item">
+                <span class="legend-color" style="background-color: #FDBD27;"></span>
+                <span>清醒</span>
+              </div>
+            </div>
+          </div>
+          
+         
+        </div>
+  
+        
+        <div class="health-archive-section">
+          <div class="section-title">健康档案</div>
+          <div class="archive-items">
+            <!-- 健康预测 -->
+            <div class="archive-item">
+              <div class="archive-icon warning">
+                <i class="el-icon-warning-outline"></i>
+              </div>
+              <div class="archive-content">
+                <div class="archive-title">健康预测</div>
+                <div class="archive-text" v-for="(item, idx) in healthArchive" :key="'prediction' + idx">
+                  {{ item.prediction }}
+                </div>
+              </div>
+            </div>
+
+            <!-- 解析 -->
+            <div class="archive-item">
+              <div class="archive-icon analysis">
+                <i class="el-icon-data-analysis"></i>
+              </div>
+              <div class="archive-content">
+                <div class="archive-title">解析</div>
+                <div class="archive-text" v-for="(item, idx) in healthArchive" :key="'analysis' + idx">
+                  {{ item.analysis }}
+                </div>
+              </div>
+            </div>
+
+            <!-- 治疗建议 -->
+            <div class="archive-item">
+              <div class="archive-icon suggestion">
+                <i class="el-icon-first-aid-kit"></i>
+              </div>
+              <div class="archive-content">
+                <div class="archive-title">治疗建议</div>
+                <div class="archive-text" v-for="(item, idx) in healthArchive" :key="'suggestion' + idx">
+                  {{ item.suggestion }}
+                </div>
+              </div>
+            </div>
+
+            <!-- 注意事项 -->
+            <div class="archive-item">
+              <div class="archive-icon attention">
+                <i class="el-icon-info"></i>
+              </div>
+              <div class="archive-content">
+                <div class="archive-title">注意事项</div>
+                <div class="archive-text" v-for="(item, idx) in healthArchive" :key="'precautions' + idx">
+                  {{ item.precautions }}
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        
+        <!-- AI舌诊 (AI Tongue Diagnosis) Section -->
+        <div class="ai-diagnosis-section">
+          <div class="section-title">AI舌诊</div>
+          <div class="date-selector-tabs">
+            <div 
+              v-for="date in weekDates" 
+              :key="date"
+              :class="['date-tab', selectedDiagnosisDate === date ? 'active' : '']"
+              @click="selectedDiagnosisDate = date"
+            >
+              {{ date }}
+            </div>
+          </div>
+          
+          <div class="diagnosis-content" v-if="tongueData">
+            <div class="diagnosis-time">检测时间 {{ tongueData.createTime || '未知时间' }}</div>
+            
+            <div class="diagnosis-result">
+              <div class="diagnosis-label">您属于</div>
+              <div class="diagnosis-type">{{ tongueData.typeName || '未知体质' }}</div>
+            </div>
+            
+            <div class="diagnosis-section">
+              <div class="diagnosis-section-title">舌苔特征</div>
+              <div class="diagnosis-feature">
+                <div class="feature-dot"></div>
+                <div class="feature-title">{{ tongueData.taiseName || '未知' }}</div>
+                <div class="feature-description">{{ tongueData.taiseDesc || '未知' }}</div>
+              </div>
+              <div class="diagnosis-feature">
+                <div class="feature-dot"></div>
+                <div class="feature-title">{{ tongueData.shemianName || '未知' }}</div>
+                <div class="feature-description">{{ tongueData.shemianDesc || '未知' }}</div>
+              </div>
+            </div>
+            
+            <div class="diagnosis-section">
+              <!-- <div class="diagnosis-section-title">体质解析</div> -->
+              <div 
+                class="diagnosis-analysis" 
+                v-for="(item, index) in tongueData.typeJsonObj" 
+                :key="index"
+              >
+                <div class="diagnosis-section-title">{{ item.name }}</div>
+                <div class="analysis-content">{{ item.value }}</div>
+              </div>
+            </div>
+          </div>
+          <div class="diagnosis-content" v-else>
+            <div class="no-data">暂无舌诊数据</div>
+          </div>
+        </div>
+      </el-card>
+    </div>
+  </template>
+  
+  <script>
+  import * as echarts from 'echarts';
+  import {getUserHealthInfoByDeviceId,queryHealthReport,queryGlucoseList,queryUaList,queryPressureList,queryHrList,querySpo2List,querySleepList,queryTongueList} from "@/api/watch/deviceInfo";
+  export default {
+    props: {
+        // detailsType: { 
+        //     type: Boolean,
+        //     default: false
+        // },
+        userInfo: {
+          type: Object,
+          default: () => ({})
+        },
+        deviceId: {
+            type: String || Number,
+            default: "",
+        },
+    },
+    name: 'WeeklyReport',
+    data() {
+      return {
+        sleepDefaultInfo: {
+          4: { name: "浅睡", color: "#D138CF", yValue: 7 },
+          3: { name: "深睡", color: "#8C37E6", yValue: 3 },
+          6: { name: "清醒", color: "#FDBD27", yValue: 9 },
+          7: { name: "快速眼动", color: "#F88082", yValue: 12 },
+        },
+        startTime: null,
+        endTime:  null,
+        // 基础数据
+        height: '--',
+        weight: '--',
+        bmi: 0,
+        bmiStatus: '--',
+        healthIndex: 0,
+        healthStatus: '--',
+        healthDesc:"",
+        // 健康指标数据
+        caloriesData: {
+          value: '--',
+          unit: 'kcal',
+          label: '卡路里'
+        },
+        stepsData: {
+          value: '--',
+          unit: '步',
+          label: '步数'
+        },
+        sleepCardData: {
+          status: '--',
+          label: '睡眠'
+        },
+        selectedDate: new Date(),
+        // 健康档案
+        healthArchive: [],
+        selectedDiagnosisDate: '12/27',
+        bloodSugarChart: null,
+        uricAcidChart: null,
+        bloodPressureChart:null,
+        heartRateChart:null,
+        bloodOxygenChart:null,
+        sleepChart:null,
+        bloodSugarData: {
+          values: []
+        },
+       
+        uricAcidData: {
+          values: [
+          ]
+        },
+        bloodPressureData:{},
+        heartRateData:{},
+        bloodOxygenData:{values: []},
+        sleepData:[],
+        tongueData:null
+      };
+    },
+    mounted() {
+      this.$nextTick(() => {
+        this.initBloodSugarChart();
+        this.initBloodPressureChart();
+        this.initUricAcidChart();
+        this.initHeartRateChart();
+        this.initBloodOxygenChart();
+        this.initSleepChart();
+        this.setInitialDiagnosisDate();
+      });
+    },
+    computed: {
+      weekDates() {
+        const dates = [];
+        const startOfWeek = new Date(this.selectedDate);
+        startOfWeek.setDate(this.selectedDate.getDate() - (this.selectedDate.getDay() || 7) + 1); // Set to Monday
+        for (let i = 0; i < 7; i++) {
+          const date = new Date(startOfWeek);
+          date.setDate(startOfWeek.getDate() + i);
+          dates.push(this.formatDate(date));
+        }
+        return dates;
+      }
+    },
+    watch: {
+      userInfo: {
+        handler(newVal) {
+          if (newVal) {
+            this.updateUserInfo();
+          }
+        },
+        immediate: true,
+        deep: true
+      },
+      selectedDate() {
+        this.setInitialDiagnosisDate();
+      },
+      selectedDiagnosisDate(newVal) {
+        if (newVal) {
+          this.getTongueDate();
+        }
+      }
+    },
+    methods: {
+      formatDate(date) {
+        return `${date.getMonth() + 1}/${date.getDate()}`;
+      },
+      setInitialDiagnosisDate() {
+        this.selectedDiagnosisDate = this.weekDates[0] || null;
+      },
+      getWeekDates(date) {
+        const startOfWeek = new Date(date);
+        const endOfWeek = new Date(date);
+        startOfWeek.setDate(date.getDate() - (date.getDay() || 7) + 1); // 如果是周日,getDay() 返回 0,需要加 7
+         // 将日期设置为周一,时间为00:00:00
+        // startOfWeek.setDate(date.getDate() - date.getDay());
+        startOfWeek.setHours(0, 0, 0, 0);
+
+        // 将日期设置为周日,时间为23:59:59
+        endOfWeek.setDate(date.getDate() - (date.getDay() || 7) + 7); // 如果是周日,getDay() 返回 0,需要加 7
+        // endOfWeek.setDate(date.getDate() - date.getDay() + 6);
+        endOfWeek.setHours(23, 59, 59, 999);
+       
+        this.startTime= startOfWeek,
+        this.endTime=  endOfWeek
+      },
+      // 更新基本信息
+      updateUserInfo() {
+        if (this.userInfo) {
+          // 设置身高体重
+          this.height = this.userInfo.height || '--';
+          this.weight = this.userInfo.weight || '--';
+          
+          // 计算BMI
+          this.calculateBMI();}
+      },
+      // 计算BMI
+      calculateBMI() {
+        if (this.height && this.weight && this.height !== '--' && this.weight !== '--') {
+          // BMI = 体重(kg) / 身高(m)²
+          const heightInMeters = parseFloat(this.height) / 100;
+          const weightInKg = parseFloat(this.weight);
+          
+          if (!isNaN(heightInMeters) && !isNaN(weightInKg) && heightInMeters > 0) {
+            this.bmi = (weightInKg / (heightInMeters * heightInMeters)).toFixed(1);
+            
+            // 设置BMI状态
+            if (this.bmi < 18.5) {
+              this.bmiStatus = '偏瘦';
+            } else if (this.bmi >= 18.5 && this.bmi < 24) {
+              this.bmiStatus = '正常';
+            } else if (this.bmi >= 24 && this.bmi < 28) {
+              this.bmiStatus = '超重';
+            } else {
+              this.bmiStatus = '肥胖';
+            }
+          }
+        }
+      },
+      async getSportData() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime),
+            endTime: this.parseTime(this.endTime),
+          };
+          const response = await getUserHealthInfoByDeviceId(params);
+          if(response.data){
+            this.caloriesData.value = response.data.calorie;
+            this.stepsData.value = response.data.step;
+            this.sleepData.status = response.data.sleepStatus;
+          }
+        }catch(error){
+          console.error("获取步数,卡路里,睡眠等信息数据失败:", error);
+        }
+      },
+
+      async getHealthArchive() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime),
+            endTime: this.parseTime(this.endTime),
+          };
+          const response = await queryHealthReport(params);
+          if(response.data){
+            this.healthArchive = response.data.list;
+            this.healthIndex = response.data.score;
+            this.healthStatus = response.data.title;
+            this.healthDesc = response.data.desc;
+
+          }
+        }catch(error){
+          console.error("获取步数,卡路里,睡眠等信息数据失败:", error);
+        }
+      },
+      async getGlucoseDate() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+            endTime: this.parseTime(this.endTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+          };
+          const response = await queryGlucoseList(params);
+          if(response.data && response.data.length > 0){
+            const values = response.data.map(item => {
+              const timestamp = new Date(item.createTime).getTime();
+              return [timestamp, item.bloodGlucose, item.createTime];
+            });
+            this.bloodSugarData = {
+              values: values
+            };
+        
+          } else {
+            this.bloodSugarData = {
+              values: []
+            };
+          }
+        }catch(error){
+          console.error("获取血糖数据失败:", error);
+          this.bloodSugarData = {
+            values: []
+          };
+        }
+      },
+
+      async getUaDate() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+            endTime: this.parseTime(this.endTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+          };
+          const response = await queryUaList(params);
+          if(response.data && response.data.length > 0){
+            const values = response.data.map(item => {
+              const timestamp = new Date(item.createTime).getTime();
+              const val = item.val/10;
+              let color;
+              if (val < 150) {
+                  color = '#FFCC00';
+              } else if (val < 416) {
+                color = '#4CD964';
+              } else {
+                color = '#FF6B6B';
+              }
+              return [timestamp, val, item.createTime,color];
+            });
+            this.uricAcidData.values = values;
+        
+          } else {
+            this.uricAcidChart.values = [];
+          }
+        }catch(error){
+          console.error("获取尿酸数据失败:", error);
+          this.uricAcidChart.values = [];
+        }
+      },
+      async getSleepDate() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+            endTime: this.parseTime(this.endTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+          };
+          const response = await querySleepList(params);
+          if(response.data.sleepSection && response.data.sleepSection.length > 0){
+            this.sleepData = response.data.sleepSection;
+          }
+        }catch(error){
+          console.error("获取睡眠数据失败:", error);
+        }
+      },
+      async querySpo2Data() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+            endTime: this.parseTime(this.endTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+          };
+          const response = await querySpo2List(params);
+          if(response.data.list && response.data.list.length > 0){
+            const values = response.data.list.map(item => {
+              const timestamp = new Date(item.createTime).getTime();
+              const val = item.avgBoxy;
+              let color;
+              if (val < 150) {
+                  color = '#FFCC00';
+              } else if (val < 416) {
+                color = '#4CD964';
+              } else {
+                color = '#FF6B6B';
+              }
+              return [timestamp, val, item.createTime,color];
+            });
+            this.bloodOxygenData.values = values;
+        
+          } else {
+            this.bloodOxygenData.values = [];
+          }
+        }catch(error){
+          console.error("获取尿酸数据失败:", error);
+          this.bloodOxygenData.values = [];
+        }
+      },
+
+      async getHrDate() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+            endTime: this.parseTime(this.endTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+          };
+          const response = await queryHrList(params);
+          if(response.data.list && response.data.list.length > 0){
+            const values = response.data.list.map(item => {
+              const timestamp = new Date(item.createTime).getTime();
+              return [timestamp, (item.maxBpm + item.minBpm)/2, item.createTime];
+            });
+            this.heartRateData = {
+              values: values
+            };
+           
+          } else {
+            this.heartRateData = {
+              values: []
+            };
+          }
+        }catch(error){
+          console.error("获取心率数据失败:", error);
+          this.bloodSugarData = {
+            values: []
+          };
+        }
+      },
+
+      
+      async queryPressureData() {
+        try{
+          const params = {
+            deviceId: this.deviceId,
+            startTime: this.parseTime(this.startTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+            endTime: this.parseTime(this.endTime,'{y}/{m}/{d} {h}:{i}:{s}'),
+          };
+          const response = await queryPressureList(params);
+          if(response.data && response.data.length > 0){
+            
+
+            const sbp = response.data.map((item) => ({
+              value: [
+                new Date(item.createTime).getTime(),
+                item.sbp,
+              ]
+            }));
+            const dbp = response.data.map((item) => ({
+              value: [
+                  new Date(item.createTime).getTime(),
+                  item.dbp,
+              ]
+            }));
+            const hr = response.data.map((item) => ({
+              value: [
+                  new Date(item.createTime).getTime(),
+                  item.hr,
+              ]
+            }));
+            const createTime = response.data.map((item) => ({
+              value: [
+                  item.createTime
+              ]
+            }));
+            this.bloodPressureData = {
+              sbp : sbp,
+              dbp : dbp,
+              hr : hr,
+              createTime:createTime,
+            };
+          } else {
+            this.bloodPressureData = {
+              sbp : [],
+              dbp : [],
+              hr :  [],
+              createTime:[]
+            };
+          }
+        }catch(error){
+          console.error("获取血压数据失败:", error);
+          this.bloodPressureData = {
+            sbp : [],
+            dbp : [],
+            hr :  [],
+            createTime:[]
+          };
+        }
+      },
+
+      formatCreateDay(dateStr) {
+        const [month, day] = dateStr.split('/').map(Number);
+        const year = this.selectedDate.getFullYear();
+        const date = new Date(year, month - 1, day);
+        return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
+      },
+
+      async getTongueDate(){
+        if(this.userInfo && this.userInfo.userId){
+          const params = {
+            userId: this.userInfo.userId,
+            createDay: this.formatCreateDay(this.selectedDiagnosisDate),
+          };
+          
+          const response = await queryTongueList(params);
+          if(response && response.rows.length > 0){
+            this.tongueData = response.rows[0]
+            this.tongueData.typeJsonObj = JSON.parse(this.tongueData.typeJson || '[]')
+            console.log(this.tongueData)
+          } else {
+            this.tongueData = null;
+          }
+        }
+      },
+      // 获取周报详情数据
+      async getDetailsData() {
+        try {
+          this.getWeekDates(this.selectedDate);
+          // 获取健康周报-步数,卡路里,睡眠等信息
+          await this.getSportData();
+          await this.getHealthArchive();
+          await this.getGlucoseDate();
+          await this.getUaDate();
+          await this.queryPressureData();
+          await this.getHrDate();
+          await this.querySpo2Data();
+          await this.getSleepDate();
+          await this.getTongueDate();
+          this.updateCharts();
+        } catch (error) {
+          console.error("获取周报数据失败:", error);
+        }
+      },
+
+        
+      handleDateChange(date) {
+        this.selectedDate = date || this.parseTime(new Date(), "{y}-{m}-{d}");
+        this.getDetailsData();
+      },
+     
+      initBloodSugarChart() {
+        const chartDom = this.$refs.bloodSugarChart;
+        this.bloodSugarChart = echarts.init(chartDom);
+        const option = {
+          tooltip: {
+            trigger: 'item',
+            formatter: function(params) {
+              if (!params.data || params.data.length < 3) {
+                return '无数据';
+              }
+              const value = params.data[1];
+              const createTime = params.data[2];
+              return `时间: ${createTime}<br/>血糖: ${value} mmol/L`;
+            }
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            top: '3%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'time',
+            boundaryGap: false,
+            splitNumber: 7,
+            min:new Date(this.startTime).getTime(),
+            max:new Date(this.endTime).getTime() + 1,
+            axisLabel: {
+              color: "#999999",
+              margin: 20,
+              // fontSize: 14,
+              fontWeight: "bold",
+              formatter: (value) => {
+                return this.parseTime(value, "{m}/{d}");
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          yAxis: {
+            type: 'value',
+            min: 0,
+            max: 12,
+            interval: 2,
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          series: [
+            {
+              name: '血糖',
+              data: this.bloodSugarData.values,
+              type: 'line',
+              smooth: true,
+              symbol: 'circle',
+              symbolSize: 7,
+              itemStyle: {
+                color: '#FF9F43'
+              },
+              lineStyle: {
+                color: '#FF9F43'
+              },
+              areaStyle: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 0,
+                  y2: 1,
+                  colorStops: [
+                    {
+                      offset: 0,
+                      color: 'rgba(255, 159, 67, 0.3)'
+                    },
+                    {
+                      offset: 1,
+                      color: 'rgba(255, 159, 67, 0.1)'
+                    }
+                  ]
+                }
+              }
+            }
+          ]
+        };
+        
+        this.bloodSugarChart.setOption(option);
+        
+        // 响应式调整
+        window.addEventListener('resize', () => {
+          this.bloodSugarChart.resize();
+        });
+      },
+      initBloodPressureChart() {
+        const chartDom = this.$refs.bloodPressureChart;
+        this.bloodPressureChart = echarts.init(chartDom);
+        const option = {
+          tooltip: {
+            trigger: 'axis',
+            formatter: function(params) {
+              if (!params) {
+                return '无数据';
+              }
+              const sbp = params[0].data.value;
+              const dbp = params[1].data.value;
+              const hr = params[2].data.value;
+              const createTime = new Date(sbp[0]).toLocaleString();
+              return `时间: ${createTime}<br/>sbp: ${sbp[1]} mmgh<br/>bdp: ${dbp[1]} mmgh<br/>hr: ${hr[1]} 次/分`;
+            }
+          },
+          legend: {},
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            top: '3%',
+            containLabel: true
+          },
+          xAxis: {
+            type: "time",
+            boundaryGap: false,
+            splitNumber: 7,
+            min:new Date(this.startTime).getTime(),
+            max:new Date(this.endTime).getTime(),
+            axisLabel: {
+              color: "#999999",
+              margin: 20,
+              fontWeight: "bold",
+              formatter: (value) => {
+                return this.parseTime(value, "{m}/{d}");
+              },
+            },
+            axisTick: {
+                show: false,
+            },
+            splitLine: {
+                show: false,
+            },
+          },
+          yAxis: {
+              type: 'value',
+              min: 0,
+              max: 180,
+              interval: 30,
+              axisLabel: {
+                  formatter: '{value}'
+              },
+              axisTick: {
+                show: false,
+              },
+              splitLine: {
+                show: false,
+              },
+          },
+          
+          series: [
+              {
+                  name: 'sbp(mmgh)',
+                  type: "line",
+                  symbol: "none",
+                  data: this.bloodPressureData.sbp
+              },
+              {
+                  name: 'dbp(mmgh)',
+                  type: "line",
+                  symbol: "none",
+                  data: this.bloodPressureData.dbp
+              },
+              {
+                  name: 'hr(次/分)',
+                  type: "line",
+                  symbol: "none",
+                  data: this.bloodPressureData.hr
+              }
+          ]
+          
+        };
+        
+        this.bloodPressureChart.setOption(option);
+        
+        // 响应式调整
+        window.addEventListener('resize', () => {
+          this.bloodPressureChart.resize();
+        });
+      },
+      initUricAcidChart() {
+        const chartDom = this.$refs.uricAcidChart;
+        this.uricAcidChart = echarts.init(chartDom);
+
+        const data = this.uricAcidData.values.map((item, index) => {
+          return {
+            value: [item[0],item[1]],
+            itemStyle: {
+              color: item[3]
+            },
+            time:item[2]
+          };
+        });
+        
+        const option = {
+          tooltip: {
+            trigger: 'item',
+            formatter: function(params) {
+              if (!params.data || params.data.length < 4) {
+                return '无数据';
+              }
+              const value = params.data.value[1];
+              const createTime = params.data.time;
+              return `时间: ${createTime}<br/>尿酸: ${value} μmol/L`;
+            }
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            top: '3%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'time',
+            splitNumber: 7,
+            min:new Date(this.startTime).getTime(),
+            max:new Date(this.endTime).getTime() + 1,
+            axisLabel: {
+              color: "#999999",
+              margin: 20,
+              fontWeight: "bold",
+              formatter: (value) => {
+                return this.parseTime(value, "{m}/{d}");
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          yAxis: {
+            type: 'value',
+            min: 0,
+            max: 600,
+            interval: 100,
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          series: [
+            {
+              name: '尿酸',
+              type: 'bar',
+              data: data,
+              // barWidth: '40%'
+              barWidth: 10, // 设置柱子的宽度为 20 像素
+            }
+          ]
+        };
+        
+        this.uricAcidChart.setOption(option);
+        
+        // 响应式调整
+        window.addEventListener('resize', () => {
+          if (this.uricAcidChart) {
+            this.uricAcidChart.resize();
+          }
+        });
+      },
+      initHeartRateChart(){
+        const chartDom = this.$refs.heartRateChart;
+        this.heartRateChart = echarts.init(chartDom);
+        const option = {
+          tooltip: {
+            trigger: 'item',
+            formatter: function(params) {
+              if (!params.data || params.data.length < 3) {
+                return '无数据';
+              }
+              const value = params.data[1];
+              const createTime = params.data[2];
+              return `时间: ${createTime}<br/>心率: ${value} 次/分`;
+            }
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            top: '3%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'time',
+            boundaryGap: false,
+            splitNumber: 7,
+            min:new Date(this.startTime).getTime(),
+            max:new Date(this.endTime).getTime() + 1,
+            axisLabel: {
+              color: "#999999",
+              margin: 20,
+              // fontSize: 14,
+              fontWeight: "bold",
+              formatter: (value) => {
+                return this.parseTime(value, "{m}/{d}");
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          yAxis: {
+            type: 'value',
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          series: [
+            {
+              name: '心率',
+              data: this.heartRateData.values,
+              type: 'line',
+              smooth: true,
+              symbol: 'circle',
+              symbolSize: 7,
+              itemStyle: {
+                color: '#FF9F43'
+              },
+              lineStyle: {
+                color: '#FF9F43'
+              },
+              areaStyle: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 0,
+                  y2: 1,
+                  colorStops: [
+                    {
+                      offset: 0,
+                      color: 'rgba(255, 159, 67, 0.3)'
+                    },
+                    {
+                      offset: 1,
+                      color: 'rgba(255, 159, 67, 0.1)'
+                    }
+                  ]
+                }
+              }
+            }
+          ]
+        };
+        
+        this.heartRateChart.setOption(option);
+        
+        // 响应式调整
+        window.addEventListener('resize', () => {
+          this.heartRateChart.resize();
+        });
+      },
+      initBloodOxygenChart(){
+        const chartDom = this.$refs.bloodOxygenChart;
+        this.bloodOxygenChart = echarts.init(chartDom);
+
+        const data = this.bloodOxygenData.values.map((item, index) => {
+          return {
+            value: [item[0],item[1]],
+            itemStyle: {
+              color: item[3]
+            },
+            time:item[2]
+          };
+        });
+        
+        const option = {
+          tooltip: {
+            trigger: 'item',
+            formatter: function(params) {
+              if (!params.data || params.data.length < 4) {
+                return '无数据';
+              }
+              const value = params.data.value[1];
+              const createTime = params.data.time;
+              return `时间: ${createTime}<br/>血氧: ${value} %`;
+            }
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            top: '3%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'time',
+            splitNumber: 7,
+            min:new Date(this.startTime).getTime(),
+            max:new Date(this.endTime).getTime() + 1,
+            axisLabel: {
+              color: "#999999",
+              margin: 20,
+              fontWeight: "bold",
+              formatter: (value) => {
+                return this.parseTime(value, "{m}/{d}");
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          yAxis: {
+            type: 'value',
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          series: [
+            {
+              name: '血氧',
+              type: 'bar',
+              data: data,
+              // barWidth: '40%'
+              barWidth: 10, // 设置柱子的宽度为 20 像素
+            }
+          ]
+        };
+        
+        this.bloodOxygenChart.setOption(option);
+        
+        // 响应式调整
+        window.addEventListener('resize', () => {
+          if (this.bloodOxygenChart) {
+            this.bloodOxygenChart.resize();
+          }
+        });
+      },
+      initSleepChart(){
+        const chartDom = this.$refs.sleepChart;
+        this.sleepChart = echarts.init(chartDom);
+        const option = {
+          tooltip: {
+            show: true,
+            formatter: (params) => {
+              const start = params.value[3]
+              const end = params.value[4]
+              return `${start}到${end}<br/>${params.name}`;
+            },
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            top: '3%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'time',
+            boundaryGap: false,
+            splitNumber: 7,
+            min:new Date(this.startTime).getTime(),
+            max:new Date(this.endTime).getTime() + 1,
+            axisLabel: {
+              color: "#999999",
+              margin: 20,
+              // fontSize: 14,
+              fontWeight: "bold",
+              formatter: (value) => {
+                return this.parseTime(value, "{m}/{d}");
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          yAxis: {
+            max: 14,
+            show: false,
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          series: [
+          {
+            type: "custom",
+            renderItem: (params, api) => {
+              let yValue = api.value(2);
+              let start = api.coord([api.value(0), yValue]);
+              let size = api.size([api.value(1) - api.value(0), yValue]);
+              let style = api.style();
+              return {
+                type: "rect",
+                shape: {
+                  x: start[0],
+                  y: start[1],
+                  width: size[0],
+                  height: size[1],
+                },
+                style: style,
+              };
+            },
+            data: [],
+          },
+          ]
+        };
+        
+        this.sleepChart.setOption(option);
+        
+        // 响应式调整
+        window.addEventListener('resize', () => {
+          this.sleepChart.resize();
+        });
+      },
+      updateCharts() {
+        if (this.bloodSugarChart) {
+          // 更新血糖图表数据
+          this.bloodSugarChart.setOption({
+            series: [
+              {
+                data: this.bloodSugarData.values
+              }
+            ],
+            xAxis: {
+              min:new Date(this.startTime).getTime(),
+              max:new Date(this.endTime).getTime() + 1,
+            },
+          });
+        }
+
+        if (this.bloodPressureChart) {
+          this.bloodPressureChart.setOption({
+            series: [
+              {
+                name: 'sbp(mmgh)',
+                type: "line",
+                symbol: "none",
+                data: this.bloodPressureData.sbp
+              },
+              {
+                name: 'dbp(mmgh)',
+                type: "line",
+                symbol: "none",
+                data: this.bloodPressureData.dbp
+              },
+              {
+                name: 'hr(次/分)',
+                type: "line",
+                symbol: "none",
+                data: this.bloodPressureData.hr
+              },
+            ],
+            xAxis: {
+              min:new Date(this.startTime).getTime(),
+              max:new Date(this.endTime).getTime()  + 1,
+            },
+          });
+        }
+        
+        if (this.uricAcidChart) {
+          // 更新尿酸图表数据
+          const data = this.uricAcidData.values.map((item, index) => {
+            return {
+              value: [item[0],item[1]],
+              itemStyle: {
+                color: item[3]
+              },
+              time:item[2]
+            };
+          });
+          
+          this.uricAcidChart.setOption({
+            series: [
+              {
+                // type: 'bar',
+                data: data
+              }
+            ],
+            xAxis: {
+              min:new Date(this.startTime).getTime(),
+              max:new Date(this.endTime).getTime() + 1,
+            },
+          });
+        }
+        if (this.heartRateChart) {
+          this.heartRateChart.setOption({
+            series: [
+              {
+                data: this.heartRateData.values
+              }
+            ],
+            xAxis: {
+              min:new Date(this.startTime).getTime(),
+              max:new Date(this.endTime).getTime() + 1,
+            },
+          });
+        }
+        if (this.bloodOxygenChart) {
+          const data = this.bloodOxygenData.values.map((item, index) => {
+            return {
+              value: [item[0],item[1]],
+              itemStyle: {
+                color: item[3]
+              },
+              time:item[2]
+            };
+          });
+          
+          this.bloodOxygenChart.setOption({
+            series: [
+              {
+                // type: 'bar',
+                data: data
+              }
+            ],
+            xAxis: {
+              min:new Date(this.startTime).getTime(),
+              max:new Date(this.endTime).getTime() + 1,
+            },
+          });
+        }
+       
+        if (this.sleepChart) {
+          const chartData = this.sleepData.map((item, index) => {
+            return {
+              name: this.sleepDefaultInfo[item.type] && this.sleepDefaultInfo[item.type].name,
+              value: [
+                new Date(item.start).getTime(),
+                new Date(item.end).getTime(),
+                this.sleepDefaultInfo[item.type] && this.sleepDefaultInfo[item.type].yValue,
+                item.start,
+                item.end
+              ],
+              itemStyle: {
+                color: this.sleepDefaultInfo[item.type] && this.sleepDefaultInfo[item.type].color,
+              },
+            };
+          });
+          this.sleepChart.setOption({
+            series: [
+              {
+                data: chartData
+              }
+            ],
+            xAxis: {
+              min:new Date(this.startTime).getTime(),
+              max:new Date(this.endTime).getTime() + 1,
+            },
+          });
+        }
+      }
+    },
+    beforeDestroy() {
+      // 清除事件监听
+      window.removeEventListener('resize', this.resizeHandler);
+      
+      // 销毁图表实例
+      if (this.bloodSugarChart) {
+        this.bloodSugarChart.dispose();
+        this.bloodSugarChart = null;
+      }
+      if (this.bloodPressureChart) {
+        this.bloodPressureChart.dispose();
+        this.bloodPressureChart = null;
+      }
+      if (this.uricAcidChart) {
+        this.uricAcidChart.dispose();
+        this.uricAcidChart = null;
+      }
+      if (this.heartRateChart) {
+        this.heartRateChart.dispose();
+        this.heartRateChart = null;
+      }
+      if (this.bloodOxygenChart) {
+        this.bloodOxygenChart.dispose();
+        this.bloodOxygenChart = null;
+      }
+      if (this.sleepChart) {
+        this.sleepChart.dispose();
+        this.sleepChart = null;
+      }
+    }
+  };
+  </script>
+  
+  <style scoped lang="scss">
+  
+  /* 确保内容不会因为隐藏滚动条而被截断 */
+  .weekly-report {
+    padding: 20px;
+    background-color: #f5f7fa;
+    min-height: 100%;
+    overflow-y: auto;
+    overflow-x: hidden;
+  }
+  
+  .report-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+  }
+  
+  .report-title {
+    display: flex;
+    align-items: center;
+    font-size: 18px;
+    font-weight: bold;
+    color: #2284ff;
+    
+    .title-icon {
+      width: 13px;
+      height: 20px;
+      margin-right: 10px;
+    }
+  }
+  
+  .report-card {
+    margin-bottom: 20px;
+    border-radius: 8px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    overflow: hidden; /* 确保内容不会溢出卡片 */
+  }
+  
+  .progress-section {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 20px 0;
+    
+    @media (min-width: 768px) {
+      flex-direction: row;
+      justify-content: space-around;
+      align-items: flex-start;
+    }
+  }
+  
+  .progress-container {
+    position: relative;
+    margin-bottom: 20px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    
+    @media (min-width: 768px) {
+      margin-bottom: 0;
+    }
+    
+    .progress-info {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      text-align: center;
+      
+      .progress-value {
+        font-size: 24px;
+        font-weight: bold;
+        color: #FF9F43;
+        
+        .progress-unit {
+          font-size: 14px;
+        }
+      }
+      
+      .progress-label {
+        font-size: 12px;
+        color: #606266;
+      }
+    }
+    
+    .health-status {
+      margin-top: 10px;
+      font-size: 16px;
+      font-weight: bold;
+      color: #FF9F43;
+    }
+    .health-description {
+    margin-top: 8px;
+    font-size: 12px;
+    color: #606266;
+    text-align: center;
+    max-width: 240px;
+    line-height: 1.5;
+    padding: 0 10px;
+  }
+}
+  
+  .health-metrics-container {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+    
+    @media (min-width: 768px) {
+      width: 60%;
+    }
+  }
+  
+  .health-metrics-row {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 10px;
+  }
+  
+  .metric-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background-color: #fff;
+    border-radius: 8px;
+    padding: 10px 15px;
+    width: 48%;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    
+    .metric-data {
+      .metric-value {
+        font-size: 16px;
+        font-weight: bold;
+        
+        .metric-unit {
+          font-size: 12px;
+          font-weight: normal;
+        }
+      }
+      
+      .metric-label {
+        font-size: 12px;
+        color: #606266;
+      }
+    }
+    
+    .metric-icon {
+      width: 32px;
+      height: 32px;
+      border-radius: 50%;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      
+      i {
+        font-size: 16px;
+        color: white;
+      }
+      
+      &.green {
+        background-color: #4CD964;
+      }
+      
+      &.blue {
+        background-color: #2284FF;
+      }
+      
+      &.orange {
+        background-color: #FF9F43;
+      }
+      
+      &.red {
+        background-color: #FF6B6B;
+      }
+      
+      &.purple {
+        background-color: #8A70D6;
+      }
+    }
+  }
+  
+  .section-title {
+    font-size: 16px;
+    font-weight: bold;
+    margin: 20px 0 15px;
+    color: #303133;
+    padding-left: 10px;
+  }
+  
+  /* 健康数据部分 */
+  .health-data-section {
+    padding: 0 10px;
+  }
+  
+  .trend-chart {
+    background-color: #fff;
+    border-radius: 8px;
+    padding: 15px;
+    margin-bottom: 20px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+  }
+  
+  .trend-title {
+    font-size: 14px;
+    font-weight: bold;
+    color: #303133;
+  }
+  
+  .trend-subtitle {
+    font-size: 12px;
+    color: #909399;
+    margin-bottom: 10px;
+  }
+  
+  .line-chart-container,
+  .bar-chart-container {
+    height: 250px;
+    width: 100%;
+  }
+  
+  .trend-advice {
+    font-size: 12px;
+    color: #606266;
+    background-color: #f5f7fa;
+    padding: 10px;
+    border-radius: 4px;
+    margin-top: 10px;
+  }
+  
+  .legend {
+    display: flex;
+    flex-wrap: wrap;
+    margin-top: 10px;
+  }
+  
+  .legend-item {
+    display: flex;
+    align-items: center;
+    margin-right: 15px;
+    font-size: 12px;
+    color: #606266;
+  }
+  
+  .legend-color {
+    display: inline-block;
+    width: 12px;
+    height: 12px;
+    margin-right: 5px;
+    border-radius: 2px;
+  }
+  
+  .health-tabs {
+    margin-top: 20px;
+  }
+  
+  /* 健康档案部分 */
+  .health-archive-section {
+    padding: 0 10px;
+  }
+  
+  .archive-items {
+    display: flex;
+    flex-direction: column;
+    gap: 15px;
+  }
+  
+  .archive-item {
+    display: flex;
+    background-color: #fff;
+    border-radius: 8px;
+    padding: 15px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+  }
+  
+  .archive-icon {
+    width: 36px;
+    height: 36px;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-right: 15px;
+    flex-shrink: 0;
+    
+    i {
+      font-size: 18px;
+      color: white;
+    }
+    
+    &.warning {
+      background-color: #FF6B6B;
+    }
+    
+    &.analysis {
+      background-color: #4CD964;
+    }
+    
+    &.suggestion {
+      background-color: #2284FF;
+    }
+    
+    &.attention {
+      background-color: #FF9F43;
+    }
+  }
+  
+  .archive-content {
+    flex: 1;
+  }
+  
+  .archive-title {
+    font-size: 14px;
+    font-weight: bold;
+    color: #303133;
+    margin-bottom: 5px;
+  }
+  
+  .archive-text {
+    font-size: 12px;
+    color: #606266;
+    line-height: 1.5;
+  }
+  
+  /* AI舌诊部分 */
+  .ai-diagnosis-section {
+    padding: 0 10px 20px;
+  }
+  
+  .date-selector-tabs {
+    display: flex;
+    overflow-x: auto;
+    margin-bottom: 15px;
+  }
+  
+  .date-tab {
+    padding: 8px 15px;
+    background-color: #f5f7fa;
+    border-radius: 4px;
+    margin-right: 8px;
+    font-size: 14px;
+    cursor: pointer;
+    white-space: nowrap;
+    
+    &.active {
+      background-color: #FF9F43;
+      color: white;
+    }
+  }
+  
+  .diagnosis-content {
+    background-color: #fff;
+    border-radius: 8px;
+    padding: 15px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+  }
+  
+  .diagnosis-time {
+    text-align: center;
+    font-size: 14px;
+    color: #909399;
+    margin-bottom: 15px;
+  }
+  
+  .diagnosis-result {
+    text-align: center;
+    margin-bottom: 20px;
+  }
+  
+  .diagnosis-label {
+    font-size: 14px;
+    color: #606266;
+  }
+  
+  .diagnosis-type {
+    font-size: 20px;
+    font-weight: bold;
+    color: #FF6B6B;
+    margin-top: 5px;
+  }
+  
+  .diagnosis-section {
+    margin-bottom: 20px;
+  }
+  
+  .diagnosis-section-title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #FF9F43;
+    margin-bottom: 10px;
+    position: relative;
+    padding-left: 10px;
+    
+    &:before {
+      content: '';
+      position: absolute;
+      left: 0;
+      top: 50%;
+      transform: translateY(-50%);
+      width: 4px;
+      height: 16px;
+      background-color: #FF9F43;
+      border-radius: 2px;
+    }
+  }
+  
+  .diagnosis-feature {
+    margin-bottom: 10px;
+    display: flex;
+    flex-wrap: wrap;
+  }
+  
+  .feature-dot {
+    width: 8px;
+    height: 8px;
+    background-color: #FF9F43;
+    border-radius: 50%;
+    margin-right: 8px;
+    margin-top: 6px;
+  }
+  
+  .feature-title {
+    font-size: 14px;
+    font-weight: bold;
+    color: #303133;
+    margin-right: 10px;
+  }
+  
+  .feature-description {
+    font-size: 12px;
+    color: #606266;
+    flex: 1;
+  }
+  
+  .diagnosis-analysis {
+    margin-bottom: 15px;
+  }
+  
+  .analysis-title {
+    font-size: 14px;
+    font-weight: bold;
+    color: #303133;
+    margin-bottom: 5px;
+  }
+  
+  .analysis-content {
+    font-size: 12px;
+    color: #606266;
+    line-height: 1.5;
+  }
+  
+  .diagnosis-characteristics {
+    margin-bottom: 10px;
+  }
+  
+  .characteristics-title {
+    font-size: 13px;
+    font-weight: bold;
+    color: #303133;
+    margin-bottom: 3px;
+  }
+  
+  .characteristics-content {
+    font-size: 12px;
+    color: #606266;
+    line-height: 1.5;
+  }
+  </style>

+ 13 - 183
src/components/DeviceInfo/SettingDialog/SetInfoDialog.vue

@@ -2,7 +2,6 @@
   <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body :close-on-click-modal="false">
     <el-form ref="form" :model="form" :rules="rules" label-width="80px">
       <el-row>
-        
         <el-col :span="24"
           v-if="type != 'goal' && type != 'languageSet' && type != 'messageSend' && type != 'fallcheckSensitivity' && type != 'measureIntervalHr' && type != 'measureIntervalOther' && type != 'phonebookSync'">
           <el-form-item label="开关设置" prop="flag">
@@ -10,51 +9,6 @@
             </el-switch>
           </el-form-item>
         </el-col>
-        <el-col :span="24" v-if="type == 'medication' && form.flag">
-          <el-form-item label="开始提醒时间" prop="medicationStart" label-width="110px">
-            <el-time-picker
-              value-format="HH:mm:ss"
-              v-model="form.medicationStart"
-              placeholder="请选择开始时间"
-              :picker-options="{
-                selectableRange: '00:00:00 - 23:59:59'
-              }"
-            ></el-time-picker>
-          </el-form-item>
-          <el-form-item label="结束提醒时间" prop="medicationEnd" label-width="110px">
-            <el-time-picker
-              value-format="HH:mm:ss"
-              v-model="form.medicationEnd"
-              placeholder="请选择结束时间"
-              :picker-options="{
-                selectableRange: '00:00:00 - 23:59:59'
-              }"
-            ></el-time-picker>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24" v-if="type == 'study' && form.flag">
-          <el-form-item label="开始提醒时间" prop="studyStart" label-width="110px">
-            <el-time-picker
-              value-format="HH:mm:ss"
-              v-model="form.studyStart"
-              placeholder="请选择开始时间"
-              :picker-options="{
-                selectableRange: '00:00:00 - 23:59:59'
-              }"
-            ></el-time-picker>
-          </el-form-item>
-          <el-form-item label="结束提醒时间" prop="studyEnd" label-width="110px">
-            <el-time-picker
-              value-format="HH:mm:ss"
-              v-model="form.studyEnd"
-              placeholder="请选择结束时间"
-              :picker-options="{
-                selectableRange: '00:00:00 - 23:59:59'
-              }"
-            ></el-time-picker>
-          </el-form-item>
-        </el-col>
-
         <el-col :span="24" v-if="type == 'autolocate' || type == 'datafreq'">
           <el-form-item label="设备省电设置" prop="mode" label-width="105px">
             <el-radio-group v-model="form.mode">
@@ -303,8 +257,6 @@ import {
   fallcheck,
   autolocate,
   datafreq,
-  medication,
-  study,
   lcdgesture,
   hralarm,
   spo2alarm,
@@ -316,8 +268,7 @@ import {
   messageSend,
   fallcheckSensitivity,
   measureIntervalHr,
-  measureIntervalOther,
-  getSet
+  measureIntervalOther
 } from "@/api/watch/deviceInfoSet.js";
 
 export default {
@@ -329,50 +280,6 @@ export default {
         callback();
       }
     };
-    const checkStudyTimes = (rule, value, callback, type) => {
-      if (!value) {
-        return callback(new Error('时间不能为空'));
-      }
-
-      const start = this.form.studyStart;
-      const end = this.form.studyEnd;
-
-      if (type === 'start') {
-        if (end && start && new Date(start) >= new Date(end)) {
-          callback(new Error('开始时间必须小于结束时间'));
-        } else {
-          callback();
-        }
-      } else if (type === 'end') {
-        if (start && new Date(start) > new Date(end)) {
-          callback(new Error('结束时间必须大于开始时间'));
-        } else {
-          callback();
-        }
-      }
-    };
-    const checkMedicationTimes = (rule, value, callback, type) => {
-      if (!value) {
-        return callback(new Error('时间不能为空'));
-      }
-
-      const start = this.form.medicationStart;
-      const end = this.form.medicationEnd;
-
-      if (type === 'start') {
-        if (end && start && new Date(start) >= new Date(end)) {
-          callback(new Error('开始时间必须小于结束时间'));
-        } else {
-          callback();
-        }
-      } else if (type === 'end') {
-        if (start && new Date(start) > new Date(end)) {
-          callback(new Error('结束时间必须大于开始时间'));
-        } else {
-          callback();
-        }
-      }
-    };
     //  检查翻腕亮屏开始时间
     const checkStart = (rule, value, callback) => {
       if (value && this.form.end) {
@@ -568,12 +475,6 @@ export default {
       open: false,
       // 表单参数
       form: {},
-      //
-      param:{
-        flag:null,
-        start:null,
-        end:null
-      },
       // 表单校验
       rules: {
         time: [
@@ -587,22 +488,6 @@ export default {
           { required: true, message: "结束时间不能为空", trigger: ["blur", "change"] },
           { validator: checkEnd, trigger: ["blur", "change"] }
         ],
-        medicationStart: [
-          { required: true, message: "开始时间不能为空", trigger: "blur" },
-          { validator: (rule, value, callback) => checkMedicationTimes(rule, value, callback, 'start'), trigger: "blur" }
-        ],
-        medicationEnd: [
-          { required: true, message: "结束时间不能为空", trigger: "blur" },
-          { validator: (rule, value, callback) => checkMedicationTimes(rule, value, callback, 'end'), trigger: "blur" }
-        ],
-        studyStart: [
-          { required: true, message: "看课提醒开始时间不能为空", trigger: "blur" },
-          { validator: (rule, value, callback) => checkStudyTimes(rule, value, callback, 'start'), trigger: "blur" }
-        ],
-        studyEnd: [
-          { required: true, message: "看课提醒结束时间不能为空", trigger: "blur" },
-          { validator: (rule, value, callback) => checkStudyTimes(rule, value, callback, 'end'), trigger: "blur" }
-        ],
         high: [
           { required: true, message: "正常心率最高值不能为空", trigger: ["blur", "change"] },
           { validator: checkHigh, trigger: ["blur", "change"] }
@@ -732,14 +617,11 @@ export default {
         description: undefined, // 发送设备消息 描述
         fallThreshold: 14000, // 跌倒检测的灵敏度,默认14000
         measureIntervalHr: undefined, // 心率数据测量间隔设置 分钟
-        medicationStart: undefined, // 用药提醒的开始时间
-        medicationEnd: undefined, // 用药提醒的结束时间
-        studyStart: undefined, // 看课提醒的开始时间
-        studyEnd: undefined, // 看课提醒的结束时间
       };
       this.resetForm("form");
       this.btnLoading = false
     },
+    /** 修改按钮操作 */
     handleSet(deviceid, deviceNumber, item) {
       this.reset();
       this.form.deviceid = deviceid
@@ -748,35 +630,10 @@ export default {
       this.title = item.label;
       this.type = item.eventName
     },
-    handleTimeSet(item) {
-      console.log('设置用药提醒发送时间');
-      //查询对应设置
-      this.reset();
-      this.type = item.eventName;
-      this.open = true;
-      getSet({type:this.type}).then(response => {
-        this.param = response.data;
-        console.log("==========================",JSON.stringify(this.param,null,2));
-        this.form.flag = this.param.flag;
-        console.log("==========================开关:"+ this.form.flag);
-        this.title = item.label;
-        if(this.type == 'medication'){
-          this.form.medicationStart = this.param.start;
-          this.form.medicationEnd = this.param.end;
-        } else if(this.type == 'study'){
-          this.form.studyStart = this.param.start;
-          this.form.studyEnd = this.param.end;
-          console.log("==========================开关:"+ JSON.stringify(this.form,null,2));
-        }
-      });
-      
-    },
     /** 提交按钮 */
     submitForm() {
       this.$refs["form"].validate((valid) => {
-        if(this.type=='medication' || this.type=='study'){
-          this.confirmFun()
-        } else if (valid) {
+        if (valid) {
           if (this.form.deviceNumber != undefined) {
             this.confirmFun()
           } else {
@@ -791,31 +648,16 @@ export default {
         fallcheck: `是否确认${flagTxt}设备信息编号为${this.form.deviceNumber}的跌倒检测?`,
         autolocate: `是否确认${flagTxt}设备信息编号为${this.form.deviceNumber}的自动定位?`,
       }
-      if(this.type=='medication' || this.type=='study'){
-        this.$confirm(`是否确认对所有设备进行以上操作?`, "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(() => {
-          this.handleFun()
-        }).then(() => {
-          this.open = false
-          // this.$emit("refreshList")
-        }).catch(() => { });
-        
-      } else {
-        this.$confirm(typeTxt[this.type] || `是否确认对设备id为${this.form.deviceNumber}进行以上操作?`, "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(() => {
-          this.handleFun()
-        }).then(() => {
-          this.open = false
-          // this.$emit("refreshList")
-        }).catch(() => { });
-        }
-      
+      this.$confirm(typeTxt[this.type] || `是否确认对设备id为${this.form.deviceNumber}进行以上操作?`, "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.handleFun()
+      }).then(() => {
+        this.open = false
+        // this.$emit("refreshList")
+      }).catch(() => { });
     },
     handleFun() {
       const options = {
@@ -838,18 +680,6 @@ export default {
           time: this.form.time,
           mode: this.form.mode
         }),
-        // 用药提醒设置
-        medication: () => medication({
-          flag: this.form.flag,
-          start: this.form.flag ? this.form.medicationStart : undefined,
-          end: this.form.flag ? this.form.medicationEnd : undefined
-        }),
-        // 看课提醒设置
-        study: () => study({
-          flag: this.form.flag,
-          start: this.form.flag ? this.form.studyStart : undefined,
-          end: this.form.flag ? this.form.studyEnd : undefined
-        }),
         // 翻腕亮屏设置
         lcdgesture: () => lcdgesture({
           deviceNumber: this.form.deviceNumber,

+ 22 - 27
src/components/DeviceInfo/Sleep.vue

@@ -117,8 +117,13 @@
             <span v-if="scope.row.type === 7">快速眼动</span>
           </template>
         </el-table-column>
+        <template #empty>
+            <div>
+                今日暂无数据,请选择其他日期
+            </div>
+        </template>
       </el-table>
-      <pagination v-show="(total > 0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
+      <pagination v-show="(total>0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
     </div> 
   </div>
 </template>
@@ -157,10 +162,10 @@ export default {
       startTime: "2024-08-04 20:58:00",
       endTime: "2024-08-05 00:27:00",
       sleepDefaultInfo: {
-        4: { name: "浅睡", color: "#93c0fa", yValue: 7 },
-        3: { name: "深睡", color: "#427ff7", yValue: 3 },
-        6: { name: "清醒", color: "#fadeaf", yValue: 9 },
-        7: { name: "快速眼动", color: "#9899f5", yValue: 12 },
+        1: { name: "浅睡", color: "#93c0fa", yValue: 7 },
+        2: { name: "深睡", color: "#427ff7", yValue: 3 },
+        3: { name: "清醒", color: "#fadeaf", yValue: 9 },
+        4: { name: "快速眼动", color: "#9899f5", yValue: 12 },
       },
       sleepInfo: {
         score: '',
@@ -390,58 +395,48 @@ export default {
 
             //统计
             this.sleepInfo.score = response.data.score==null?0:response.data.score;
-            
             //浅睡
             if (response.data.lightSleep != null) {
-              // this.sportChartOption.series[0].data[0] = { value: response.data.lightSleep, name: '浅睡', itemStyle: { color: "#93c0fa" } };
+              this.sportChartOption.series[0].data[0] = { value: response.data.lightSleep, name: '浅睡', itemStyle: { color: "#93c0fa" } };
               this.sleepInfo.light_sleep = response.data.lightSleep;
 
             } else{
-              // this.sportChartOption.series[0].data[0] = { value: response.data.lightSleep, name: '浅睡', itemStyle: { color: "#93c0fa" } };
+              this.sportChartOption.series[0].data[0] = { value: response.data.lightSleep, name: '浅睡', itemStyle: { color: "#93c0fa" } };
               this.sleepInfo.light_sleep = 0;
             }
-            this.sportChartOption.series[0].data[0] = { value: response.data.lightSleep, name: '浅睡', itemStyle: { color: "#93c0fa" } };
-
             //深睡
             if (response.data.deepSleep != null) {
-              // this.sportChartOption.series[0].data[1] = { value: response.data.deepSleep, name: '深睡', itemStyle: { color: "#427ff7" } };
+              this.sportChartOption.series[0].data[1] = { value: response.data.deepSleep, name: '深睡', itemStyle: { color: "#427ff7" } };
               this.sleepInfo.deep_sleep = response.data.deepSleep;
 
             } else{
-              // this.sportChartOption.series[0].data[1] = { value: response.data.deepSleep, name: '深睡', itemStyle: { color: "#427ff7" } };
+              this.sportChartOption.series[0].data[1] = { value: response.data.deepSleep, name: '深睡', itemStyle: { color: "#427ff7" } };
               this.sleepInfo.deep_sleep = 0;
             }
-            this.sportChartOption.series[0].data[1] = { value: response.data.deepSleep, name: '深睡', itemStyle: { color: "#427ff7" } };
             //清醒
             if (response.data.weakSleep != null) {
-              // this.sportChartOption.series[0].data[2] = { value: response.data.weakSleep, name: '清醒', itemStyle: { color: "#fadeaf" } };
+              this.sportChartOption.series[0].data[2] = { value: response.data.weakSleep, name: '清醒', itemStyle: { color: "#fadeaf" } };
               this.sleepInfo.weak_sleep = response.data.weakSleep;
 
             } else{
-              // this.sportChartOption.series[0].data[2] = { value: response.data.weakSleep, name: '清醒', itemStyle: { color: "#fadeaf" } };
+              this.sportChartOption.series[0].data[2] = { value: response.data.weakSleep, name: '清醒', itemStyle: { color: "#fadeaf" } };
               this.sleepInfo.weak_sleep = 0;
             }
-            this.sportChartOption.series[0].data[2] = { value: response.data.weakSleep, name: '清醒', itemStyle: { color: "#fadeaf" } };
             //快速眼动
             if (response.data.eyemoveSleep != null) {
-              // this.sportChartOption.series[0].data[3] = { value: response.data.eyemoveSleep, name: '快速眼动', itemStyle: { color: "#9899f5" } };
+              this.sportChartOption.series[0].data[3] = { value: response.data.eyemoveSleep, name: '快速眼动', itemStyle: { color: "#9899f5" } };
               this.sleepInfo.eyemove_sleep = response.data.eyemoveSleep;
 
             } else{
-              // this.sportChartOption.series[0].data[3] = { value: response.data.eyemoveSleep, name: '快速眼动', itemStyle: { color: "#9899f5" } };
+              this.sportChartOption.series[0].data[3] = { value: response.data.eyemoveSleep, name: '快速眼动', itemStyle: { color: "#9899f5" } };
               this.sleepInfo.eyemove_sleep = 0;
             }
-            this.sportChartOption.series[0].data[3] = { value: response.data.eyemoveSleep, name: '快速眼动', itemStyle: { color: "#9899f5" } };
-            // if (this.sportChart) {
-            //   this.sportChart.setOption(this.sportChartOption);
-            // }
+            if (this.sportChart) {
+              this.sportChart.setOption(this.sportChartOption);
+            }
 
           } else {
-            this.defaultChart();
-            console.warn("睡眠数据返回为空", response);
-          }
-          if (this.sportChart) {
-              this.sportChart.setOption(this.sportChartOption);
+            console.warn("睡眠数据返回为空或格式不正确:", response);
           }
         })
         .catch((error) => {

+ 6 - 1
src/components/DeviceInfo/Sports.vue

@@ -29,8 +29,13 @@
       <el-table-column prop="sportTime" label="运动时长(min)" />
       <el-table-column prop="startTime" label="开始时间" />
       <el-table-column prop="type" label="运动类型" />
+      <template #empty>
+          <div>
+              今日暂无数据,请选择其他日期
+          </div>
+      </template>
     </el-table>
-    <pagination v-show="(total > 0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
+    <pagination v-show="(total>0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
     </div>
   </div>
 </template>

+ 9 - 5
src/components/DeviceInfo/Temperature.vue

@@ -24,9 +24,13 @@
                 <el-table-column prop="createTime" label="时间" />
                 <el-table-column prop="estTemp" label="体温(℃)" />
                 <el-table-column prop="shellTemp" label="体表温度(℃)" />
-                
+                <template #empty>
+                    <div>
+                        今日暂无数据,请选择其他日期
+                    </div>
+                </template>
             </el-table>
-            <pagination v-show="(total > 0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
+            <pagination v-show="(total>0) && detailsType" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getDataPage"/>
         </div>
         
     </div>
@@ -70,9 +74,9 @@ export default {
                     boundaryGap: false,
                     type: "time",
                     splitNumber: 6,
-                    axisLine: {
-                        show: false,
-                    },
+                    // axisLine: {
+                    //     show: false,
+                    // },
                     axisTick: {
                         show: false,
                     },

+ 5 - 0
src/components/DeviceInfo/Uricacid.vue

@@ -17,6 +17,11 @@
             </el-table-column>
             <el-table-column prop="val" label="测量结果">
             </el-table-column>
+            <template #empty>
+                <div>
+                    今日暂无数据,请选择其他日期
+                </div>
+            </template>
         </el-table>
 
     </div>

+ 5 - 0
src/components/DeviceInfo/Urineketones.vue

@@ -16,6 +16,11 @@
             </el-table-column>
             <el-table-column prop="val" align="center" label="测量结果">
             </el-table-column>
+            <template #empty>
+                <div>
+                    今日暂无数据,请选择其他日期
+                </div>
+            </template>
         </el-table>
 
     </div>

+ 35 - 13
src/views/watch/deviceInfo/details.vue

@@ -64,7 +64,7 @@
           </div>
         </div>
         <div class="equipment-day">
-          已绑定 <span>400</span> 天, 佩戴 <span>4365</span> 天
+          <!-- 已绑定 <span>400</span> 天, 佩戴 <span>4365</span> 天 -->
         </div>
         <div class="equipment-btn">
           <el-button type="primary" size="small">一键上传</el-button>
@@ -83,7 +83,7 @@
       </el-tabs>
       
       <keep-alive>
-        <component :ref="currentTabComponent" :is="currentTabComponent" :deviceId="deviceId" :basicInfo="basicInfo" :detailsType="detailsType">
+        <component :ref="currentTabComponent" :is="currentTabComponent" :deviceId="deviceId" :basicInfo="basicInfo" :detailsType="detailsType" :userInfo="userInfo">
         </component>
       </keep-alive>
     </el-main>
@@ -115,6 +115,8 @@ import Overview from '@/components/DeviceInfo/Overview.vue';
 import Bloodoxygen from '@/components/DeviceInfo/Bloodoxygen.vue';
 import Uricacid from '@/components/DeviceInfo/Uricacid.vue';
 import Urineketones from '@/components/DeviceInfo/Urineketones.vue';
+import PressureValue from '@/components/DeviceInfo/PressureValue.vue';
+import Report from '@/components/DeviceInfo/Report.vue';
 
 export default {
   name: "DeviceDetails",
@@ -134,7 +136,9 @@ export default {
     Overview,
     Bloodoxygen,
     Uricacid,
-    Urineketones
+    Urineketones,
+    PressureValue,
+    Report
   },
   data() {
     return {
@@ -179,10 +183,10 @@ export default {
           label: '位置',
           name: 'location'
         },
-        {
-          label: '脉搏',
-          name: 'pulse'
-        },
+        // {
+        //   label: '脉搏',
+        //   name: 'pulse'
+        // },
         {
           label: '血糖',
           name: 'bloodsugar'
@@ -191,10 +195,10 @@ export default {
           label: '血压',
           name: 'bloodpressure'
         },
-        {
-          label: '血酮',
-          name: 'urineketones'
-        },
+        // {
+        //   label: '血酮',
+        //   name: 'urineketones'
+        // },
         {
           label: '尿酸',
           name: 'uricacid'
@@ -211,6 +215,14 @@ export default {
         //   label: '血脂',
         //   name: 'bloodfat'
         // },
+        {
+          label: '压力',
+          name: 'pressureValue'
+        },
+        {
+          label: '周报',
+          name: 'report'
+        },
       ]
     };
   },
@@ -238,7 +250,9 @@ export default {
         overview: Overview,
         bloodoxygen: Bloodoxygen,
         uricacid: Uricacid,
-        urineketones: Urineketones
+        urineketones: Urineketones,
+        pressureValue:PressureValue,
+        report:Report
 
 
 
@@ -342,9 +356,12 @@ export default {
      */
     async getUserinfo(deviceId) {
       try {
-        const response = await getUser(deviceId);
+        const userId = this.$route.params.userId;
+        const selectType = this.$route.params.selectType;
+        const response = await getUser({deviceId:deviceId,userId:userId,selectType});
         if (response && response.data) {
           this.userInfo = response.data; // 确保数据被正确赋值
+          this.userInfo.userId = userId;
           // console.log("用户信息:", this.userInfo);
         } else {
           console.warn("用户信息返回为空或格式不正确:", response);
@@ -517,6 +534,11 @@ export default {
   // line-height: 160px;
   padding: 0;
 }
+::v-deep .el-main::-webkit-scrollbar {
+  width: 0;
+  display: none;  /* Chrome, Safari and Opera */
+}
+
 
 body>.el-container {
   margin-bottom: 40px;

+ 160 - 13
src/views/watch/deviceInfo/index.vue

@@ -5,10 +5,17 @@
         <el-input v-model="queryParams.doctorName" placeholder="请输入所属医生" clearable size="small"
           @keyup.enter.native="handleQuery" />
       </el-form-item>
-      <el-form-item label="绑定用户" prop="watchUserName">
+      <el-form-item label="所属员工" prop="companyUserId">
+        <el-select v-model="queryParams.companyUserId" placeholder="请选择所属员工" clearable size="small">
+          <el-option v-for="item in companyUserList" :key="item.userId" :label="item.nickName"
+            :value="item.userId">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <!-- <el-form-item label="绑定用户" prop="watchUserName">
         <el-input v-model="queryParams.watchUserName" placeholder="请输入绑定用户" clearable size="small"
           @keyup.enter.native="handleQuery" />
-      </el-form-item>
+      </el-form-item> -->
       <el-form-item label="设备编号" prop="deviceNumber">
         <el-input v-model="queryParams.deviceNumber" placeholder="请输入设备编号" clearable size="small"
           @keyup.enter.native="handleQuery" />
@@ -27,6 +34,12 @@
           </el-option>
         </el-select>
       </el-form-item>
+      <el-form-item label="健康状态" prop="isNormal">
+        <el-select v-model="queryParams.isNormal" placeholder="请选择健康状态" clearable size="small">
+          <el-option v-for="item in healthOptions" :key="item.value" :label="item.label" :value="item.value">
+          </el-option>
+        </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>
@@ -82,8 +95,29 @@
     <el-table v-loading="loading" :data="deviceInfoList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="设备id" align="center" prop="deviceId" />
+      <el-table-column label="所属员工" align="center" prop="companyUserName" />
       <el-table-column label="所属医生" align="center" prop="doctorName" />
-      <el-table-column label="绑定用户" align="center" prop="watchUserName" />
+      <el-table-column  label="绑定用户"  align="center" prop="watchUserName">
+        <!-- <template slot-scope="scope"> 
+          <div v-if="scope.row.users && scope.row.users!=null">
+              <el-link :underline="false" @click="handleDetails(scope.row.deviceId, scope.row.users.userId)">
+                {{ scope.row.users.nickName }}
+              </el-link>
+          </div>
+        </template> -->
+        
+      </el-table-column>
+      <el-table-column  label="绑定家人用户"  align="center" prop="familyUserName">
+          <!-- <template slot-scope="scope">
+            <div v-if="scope.row.familyUsers">
+              <div v-for="(item, index) in scope.row.familyUsers" :key="index">
+                <el-link :underline="false" @click="handleDetails(scope.row.deviceId, item.userId)">
+                  {{ item.nickName }}
+                </el-link>
+              </div>
+            </div>
+          </template> -->
+      </el-table-column>
       <el-table-column label="设备编号" align="center" prop="deviceNumber" width="150"/>
       <el-table-column label="电量" align="center" prop="battery" />
       <el-table-column label="信号" align="center" prop="rssi" />
@@ -97,20 +131,71 @@
           >
             最新数据
           </span>
-          <el-tag size="mini" :type="scope.row.isNormal == '异常'?'danger':'primary'">{{scope.row.isNormal}}</el-tag>
+          <el-tag size="mini" :type="scope.row.isNormal == 0?'danger':'primary'">{{ scope.row.isNormal === 1 ? '正常' : '异常' }}</el-tag>
 
         </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="handleDetails(scope.row.deviceId)"
+          <el-button size="mini" type="text" icon="el-icon-view" @click="handleDetailsAndType(scope.row)"
             v-hasPermi="['watchApi:deviceInfo:query']">查询详情</el-button>
           <el-button size="mini" type="text" icon="el-icon-phone-outline" @click="handleSoSPeople(scope.row.deviceNumber)"
             v-hasPermi="['watchApi:deviceInfo:query']">查看紧急联系人</el-button>
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+            v-hasPermi="['watchApi:deviceInfo:edit']">修改</el-button>  
         </template>
       </el-table-column>
     </el-table>
 
+    <!-- 添加或修改设备信息对话框 -->
+    <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="companyUserId">
+          <template #label>
+            <span class="required-label">所属员工</span>
+          </template>
+          <el-select v-model="form.companyUserId" placeholder="请选择所属员工" clearable size="small">
+            <el-option v-for="item in companyUserList" :key="item.userId" :label="item.nickName"
+              :value="item.userId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="所属医生" prop="doctorId">
+          <template #label>
+            <span class="required-label">所属医生</span>
+          </template>
+          <el-select v-model="form.doctorId" placeholder="请选择所属医生" clearable size="small">
+            <el-option v-for="item in doctorList" :key="item.doctorId" :label="item.doctorName"
+              :value="item.doctorId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="设备编号" prop="deviceNumber">
+          <el-input v-model="form.deviceNumber" placeholder="请输入设备编号" disabled/>
+        </el-form-item>
+        <el-form-item label="电量" prop="battery">
+          <el-input v-model="form.battery" placeholder="请输入电量" disabled/>
+        </el-form-item>
+        <el-form-item label="信号" prop="rssi">
+          <el-input v-model="form.rssi" placeholder="请输入信号" disabled/>
+        </el-form-item>
+        <el-form-item label="设备状态">
+          <el-radio-group v-model="form.status">
+            <el-radio :label="0">OFFLINE</el-radio>
+            <el-radio :label="1">ONLINE</el-radio>
+            <el-radio :label="2">UNACTIVE</el-radio>
+            <el-radio :label="3">DISABLE</el-radio>
+            <el-radio :label="4">NOT EXIST</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>
+
     <!-- 弹窗展示紧急联系人列表 -->
     <el-dialog :visible.sync="sosVisible" title="紧急联系人" width="50%">
         <el-table v-loading="sosLoading" :data="sosPeopleList">
@@ -169,15 +254,15 @@
 
 <script>
 import { listDeviceInfo, getDeviceInfo, delDeviceInfo, addDeviceInfo, updateDeviceInfo, exportDeviceInfo, queryAlarm, setStatus, queryPageAlarm,queryLastHealthData,querySos} from "@/api/watch/deviceInfo";
-import { getAllUserlist } from "@/api/company/companyUser";
+import { getSelectUserList } from "@/api/company/companyUser";
 import { messageSend } from "@/api/watch/deviceInfoSet.js";
+import { listDoctor } from "@/api/doctor/doctor";
 import setUpUserInfoDialog from "@/components/DeviceInfo/SettingDialog/setUpUserInfoDialog.vue";
 import SetInfoDialog from "@/components/DeviceInfo/SettingDialog/SetInfoDialog.vue";
 import Phonebook from "@/components/DeviceInfo/SettingDialog/Phonebook.vue";
 import Clockalarm from "@/components/DeviceInfo/SettingDialog/Clockalarm.vue";
 import Sedentary from "@/components/DeviceInfo/SettingDialog/Sedentary.vue";
-// import {getInfo} from "@/api/login"
-
+import {watchDownload} from "@/api/watch/common";
 export default {
   name: "DeviceInfo",
   components: {
@@ -273,6 +358,13 @@ export default {
           { max: 240, message: '详情最多240个字节', trigger: 'blur' }
         ]
       },
+      healthOptions: [{
+          value: 0,
+          label: '异常'
+        }, {
+          value: 1,
+          label: '正常'
+        }],
       options: [{
         value: '0',
         label: 'OFFLINE'
@@ -311,6 +403,8 @@ export default {
   },
   created() {
     this.getList();
+    this.getCompanyUserList();
+    this.getDoctorList();
   },
   computed: {
     // 计算属性来控制按钮的disabled状态
@@ -319,9 +413,51 @@ export default {
     }
   },
   methods: {
+    getDoctorList(){
+      listDoctor({ doctorType:1,isAudit:1 }).then(response => {
+        this.doctorList = response.rows;
+      });
+    },
+    getCompanyUserList(){
+      getSelectUserList().then(response => {
+          this.companyUserList = response.rows;
+        }).catch(error => {
+          console.error("获取员工列表失败:", error);
+        });
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const deviceId = row.deviceId || this.ids
+      getDeviceInfo(deviceId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改设备信息";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.deviceId != null) {
+            console.log("===============================" + JSON.stringify(this.form, null, 2))
+            updateDeviceInfo(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addDeviceInfo(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
     rowClassName({row}) {
-      if (row.status && row.status.includes('偏')) {
-        // console.log("=============================" + JSON.stringify(row.status, null, 2))
+      if (row.status && (!row.status.includes('正常') && !row.status.includes('得分') && !row.status.includes('无结果') && !row.status.includes('窦性心率'))) {
         return 'text-red';
         // return true
       }
@@ -403,9 +539,18 @@ export default {
 
       }
     },
+    handleDetailsAndType(row){
+      if(row.userId != null){
+        this.handleDetails(row.deviceId,row.userId)
+      } else if(row.familyUserId !=null){
+        this.handleDetails(row.deviceId,row.familyUserId)
+      } else {
+        this.handleDetails(row.deviceId,null);
+      }
+    },
     /** 处理查询详情按钮点击事件 */
-    handleDetails(deviceId) {
-      this.$router.push({ name: 'details', params: { deviceId } });
+    handleDetails(deviceId,userId,type) {
+      this.$router.push({ name: 'details', params: { deviceId:deviceId,userId:userId,selectType:type } });
     },
 
     /** 查询设备信息列表 */
@@ -501,7 +646,9 @@ export default {
         this.exportLoading = true;
         return exportDeviceInfo(queryParams);
       }).then(response => {
-        this.download(response.msg);
+        debugger;
+        // this.download(response.msg);
+        watchDownload(response.msg);
         this.exportLoading = false;
       }).catch(() => { });
     },

+ 46 - 14
src/views/watch/deviceInfo/my.vue

@@ -27,6 +27,12 @@
             </el-option>
           </el-select>
         </el-form-item>
+        <el-form-item label="健康状态" prop="isNormal">
+        <el-select v-model="queryParams.isNormal" placeholder="请选择健康状态" clearable size="small">
+          <el-option v-for="item in healthOptions" :key="item.value" :label="item.label" :value="item.value">
+          </el-option>
+        </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>
@@ -83,15 +89,26 @@
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="设备id" align="center" prop="deviceId" />
         <el-table-column label="所属医生" align="center" prop="doctorName" />
-        <el-table-column  label="绑定用户"  align="center">
-          <template slot-scope="scope">
-              <el-link :underline="false" prop="item.userId" v-for="(item, index) in scope.row.users"  v-if="scope.row.users"  @click="handleDetails(scope.row.deviceId,item.userId,0)">{{item.nickName}}</el-link>
-          </template>
+        <el-table-column  label="绑定用户"  align="center" prop="watchUserName">
+          <!-- <template slot-scope="scope"> 
+          <div v-if="scope.row.users && scope.row.users!=null">
+              <el-link :underline="false" @click="handleDetails(scope.row.deviceId, scope.row.users.userId)">
+                {{ scope.row.users.nickName }}
+              </el-link>
+          </div>
+        </template> -->
+          
         </el-table-column>
-        <el-table-column  label="绑定家人用户"  align="center">
-            <template slot-scope="scope">
-                <el-link :underline="false" prop="item.userId" v-for="(item, index) in scope.row.familyUsers"  v-if="scope.row.familyUsers"  @click="handleDetails(scope.row.deviceId,item.userId,1)">{{item.nickName}}</el-link>
-            </template>
+        <el-table-column  label="绑定家人用户"  align="center" prop="familyUserName">
+            <!-- <template slot-scope="scope">
+              <div v-if="scope.row.familyUsers">
+                <div v-for="(item, index) in scope.row.familyUsers" :key="index">
+                  <el-link :underline="false" @click="handleDetails(scope.row.deviceId, item.userId)">
+                    {{ item.nickName }}
+                  </el-link>
+                </div>
+              </div>
+            </template> -->
         </el-table-column>
         <el-table-column label="设备编号" align="center" prop="deviceNumber" width="150"/>
         <el-table-column label="电量" align="center" prop="battery" />
@@ -106,13 +123,13 @@
             >
               最新数据
             </span>
-            <el-tag size="mini" :type="scope.row.isNormal == '异常'?'danger':'primary'">{{scope.row.isNormal}}</el-tag>
+            <el-tag size="mini" :type="scope.row.isNormal == 0?'danger':'primary'">{{ scope.row.isNormal === 1 ? '正常' : '异常' }}</el-tag>
   
           </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="handleDetails(scope.row.deviceId,null,0)"
+            <el-button size="mini" type="text" icon="el-icon-view" @click="handleDetailsAndType(scope.row)"
               v-hasPermi="['watchApi:deviceInfo:query']">查询详情</el-button>
             <el-button size="mini" type="text" icon="el-icon-phone-outline" @click="handleSoSPeople(scope.row.deviceNumber)"
               v-hasPermi="['watchApi:deviceInfo:query']">查看紧急联系人</el-button>
@@ -186,7 +203,7 @@
   import Clockalarm from "@/components/DeviceInfo/SettingDialog/Clockalarm.vue";
   import Sedentary from "@/components/DeviceInfo/SettingDialog/Sedentary.vue";
   // import {getInfo} from "@/api/login"
-  
+  import {watchDownload} from "@/api/watch/common";
   export default {
     name: "my",
     components: {
@@ -282,6 +299,13 @@
             { max: 240, message: '详情最多240个字节', trigger: 'blur' }
           ]
         },
+        healthOptions: [{
+          value: 0,
+          label: '异常'
+        }, {
+          value: 1,
+          label: '正常'
+        }],
         options: [{
           value: '0',
           label: 'OFFLINE'
@@ -329,8 +353,7 @@
     },
     methods: {
       rowClassName({row}) {
-        if (row.status && row.status.includes('偏')) {
-          // console.log("=============================" + JSON.stringify(row.status, null, 2))
+        if (row.status && (!row.status.includes('正常') && !row.status.includes('得分') && !row.status.includes('无结果') && !row.status.includes('窦性心率'))) {
           return 'text-red';
           // return true
         }
@@ -412,6 +435,15 @@
   
         }
       },
+      handleDetailsAndType(row){
+        if(row.userId != null){
+          this.handleDetails(row.deviceId,row.userId,0)
+        } else if(row.familyUserId !=null ){
+          this.handleDetails(row.deviceId,row.familyUserId,1)
+        } else {
+          this.handleDetails(row.deviceId,null,0);
+        }
+      },
       /** 处理查询详情按钮点击事件 */
       handleDetails(deviceId,userId,type) {
         this.$router.push({ name: 'details', params: { deviceId:deviceId,userId:userId,selectType:type } });
@@ -510,7 +542,7 @@
           this.exportLoading = true;
           return exportMy(queryParams);
         }).then(response => {
-          this.download(response.msg);
+          watchDownload(response.msg);
           this.exportLoading = false;
         }).catch(() => { });
       },