summaryrefslogtreecommitdiff
path: root/lib/users/service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/users/service.ts')
-rw-r--r--lib/users/service.ts250
1 files changed, 246 insertions, 4 deletions
diff --git a/lib/users/service.ts b/lib/users/service.ts
index ad01c22a..9671abfb 100644
--- a/lib/users/service.ts
+++ b/lib/users/service.ts
@@ -6,15 +6,15 @@ import { getAllUsers, createUser, getUserById, updateUser, deleteUser, getUserBy
import logger from '@/lib/logger';
import { Role, userRoles, users, userView, type User } from '@/db/schema/users';
import { saveDocument } from '../storage';
-import { GetUsersSchema } from '../admin-users/validations';
-import { revalidateTag, unstable_cache, unstable_noStore } from 'next/cache';
+import { GetSimpleUsersSchema, GetUsersSchema } from '../admin-users/validations';
+import { revalidatePath, revalidateTag, unstable_cache, unstable_noStore } from 'next/cache';
import { filterColumns } from '../filter-columns';
-import { countUsers, selectUsersWithCompanyAndRoles } from '../admin-users/repository';
+import { countUsers, countUsersSimple, selectUsers, selectUsersWithCompanyAndRoles } from '../admin-users/repository';
import db from "@/db/db";
import { getErrorMessage } from "@/lib/handle-error";
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/app/api/auth/[...nextauth]/route"
-import { and, or, desc, asc, ilike, eq, isNull, sql, count, inArray } from "drizzle-orm";
+import { and, or, desc, asc, ilike, eq, isNull, sql, count, inArray, ne } from "drizzle-orm";
interface AssignUsersArgs {
roleId: number
@@ -340,6 +340,82 @@ export async function getUsersEVCP(input: GetUsersSchema) {
)();
}
+
+export async function getUsersNotPartners(input: GetSimpleUsersSchema) {
+ return unstable_cache(
+ async () => {
+ try {
+ const offset = (input.page - 1) * input.perPage;
+
+ // (1) advancedWhere
+ const advancedWhere = filterColumns({
+ table: users,
+ filters: input.filters,
+ joinOperator: input.joinOperator,
+ });
+
+ // (2) globalWhere
+ let globalWhere;
+ if (input.search) {
+ const s = `%${input.search}%`;
+ globalWhere = or(
+ ilike(users.name, s),
+ ilike(users.email, s),
+ ilike(users.deptName, s),
+ );
+ }
+
+ // (3) 디폴트 domainWhere = eq(userView.domain, "partners")
+ // 다만, 사용자가 이미 domain 필터를 줬다면 적용 X
+ let domainWhere;
+ const hasDomainFilter = input.filters?.some((f) => f.id === "domain");
+ if (!hasDomainFilter) {
+ domainWhere = ne(users.domain, "partners");
+ }
+
+ // (4) 최종 where
+ const finalWhere = and(advancedWhere, globalWhere, domainWhere);
+
+ // (5) 정렬
+ const orderBy =
+ input.sort.length > 0
+ ? input.sort.map((item) =>
+ item.desc ? desc(users[item.id]) : asc(users[item.id])
+ )
+ : [desc(users.createdAt)];
+
+ // ...
+ const { data, total } = await db.transaction(async (tx) => {
+ const data = await selectUsers(tx, {
+ where: finalWhere,
+ orderBy,
+ offset,
+ limit: input.perPage,
+ });
+
+
+ console.log(data)
+
+ const total = await countUsersSimple(tx, finalWhere);
+ return { data, total };
+ });
+
+ const pageCount = Math.ceil(total / input.perPage);
+ return { data, pageCount };
+ } catch (err) {
+
+ console.log(err)
+ return { data: [], pageCount: 0 };
+ }
+ },
+ [JSON.stringify(input)],
+ {
+ revalidate: 3600,
+ tags: ["users-access-control"],
+ }
+ )();
+}
+
export async function getAllRoles(): Promise<Role[]> {
try {
return await findAllRoles();
@@ -507,3 +583,169 @@ export async function assignUsersToRole(roleId: number, userIds: number[]) {
}
}
+
+
+export type UserDomain = "pending" | "evcp" | "procurement" | "sales" | "engineering" | "partners"
+
+/**
+ * 여러 사용자에게 도메인을 일괄 할당하는 함수
+ */
+export async function assignUsersDomain(
+ userIds: number[],
+ domain: UserDomain
+) {
+ try {
+ if (!userIds.length) {
+ return {
+ success: false,
+ message: "할당할 사용자가 없습니다."
+ }
+ }
+
+ if (!domain) {
+ return {
+ success: false,
+ message: "도메인을 선택해주세요."
+ }
+ }
+
+ // 사용자들의 도메인 업데이트
+ const result = await db
+ .update(users)
+ .set({
+ domain,
+ updatedAt: new Date(),
+ })
+ .where(inArray(users.id, userIds))
+ .returning({
+ id: users.id,
+ name: users.name,
+ email: users.email,
+ domain: users.domain,
+ })
+
+ // 관련 페이지들 revalidate
+ revalidatePath("/evcp/user-management")
+ revalidatePath("/")
+
+ return {
+ success: true,
+ message: `${result.length}명의 사용자 도메인이 업데이트되었습니다.`,
+ data: result
+ }
+ } catch (error) {
+ console.error("사용자 도메인 할당 오류:", error)
+ return {
+ success: false,
+ message: "도메인 할당 중 오류가 발생했습니다."
+ }
+ }
+}
+
+/**
+ * 단일 사용자의 도메인을 변경하는 함수
+ */
+export async function assignUserDomain(
+ userId: number,
+ domain: UserDomain
+) {
+ try {
+ const result = await db
+ .update(users)
+ .set({
+ domain,
+ updatedAt: new Date(),
+ })
+ .where(eq(users.id, userId))
+ .returning({
+ id: users.id,
+ name: users.name,
+ email: users.email,
+ domain: users.domain,
+ })
+
+ if (result.length === 0) {
+ return {
+ success: false,
+ message: "사용자를 찾을 수 없습니다."
+ }
+ }
+
+ revalidatePath("/evcp/user-management")
+ revalidatePath("/evcp/users")
+
+ return {
+ success: true,
+ message: `${result[0].name}님의 도메인이 ${domain}으로 변경되었습니다.`,
+ data: result[0]
+ }
+ } catch (error) {
+ console.error("사용자 도메인 할당 오류:", error)
+ return {
+ success: false,
+ message: "도메인 할당 중 오류가 발생했습니다."
+ }
+ }
+}
+
+/**
+ * 도메인별 사용자 통계를 조회하는 함수
+ */
+export async function getUserDomainStats() {
+ try {
+ const stats = await db
+ .select({
+ domain: users.domain,
+ count: count(),
+ })
+ .from(users)
+ .where(eq(users.isActive, true))
+ .groupBy(users.domain)
+
+ return {
+ success: true,
+ data: stats
+ }
+ } catch (error) {
+ console.error("도메인 통계 조회 오류:", error)
+ return {
+ success: false,
+ message: "통계 조회 중 오류가 발생했습니다.",
+ data: []
+ }
+ }
+}
+
+/**
+ * pending 도메인 사용자 목록을 조회하는 함수 (관리자용)
+ */
+export async function getPendingUsers() {
+ try {
+ const pendingUsers = await db
+ .select({
+ id: users.id,
+ name: users.name,
+ email: users.email,
+ createdAt: users.createdAt,
+ domain: users.domain,
+ })
+ .from(users)
+ .where(and(
+ eq(users.domain, "pending"),
+ eq(users.isActive, true)
+ ))
+ .orderBy(desc(users.createdAt))
+
+ return {
+ success: true,
+ data: pendingUsers
+ }
+ } catch (error) {
+ console.error("pending 사용자 조회 오류:", error)
+ return {
+ success: false,
+ message: "사용자 조회 중 오류가 발생했습니다.",
+ data: []
+ }
+ }
+} \ No newline at end of file