CODE_EXAMPLES.md 9.3 KB

长者档案功能 - 代码示例

1. 组件使用示例

在父组件中使用 ElderProfileDialog

<template>
  <div>
    <!-- 其他内容 -->
    
    <!-- 长者档案弹窗 -->
    <ElderProfileDialog
      v-model="elderProfileDialogVisible"
      :elder-id="currentProfileElderId"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import ElderProfileDialog from './components/ElderProfileDialog.vue'

const elderProfileDialogVisible = ref(false)
const currentProfileElderId = ref(0)

// 打开档案弹窗
const openElderProfileDialog = (elderId: number) => {
  currentProfileElderId.value = elderId
  elderProfileDialogVisible.value = true
}
</script>

2. 事件处理示例

监听档案按钮点击事件

<template>
  <div>
    <!-- 长者卡片 -->
    <ElderlyCard
      v-for="elderly in elderlyList"
      :key="elderly.id"
      :elderly="elderly"
      @view-profile="handleViewProfile"
    />
  </div>
</template>

<script lang="ts" setup>
interface Elderly {
  id: number
  name: string
  age: number
}

const handleViewProfile = (elderly: Elderly) => {
  console.log(`查看 ${elderly.name} 的档案`)
  // 打开档案弹窗
  openElderProfileDialog(elderly.id)
}
</script>

3. 数据结构示例

长者档案数据结构

interface ElderProfileData {
  id?: number                    // 长者ID
  name: string                   // 长者名称
  avatar?: string                // 头像URL
  age: number                    // 年龄
  gender: string                 // 性别
  relativePhone?: string         // 家属电话
  elderPhone?: string            // 长者电话
  address?: string               // 长者地址
  warningData?: WarningRecord[]  // 预警历史
}

interface WarningRecord {
  eventType: string              // 预警类型
  message: string                // 预警信息
  happensAt: string              // 发生时间
}

4. API 调用示例

获取长者档案

import fetchHttp from '@/config/axios/fetchHttp'
import { getAccessToken } from '@/utils/auth'

// 调用接口获取长者档案
const fetchElderDetail = async (elderId: number) => {
  try {
    const res = await fetchHttp.get(
      `/api/pc/admin/getElderDetail?elderId=${elderId}`,
      {},
      {
        headers: {
          Authorization: `Bearer ${getAccessToken()}`
        }
      }
    )
    
    if (res) {
      console.log('长者档案:', res)
      return res
    }
  } catch (error) {
    console.error('获取长者档案失败:', error)
  }
}

5. 假数据生成示例

生成测试用的假数据

// 生成假数据
const generateMockData = (elderId: number) => {
  const names = ['王奶奶', '李爷爷', '张奶奶', '刘爷爷', '陈奶奶', '杨爷爷']
  const genders = ['女', '男']
  const addresses = [
    '北京市朝阳区建国路1号',
    '上海市浦东新区世纪大道100号',
    '广州市天河区珠江新城',
    '深圳市南山区科技园路1号',
    '杭州市西湖区文三路477号'
  ]
  
  return {
    id: elderId,
    name: names[elderId % names.length],
    age: 65 + (elderId % 20),
    gender: genders[elderId % 2],
    elderPhone: `1${Math.floor(Math.random() * 9) + 3}${String(Math.floor(Math.random() * 1000000000)).padStart(9, '0')}`,
    relativePhone: `1${Math.floor(Math.random() * 9) + 3}${String(Math.floor(Math.random() * 1000000000)).padStart(9, '0')}`,
    address: addresses[elderId % addresses.length],
    warningData: [
      {
        eventType: '跌倒预警',
        message: '检测到长者跌倒,请立即查看',
        happensAt: new Date().toISOString()
      }
    ]
  }
}

6. 样式自定义示例

自定义弹窗样式

<style lang="scss" scoped>
// 自定义对话框样式
:deep(.el-dialog__header) {
  background: linear-gradient(90deg, #1a73e8, #7b61ff) !important;
  border-radius: 12px 12px 0 0 !important;
}

// 自定义头像样式
.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: linear-gradient(135deg, #1a73e8, #7b61ff);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  font-weight: bold;
  color: white;
}

// 自定义预警样式
.warning-item {
  padding: 12px;
  background: rgb(253 150 68 / 10%);
  border-left: 3px solid #fd9644;
  border-radius: 6px;
}
</style>

7. 完整示例

完整的长者档案功能实现

<template>
  <div class="elder-profile-container">
    <!-- 长者列表 -->
    <div class="elderly-list">
      <div
        v-for="elderly in elderlyList"
        :key="elderly.id"
        class="elderly-item"
      >
        <span>{{ elderly.name }}</span>
        <button @click="openProfile(elderly.id)">查看档案</button>
      </div>
    </div>

    <!-- 档案弹窗 -->
    <ElderProfileDialog
      v-model="profileVisible"
      :elder-id="selectedElderId"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import ElderProfileDialog from './components/ElderProfileDialog.vue'

interface Elderly {
  id: number
  name: string
}

const elderlyList = ref<Elderly[]>([
  { id: 1, name: '王奶奶' },
  { id: 2, name: '李爷爷' },
  { id: 3, name: '张奶奶' }
])

const profileVisible = ref(false)
const selectedElderId = ref(0)

const openProfile = (elderId: number) => {
  selectedElderId.value = elderId
  profileVisible.value = true
}
</script>

<style scoped>
.elder-profile-container {
  padding: 20px;
}

.elderly-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.elderly-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

button {
  padding: 5px 15px;
  background: #1a73e8;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background: #1557b0;
}
</style>

8. 错误处理示例

处理接口错误和网络问题

const fetchElderDetail = async (elderId: number) => {
  loading.value = true
  
  try {
    const res = await fetchHttp.get(
      `/api/pc/admin/getElderDetail?elderId=${elderId}`,
      {},
      {
        headers: {
          Authorization: `Bearer ${getAccessToken()}`
        }
      }
    )

    if (res) {
      // 接口有数据
      elderData.value = res
    } else {
      // 接口暂无数据,使用假数据
      console.warn('接口暂无数据,使用假数据')
      elderData.value = generateMockData(elderId)
    }
  } catch (error) {
    // 接口出错,使用假数据
    console.error('获取长者档案失败:', error)
    ElMessage.warning('使用本地数据显示')
    elderData.value = generateMockData(elderId)
  } finally {
    loading.value = false
  }
}

9. 时间格式化示例

格式化预警时间

import { formatToDateTime } from '@/utils/dateUtil'

// 格式化时间
const formatTime = (time: string | number) => {
  if (!time) return '未知'
  return formatToDateTime(time)
}

// 使用示例
const warningTime = '2024-01-15T10:30:00Z'
console.log(formatTime(warningTime))  // 输出: 2024-01-15 10:30:00

10. 类型定义示例

完整的 TypeScript 类型定义

// 长者档案数据
interface ElderProfileData {
  id?: number
  name: string
  avatar?: string
  age: number
  gender: string
  relativePhone?: string
  elderPhone?: string
  address?: string
  warningData?: WarningRecord[]
}

// 预警记录
interface WarningRecord {
  eventType: string
  message: string
  happensAt: string
}

// 组件 Props
interface ElderProfileDialogProps {
  modelValue: boolean
  elderId?: number
}

// 组件 Emits
interface ElderProfileDialogEmits {
  'update:modelValue': [value: boolean]
}

11. 集成测试示例

测试长者档案功能

import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import ElderProfileDialog from './ElderProfileDialog.vue'

describe('ElderProfileDialog', () => {
  it('应该正确显示长者信息', () => {
    const wrapper = mount(ElderProfileDialog, {
      props: {
        modelValue: true,
        elderId: 1
      }
    })
    
    expect(wrapper.find('.profile-content').exists()).toBe(true)
  })

  it('应该在关闭时触发 update:modelValue 事件', async () => {
    const wrapper = mount(ElderProfileDialog, {
      props: {
        modelValue: true,
        elderId: 1
      }
    })
    
    await wrapper.vm.$emit('update:modelValue', false)
    expect(wrapper.emitted('update:modelValue')).toBeTruthy()
  })
})

12. 性能优化示例

使用缓存优化性能

// 缓存长者档案数据
const elderProfileCache = new Map<number, ElderProfileData>()

const fetchElderDetail = async (elderId: number) => {
  // 检查缓存
  if (elderProfileCache.has(elderId)) {
    elderData.value = elderProfileCache.get(elderId)!
    return
  }

  loading.value = true
  try {
    const res = await fetchHttp.get(
      `/api/pc/admin/getElderDetail?elderId=${elderId}`,
      {},
      {
        headers: {
          Authorization: `Bearer ${getAccessToken()}`
        }
      }
    )

    if (res) {
      // 缓存数据
      elderProfileCache.set(elderId, res)
      elderData.value = res
    }
  } catch (error) {
    console.error('获取长者档案失败:', error)
  } finally {
    loading.value = false
  }
}