import bcrypt from 'bcryptjs' import prisma from '../lib/prisma' import { signAccessToken, signRefreshToken, verifyRefreshToken } from '../lib/jwt' export async function register(orgName: string, phone: string, password: string) { const existing = await prisma.user.findUnique({ where: { phone } }) if (existing) { throw { code: 'DUPLICATE', message: '该手机号已注册' } } const org = await prisma.organization.create({ data: { name: orgName, plan: 'FREE', maxEmployees: 20, }, }) const passwordHash = await bcrypt.hash(password, 10) const user = await prisma.user.create({ data: { orgId: org.id, phone, name: '管理员', passwordHash, role: 'ADMIN', }, }) // 自动创建根部门(公司名),作为组织架构的顶层节点 await prisma.department.create({ data: { orgId: org.id, name: orgName, parentId: null, level: 0, sortOrder: 0, description: '组织根节点', createdBy: user.id, }, }) await prisma.user.update({ where: { id: user.id }, data: { lastLoginAt: new Date() }, }) const accessToken = signAccessToken({ id: user.id, orgId: user.orgId, role: user.role }) const refreshToken = signRefreshToken({ id: user.id, orgId: user.orgId, role: user.role }) return { user: { id: user.id, orgId: user.orgId, name: user.name, phone: user.phone, role: user.role }, accessToken, refreshToken, } } /** * 平台管理员登录(仅 SUPER_ADMIN 角色可登录平台端) */ export async function platformLogin(phone: string, password: string) { const user = await prisma.user.findUnique({ where: { phone } }) if (!user) { throw { code: 'NOT_FOUND', message: '手机号或密码错误' } } const valid = await bcrypt.compare(password, user.passwordHash) if (!valid) { throw { code: 'AUTH_FAILED', message: '手机号或密码错误' } } if (user.role !== 'SUPER_ADMIN') { throw { code: 'FORBIDDEN', message: '该账号无平台管理权限' } } if (user.disabled) { throw { code: 'ACCOUNT_DISABLED', message: '该账号已被禁用' } } await prisma.user.update({ where: { id: user.id }, data: { lastLoginAt: new Date() }, }) const accessToken = signAccessToken({ id: user.id, orgId: user.orgId, role: user.role }) const refreshToken = signRefreshToken({ id: user.id, orgId: user.orgId, role: user.role }) return { user: { id: user.id, orgId: user.orgId, name: user.name, phone: user.phone, role: user.role }, accessToken, refreshToken, } } export async function login(phone: string, password: string) { const user = await prisma.user.findUnique({ where: { phone } }) if (!user) { throw { code: 'NOT_FOUND', message: '手机号或密码错误' } } const valid = await bcrypt.compare(password, user.passwordHash) if (!valid) { throw { code: 'AUTH_FAILED', message: '手机号或密码错误' } } if (user.disabled) { throw { code: 'ACCOUNT_DISABLED', message: '该账号已被禁用,请联系管理员' } } if (user.role === 'SUPER_ADMIN') { throw { code: 'FORBIDDEN', message: '平台管理员请使用平台管理入口登录' } } await prisma.user.update({ where: { id: user.id }, data: { lastLoginAt: new Date() }, }) const accessToken = signAccessToken({ id: user.id, orgId: user.orgId, role: user.role }) const refreshToken = signRefreshToken({ id: user.id, orgId: user.orgId, role: user.role }) return { user: { id: user.id, orgId: user.orgId, name: user.name, phone: user.phone, role: user.role }, accessToken, refreshToken, } } export async function refresh(refreshToken: string) { const payload = verifyRefreshToken(refreshToken) if (!payload) { throw { code: 'TOKEN_INVALID', message: 'Refresh Token 无效或已过期' } } const user = await prisma.user.findUnique({ where: { id: payload.id } }) if (!user) { throw { code: 'NOT_FOUND', message: '用户不存在' } } const accessToken = signAccessToken({ id: user.id, orgId: user.orgId, role: user.role }) return { accessToken } } export async function resetPassword(phone: string, newPassword: string) { const user = await prisma.user.findUnique({ where: { phone } }) if (!user) { throw { code: 'NOT_FOUND', message: '手机号未注册' } } const passwordHash = await bcrypt.hash(newPassword, 10) await prisma.user.update({ where: { id: user.id }, data: { passwordHash }, }) return { success: true } }