|
|
@@ -92,6 +92,8 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { ref, computed, onMounted, watch, nextTick, onBeforeUnmount, getCurrentInstance } from 'vue'
|
|
|
+import { onShow } from '@dcloudio/uni-app'
|
|
|
+import { listBloodPressure, addBloodPressure, deleteBloodPressure } from '@/api/bloodPressure'
|
|
|
import { createUChart } from '@/composables/useUChart'
|
|
|
import CustomNav from '@/components/custom-nav.vue'
|
|
|
|
|
|
@@ -144,34 +146,53 @@ const displayPeriod = computed(() => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-const records = ref<RecordItem[]>(generateMockRecords(current.value))
|
|
|
+const records = ref<RecordItem[]>([])
|
|
|
|
|
|
-function generateMockRecords(d: Date): RecordItem[] {
|
|
|
- const arr: RecordItem[] = []
|
|
|
+async function fetchRecords() {
|
|
|
+ let startTime = ''
|
|
|
+ let endTime = ''
|
|
|
if (viewMode.value === 'month') {
|
|
|
- const y = d.getFullYear()
|
|
|
- const m = d.getMonth()
|
|
|
- const n = Math.floor(Math.random() * Math.min(daysInMonth(y, m), 7))
|
|
|
- for (let i = 0; i < n; i++) {
|
|
|
- const day = Math.max(1, Math.floor(Math.random() * daysInMonth(y, m)) + 1)
|
|
|
- const date = new Date(y, m, day)
|
|
|
- const s = 100 + Math.floor(Math.random() * 40)
|
|
|
- const dval = 60 + Math.floor(Math.random() * 30)
|
|
|
- arr.push({ id: `${date.getTime()}-${i}`, date: formatDisplayDate(date), s, d: dval })
|
|
|
- }
|
|
|
+ const y = current.value.getFullYear()
|
|
|
+ const m = current.value.getMonth()
|
|
|
+ startTime = new Date(y, m, 1).toISOString()
|
|
|
+ const endDate = new Date(y, m + 1, 0)
|
|
|
+ endDate.setHours(23, 59, 59, 999)
|
|
|
+ endTime = endDate.toISOString()
|
|
|
} else {
|
|
|
- const weekStart = getWeekStart(d)
|
|
|
- const n = Math.floor(Math.random() * 7)
|
|
|
- for (let i = 0; i < n; i++) {
|
|
|
- const dayOffset = Math.floor(Math.random() * 7)
|
|
|
- const date = new Date(weekStart)
|
|
|
- date.setDate(weekStart.getDate() + dayOffset)
|
|
|
- const s = 100 + Math.floor(Math.random() * 40)
|
|
|
- const dval = 60 + Math.floor(Math.random() * 30)
|
|
|
- arr.push({ id: `${date.getTime()}-${i}`, date: formatDisplayDate(date), s, d: dval })
|
|
|
+ const weekStart = getWeekStart(current.value)
|
|
|
+ const weekEnd = getWeekEnd(current.value)
|
|
|
+ startTime = weekStart.toISOString()
|
|
|
+ try {
|
|
|
+ const we = new Date(weekEnd)
|
|
|
+ we.setHours(23, 59, 59, 999)
|
|
|
+ endTime = we.toISOString()
|
|
|
+ } catch (e) {
|
|
|
+ endTime = weekEnd.toISOString()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ try { if (typeof uni !== 'undefined' && uni.showLoading) uni.showLoading({ title: '加载中...' }) } catch (e) {}
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res: any = await listBloodPressure({ pageNum: 1, pageSize: 100, startTime, endTime })
|
|
|
+ if (res.statusCode === 401) {
|
|
|
+ uni.removeStorageSync('token')
|
|
|
+ uni.removeStorageSync('role')
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
+ return
|
|
|
}
|
|
|
+ if ((res.data as any) && (res.data as any).code === 200) {
|
|
|
+ const apiRecords = (res.data as any).data?.records || []
|
|
|
+ records.value = apiRecords.map((item: any) => ({ id: String(item.id), date: formatDisplayDate(new Date(item.measureTime)), s: Number(item.systolicPressure || 0), d: Number(item.diastolicPressure || 0) }))
|
|
|
+ try { await bpChart.draw(records, current, viewMode) } catch (e) { console.warn('bpChart draw failed', e) }
|
|
|
+ } else {
|
|
|
+ console.error('Fetch blood-pressure records failed', res.data)
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('Fetch blood-pressure error', e)
|
|
|
+ } finally {
|
|
|
+ try { if (typeof uni !== 'undefined' && uni.hideLoading) uni.hideLoading() } catch (e) {}
|
|
|
}
|
|
|
- return arr.sort((a, b) => (a.date < b.date ? 1 : -1))
|
|
|
}
|
|
|
|
|
|
// 将 records 聚合为每天一个点(取最新记录)
|
|
|
@@ -239,10 +260,20 @@ onMounted(() => {
|
|
|
} catch (e) {
|
|
|
console.warn('getCanvasSize failed on mounted', e)
|
|
|
}
|
|
|
- await bpChart.draw(records, current, viewMode)
|
|
|
+ // 拉取数据并绘制
|
|
|
+ await fetchRecords()
|
|
|
+ try { await bpChart.draw(records, current, viewMode) } catch (e) { console.warn('bpChart draw failed', e) }
|
|
|
}, 500)
|
|
|
})
|
|
|
|
|
|
+// 页面显示时检查登录态
|
|
|
+onShow(() => {
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
+ if (!token) {
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
// 监听并更新图表(轻微去抖)
|
|
|
watch([() => current.value], async () => {
|
|
|
setTimeout(async () => {
|
|
|
@@ -277,7 +308,7 @@ async function prevPeriod() {
|
|
|
}
|
|
|
current.value = d
|
|
|
pickerValue.value = [d.getFullYear() - 2000, d.getMonth()]
|
|
|
- records.value = generateMockRecords(d)
|
|
|
+ await fetchRecords()
|
|
|
await rebuildChart()
|
|
|
}
|
|
|
|
|
|
@@ -298,14 +329,14 @@ async function nextPeriod() {
|
|
|
}
|
|
|
current.value = d
|
|
|
pickerValue.value = [d.getFullYear() - 2000, d.getMonth()]
|
|
|
- records.value = generateMockRecords(d)
|
|
|
+ await fetchRecords()
|
|
|
await rebuildChart()
|
|
|
}
|
|
|
|
|
|
async function setViewMode(mode: 'month' | 'week') {
|
|
|
if (viewMode.value !== mode) {
|
|
|
viewMode.value = mode
|
|
|
- records.value = generateMockRecords(current.value)
|
|
|
+ await fetchRecords()
|
|
|
await rebuildChart()
|
|
|
}
|
|
|
}
|
|
|
@@ -326,7 +357,7 @@ async function onPickerChange(e: any) {
|
|
|
pickerValue.value = [val[0], val[1]]
|
|
|
}
|
|
|
current.value = d
|
|
|
- records.value = generateMockRecords(d)
|
|
|
+ await fetchRecords()
|
|
|
await rebuildChart()
|
|
|
}
|
|
|
}
|
|
|
@@ -388,13 +419,7 @@ async function confirmAdd() {
|
|
|
confirmText: '知道了'
|
|
|
})
|
|
|
}
|
|
|
- const id = `user-${Date.now()}`
|
|
|
- const item: RecordItem = {
|
|
|
- id,
|
|
|
- date: addDateLabel.value,
|
|
|
- s: Math.round(addSystolic.value),
|
|
|
- d: Math.round(addDiastolic.value)
|
|
|
- }
|
|
|
+ // 校验日期
|
|
|
const parts = addDate.value.split('-')
|
|
|
const addY = parseInt(parts[0], 10)
|
|
|
const addM = parseInt(parts[1], 10) - 1
|
|
|
@@ -404,25 +429,26 @@ async function confirmAdd() {
|
|
|
uni.showToast && uni.showToast({ title: '不能添加未来日期的数据', icon: 'none' })
|
|
|
return
|
|
|
}
|
|
|
- if (viewMode.value === 'month') {
|
|
|
- if (addY === current.value.getFullYear() && addM === current.value.getMonth()) {
|
|
|
- records.value = [item, ...records.value]
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res: any = await addBloodPressure({ systolicPressure: Math.round(addSystolic.value), diastolicPressure: Math.round(addDiastolic.value), measureTime: new Date(addDate.value).toISOString() })
|
|
|
+ if (res.statusCode === 401) {
|
|
|
+ uni.removeStorageSync('token')
|
|
|
+ uni.removeStorageSync('role')
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
+ return
|
|
|
}
|
|
|
- } else {
|
|
|
- // addDateObj already computed above
|
|
|
- const addWeekStart = getWeekStart(addDateObj)
|
|
|
- const curWeekStart = getWeekStart(current.value)
|
|
|
- if (addWeekStart.getTime() === curWeekStart.getTime()) {
|
|
|
- records.value = [item, ...records.value]
|
|
|
+ if ((res.data as any) && (res.data as any).code === 200) {
|
|
|
+ uni.showToast && uni.showToast({ title: '已添加', icon: 'success' })
|
|
|
+ closeAdd()
|
|
|
+ await fetchRecords()
|
|
|
+ try { await rebuildChart() } catch (e) { console.warn('rebuildChart after add failed', e) }
|
|
|
+ } else {
|
|
|
+ uni.showToast && uni.showToast({ title: '添加失败', icon: 'none' })
|
|
|
}
|
|
|
- }
|
|
|
- uni.showToast && uni.showToast({ title: '已添加', icon: 'success' })
|
|
|
- closeAdd()
|
|
|
- // 新增记录后彻底重建图表,确保像退出再进入一样刷新
|
|
|
- try {
|
|
|
- await rebuildChart()
|
|
|
} catch (e) {
|
|
|
- console.warn('rebuildChart after add failed', e)
|
|
|
+ console.error('Add blood-pressure error', e)
|
|
|
+ uni.showToast && uni.showToast({ title: '添加失败', icon: 'none' })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -433,8 +459,25 @@ async function confirmDeleteRecord(id: string) {
|
|
|
content: '确认删除该条记录吗?',
|
|
|
success: async (res: any) => {
|
|
|
if (res.confirm) {
|
|
|
- records.value = records.value.filter(r => r.id !== id)
|
|
|
- try { await rebuildChart() } catch (e) { console.warn('rebuildChart after delete failed', e) }
|
|
|
+ try {
|
|
|
+ const delRes: any = await deleteBloodPressure(id)
|
|
|
+ if (delRes.statusCode === 401) {
|
|
|
+ uni.removeStorageSync('token')
|
|
|
+ uni.removeStorageSync('role')
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if ((delRes.data as any) && (delRes.data as any).code === 200) {
|
|
|
+ records.value = records.value.filter(r => r.id !== id)
|
|
|
+ uni.showToast && uni.showToast({ title: '已删除', icon: 'success' })
|
|
|
+ try { await rebuildChart() } catch (e) { console.warn('rebuildChart after delete failed', e) }
|
|
|
+ } else {
|
|
|
+ uni.showToast && uni.showToast({ title: '删除失败', icon: 'none' })
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('Delete blood-pressure error', e)
|
|
|
+ uni.showToast && uni.showToast({ title: '删除失败', icon: 'none' })
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
})
|