feat(members): add members listing page

This commit introduces a new `/members` page to display a directory of alumni association members.

- Member data is sourced from a CSV file (`content/members/members.csv`) and managed via Nuxt Content.
- The page presents member information in a table, including calculated graduation class (`届别`).
- A link to the new page has been added to the main navigation.
- Minor UI tweaks and data corrections in other sections are also included.
This commit is contained in:
xiaomai
2025-11-02 21:53:33 +08:00
parent f5d9963f3c
commit 3da20d0097
11 changed files with 158 additions and 14 deletions

111
app/pages/members/index.vue Normal file
View File

@@ -0,0 +1,111 @@
<template>
<UPage>
<UContainer>
<UPageHeader title="会员总览" description="查询每个会员的信息" />
<UPageBody>
<UTable :data="members" :columns="columns" />
</UPageBody>
</UContainer>
</UPage>
</template>
<script lang="ts" setup>
import type { TableColumn } from "@nuxt/ui";
import { z } from "zod";
useSeoMeta({
title: "会员总览",
description: "永平中学校友会会员总览,查询每位校友的毕业年份、届别、加入年份与现居国家。",
keywords: "永平中学校友会, 校友会员, 毕业届别, 会员名录, 校友查询",
ogTitle: "永平中学校友会会员总览",
ogDescription:
"浏览永平中学校友会会员资料,了解各届校友的分布与加入年份。",
// ogImage: "/members/ogImage.png",
ogType: "website",
})
const MemberSchema = z.object({
chineseName: z.string(),
englishName: z.string(),
// ic: z.string(),
// mobile: z.string(),
// home: z.string(),
// email: z.string(),
graduateLevel: z.string(),
graduateYear: z.string(),
// marriageNtatus: z.string(),
livingCountry: z.string(),
// addressLine1: z.string(),
// addressLine2: z.string(),
// addressLine3: z.string(),
joinedYear: z.string(),
// receiptNumber: z.string(),
});
type Member = z.infer<typeof MemberSchema>;
const { data: members } = await useAsyncData("members", async () => {
const file = await queryCollection("members").first();
// ✅ 关键点:取 meta.body
return MemberSchema.array().parse(file?.meta.body);
});
const columns: TableColumn<Member>[] = [
{
accessorKey: "chineseName",
header: "中文姓名",
},
{
accessorKey: "englishName",
header: "英文姓名",
},
{
accessorKey: "graduateYear",
header: "毕业/离校年份",
},
{
accessorKey: "graduateLevel",
header: "毕业/离校届别",
cell: ({ row }) => {
switch (row.original.graduateLevel) {
case "j":
// 初中毕业
// 如果 row.original.graduateYear 不能转换成数字,就写成初中毕业
// 否则计算届别
return isNaN(Number(row.original.graduateYear))
? "初中毕业"
: `初中第 ${Number(row.original.graduateYear) - 1958}`;
case "s":
// 高中毕业
return isNaN(Number(row.original.graduateYear))
? "高中毕业"
: `高中第 ${Number(row.original.graduateYear) - 1965}`;
case "dj1":
return "初一肆业";
case "dj2":
return "初二肆业";
case "dj3":
return "初三肆业";
case "ds1":
return "高一肆业";
case "ds2":
return "高二肆业";
case "ds3":
return "高三肆业";
default:
break;
}
},
},
{
accessorKey: "joinedYear",
header: "加入年份",
},
{
accessorKey: "livingCountry",
header: "现居国家",
},
];
</script>
<style></style>