1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
"use server"; // Next.js 서버 액션에서 직접 import하려면 (선택)
import { revalidateTag, unstable_noStore } from "next/cache";
import db from "@/db/db";
import { unstable_cache } from "@/lib/unstable-cache";
import { filterColumns } from "@/lib/filter-columns";
import { asc, desc, ilike, inArray, and, gte, lte, not, or, eq } from "drizzle-orm";
import { countProjectLists, selectProjectLists } from "./repository";
import { biddingProjects, ProjectSeries, projectSeries } from "@/db/schema";
import { GetBidProjectListsSchema } from "./validation";
export async function getBidProjectLists(input: GetBidProjectListsSchema) {
return unstable_cache(
async () => {
try {
const offset = (input.page - 1) * input.perPage;
// const advancedTable = input.flags.includes("advancedTable");
const advancedTable = true;
// advancedTable 모드면 filterColumns()로 where 절 구성
const advancedWhere = filterColumns({
table: biddingProjects,
filters: input.filters,
joinOperator: input.joinOperator,
});
let globalWhere
if (input.search) {
const s = `%${input.search}%`
globalWhere = or(
ilike(biddingProjects.pspid, s),
ilike(biddingProjects.projNm, s),
ilike(biddingProjects.kunnrNm, s),
)
// 필요시 여러 칼럼 OR조건 (status, priority, etc)
}
const finalWhere = and(
// advancedWhere or your existing conditions
advancedWhere,
globalWhere // and()함수로 결합 or or() 등으로 결합
)
// 아니면 ilike, inArray, gte 등으로 where 절 구성
const where = finalWhere
const orderBy =
input.sort.length > 0
? input.sort.map((item) =>
item.desc ? desc(biddingProjects[item.id]) : asc(biddingProjects[item.id])
)
: [asc(biddingProjects.createdAt)];
// 트랜잭션 내부에서 Repository 호출
const { data, total } = await db.transaction(async (tx) => {
const data = await selectProjectLists(tx, {
where,
orderBy,
offset,
limit: input.perPage,
});
const total = await countProjectLists(tx, where);
return { data, total };
});
const pageCount = Math.ceil(total / input.perPage);
return { data, pageCount };
} catch (err) {
// 에러 발생 시 디폴트
return { data: [], pageCount: 0 };
}
},
[JSON.stringify(input)], // 캐싱 키
{
revalidate: 3600,
tags: ["project-lists"],
}
)();
}
/**
* 특정 프로젝트의 시리즈 데이터를 가져오는 서버 액션
* @param pspid 견적프로젝트번호
* @returns 프로젝트 시리즈 데이터 배열
*/
export async function getProjectSeriesForProject(pspid: string) {
try {
if (!pspid) {
throw new Error("프로젝트 ID가 제공되지 않았습니다.")
}
// 트랜잭션을 사용하여 데이터 조회
const seriesData = await db.transaction(async (tx) => {
const results = await tx
.select()
.from(projectSeries)
.where(eq(projectSeries.pspid, pspid))
.orderBy(projectSeries.sersNo)
return results
})
return seriesData
} catch (error) {
console.error(`프로젝트 시리즈 데이터 가져오기 실패 (pspid: ${pspid}):`, error)
return []
}
}
/**
* 프로젝트 코드 기준으로 프로젝트 정보 반환
* 사용처:
* - 프로젝트 AVL 등록시 프로젝트 정보 가져오기
*/
export async function getProjectInfoByProjectCode(projectCode: string) {
const projectInfo = await db.select().from(biddingProjects).where(eq(biddingProjects.pspid, projectCode)).limit(1);
// 프로젝트가 존재하지 않으면 null 반환
if (projectInfo.length === 0) {
return null;
}
//projectInfo[0].pjtType SHIP/HULL/TOP
//TODO evcp는 공통이라는 걸 받지 않는걸로 보임. 여긴 한번 확인..
let projectHtDivision = null;
if (projectInfo[0].pjtType === 'SHIP') {
projectHtDivision = 'H';
} else if (projectInfo[0].pjtType === 'HULL') {
projectHtDivision = 'H';
} else if (projectInfo[0].pjtType === 'TOP') {
projectHtDivision = 'T';
}
const projectInfoForAvl = {
// 프로젝트코드
projectCode: projectInfo[0].pspid,
// 프로젝트명
projectName: projectInfo[0].projNm,
// 선종
projectMsrm: projectInfo[0].ptypeNm,
// H/T 구분
projectHtDivision,
};
return projectInfoForAvl;
}
|