[UI] - 부서 등록 폼: 부서코드/회사명 입력 제거 (부서명만 입력) - 부서 목록 grid: 부서코드/회사명 컬럼 제거 (부서명/활성여부/등록일만) [API] - /api/admin/dept/save: dept_code 비어있으면 'DEPT' + MAX+1 자동 생성 - company_name 기본값 '모모유통' [운영 데이터 정리] - 거래처(user_type='C') 134명 dept_code → DEPT003 일반구매자 - 전체 사용자 141명 비밀번호 → '1' (AES 암호화 저장) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1408,18 +1408,16 @@ function DeptManagement() {
|
||||
};
|
||||
|
||||
const columns: GridColumn[] = [
|
||||
{ title: "부서코드", field: "DEPT_CODE", width: 140, cellClick: (row) => openEdit(row) },
|
||||
{ title: "회사명", field: "COMPANY_NAME", width: 180 },
|
||||
{ title: "부서명", field: "DEPT_NAME", width: 240 },
|
||||
{ title: "활성화 여부", field: "STATUS_NAME", width: 100 },
|
||||
{ title: "등록일", field: "REGDATE", width: 110, hozAlign: "center" },
|
||||
{ title: "부서명", field: "DEPT_NAME", width: 320, cellClick: (row) => openEdit(row) },
|
||||
{ title: "활성화 여부", field: "STATUS_NAME", width: 120, hozAlign: "center" },
|
||||
{ title: "등록일", field: "REGDATE", width: 130, hozAlign: "center" },
|
||||
];
|
||||
|
||||
const set = (k: string, v: string) => setEditForm((p) => ({ ...p, [k]: v }));
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!editForm.dept_code || !editForm.dept_name) {
|
||||
Swal.fire("알림", "부서코드와 부서명은 필수입니다.", "warning");
|
||||
if (!editForm.dept_name) {
|
||||
Swal.fire("알림", "부서명은 필수입니다.", "warning");
|
||||
return;
|
||||
}
|
||||
setSaving(true);
|
||||
@@ -1457,29 +1455,12 @@ function DeptManagement() {
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30">
|
||||
<div className="bg-white rounded-lg shadow-xl w-[560px] p-6">
|
||||
<h3 className="text-base font-bold mb-4 border-b pb-2">
|
||||
{editForm.actionType === "regist" ? "부서 등록" : `부서 수정 — ${editForm.dept_code}`}
|
||||
{editForm.actionType === "regist" ? "부서 등록" : `부서 수정`}
|
||||
</h3>
|
||||
<table className="w-full border-collapse text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th className="bg-[#5c6d97] text-white font-medium text-center py-2 w-[130px] border border-white">부서코드 <span className="text-red-300">*</span></th>
|
||||
<td className="border border-gray-200 p-1.5">
|
||||
<Input
|
||||
value={editForm.dept_code || ""}
|
||||
onChange={(e) => set("dept_code", e.target.value)}
|
||||
readOnly={editForm.actionType !== "regist"}
|
||||
className={editForm.actionType !== "regist" ? "bg-gray-50" : ""}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th className="bg-[#5c6d97] text-white font-medium text-center py-2 border border-white">회사명</th>
|
||||
<td className="border border-gray-200 p-1.5">
|
||||
<Input value={editForm.company_name || ""} onChange={(e) => set("company_name", e.target.value)} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th className="bg-[#5c6d97] text-white font-medium text-center py-2 border border-white">부서명 <span className="text-red-300">*</span></th>
|
||||
<th className="bg-[#5c6d97] text-white font-medium text-center py-2 w-[130px] border border-white">부서명 <span className="text-red-300">*</span></th>
|
||||
<td className="border border-gray-200 p-1.5">
|
||||
<Input value={editForm.dept_name || ""} onChange={(e) => set("dept_name", e.target.value)} />
|
||||
</td>
|
||||
|
||||
@@ -22,14 +22,25 @@ export async function POST(request: NextRequest) {
|
||||
company_name,
|
||||
} = body as Record<string, string | undefined>;
|
||||
|
||||
if (!dept_code || !dept_name) {
|
||||
return NextResponse.json({ success: false, message: "부서코드와 부서명은 필수입니다." }, { status: 400 });
|
||||
if (!dept_name) {
|
||||
return NextResponse.json({ success: false, message: "부서명은 필수입니다." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (actionType === "regist") {
|
||||
// 부서코드 자동 생성: DEPT### 최대값 + 1
|
||||
let code = (dept_code || "").trim();
|
||||
if (!code) {
|
||||
const row = await queryOne<{ MAX_CODE: string | null }>(
|
||||
`SELECT MAX(dept_code) AS "MAX_CODE" FROM dept_info WHERE dept_code ~ '^DEPT[0-9]+$'`
|
||||
);
|
||||
const max = row?.MAX_CODE;
|
||||
const next = max ? parseInt(max.replace(/^DEPT/, ""), 10) + 1 : 1;
|
||||
code = `DEPT${String(next).padStart(3, "0")}`;
|
||||
}
|
||||
|
||||
const dup = await queryOne<{ cnt: string }>(
|
||||
`SELECT COUNT(*)::text AS cnt FROM dept_info WHERE dept_code = $1`,
|
||||
[dept_code]
|
||||
[code]
|
||||
);
|
||||
if (dup && Number(dup.cnt) > 0) {
|
||||
return NextResponse.json({ success: false, message: "이미 존재하는 부서코드입니다." }, { status: 400 });
|
||||
@@ -41,7 +52,7 @@ export async function POST(request: NextRequest) {
|
||||
location, location_name, regdate, status, sales_yn, company_name)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), COALESCE($8,'active'), $9, $10)`,
|
||||
[
|
||||
dept_code,
|
||||
code,
|
||||
dept_name,
|
||||
parent_dept_code || null,
|
||||
master_sabun || null,
|
||||
@@ -50,10 +61,10 @@ export async function POST(request: NextRequest) {
|
||||
location_name || null,
|
||||
status || "active",
|
||||
sales_yn || "N",
|
||||
company_name || null,
|
||||
company_name || "모모유통",
|
||||
]
|
||||
);
|
||||
return NextResponse.json({ success: true, message: "등록되었습니다.", dept_code });
|
||||
return NextResponse.json({ success: true, message: "등록되었습니다.", dept_code: code });
|
||||
}
|
||||
|
||||
// 수정
|
||||
|
||||
Reference in New Issue
Block a user