diff --git a/app/api/roles/users/route.ts b/app/api/roles/users/route.ts
index ed78dda..f6e8a24 100644
--- a/app/api/roles/users/route.ts
+++ b/app/api/roles/users/route.ts
@@ -1,43 +1,49 @@
import { createDb } from "@/lib/db"
-import { userRoles, users } from "@/lib/schema"
+import { users } from "@/lib/schema"
import { eq } from "drizzle-orm"
export const runtime = "edge"
-export async function GET(request: Request) {
- const url = new URL(request.url)
- const email = url.searchParams.get('email')
+export async function POST(request: Request) {
+ try {
+ const json = await request.json()
+ const { searchText } = json as { searchText: string }
- if (!email) {
- return Response.json(
- { error: "邮箱地址不能为空" },
- { status: 400 }
- )
- }
+ if (!searchText) {
+ return Response.json({ error: "请提供用户名或邮箱地址" }, { status: 400 })
+ }
- const db = createDb()
-
- const user = await db.query.users.findFirst({
- where: eq(users.email, email),
- })
+ const db = createDb()
- if (!user) {
- return Response.json({ user: null })
- }
+ const user = await db.query.users.findFirst({
+ where: searchText.includes('@') ? eq(users.email, searchText) : eq(users.username, searchText),
+ with: {
+ userRoles: {
+ with: {
+ role: true
+ }
+ }
+ }
+ });
- const userRole = await db.query.userRoles.findFirst({
- where: eq(userRoles.userId, user.id),
- with: {
- role: true
+ if (!user) {
+ return Response.json({ error: "未找到用户" }, { status: 404 })
}
- })
- return Response.json({
- user: {
- id: user.id,
- name: user.name,
- email: user.email,
- role: userRole?.role.name
- }
- })
+ return Response.json({
+ user: {
+ id: user.id,
+ name: user.name,
+ username: user.username,
+ email: user.email,
+ role: user.userRoles[0]?.role.name
+ }
+ })
+ } catch (error) {
+ console.error("Failed to find user:", error)
+ return Response.json(
+ { error: "查询用户失败" },
+ { status: 500 }
+ )
+ }
}
\ No newline at end of file
diff --git a/app/components/profile/profile-card.tsx b/app/components/profile/profile-card.tsx
index ea8bb2c..d45f2d4 100644
--- a/app/components/profile/profile-card.tsx
+++ b/app/components/profile/profile-card.tsx
@@ -58,7 +58,9 @@ export function ProfileCard({ user }: ProfileCardProps) {
}
- {user.email}
+ {
+ user.email ? user.email : `用户名: ${user.username}`
+ }
{user.roles && (
diff --git a/app/components/profile/promote-panel.tsx b/app/components/profile/promote-panel.tsx
index e51e724..8265029 100644
--- a/app/components/profile/promote-panel.tsx
+++ b/app/components/profile/promote-panel.tsx
@@ -8,20 +8,34 @@ import { useToast } from "@/components/ui/use-toast"
import { ROLES } from "@/lib/permissions"
export function PromotePanel() {
- const [email, setEmail] = useState("")
+ const [searchText, setSearchText] = useState("")
const [loading, setLoading] = useState(false)
const [action, setAction] = useState<"promote" | "demote">("promote")
const { toast } = useToast()
const handleAction = async () => {
- if (!email) return
+ if (!searchText) return
setLoading(true)
try {
- const res = await fetch(`/api/roles/users?email=${encodeURIComponent(email)}`)
- const data = await res.json() as { user?: { id: string; name?: string; email: string; role?: string }; error?: string }
+ const res = await fetch("/api/roles/users", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ searchText })
+ })
+ const data = await res.json() as {
+ user?: {
+ id: string
+ name?: string
+ username?: string
+ email: string
+ role?: string
+ }
+ error?: string
+ }
+
+ if (!res.ok) throw new Error(data.error || "未知错误")
- if (!res.ok) throw new Error(data.error || '未知错误')
if (!data.user) {
toast({
title: "未找到用户",
@@ -61,9 +75,9 @@ export function PromotePanel() {
toast({
title: action === "promote" ? "册封成功" : "贬为平民",
- description: `已将 ${data.user.email} ${action === "promote" ? "册封为骑士" : "贬为平民"}`
+ description: `已将 ${data.user.email || data.user.username} ${action === "promote" ? "册封为骑士" : "贬为平民"}`
})
- setEmail("")
+ setSearchText("")
} catch (error) {
toast({
@@ -86,9 +100,9 @@ export function PromotePanel() {
setEmail(e.target.value)}
+ placeholder="输入用户名或邮箱"
+ value={searchText}
+ onChange={(e) => setSearchText(e.target.value)}
disabled={loading}
/>
@@ -98,7 +112,7 @@ export function PromotePanel() {
setAction("promote")
handleAction()
}}
- disabled={!email || loading}
+ disabled={!searchText || loading}
className="flex-1 sm:flex-initial gap-2"
>
{loading && action === "promote" ? (
@@ -113,7 +127,7 @@ export function PromotePanel() {
setAction("demote")
handleAction()
}}
- disabled={!email || loading}
+ disabled={!searchText || loading}
variant="destructive"
className="flex-1 sm:flex-initial gap-2"
>
diff --git a/app/lib/schema.ts b/app/lib/schema.ts
index 1d80ae6..ed21e30 100644
--- a/app/lib/schema.ts
+++ b/app/lib/schema.ts
@@ -85,10 +85,6 @@ export const roles = sqliteTable("role", {
updatedAt: integer("updated_at", { mode: "timestamp" }).$defaultFn(() => new Date()),
});
-export const rolesRelations = relations(roles, ({ many }) => ({
- userRoles: many(userRoles),
-}));
-
export const userRoles = sqliteTable("user_role", {
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
roleId: text("role_id").notNull().references(() => roles.id, { onDelete: "cascade" }),
@@ -106,4 +102,12 @@ export const userRolesRelations = relations(userRoles, ({ one }) => ({
fields: [userRoles.roleId],
references: [roles.id],
}),
-}));
\ No newline at end of file
+}));
+
+export const usersRelations = relations(users, ({ many }) => ({
+ userRoles: many(userRoles),
+}));
+
+export const rolesRelations = relations(roles, ({ many }) => ({
+ userRoles: many(userRoles),
+}));
\ No newline at end of file