import { query } from "./_generated/server"; import { mutation } from "./_generated/server"; import { v } from "convex/values"; import { getAuthUserId } from "@convex-dev/auth/server"; /** * 获取当前登录用户 */ export const currentUser = query({ args: {}, handler: async (ctx) => { const userId = await getAuthUserId(ctx); if (userId === null) { return null; } return await ctx.db.get(userId); }, }); function normalizeUsername(raw: string): string { const username = String(raw ?? "").trim(); if (!username) throw new Error("用户名不能为空"); if (username.length < 2 || username.length > 32) throw new Error("用户名长度需为 2-32 个字符"); if (/\s/.test(username)) throw new Error("用户名不能包含空格"); return username; } /** * 设置当前用户的唯一用户名(写入 users.name) */ export const setMyUsername = mutation({ args: { username: v.string() }, handler: async (ctx, args) => { const userId = await getAuthUserId(ctx); if (userId === null) throw new Error("未登录"); const username = normalizeUsername(args.username); // 说明:authTables 的 users 表目前没有为 name 建索引,这里用 filter 做一次全表扫描。 // 用户量较小的桌面场景可接受;后续如需优化可增加独立 username 索引表。 const existing = await ctx.db .query("users") .filter((q) => q.eq(q.field("name"), username)) .first(); if (existing && String(existing._id) !== String(userId)) { throw new Error("用户名已被占用"); } await ctx.db.patch(userId, { name: username }); return { ok: true, username }; }, });