diff --git a/app/modules/scoreboard/DataTable.vue b/app/modules/scoreboard/DataTable.vue new file mode 100644 index 0000000..0dcc013 --- /dev/null +++ b/app/modules/scoreboard/DataTable.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/app/modules/scoreboard/ModuleLayout.vue b/app/modules/scoreboard/ModuleLayout.vue new file mode 100644 index 0000000..1749a0e --- /dev/null +++ b/app/modules/scoreboard/ModuleLayout.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/app/modules/scoreboard/README.md b/app/modules/scoreboard/README.md new file mode 100644 index 0000000..2ae860f --- /dev/null +++ b/app/modules/scoreboard/README.md @@ -0,0 +1,155 @@ +# 运动会记分板模块 + +可复用的运动会管理模块,提供完整的比赛项目、队伍、成绩管理功能。 + +## 目录结构 + +``` +modules/scoreboard/ +├── index.ts # 模块配置和常量 +├── api.ts # API 工具函数 +├── mod.ts # 模块导出 +├── ModuleLayout.vue # 模块布局组件 +├── StatCard.vue # 统计卡片组件 +└── DataTable.vue # 数据表格组件 +``` + +## 使用方式 + +### 1. 导入配置常量 + +```ts +import { + EVENT_CATEGORIES, + TEAM_GROUPS, + EVENT_TYPES, + SCORING_RULES +} from '~/modules/scoreboard' + +// 使用示例 +const categories = Object.values(EVENT_CATEGORIES) +// ['田赛', '径赛', '团体赛'] +``` + +### 2. 使用 API 函数 + +```ts +import { + fetchEvents, + fetchTeams, + fetchResults, + fetchScoreboard, + createResult +} from '~/modules/scoreboard' + +// 获取所有比赛项目 +const events = await fetchEvents() + +// 按类别筛选 +const trackEvents = await fetchEvents({ category: '径赛' }) + +// 获取队伍 +const teams = await fetchTeams({ group: '文化班甲组' }) + +// 录入成绩 +await createResult({ + event_id: 1, + team_id: 1, + score: '10.5', + rank: 1 +}) + +// 获取记分板 +const scoreboard = await fetchScoreboard() +``` + +### 3. 使用 UI 组件 + +```vue + + + +``` + +## 积分规则 + +| 名次 | 积分 | 奖牌 | +|------|------|------| +| 第 1 名 | 7 分 | 金牌 | +| 第 2 名 | 5 分 | 银牌 | +| 第 3 名 | 3 分 | 铜牌 | + +## 比赛项目 + +### 田赛 +- 跳高(米) +- 跳远(米) +- 掷铅球(米) + +### 径赛 +- 100m(秒) +- 200m(秒) +- 400m(秒) +- 4×100m(秒) +- 4×400m(秒) +- 20×50m(秒) + +### 团体赛 +- 旱地龙舟(秒) +- 跳长绳(次) +- 折返跑(秒) + +## 组别 + +- 教师组 +- 航空班组 +- 体育班组 +- 文化班甲组 +- 文化班乙组 + +## API 接口 + +| 接口 | 方法 | 描述 | +|------|------|------| +| `/api/config` | GET | 获取系统配置 | +| `/api/events` | GET/POST | 比赛项目管理 | +| `/api/teams` | GET/POST | 队伍管理 | +| `/api/results` | GET/POST | 成绩管理 | +| `/api/scoreboard` | GET | 记分板数据 | +| `/api/seed` | POST | 初始化数据 | + +## 扩展模块 + +可以通过以下方式扩展模块功能: + +1. 添加新的比赛项目类型 +2. 自定义积分规则 +3. 添加数据导出功能 +4. 集成图表展示 +5. 添加实时通知 + +## License + +MIT diff --git a/app/modules/scoreboard/StatCard.vue b/app/modules/scoreboard/StatCard.vue new file mode 100644 index 0000000..5f96b6d --- /dev/null +++ b/app/modules/scoreboard/StatCard.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/app/modules/scoreboard/api.ts b/app/modules/scoreboard/api.ts new file mode 100644 index 0000000..7ae52b6 --- /dev/null +++ b/app/modules/scoreboard/api.ts @@ -0,0 +1,106 @@ +/** + * 记分板模块 API 工具函数 + */ + +/** + * 获取配置信息 + */ +export const fetchConfig = async () => { + const res = await $fetch('/api/config') + return res.data +} + +/** + * 获取比赛项目列表 + */ +export const fetchEvents = async (params?: { category?: string; group?: string }) => { + const query = new URLSearchParams() + if (params?.category) query.append('category', params.category) + if (params?.group) query.append('group', params.group) + const res = await $fetch(`/api/events?${query}`) + return res.data +} + +/** + * 创建比赛项目 + */ +export const createEvent = async (data: { + name: string + category: string + event_group: string + unit: string +}) => { + const res = await $fetch('/api/events', { + method: 'POST', + body: data + }) + return res.data +} + +/** + * 获取队伍列表 + */ +export const fetchTeams = async (params?: { group?: string }) => { + const query = new URLSearchParams() + if (params?.group) query.append('group', params.group) + const res = await $fetch(`/api/teams?${query}`) + return res.data +} + +/** + * 创建队伍 + */ +export const createTeam = async (data: { name: string; team_group: string }) => { + const res = await $fetch('/api/teams', { + method: 'POST', + body: data + }) + return res.data +} + +/** + * 获取成绩列表 + */ +export const fetchResults = async (params?: { event_id?: number; team_id?: number }) => { + const query = new URLSearchParams() + if (params?.event_id) query.append('event_id', String(params.event_id)) + if (params?.team_id) query.append('team_id', String(params.team_id)) + const res = await $fetch(`/api/results?${query}`) + return res.data +} + +/** + * 录入成绩 + */ +export const createResult = async (data: { + event_id: number + team_id: number + score: string + rank?: number +}) => { + const res = await $fetch('/api/results', { + method: 'POST', + body: data + }) + return res.data +} + +/** + * 获取记分板数据 + */ +export const fetchScoreboard = async (params?: { group?: string }) => { + const query = new URLSearchParams() + if (params?.group) query.append('group', params.group) + const res = await $fetch(`/api/scoreboard?${query}`) + return res.data +} + +/** + * 初始化示例数据 + */ +export const seedData = async () => { + const res = await $fetch('/api/seed', { + method: 'POST' + }) + return res +} diff --git a/app/modules/scoreboard/index.ts b/app/modules/scoreboard/index.ts new file mode 100644 index 0000000..ab73c68 --- /dev/null +++ b/app/modules/scoreboard/index.ts @@ -0,0 +1,77 @@ +/** + * 运动会记分板系统模块 + * + * 此模块提供完整的运动会管理功能 + * 可作为独立模块集成到更大的系统中 + */ + +// 模块配置 +export const scoreboardModule = { + name: 'scoreboard', + version: '1.0.0', + description: '运动会记分板管理模块' +} + +// 比赛类别配置 +export const EVENT_CATEGORIES = { + FIELD: '田赛', + TRACK: '径赛', + TEAM: '团体赛' +} as const + +// 组别配置 +export const TEAM_GROUPS = { + TEACHER: '教师组', + AVIATION: '航空班组', + SPORTS: '体育班组', + CULTURE_A: '文化班甲组', + CULTURE_B: '文化班乙组' +} as const + +// 项目配置 +export const EVENT_TYPES = { + [EVENT_CATEGORIES.FIELD]: [ + { name: '跳高', unit: '米' }, + { name: '跳远', unit: '米' }, + { name: '掷铅球', unit: '米' } + ], + [EVENT_CATEGORIES.TRACK]: [ + { name: '100m', unit: '秒' }, + { name: '200m', unit: '秒' }, + { name: '400m', unit: '秒' }, + { name: '4×100m', unit: '秒' }, + { name: '4×400m', unit: '秒' }, + { name: '20×50m', unit: '秒' } + ], + [EVENT_CATEGORIES.TEAM]: [ + { name: '旱地龙舟', unit: '秒' }, + { name: '跳长绳', unit: '次' }, + { name: '折返跑', unit: '秒' } + ] +} + +// 积分规则 +export const SCORING_RULES = { + GOLD: { rank: 1, points: 7, medal: 'gold' }, + SILVER: { rank: 2, points: 5, medal: 'silver' }, + BRONZE: { rank: 3, points: 3, medal: 'bronze' } +} + +// API 路由 +export const API_ROUTES = { + EVENTS: '/api/events', + TEAMS: '/api/teams', + RESULTS: '/api/results', + SCOREBOARD: '/api/scoreboard', + CONFIG: '/api/config', + SEED: '/api/seed' +} as const + +// 页面路由 +export const PAGE_ROUTES = { + HOME: '/', + EVENTS: '/events', + TEAMS: '/teams', + RESULTS: '/results', + SCOREBOARD: '/scoreboard' +} as const diff --git a/app/modules/scoreboard/mod.ts b/app/modules/scoreboard/mod.ts new file mode 100644 index 0000000..855d46d --- /dev/null +++ b/app/modules/scoreboard/mod.ts @@ -0,0 +1,50 @@ +/** + * 运动会记分板模块导出 + * + * 使用示例: + * ```ts + * import { + * EVENT_CATEGORIES, + * TEAM_GROUPS, + * EVENT_TYPES, + * SCORING_RULES, + * API_ROUTES, + * fetchEvents, + * fetchTeams, + * fetchResults, + * fetchScoreboard + * } from '~/modules/scoreboard' + * ``` + */ + +// 配置常量 +export { + EVENT_CATEGORIES, + TEAM_GROUPS, + EVENT_TYPES, + SCORING_RULES, + API_ROUTES, + PAGE_ROUTES, + scoreboardModule +} from './index' + +// API 函数 +export { + fetchConfig, + fetchEvents, + createEvent, + fetchTeams, + createTeam, + fetchResults, + createResult, + fetchScoreboard, + seedData +} from './api' + +// Vue 组件 +export { default as ModuleLayout } from './ModuleLayout.vue' +export { default as StatCard } from './StatCard.vue' +export { default as DataTable } from './DataTable.vue' + +// 类型导出 +export type { Column } from './DataTable.vue'