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:
@@ -58,6 +58,7 @@ const generation = route.params.slug;
|
||||
|
||||
const categories = ref(["领导团队", "职能部门", "专项部门"]);
|
||||
|
||||
// TODO: Fetch from api
|
||||
const orgStructure = ref([
|
||||
{
|
||||
name: "李煜斌",
|
||||
@@ -132,14 +133,14 @@ const orgStructure = ref([
|
||||
},
|
||||
{
|
||||
name: "胡少菲",
|
||||
position: "总务",
|
||||
position: "康乐",
|
||||
category: "职能部门",
|
||||
photo: "/org-structure/胡少菲.png",
|
||||
description: "文化活动策划、康乐项目组织与会员联谊活动。",
|
||||
},
|
||||
{
|
||||
name: "林剑宝",
|
||||
position: "副总务",
|
||||
position: "副康乐",
|
||||
category: "职能部门",
|
||||
photo: "/org-structure/林剑宝.png",
|
||||
description: "协助文康组织文体活动、兴趣小组与社交聚会。",
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
<UPageHero
|
||||
class="bg-cover bg-center"
|
||||
style="
|
||||
background-image: url("/hero-image.jpg");
|
||||
background-image: url("/hero-image-2.jpg");
|
||||
background-position-y: -40px;
|
||||
background-repeat: no-repeat;
|
||||
background-color: rgba(255, 255, 255, 0.5); /* Semi-transparent black */
|
||||
background-blend-mode: lighten;
|
||||
"
|
||||
|
||||
111
app/pages/members/index.vue
Normal file
111
app/pages/members/index.vue
Normal 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>
|
||||
Reference in New Issue
Block a user