Files
martial-admin-mini/doc/数据结构设计.md
宅房 7bd197f4ac Mock版本完成 - UI冻结版本
完成内容:
- 5个完整的UI页面(登录、评分列表、评分详情、多场地列表、修改评分)
- 完整的Mock数据展示
- 完整的业务逻辑实现
- 文档体系建立(2000+行文档)

文档包含:
- 项目概述.md
- 页面功能说明.md
- API接口设计.md (17个接口)
- 数据结构设计.md (17个接口定义)
- 功能模块划分.md
- 后端实现对比报告.md
- 数据可行性分析报告.md (95分评估)
- 保护Mock版本的实施方案.md (4层保护机制)
- API对接完成度检查报告.md

此版本为Mock原型版本,所有UI功能完整,数据为硬编码Mock数据。
2025-12-11 13:22:19 +08:00

26 KiB
Raw Blame History

数据结构设计文档

文档说明

本文档定义了武术评分系统中所有核心数据结构和数据模型。这些数据结构用于前端状态管理、API请求响应、以及数据库设计参考。


一、用户角色相关

1.1 用户信息 (UserInfo)

interface UserInfo {
  userId: string              // 用户ID
  username: string            // 用户名
  realName: string            // 真实姓名
  role: 'pub' | 'admin'       // 角色: pub-普通评委, admin-裁判长
  phone?: string              // 手机号
  email?: string              // 邮箱
  avatar?: string             // 头像URL
  status: 'active' | 'inactive'  // 状态
  createdAt: string           // 创建时间 (ISO 8601)
  updatedAt: string           // 更新时间 (ISO 8601)
}

示例:

{
  "userId": "user_001",
  "username": "judge001",
  "realName": "欧阳丽娜",
  "role": "pub",
  "phone": "13800138000",
  "email": "judge001@example.com",
  "avatar": "https://example.com/avatar.jpg",
  "status": "active",
  "createdAt": "2025-01-01T00:00:00Z",
  "updatedAt": "2025-06-25T08:00:00Z"
}

1.2 登录凭证 (LoginCredentials)

interface LoginCredentials {
  matchCode: string           // 比赛编码
  inviteCode: string          // 邀请码
}

1.3 认证响应 (AuthResponse)

interface AuthResponse {
  token: string               // JWT Token
  userRole: 'pub' | 'admin'   // 用户角色
  matchId: string             // 比赛ID
  matchName: string           // 比赛名称
  matchTime: string           // 比赛时间
  judgeId: string             // 评委ID
  judgeName: string           // 评委姓名
  venueId?: string            // 场地ID (普通评委)
  venueName?: string          // 场地名称 (普通评委)
}

二、比赛相关

2.1 比赛信息 (Match)

interface Match {
  matchId: string             // 比赛ID
  matchName: string           // 比赛名称
  matchTime: string           // 比赛开始时间 (ISO 8601)
  matchEndTime: string        // 比赛结束时间 (ISO 8601)
  location: string            // 比赛地点
  status: MatchStatus         // 比赛状态
  description?: string        // 比赛说明
  venueCount: number          // 场地数量
  projectCount: number        // 项目数量
  athleteCount: number        // 选手总数
  judgeCount: number          // 评委总数
  createdAt: string           // 创建时间
  updatedAt: string           // 更新时间
}

type MatchStatus = 'upcoming' | 'ongoing' | 'finished'

示例:

{
  "matchId": "match_001",
  "matchName": "2025年全国武术散打锦标赛暨第十七届世界武术锦标赛选拔赛",
  "matchTime": "2025-06-25T09:00:00Z",
  "matchEndTime": "2025-06-25T18:00:00Z",
  "location": "北京体育馆",
  "status": "ongoing",
  "description": "全国性武术比赛",
  "venueCount": 5,
  "projectCount": 8,
  "athleteCount": 150,
  "judgeCount": 30,
  "createdAt": "2025-01-01T00:00:00Z",
  "updatedAt": "2025-06-25T08:00:00Z"
}

三、场地相关

3.1 场地信息 (Venue)

interface Venue {
  venueId: string             // 场地ID
  venueName: string           // 场地名称
  matchId: string             // 所属比赛ID
  order: number               // 排序顺序
  athleteCount: number        // 选手数量
  scoredCount: number         // 已评分数量
  status: VenueStatus         // 场地状态
  description?: string        // 场地描述
  createdAt: string           // 创建时间
}

type VenueStatus = 'active' | 'completed' | 'paused'

示例:

{
  "venueId": "venue_001",
  "venueName": "第一场地",
  "matchId": "match_001",
  "order": 1,
  "athleteCount": 30,
  "scoredCount": 25,
  "status": "active",
  "description": "主场地",
  "createdAt": "2025-01-01T00:00:00Z"
}

3.2 场地列表 (VenueList)

type VenueList = Venue[]

四、项目相关

4.1 项目信息 (Project)

interface Project {
  projectId: string           // 项目ID
  projectName: string         // 项目名称
  matchId: string             // 所属比赛ID
  category: string            // 项目类别 (如: 套路、太极拳)
  order: number               // 排序顺序
  athleteCount: number        // 参赛选手数
  minScore: number            // 最低分
  maxScore: number            // 最高分
  scoreStep: number           // 评分步进值
  status: ProjectStatus       // 项目状态
  description?: string        // 项目说明
  rules?: string              // 评分规则
  createdAt: string           // 创建时间
}

type ProjectStatus = 'upcoming' | 'ongoing' | 'completed'

示例:

{
  "projectId": "project_001",
  "projectName": "女子组长拳",
  "matchId": "match_001",
  "category": "套路",
  "order": 1,
  "athleteCount": 15,
  "minScore": 5.0,
  "maxScore": 10.0,
  "scoreStep": 0.001,
  "status": "ongoing",
  "description": "女子组长拳套路比赛",
  "rules": "按照国家标准执行",
  "createdAt": "2025-01-01T00:00:00Z"
}

4.2 项目列表

type ProjectList = Project[]

前端Mock数据:

const projectList = [
  '女子组长拳',
  '男子组陈氏太极拳',
  '女子组双剑(含长穗双剑)',
  '男子组杨氏太极拳',
  '女子组刀术',
  '男子组棍术',
  '女子组枪术',
  '男子组剑术'
]

五、选手相关

5.1 选手信息 (Athlete)

interface Athlete {
  athleteId: string           // 选手ID
  name: string                // 姓名
  gender: 'male' | 'female'   // 性别
  age?: number                // 年龄
  idCard: string              // 身份证号
  team: string                // 队伍/单位
  number: string              // 比赛编号
  order: number               // 出场顺序
  projectId: string           // 参赛项目ID
  projectName: string         // 参赛项目名称
  venueId: string             // 比赛场地ID
  venueName: string           // 比赛场地名称
  matchId: string             // 比赛ID
  photo?: string              // 照片URL
  defaultScore?: number       // 默认起评分
  status: AthleteStatus       // 选手状态
  createdAt: string           // 创建时间
}

type AthleteStatus = 'waiting' | 'performing' | 'finished'

示例:

{
  "athleteId": "athlete_001",
  "name": "张三",
  "gender": "male",
  "age": 25,
  "idCard": "123456789000000000",
  "team": "少林寺武术大学院",
  "number": "123-4567898275",
  "order": 1,
  "projectId": "project_001",
  "projectName": "女子组长拳",
  "venueId": "venue_001",
  "venueName": "第一场地",
  "matchId": "match_001",
  "photo": "https://example.com/athlete.jpg",
  "defaultScore": 8.907,
  "status": "finished",
  "createdAt": "2025-01-01T00:00:00Z"
}

5.2 选手列表项(普通评委视图)

interface AthleteListItem {
  athleteId: string           // 选手ID
  name: string                // 姓名
  gender: 'male' | 'female'   // 性别
  idCard: string              // 身份证号
  team: string                // 队伍
  number: string              // 比赛编号
  order: number               // 出场顺序
  myScore?: number            // 我的评分
  totalScore?: number         // 总分
  scored: boolean             // 是否已评分
  scoreTime?: string          // 评分时间
  status: AthleteStatus       // 状态
}

示例:

{
  "athleteId": "athlete_001",
  "name": "张三",
  "gender": "male",
  "idCard": "123456789000000000",
  "team": "少林寺武术大学院",
  "number": "123-4567898275",
  "order": 1,
  "myScore": 8.906,
  "totalScore": 8.907,
  "scored": true,
  "scoreTime": "2025-06-25T09:15:00Z",
  "status": "finished"
}

5.3 选手列表项(裁判长视图)

interface AthleteListItemAdmin {
  athleteId: string           // 选手ID
  name: string                // 姓名
  gender: 'male' | 'female'   // 性别
  idCard: string              // 身份证号
  team: string                // 队伍
  number: string              // 比赛编号
  order: number               // 出场顺序
  venueId: string             // 场地ID
  venueName: string           // 场地名称
  projectId: string           // 项目ID
  projectName: string         // 项目名称
  totalScore?: number         // 总分
  judgeCount: number          // 已评分评委数
  totalJudges: number         // 总评委数
  canModify: boolean          // 是否可修改
  status: AthleteStatus       // 状态
}

示例:

{
  "athleteId": "athlete_001",
  "name": "张三",
  "gender": "male",
  "idCard": "123456789000000000",
  "team": "少林寺武术大学院",
  "number": "123-4567898275",
  "order": 1,
  "venueId": "venue_001",
  "venueName": "第一场地",
  "projectId": "project_001",
  "projectName": "女子组长拳",
  "totalScore": 8.907,
  "judgeCount": 6,
  "totalJudges": 6,
  "canModify": true,
  "status": "finished"
}

六、评分相关

6.1 评分提交数据 (ScoreSubmit)

interface ScoreSubmit {
  matchId: string             // 比赛ID
  athleteId: string           // 选手ID
  judgeId: string             // 评委ID
  projectId: string           // 项目ID
  venueId: string             // 场地ID
  score: number               // 评分 (5.000 - 10.000)
  deductions: string[]        // 扣分项ID列表
  note?: string               // 备注
}

示例:

{
  "matchId": "match_001",
  "athleteId": "athlete_001",
  "judgeId": "judge_001",
  "projectId": "project_001",
  "venueId": "venue_001",
  "score": 8.907,
  "deductions": ["deduction_001", "deduction_003"],
  "note": "整体表现良好"
}

6.2 评分记录 (Score)

interface Score {
  scoreId: string             // 评分ID
  matchId: string             // 比赛ID
  athleteId: string           // 选手ID
  judgeId: string             // 评委ID
  projectId: string           // 项目ID
  venueId: string             // 场地ID
  score: number               // 评分
  deductions: Deduction[]     // 扣分项详情
  note?: string               // 备注
  scoreTime: string           // 评分时间 (ISO 8601)
  createdAt: string           // 创建时间
  updatedAt: string           // 更新时间
}

示例:

{
  "scoreId": "score_001",
  "matchId": "match_001",
  "athleteId": "athlete_001",
  "judgeId": "judge_001",
  "projectId": "project_001",
  "venueId": "venue_001",
  "score": 8.907,
  "deductions": [
    {
      "deductionId": "deduction_001",
      "text": "起势不稳",
      "score": -0.1
    }
  ],
  "note": "整体表现良好",
  "scoreTime": "2025-06-25T09:15:00Z",
  "createdAt": "2025-06-25T09:15:00Z",
  "updatedAt": "2025-06-25T09:15:00Z"
}

6.3 评委评分项(显示用)

interface JudgeScore {
  scoreId: string             // 评分ID
  judgeId: string             // 评委ID
  judgeName: string           // 评委姓名
  score: number               // 评分
  deductions: Deduction[]     // 扣分项
  note?: string               // 备注
  scoreTime: string           // 评分时间
}

示例:

{
  "scoreId": "score_001",
  "judgeId": "judge_001",
  "judgeName": "欧阳丽娜",
  "score": 8.907,
  "deductions": [
    {
      "deductionId": "deduction_001",
      "text": "起势不稳",
      "score": -0.1
    }
  ],
  "note": "整体表现良好",
  "scoreTime": "2025-06-25T09:15:00Z"
}

6.4 选手评分详情 (AthleteScoreDetail)

interface AthleteScoreDetail {
  athleteId: string           // 选手ID
  athleteName: string         // 选手姓名
  team: string                // 队伍
  number: string              // 比赛编号
  projectName: string         // 项目名称
  totalScore: number          // 总分
  judgeCount: number          // 已评分评委数
  totalJudges: number         // 总评委数
  judgeScores: JudgeScore[]   // 各评委评分
  modifications: ScoreModification[]  // 修改记录
}

示例:

{
  "athleteId": "athlete_001",
  "athleteName": "张三",
  "team": "少林寺武术大学院",
  "number": "123-4567898275",
  "projectName": "女子组长拳",
  "totalScore": 8.907,
  "judgeCount": 6,
  "totalJudges": 6,
  "judgeScores": [
    {
      "scoreId": "score_001",
      "judgeId": "judge_001",
      "judgeName": "欧阳丽娜",
      "score": 8.907,
      "deductions": [],
      "note": "表现良好",
      "scoreTime": "2025-06-25T09:15:00Z"
    }
  ],
  "modifications": []
}

七、评分修改相关

7.1 评分修改提交 (ScoreModifySubmit)

interface ScoreModifySubmit {
  athleteId: string           // 选手ID
  modifierId: string          // 修改人ID (裁判长)
  originalScore: number       // 原始分数
  modifiedScore: number       // 修改后的分数
  note: string                // 修改原因
}

示例:

{
  "athleteId": "athlete_001",
  "modifierId": "admin_001",
  "originalScore": 8.907,
  "modifiedScore": 8.910,
  "note": "技术动作优秀,加分"
}

7.2 评分修改记录 (ScoreModification)

interface ScoreModification {
  modifyId: string            // 修改记录ID
  athleteId: string           // 选手ID
  modifierId: string          // 修改人ID
  modifierName: string        // 修改人姓名
  originalScore: number       // 原始分数
  modifiedScore: number       // 修改后的分数
  note: string                // 修改原因
  modifyTime: string          // 修改时间 (ISO 8601)
  createdAt: string           // 创建时间
}

示例:

{
  "modifyId": "modify_001",
  "athleteId": "athlete_001",
  "modifierId": "admin_001",
  "modifierName": "总裁判长",
  "originalScore": 8.907,
  "modifiedScore": 8.910,
  "note": "技术动作优秀,加分",
  "modifyTime": "2025-06-25T10:00:00Z",
  "createdAt": "2025-06-25T10:00:00Z"
}

八、扣分项相关

8.1 扣分项 (Deduction)

interface Deduction {
  deductionId: string         // 扣分项ID
  projectId: string           // 所属项目ID
  text: string                // 扣分项描述
  score: number               // 扣分值 (负数)
  category?: string           // 分类
  order: number               // 排序
  createdAt: string           // 创建时间
}

示例:

{
  "deductionId": "deduction_001",
  "projectId": "project_001",
  "text": "起势不稳",
  "score": -0.1,
  "category": "基础动作",
  "order": 1,
  "createdAt": "2025-01-01T00:00:00Z"
}

8.2 扣分项选择(前端用)

interface DeductionItem {
  deductionId?: string        // 扣分项ID (对接后端后使用)
  text: string                // 扣分项描述
  checked: boolean            // 是否选中
}

前端Mock数据:

const deductions = [
  { text: '扣分项描述', checked: false },
  { text: '扣分项描述', checked: false },
  { text: '扣分项描述', checked: true },
  { text: '扣分项描述', checked: false },
  { text: '扣分项描述', checked: false },
  { text: '扣分项描述', checked: true },
  { text: '扣分项描述', checked: true },
  { text: '扣分项描述', checked: false }
]

九、统计分析相关

9.1 比赛统计 (MatchStatistics)

interface MatchStatistics {
  matchId: string             // 比赛ID
  totalAthletes: number       // 总选手数
  finishedAthletes: number    // 已完成评分选手数
  totalJudges: number         // 总评委数
  activeJudges: number        // 活跃评委数
  totalScores: number         // 总评分数
  averageScore: number        // 平均分
  highestScore: number        // 最高分
  lowestScore: number         // 最低分
  venueStats: VenueStatistics[]    // 各场地统计
  projectStats: ProjectStatistics[]  // 各项目统计
}

9.2 场地统计 (VenueStatistics)

interface VenueStatistics {
  venueId: string             // 场地ID
  venueName: string           // 场地名称
  athleteCount: number        // 选手数
  finishedCount: number       // 已完成数
  progress: number            // 进度百分比
}

示例:

{
  "venueId": "venue_001",
  "venueName": "第一场地",
  "athleteCount": 30,
  "finishedCount": 28,
  "progress": 93.3
}

9.3 项目统计 (ProjectStatistics)

interface ProjectStatistics {
  projectId: string           // 项目ID
  projectName: string         // 项目名称
  athleteCount: number        // 选手数
  finishedCount: number       // 已完成数
  averageScore: number        // 平均分
  progress: number            // 进度百分比
}

示例:

{
  "projectId": "project_001",
  "projectName": "女子组长拳",
  "athleteCount": 15,
  "finishedCount": 15,
  "averageScore": 8.650,
  "progress": 100
}

9.4 评委统计 (JudgeStatistics)

interface JudgeStatistics {
  judgeId: string             // 评委ID
  judgeName: string           // 评委姓名
  role: 'pub' | 'admin'       // 角色
  venueId?: string            // 场地ID
  venueName?: string          // 场地名称
  totalScores: number         // 总评分数
  averageScore: number        // 平均给分
  highestScore: number        // 最高给分
  lowestScore: number         // 最低给分
  lastScoreTime: string       // 最后评分时间
}

示例:

{
  "judgeId": "judge_001",
  "judgeName": "欧阳丽娜",
  "role": "pub",
  "venueId": "venue_001",
  "venueName": "第一场地",
  "totalScores": 25,
  "averageScore": 8.765,
  "highestScore": 9.500,
  "lowestScore": 7.800,
  "lastScoreTime": "2025-06-25T15:30:00Z"
}

十、前端页面数据结构

10.1 登录页数据 (LoginPageData)

interface LoginPageData {
  matchCode: string           // 比赛编码
  inviteCode: string          // 邀请码
}

10.2 评分列表页数据 (ScoreListPageData)

interface ScoreListPageData {
  matchInfo: {
    title: string             // 比赛标题
    time: string              // 比赛时间
  }
  venue: string               // 场地名称
  project: string             // 项目名称
  scoreStats: {
    scored: number            // 已评分数
    total: number             // 总数
  }
  players: AthleteListItem[]  // 选手列表
}

10.3 评分详情页数据 (ScoreDetailPageData)

interface ScoreDetailPageData {
  athleteId: string           // 选手ID
  athleteInfo: {
    name: string              // 姓名
    idCard: string            // 身份证号
    team: string              // 队伍
    number: string            // 编号
  }
  currentScore: number        // 当前评分
  note: string                // 备注
  minScore: number            // 最低分
  maxScore: number            // 最高分
  deductions: DeductionItem[] // 扣分项
}

10.4 多场地列表页数据 (ScoreListMultiPageData)

interface ScoreListMultiPageData {
  currentVenue: number        // 当前场地ID
  currentProject: number      // 当前项目索引
  venues: Venue[]             // 场地列表
  projects: string[]          // 项目列表
  scoreStats: {
    scored: number            // 已评分数
    total: number             // 总数
  }
  players: AthleteListItemAdmin[]  // 选手列表
}

10.5 修改评分页数据 (ModifyScorePageData)

interface ModifyScorePageData {
  athleteId: string           // 选手ID
  athleteInfo: {
    name: string              // 姓名
    idCard: string            // 身份证号
    team: string              // 队伍
    number: string            // 编号
  }
  originalScore: number       // 原始总分
  currentScore: number        // 修改后的分数
  note: string                // 修改备注
  minScore: number            // 最低分
  maxScore: number            // 最高分
  judgeScores: JudgeScore[]   // 评委评分列表
}

十一、全局数据结构

11.1 全局数据 (GlobalData)

interface GlobalData {
  userRole: 'pub' | 'admin'   // 用户角色
  matchCode: string           // 比赛编码
  token?: string              // JWT Token
  userInfo?: UserInfo         // 用户信息
  matchInfo?: Match           // 比赛信息
}

使用方式:

// 设置全局数据
getApp().globalData = {
  userRole: 'pub',
  matchCode: 'MATCH2025001'
}

// 获取全局数据
const globalData = getApp().globalData
const userRole = globalData.userRole

十二、WebSocket推送数据结构

12.1 新评分推送

interface NewScoreMessage {
  type: 'new_score'
  data: {
    athleteId: string
    athleteName: string
    judgeId: string
    judgeName: string
    score: number
    totalScore: number
    judgeCount: number
    timestamp: string
  }
}

12.2 评分修改推送

interface ScoreModifiedMessage {
  type: 'score_modified'
  data: {
    athleteId: string
    athleteName: string
    modifierId: string
    modifierName: string
    originalScore: number
    modifiedScore: number
    note: string
    timestamp: string
  }
}

12.3 选手状态更新推送

interface AthleteStatusMessage {
  type: 'athlete_status'
  data: {
    athleteId: string
    athleteName: string
    status: AthleteStatus
    timestamp: string
  }
}

十三、分页数据结构

13.1 分页请求参数 (PageRequest)

interface PageRequest {
  page: number                // 页码从1开始
  pageSize: number            // 每页数量
  sortBy?: string             // 排序字段
  sortOrder?: 'asc' | 'desc'  // 排序方向
}

13.2 分页响应数据 (PageResponse)

interface PageResponse<T> {
  total: number               // 总记录数
  page: number                // 当前页码
  pageSize: number            // 每页数量
  totalPages: number          // 总页数
  records: T[]                // 数据列表
}

示例:

{
  "total": 150,
  "page": 1,
  "pageSize": 20,
  "totalPages": 8,
  "records": [
    {
      "athleteId": "athlete_001",
      "name": "张三"
    }
  ]
}

十四、数据验证规则

14.1 评分验证

interface ScoreValidation {
  min: 5.000                  // 最低分
  max: 10.000                 // 最高分
  step: 0.001                 // 步进值
  precision: 3                // 小数位数
}

验证函数:

function validateScore(score) {
  return score >= 5.000 &&
         score <= 10.000 &&
         /^\d+\.\d{3}$/.test(score.toFixed(3))
}

14.2 必填字段验证

// 登录验证
const loginRequired = ['matchCode', 'inviteCode']

// 评分提交验证
const scoreSubmitRequired = [
  'matchId',
  'athleteId',
  'judgeId',
  'projectId',
  'venueId',
  'score'
]

// 评分修改验证
const scoreModifyRequired = [
  'athleteId',
  'modifierId',
  'originalScore',
  'modifiedScore',
  'note'
]

十五、枚举类型汇总

// 用户角色
enum UserRole {
  PUB = 'pub',              // 普通评委
  ADMIN = 'admin'           // 裁判长
}

// 比赛状态
enum MatchStatus {
  UPCOMING = 'upcoming',     // 未开始
  ONGOING = 'ongoing',       // 进行中
  FINISHED = 'finished'      // 已结束
}

// 场地状态
enum VenueStatus {
  ACTIVE = 'active',         // 进行中
  COMPLETED = 'completed',   // 已完成
  PAUSED = 'paused'          // 暂停
}

// 项目状态
enum ProjectStatus {
  UPCOMING = 'upcoming',     // 未开始
  ONGOING = 'ongoing',       // 进行中
  COMPLETED = 'completed'    // 已完成
}

// 选手状态
enum AthleteStatus {
  WAITING = 'waiting',       // 等待中
  PERFORMING = 'performing', // 表演中
  FINISHED = 'finished'      // 已完成
}

// 用户状态
enum UserStatus {
  ACTIVE = 'active',         // 激活
  INACTIVE = 'inactive'      // 停用
}

// 性别
enum Gender {
  MALE = 'male',             // 男
  FEMALE = 'female'          // 女
}

十六、数据关系图

Match (比赛)
  │
  ├─→ Venue (场地) [1:N]
  │     │
  │     └─→ Athlete (选手) [1:N]
  │
  ├─→ Project (项目) [1:N]
  │     │
  │     ├─→ Athlete (选手) [1:N]
  │     │
  │     └─→ Deduction (扣分项) [1:N]
  │
  ├─→ Judge (评委) [1:N]
  │     │
  │     └─→ Score (评分) [1:N]
  │
  └─→ Athlete (选手) [1:N]
        │
        ├─→ Score (评分) [1:N]
        │     │
        │     └─→ ScoreModification (修改记录) [1:N]
        │
        └─→ ScoreModification (修改记录) [1:N]

十七、数据存储建议

17.1 前端本地存储

// 使用 uni.setStorageSync 存储
const storageKeys = {
  TOKEN: 'auth_token',
  USER_INFO: 'user_info',
  MATCH_INFO: 'match_info',
  CACHE_VENUES: 'cache_venues',
  CACHE_PROJECTS: 'cache_projects'
}

// 存储Token
uni.setStorageSync(storageKeys.TOKEN, token)

// 获取Token
const token = uni.getStorageSync(storageKeys.TOKEN)

// 清除所有缓存
uni.clearStorageSync()

17.2 数据缓存策略

interface CacheStrategy {
  key: string                 // 缓存键
  ttl: number                 // 过期时间(秒)
  refresh: boolean            // 是否需要刷新
}

const cacheConfig = {
  matchInfo: { key: 'match', ttl: 3600, refresh: false },
  venues: { key: 'venues', ttl: 1800, refresh: false },
  projects: { key: 'projects', ttl: 1800, refresh: false },
  athletes: { key: 'athletes', ttl: 60, refresh: true }
}

附录TypeScript类型定义文件

建议创建 types/index.d.ts 文件,集中管理所有类型定义:

// types/index.d.ts

// 导出所有接口
export * from './user'
export * from './match'
export * from './venue'
export * from './project'
export * from './athlete'
export * from './score'
export * from './deduction'
export * from './statistics'

这样可以在项目中统一导入使用:

import { UserInfo, Match, Athlete, Score } from '@/types'