Merge pull request 'hjjeong' (#10) from hjjeong into main
Reviewed-on: https://g.wace.me/chpark/vexplor_rps/pulls/10
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
import { apiClient } from "./client";
|
||||
|
||||
// Content-Disposition 의 filename / filename* 파싱 (UTF-8 인코딩 우선)
|
||||
function extractFileName(cd: string | undefined): string | null {
|
||||
if (!cd) return null;
|
||||
const utf8 = /filename\*=UTF-8''([^;]+)/i.exec(cd);
|
||||
if (utf8 && utf8[1]) {
|
||||
try { return decodeURIComponent(utf8[1]); } catch { /* fallthrough */ }
|
||||
}
|
||||
const plain = /filename="?([^";]+)"?/i.exec(cd);
|
||||
if (plain && plain[1]) {
|
||||
try { return decodeURIComponent(plain[1]); } catch { return plain[1]; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 개발관리 E-BOM (M3 등록 / M4 조회) — wace partMng.xml 1:1
|
||||
// 라우트: /api/development/ebom/*, /api/development/ebom-tree/*
|
||||
// ============================================================
|
||||
|
||||
export interface BomReportListFilter {
|
||||
customer_cd?: string;
|
||||
project_name?: string;
|
||||
unit_code?: string;
|
||||
search_unit_name?: string;
|
||||
search_writer?: string;
|
||||
product_cd?: string;
|
||||
search_part_no?: string;
|
||||
search_part_name?: string;
|
||||
search_from_date?: string;
|
||||
search_to_date?: string;
|
||||
status?: string;
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
}
|
||||
|
||||
export interface BomReportRow {
|
||||
num: number | string;
|
||||
objid: string;
|
||||
customer_objid: string | null;
|
||||
customer_name: string | null;
|
||||
contract_objid: string | null;
|
||||
customer_project_name: string | null;
|
||||
project_no: string | null;
|
||||
unit_code: string | null;
|
||||
unit_name: string | null;
|
||||
status: string | null;
|
||||
status_title: string | null;
|
||||
writer: string | null;
|
||||
dept_name: string | null;
|
||||
user_name: string | null;
|
||||
dept_user_name: string | null;
|
||||
regdate: string | null;
|
||||
reg_date: string | null;
|
||||
deploy_date: string | null;
|
||||
revision: string | null;
|
||||
eo_no: string | null;
|
||||
eo_date: string | null;
|
||||
note: string | null;
|
||||
multi_yn: string | null;
|
||||
multi_master_yn: string | null;
|
||||
multi_break_yn: string | null;
|
||||
multi_master_objid: string | null;
|
||||
bom_cnt: number | string | null;
|
||||
product_cd: string | null;
|
||||
product_name: string | null;
|
||||
part_no: string | null;
|
||||
part_name: string | null;
|
||||
}
|
||||
|
||||
export interface BomReportListResponse {
|
||||
rows: BomReportRow[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface BomReportStatusBody {
|
||||
product_cd?: string;
|
||||
part_no?: string;
|
||||
part_name?: string;
|
||||
version?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface BomTreeFilter {
|
||||
bom_report_objid?: string;
|
||||
project_name?: string;
|
||||
unit_code?: string;
|
||||
search_part_no?: string;
|
||||
search_part_name?: string;
|
||||
}
|
||||
|
||||
export interface BomTreeRow {
|
||||
bom_report_objid: string | null;
|
||||
objid: string;
|
||||
parent_objid: string | null;
|
||||
child_objid: string | null;
|
||||
part_no: string | null; // bom_part_qty.part_no (= part_mng.objid)
|
||||
qty: string | null;
|
||||
seq: number | string | null;
|
||||
status: string | null;
|
||||
lev: number;
|
||||
path: string[] | null;
|
||||
// part_mng JOIN
|
||||
pm_part_no: string | null;
|
||||
pm_part_name: string | null;
|
||||
spec: string | null;
|
||||
material: string | null;
|
||||
weight: string | null;
|
||||
remark: string | null;
|
||||
edit_date: string | null;
|
||||
eo_no: string | null;
|
||||
revision: string | null;
|
||||
cu01_cnt: number | string | null;
|
||||
cu02_cnt: number | string | null;
|
||||
cu03_cnt: number | string | null;
|
||||
max_level: number | string | null;
|
||||
}
|
||||
|
||||
export interface BomTreeResponse {
|
||||
rows: BomTreeRow[];
|
||||
max_level: number;
|
||||
}
|
||||
|
||||
// 트리 풀 컬럼 (ascendingForExcel 1:1) — BomReportTreeDialog 용
|
||||
export interface BomTreeFullRow {
|
||||
lev: number | string;
|
||||
pm_part_no: string | null;
|
||||
pm_part_name: string | null;
|
||||
qty: string | number | null;
|
||||
p_qty: string | number | null;
|
||||
material: string | null;
|
||||
remark: string | null;
|
||||
heat_treatment_hardness: string | null;
|
||||
heat_treatment_method: string | null;
|
||||
surface_treatment: string | null;
|
||||
maker: string | null;
|
||||
part_type: string | null;
|
||||
part_type_title: string | null;
|
||||
cu01_cnt: number | string | null;
|
||||
cu02_cnt: number | string | null;
|
||||
cu03_cnt: number | string | null;
|
||||
}
|
||||
export interface BomTreeFullResponse {
|
||||
rows: BomTreeFullRow[];
|
||||
max_level: number;
|
||||
}
|
||||
|
||||
// ─── API ─────────────────────────────────────────────────
|
||||
|
||||
export const devBomApi = {
|
||||
// M3 그리드
|
||||
async list(filter: BomReportListFilter = {}): Promise<BomReportListResponse> {
|
||||
const res = await apiClient.get("/development/ebom/list", { params: filter });
|
||||
return res.data?.data as BomReportListResponse;
|
||||
},
|
||||
|
||||
async detail(objid: string): Promise<BomReportRow | null> {
|
||||
const res = await apiClient.get(`/development/ebom/${objid}`);
|
||||
return res.data?.data ?? null;
|
||||
},
|
||||
|
||||
async updateStatus(objid: string, body: BomReportStatusBody) {
|
||||
return (await apiClient.put(`/development/ebom/${objid}/status`, body)).data;
|
||||
},
|
||||
|
||||
async remove(objids: string[]) {
|
||||
const res = await apiClient.delete("/development/ebom", { data: { objids } });
|
||||
return res.data;
|
||||
},
|
||||
|
||||
// M4
|
||||
async ascending(filter: BomTreeFilter): Promise<BomTreeResponse> {
|
||||
const res = await apiClient.get("/development/ebom-tree/ascending", { params: filter });
|
||||
return res.data?.data as BomTreeResponse;
|
||||
},
|
||||
|
||||
async descending(filter: BomTreeFilter): Promise<BomTreeResponse> {
|
||||
const res = await apiClient.get("/development/ebom-tree/descending", { params: filter });
|
||||
return res.data?.data as BomTreeResponse;
|
||||
},
|
||||
|
||||
// E-BOM 트리 (풀 컬럼) — M3 그리드 행 클릭 → BomReportTreeDialog
|
||||
async treeFull(filter: BomTreeFilter): Promise<BomTreeFullResponse> {
|
||||
const res = await apiClient.get("/development/ebom-tree/full", { params: filter });
|
||||
return res.data?.data as BomTreeFullResponse;
|
||||
},
|
||||
|
||||
// M4 엑셀 다운로드 (정/역전개) — wace 1:1
|
||||
async excelAscending(filter: BomTreeFilter): Promise<{ blob: Blob; fileName: string }> {
|
||||
const res = await apiClient.get("/development/ebom-tree/ascending/excel", {
|
||||
params: filter, responseType: "blob",
|
||||
});
|
||||
return { blob: res.data as Blob, fileName: extractFileName(res.headers?.["content-disposition"]) ?? "BOM_ascending.xlsx" };
|
||||
},
|
||||
async excelDescending(filter: BomTreeFilter): Promise<{ blob: Blob; fileName: string }> {
|
||||
const res = await apiClient.get("/development/ebom-tree/descending/excel", {
|
||||
params: filter, responseType: "blob",
|
||||
});
|
||||
return { blob: res.data as Blob, fileName: extractFileName(res.headers?.["content-disposition"]) ?? "BOM_descending.xlsx" };
|
||||
},
|
||||
|
||||
// Excel Import
|
||||
async excelParse(file: File): Promise<BomExcelParseResponse> {
|
||||
const fd = new FormData();
|
||||
fd.append("file", file);
|
||||
const res = await apiClient.post("/development/ebom/excel-parse", fd, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
return res.data?.data as BomExcelParseResponse;
|
||||
},
|
||||
|
||||
async excelCheckDuplicate(partNo: string, exclude?: string): Promise<boolean> {
|
||||
const res = await apiClient.get("/development/ebom/excel-check-duplicate", {
|
||||
params: { partNo, exclude },
|
||||
});
|
||||
return !!res.data?.data?.isDuplicate;
|
||||
},
|
||||
|
||||
async excelCopySource(productCd?: string): Promise<BomCopySourceRow[]> {
|
||||
const res = await apiClient.get("/development/ebom/excel-copy-source", {
|
||||
params: productCd ? { productCd } : undefined,
|
||||
});
|
||||
return (res.data?.data as BomCopySourceRow[]) ?? [];
|
||||
},
|
||||
|
||||
async excelCopy(objid: string): Promise<BomCsvRow[]> {
|
||||
const res = await apiClient.get(`/development/ebom/excel-copy/${objid}`);
|
||||
return ((res.data?.data?.rows as BomCsvRow[]) ?? []);
|
||||
},
|
||||
|
||||
async excelSave(input: BomExcelSaveInput): Promise<BomExcelSaveResult> {
|
||||
const res = await apiClient.post("/development/ebom/excel-save", input);
|
||||
return res.data?.data as BomExcelSaveResult;
|
||||
},
|
||||
};
|
||||
|
||||
// ─── CSV Import 타입 (wace parsingCsvFile 1:1) ─────────────
|
||||
|
||||
export interface BomCsvRow {
|
||||
NOTE: string;
|
||||
LEVEL: string;
|
||||
PARENT_PART_NO: string;
|
||||
PART_NO: string;
|
||||
PART_NAME: string;
|
||||
QTY: string;
|
||||
ITEM_QTY: string;
|
||||
MATERIAL: string;
|
||||
HEAT_TREATMENT_HARDNESS: string;
|
||||
HEAT_TREATMENT_METHOD: string;
|
||||
SURFACE_TREATMENT: string;
|
||||
MAKER: string;
|
||||
PART_TYPE: string;
|
||||
PART_TYPE_NAME: string;
|
||||
ACCTFG: string;
|
||||
ODRFG: string;
|
||||
UNIT_DC: string;
|
||||
UNITMANG_DC: string;
|
||||
UNITCHNG_NB: string;
|
||||
LOT_FG: string;
|
||||
USE_YN: string;
|
||||
QC_FG: string;
|
||||
SETITEM_FG: string;
|
||||
REQ_FG: string;
|
||||
}
|
||||
|
||||
// 기존 코드 호환용 별칭 (필요 시 마이그레이션)
|
||||
export type BomExcelRow = BomCsvRow;
|
||||
|
||||
export interface BomExcelParseResponse {
|
||||
rows: BomCsvRow[];
|
||||
hasError: boolean;
|
||||
firstLevel: { part_no: string; part_name: string } | null;
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
export interface BomCopySourceRow {
|
||||
objid: string;
|
||||
part_no: string;
|
||||
part_name: string;
|
||||
revision: string | null;
|
||||
product_cd: string | null;
|
||||
regdate: string | null;
|
||||
}
|
||||
|
||||
export interface BomExcelSaveInput {
|
||||
bomReportObjid?: string;
|
||||
productCd: string;
|
||||
partNo: string;
|
||||
partName: string;
|
||||
version?: string;
|
||||
rows: BomCsvRow[];
|
||||
}
|
||||
|
||||
export interface BomExcelSaveResult {
|
||||
bomReportObjid: string;
|
||||
insertedParts: number;
|
||||
updatedParts: number;
|
||||
bomRows: number;
|
||||
mode: "create" | "update";
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { apiClient } from "./client";
|
||||
|
||||
// ============================================================
|
||||
// 개발관리 설계변경 리스트 (M5, read-only) — wace partMngHistList 1:1
|
||||
// 라우트: /api/development/eo-history/*
|
||||
// ============================================================
|
||||
|
||||
export interface EoHistoryListFilter {
|
||||
Year?: string;
|
||||
contract_objid?: string;
|
||||
unit_code?: string;
|
||||
part_no?: string;
|
||||
part_name?: string;
|
||||
change_option?: string;
|
||||
eo_start_date?: string;
|
||||
eo_end_date?: string;
|
||||
change_type?: string;
|
||||
part_type?: string;
|
||||
writer_id?: string;
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
}
|
||||
|
||||
export interface EoHistoryRow {
|
||||
objid: string;
|
||||
eo_no: string | null;
|
||||
year: string | null;
|
||||
project_no: string | null;
|
||||
project_name: string | null;
|
||||
unit_name: string | null;
|
||||
parent_part_info: string | null;
|
||||
part_no_disp: string | null;
|
||||
part_name_disp: string | null;
|
||||
part_no: string | null;
|
||||
part_name: string | null;
|
||||
bom_qty_status: string | null;
|
||||
qty: string | null;
|
||||
qty_temp: string | null;
|
||||
change_type: string | null;
|
||||
change_type_name: string | null;
|
||||
change_option: string | null;
|
||||
change_option_name: string | null;
|
||||
revision_disp: string | null;
|
||||
revision: string | null;
|
||||
eo_date: string | null;
|
||||
part_type: string | null;
|
||||
part_type_name: string | null;
|
||||
writer: string | null;
|
||||
writer_name: string | null;
|
||||
his_reg_date_title: string | null;
|
||||
bom_deploy_date: string | null;
|
||||
bom_deploy_date_title: string | null;
|
||||
}
|
||||
|
||||
export interface EoHistoryListResponse {
|
||||
rows: EoHistoryRow[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface EoHistoryDetail extends EoHistoryRow {
|
||||
// raw PART_MNG_HISTORY 추가 필드
|
||||
product_mgmt_objid?: string | null;
|
||||
upg_no?: string | null;
|
||||
unit?: string | null;
|
||||
spec?: string | null;
|
||||
material?: string | null;
|
||||
weight?: string | null;
|
||||
remark?: string | null;
|
||||
es_spec?: string | null;
|
||||
ms_spec?: string | null;
|
||||
design_apply_point?: string | null;
|
||||
management_flag?: string | null;
|
||||
status?: string | null;
|
||||
reg_date?: string | null;
|
||||
is_last?: string | null;
|
||||
sourcing_code?: string | null;
|
||||
sub_material?: string | null;
|
||||
thickness?: string | null;
|
||||
width?: string | null;
|
||||
height?: string | null;
|
||||
out_diameter?: string | null;
|
||||
in_diameter?: string | null;
|
||||
length?: string | null;
|
||||
supply_code?: string | null;
|
||||
contract_objid?: string | null;
|
||||
maker?: string | null;
|
||||
his_status?: string | null;
|
||||
bom_status?: string | null;
|
||||
heat_treatment_hardness?: string | null;
|
||||
heat_treatment_method?: string | null;
|
||||
surface_treatment?: string | null;
|
||||
customer_project_name?: string | null;
|
||||
}
|
||||
|
||||
export const devEoHistoryApi = {
|
||||
async list(filter: EoHistoryListFilter = {}): Promise<EoHistoryListResponse> {
|
||||
const res = await apiClient.get("/development/eo-history/list", { params: filter });
|
||||
return res.data?.data as EoHistoryListResponse;
|
||||
},
|
||||
async detail(objid: string): Promise<EoHistoryDetail | null> {
|
||||
const res = await apiClient.get(`/development/eo-history/${objid}`);
|
||||
return res.data?.data ?? null;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,309 @@
|
||||
import { apiClient } from "./client";
|
||||
|
||||
// ============================================================
|
||||
// 개발관리 PART (M1 등록 / M2 조회) — wace partMng.xml 1:1
|
||||
// 라우트: /api/development/part-temp/*, /api/development/part/*
|
||||
// ============================================================
|
||||
|
||||
export interface PartListFilter {
|
||||
search_part_no?: string;
|
||||
search_part_name?: string;
|
||||
search_material?: string;
|
||||
search_spec?: string;
|
||||
search_part_type?: string;
|
||||
writer?: string;
|
||||
status?: string;
|
||||
status_arr?: string[];
|
||||
product_code?: string;
|
||||
upg_no?: string;
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
|
||||
// M2 추가 필터
|
||||
search_year?: string;
|
||||
search_design_date_from?: string;
|
||||
search_design_date_to?: string;
|
||||
customer_objid?: string;
|
||||
customer_cd?: string;
|
||||
project_name?: string;
|
||||
unit_code?: string;
|
||||
is_last?: string;
|
||||
eo?: string;
|
||||
}
|
||||
|
||||
/** partMngBaseSimple + M1/M2 추가 컬럼 평탄화 — Postgres는 컬럼명을 소문자로 반환 */
|
||||
export interface PartRow {
|
||||
objid: string;
|
||||
part_no: string | null;
|
||||
part_name: string | null;
|
||||
product_mgmt_objid: string | null;
|
||||
upg_no: string | null;
|
||||
unit: string | null;
|
||||
unit_title: string | null;
|
||||
qty: string | null;
|
||||
spec: string | null;
|
||||
post_processing: string | null;
|
||||
material: string | null;
|
||||
weight: string | null;
|
||||
part_type: string | null;
|
||||
part_type_title: string | null;
|
||||
remark: string | null;
|
||||
es_spec: string | null;
|
||||
ms_spec: string | null;
|
||||
change_type: string | null;
|
||||
design_apply_point: string | null;
|
||||
change_option: string | null;
|
||||
change_option_name: string | null;
|
||||
management_flag: string | null;
|
||||
revision: string | null;
|
||||
status: string | null;
|
||||
reg_date: string | null;
|
||||
part_regdate_title: string | null;
|
||||
edit_date: string | null;
|
||||
writer: string | null;
|
||||
is_last: string | null;
|
||||
is_longd: string | null;
|
||||
eo_date: string | null;
|
||||
eo_no: string | null;
|
||||
eo_temp: string | null;
|
||||
maker: string | null;
|
||||
contract_objid: string | null;
|
||||
thickness: string | null;
|
||||
width: string | null;
|
||||
height: string | null;
|
||||
out_diameter: string | null;
|
||||
in_diameter: string | null;
|
||||
length: string | null;
|
||||
sourcing_code: string | null;
|
||||
supply_code: string | null;
|
||||
supply_name: string | null;
|
||||
sub_material: string | null;
|
||||
parent_part_no: string | null;
|
||||
design_date: string | null;
|
||||
deploy_date: string | null;
|
||||
excel_upload_seq: string | number | null;
|
||||
cu01_cnt: number | string | null;
|
||||
cu02_cnt: number | string | null;
|
||||
cu03_cnt: number | string | null;
|
||||
cu_total_cnt: number | string | null;
|
||||
|
||||
// 추가 15컬럼 + 라벨
|
||||
heat_treatment_hardness: string | null;
|
||||
heat_treatment_method: string | null;
|
||||
surface_treatment: string | null;
|
||||
acctfg: string | null;
|
||||
acctfg_nm: string | null;
|
||||
odrfg: string | null;
|
||||
odrfg_nm: string | null;
|
||||
unit_dc: string | null;
|
||||
unit_dc_nm: string | null;
|
||||
unitmang_dc: string | null;
|
||||
unitmang_dc_nm: string | null;
|
||||
unitchng_nb: string | number | null;
|
||||
lot_fg: string | null;
|
||||
lot_fg_nm: string | null;
|
||||
use_yn: string | null;
|
||||
use_yn_nm: string | null;
|
||||
qc_fg: string | null;
|
||||
qc_fg_nm: string | null;
|
||||
setitem_fg: string | null;
|
||||
setitem_fg_nm: string | null;
|
||||
req_fg: string | null;
|
||||
req_fg_nm: string | null;
|
||||
unit_length: string | null;
|
||||
unit_qty: string | null;
|
||||
|
||||
// M1 전용 부속
|
||||
partner_title?: string | null;
|
||||
parent_part_info?: string | null;
|
||||
bom_report_objid?: string | null;
|
||||
objid_qty?: string | null;
|
||||
child_objid?: string | null;
|
||||
q_qty?: string | null;
|
||||
q_qty_raw?: string | null;
|
||||
qty_temp?: string | null;
|
||||
sort?: string | null;
|
||||
|
||||
// M2 전용 부속
|
||||
num?: number | null;
|
||||
bom_qty?: string | null;
|
||||
}
|
||||
|
||||
export interface PartListResponse {
|
||||
rows: PartRow[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface PartCreateBody {
|
||||
part_objid?: string;
|
||||
part_no: string;
|
||||
part_name: string;
|
||||
unit?: string;
|
||||
qty?: string;
|
||||
spec?: string;
|
||||
material?: string;
|
||||
thickness?: string;
|
||||
width?: string;
|
||||
height?: string;
|
||||
out_diameter?: string;
|
||||
in_diameter?: string;
|
||||
length?: string;
|
||||
remark?: string;
|
||||
part_type: string;
|
||||
product_mgmt_objid?: string;
|
||||
supply_code?: string;
|
||||
maker?: string;
|
||||
contract_objid?: string;
|
||||
post_processing?: string;
|
||||
heat_treatment_hardness?: string;
|
||||
heat_treatment_method?: string;
|
||||
surface_treatment?: string;
|
||||
acctfg?: string;
|
||||
odrfg?: string;
|
||||
unit_dc?: string;
|
||||
unitmang_dc?: string;
|
||||
unitchng_nb?: string;
|
||||
lot_fg?: string;
|
||||
use_yn?: string;
|
||||
qc_fg?: string;
|
||||
setitem_fg?: string;
|
||||
req_fg?: string;
|
||||
unit_length?: string;
|
||||
unit_qty?: string;
|
||||
}
|
||||
|
||||
export interface PartUpdateBody {
|
||||
part_name?: string;
|
||||
material?: string;
|
||||
heat_treatment_hardness?: string;
|
||||
heat_treatment_method?: string;
|
||||
surface_treatment?: string;
|
||||
maker?: string;
|
||||
part_type?: string;
|
||||
acctfg?: string;
|
||||
odrfg?: string;
|
||||
spec?: string;
|
||||
unit_dc?: string;
|
||||
unitmang_dc?: string;
|
||||
unitchng_nb?: string;
|
||||
lot_fg?: string;
|
||||
use_yn?: string;
|
||||
qc_fg?: string;
|
||||
setitem_fg?: string;
|
||||
req_fg?: string;
|
||||
unit_length?: string;
|
||||
unit_qty?: string;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface DeployResult {
|
||||
deployed: number;
|
||||
eo_nos: Record<string, string>;
|
||||
}
|
||||
|
||||
// ─── Excel Import ────────────────────────────────────────────
|
||||
|
||||
export interface PartExcelRow {
|
||||
NOTE: string;
|
||||
PART_NO: string;
|
||||
PART_NAME: string;
|
||||
MATERIAL: string;
|
||||
HEAT_TREATMENT_HARDNESS: string;
|
||||
HEAT_TREATMENT_METHOD: string;
|
||||
SURFACE_TREATMENT: string;
|
||||
MAKER: string;
|
||||
PART_TYPE: string;
|
||||
PART_TYPE_NAME?: string;
|
||||
SPEC: string;
|
||||
ACCTFG: string;
|
||||
ACCTFG_NAME?: string;
|
||||
ODRFG: string;
|
||||
ODRFG_NAME?: string;
|
||||
UNIT_DC: string;
|
||||
UNIT_DC_NAME?: string;
|
||||
UNITMANG_DC: string;
|
||||
UNITMANG_DC_NAME?: string;
|
||||
UNITCHNG_NB: string;
|
||||
LOT_FG: string;
|
||||
USE_YN: string;
|
||||
QC_FG: string;
|
||||
SETITEM_FG: string;
|
||||
REQ_FG: string;
|
||||
UNIT_LENGTH: string;
|
||||
UNIT_QTY: string;
|
||||
REMARK: string;
|
||||
}
|
||||
|
||||
export interface ExcelParseResponse {
|
||||
rows: PartExcelRow[];
|
||||
hasError: boolean;
|
||||
}
|
||||
|
||||
export interface ExcelSaveResponse {
|
||||
inserted: number;
|
||||
skipped: number;
|
||||
skippedPartNos: string[];
|
||||
}
|
||||
|
||||
// ─── API ────────────────────────────────────────────────────
|
||||
|
||||
export const devPartApi = {
|
||||
// M1 그리드
|
||||
async listTemp(filter: PartListFilter = {}): Promise<PartListResponse> {
|
||||
const res = await apiClient.get("/development/part-temp/list", { params: filter });
|
||||
return res.data?.data as PartListResponse;
|
||||
},
|
||||
|
||||
// M2 그리드
|
||||
async list(filter: PartListFilter = {}): Promise<PartListResponse> {
|
||||
const res = await apiClient.get("/development/part/list", { params: filter });
|
||||
return res.data?.data as PartListResponse;
|
||||
},
|
||||
|
||||
// 단건 상세
|
||||
async detail(objid: string): Promise<PartRow | null> {
|
||||
const res = await apiClient.get(`/development/part/${objid}`);
|
||||
return res.data?.data ?? null;
|
||||
},
|
||||
|
||||
// 신규 등록 (38 컬럼)
|
||||
async create(body: PartCreateBody): Promise<{ objid: string }> {
|
||||
const res = await apiClient.post("/development/part", body);
|
||||
return res.data?.data;
|
||||
},
|
||||
|
||||
// 상세 수정 (21 컬럼)
|
||||
async update(objid: string, body: PartUpdateBody) {
|
||||
return (await apiClient.put(`/development/part/${objid}`, body)).data;
|
||||
},
|
||||
|
||||
// 확정 (M1→M2): EO_NO 채번 + part_mng_history 이력
|
||||
async deploy(objids: string[]): Promise<DeployResult> {
|
||||
const res = await apiClient.post("/development/part-temp/deploy", { objids });
|
||||
return res.data?.data as DeployResult;
|
||||
},
|
||||
|
||||
// 다중 삭제
|
||||
async remove(objids: string[]) {
|
||||
const res = await apiClient.delete("/development/part", { data: { objids } });
|
||||
return res.data;
|
||||
},
|
||||
|
||||
// Excel Import — 파싱 + 검증
|
||||
async excelParse(file: File): Promise<ExcelParseResponse> {
|
||||
const fd = new FormData();
|
||||
fd.append("file", file);
|
||||
const res = await apiClient.post("/development/part/excel-parse", fd, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
return res.data?.data as ExcelParseResponse;
|
||||
},
|
||||
|
||||
// Excel Import — 저장 (신규 PART_NO 만 INSERT)
|
||||
async excelSave(rows: PartExcelRow[]): Promise<ExcelSaveResponse> {
|
||||
const res = await apiClient.post("/development/part/excel-save", { rows });
|
||||
return res.data?.data as ExcelSaveResponse;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user