This commit is contained in:
aaron 2026-04-27 15:35:38 +08:00
parent cd80ae04ec
commit 1ad9880a14
2 changed files with 38 additions and 4 deletions

View File

@ -161,6 +161,18 @@ const COMMITTEE_PRESETS: Array<{
"resource_manage", "resource_manage",
], ],
}, },
{
role: "宣传委员",
description: "负责公告发布、班级宣传与内容协同传播",
permissions: [
"class_view",
"member_view",
"announcement_manage",
"timeline_manage",
"vote_manage",
"resource_manage",
],
},
{ {
role: "生活委员", role: "生活委员",
description: "负责生活事务通知与班费相关管理", description: "负责生活事务通知与班费相关管理",
@ -327,6 +339,17 @@ export default function MembersPage() {
toast.success("邀请码已复制"); toast.success("邀请码已复制");
}; };
const handleCopyActivationLink = () => {
if (!inviteCode) {
toast.error("当前暂无可用邀请码");
return;
}
const activationLink = `${window.location.origin}/activate?code=${encodeURIComponent(inviteCode)}`;
navigator.clipboard.writeText(activationLink);
toast.success("激活链接已复制");
};
const handleRegenerateCode = async () => { const handleRegenerateCode = async () => {
try { try {
const res = await postAPI<InviteCodeResponse>( const res = await postAPI<InviteCodeResponse>(
@ -632,13 +655,16 @@ export default function MembersPage() {
<Button variant="outline" size="sm" onClick={handleCopyCode}> <Button variant="outline" size="sm" onClick={handleCopyCode}>
</Button> </Button>
<Button variant="outline" size="sm" onClick={handleCopyActivationLink}>
</Button>
<Button variant="outline" size="sm" onClick={handleRegenerateCode}> <Button variant="outline" size="sm" onClick={handleRegenerateCode}>
</Button> </Button>
</div> </div>
</div> </div>
<p className="mt-2 text-xs text-[#9a7b68]"> <p className="mt-2 text-xs text-[#9a7b68]">
</p> </p>
</CardContent> </CardContent>
</Card> </Card>

View File

@ -1,7 +1,7 @@
"use client"; "use client";
import { useState } from "react"; import { useEffect, useState } from "react";
import { useRouter } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
@ -19,6 +19,14 @@ export default function ActivatePage() {
const [error, setError] = useState(""); const [error, setError] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams();
useEffect(() => {
const code = searchParams.get("code")?.trim();
if (code) {
setInviteCode(code.toUpperCase());
}
}, [searchParams]);
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
@ -69,7 +77,7 @@ export default function ActivatePage() {
</h1> </h1>
<p className="mt-5 max-w-xl text-base leading-8 text-[#775a4a]"> <p className="mt-5 max-w-xl text-base leading-8 text-[#775a4a]">
使 使
</p> </p>
</div> </div>