Compare commits

...

2 Commits

Author SHA1 Message Date
dohyeons 1170e34d4e Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into common/feat/dashboard-map 2025-12-16 14:44:48 +09:00
dohyeons aacedc004c 버튼 수정 2025-12-16 14:44:35 +09:00
2 changed files with 138 additions and 117 deletions

View File

@ -200,14 +200,25 @@ export const RepeaterInput: React.FC<RepeaterInputProps> = ({
const currentDeletedIds = deletedItemIdsRef.current; const currentDeletedIds = deletedItemIdsRef.current;
console.log("🗑️ [RepeaterInput] 현재 삭제 목록:", currentDeletedIds); console.log("🗑️ [RepeaterInput] 현재 삭제 목록:", currentDeletedIds);
const dataWithMeta = config.targetTable // 🆕 빈 배열일 때도 삭제 ID를 전달해야 함
? newItems.map((item, idx) => ({ let dataWithMeta: any[];
if (config.targetTable) {
if (newItems.length > 0) {
// 항목이 있으면 첫 번째 항목에 삭제 ID 포함
dataWithMeta = newItems.map((item, idx) => ({
...item, ...item,
_targetTable: config.targetTable, _targetTable: config.targetTable,
// 첫 번째 항목에만 삭제 ID 목록 포함
...(idx === 0 ? { _deletedItemIds: currentDeletedIds } : {}), ...(idx === 0 ? { _deletedItemIds: currentDeletedIds } : {}),
})) }));
: newItems; } else if (currentDeletedIds.length > 0) {
// 🆕 모든 항목 삭제 시 삭제 ID만 포함된 메타 객체 전달
dataWithMeta = [{ _targetTable: config.targetTable, _deletedItemIds: currentDeletedIds, _deleteOnly: true }];
} else {
dataWithMeta = [];
}
} else {
dataWithMeta = newItems;
}
console.log("🗑️ [RepeaterInput] onChange 호출 - dataWithMeta:", dataWithMeta); console.log("🗑️ [RepeaterInput] onChange 호출 - dataWithMeta:", dataWithMeta);
onChange?.(dataWithMeta); onChange?.(dataWithMeta);

View File

@ -802,6 +802,7 @@ export class ButtonActionExecutor {
} }
} }
// 🆕 배열이 비어있지 않거나, 하나라도 항목이 있으면 처리
if (Array.isArray(parsedValue) && parsedValue.length > 0) { if (Array.isArray(parsedValue) && parsedValue.length > 0) {
const firstItem = parsedValue[0]; const firstItem = parsedValue[0];
const deletedItemIds = firstItem?._deletedItemIds; const deletedItemIds = firstItem?._deletedItemIds;
@ -811,6 +812,7 @@ export class ButtonActionExecutor {
firstItemKeys: firstItem ? Object.keys(firstItem) : [], firstItemKeys: firstItem ? Object.keys(firstItem) : [],
deletedItemIds, deletedItemIds,
targetTable, targetTable,
isDeleteOnly: firstItem?._deleteOnly,
}); });
if (deletedItemIds && deletedItemIds.length > 0 && targetTable) { if (deletedItemIds && deletedItemIds.length > 0 && targetTable) {
@ -868,6 +870,12 @@ export class ButtonActionExecutor {
// _targetTable이 없거나, _repeatScreenModal_ 키면 스킵 (다른 로직에서 처리) // _targetTable이 없거나, _repeatScreenModal_ 키면 스킵 (다른 로직에서 처리)
if (!repeaterTargetTable || fieldKey.startsWith("_repeatScreenModal_")) continue; if (!repeaterTargetTable || fieldKey.startsWith("_repeatScreenModal_")) continue;
// 🆕 _deleteOnly 플래그가 있으면 INSERT/UPDATE 건너뛰기 (삭제 전용)
if (firstItem?._deleteOnly) {
console.log(`⏭️ [handleSave] 삭제 전용 데이터 - INSERT/UPDATE 스킵: ${fieldKey}`);
continue;
}
console.log(`📦 [handleSave] RepeaterFieldGroup 데이터 저장: ${fieldKey}${repeaterTargetTable}`, { console.log(`📦 [handleSave] RepeaterFieldGroup 데이터 저장: ${fieldKey}${repeaterTargetTable}`, {
itemCount: parsedData.length, itemCount: parsedData.length,
}); });
@ -2839,10 +2847,7 @@ export class ButtonActionExecutor {
* EditModal public으로 * EditModal public으로
* *
*/ */
public static async executeAfterSaveControl( public static async executeAfterSaveControl(config: ButtonActionConfig, context: ButtonActionContext): Promise<void> {
config: ButtonActionConfig,
context: ButtonActionContext,
): Promise<void> {
console.log("🎯 저장 후 제어 실행:", { console.log("🎯 저장 후 제어 실행:", {
enableDataflowControl: config.enableDataflowControl, enableDataflowControl: config.enableDataflowControl,
dataflowConfig: config.dataflowConfig, dataflowConfig: config.dataflowConfig,
@ -4306,19 +4311,20 @@ export class ButtonActionExecutor {
if (userId) { if (userId) {
try { try {
const { apiClient } = await import("@/lib/api/client"); const { apiClient } = await import("@/lib/api/client");
const statusTableName = config.trackingStatusTableName || this.trackingConfig?.trackingStatusTableName || context.tableName || "vehicles"; const statusTableName =
config.trackingStatusTableName ||
this.trackingConfig?.trackingStatusTableName ||
context.tableName ||
"vehicles";
const keyField = config.trackingStatusKeyField || this.trackingConfig?.trackingStatusKeyField || "user_id"; const keyField = config.trackingStatusKeyField || this.trackingConfig?.trackingStatusKeyField || "user_id";
// DB에서 현재 차량 정보 조회 // DB에서 현재 차량 정보 조회
const vehicleResponse = await apiClient.post( const vehicleResponse = await apiClient.post(`/table-management/tables/${statusTableName}/data`, {
`/table-management/tables/${statusTableName}/data`,
{
page: 1, page: 1,
size: 1, size: 1,
search: { [keyField]: userId }, search: { [keyField]: userId },
autoFilter: true, autoFilter: true,
}, });
);
const vehicleData = vehicleResponse.data?.data?.data?.[0] || vehicleResponse.data?.data?.rows?.[0]; const vehicleData = vehicleResponse.data?.data?.data?.[0] || vehicleResponse.data?.data?.rows?.[0];
if (vehicleData) { if (vehicleData) {
@ -4335,14 +4341,18 @@ export class ButtonActionExecutor {
// 마지막 위치 저장 (추적 중이었던 경우에만) // 마지막 위치 저장 (추적 중이었던 경우에만)
if (isTrackingActive) { if (isTrackingActive) {
// DB 값 우선, 없으면 formData 사용 // DB 값 우선, 없으면 formData 사용
const departure = dbDeparture || const departure =
this.trackingContext?.formData?.[this.trackingConfig?.trackingDepartureField || "departure"] || null; dbDeparture ||
const arrival = dbArrival || this.trackingContext?.formData?.[this.trackingConfig?.trackingDepartureField || "departure"] ||
this.trackingContext?.formData?.[this.trackingConfig?.trackingArrivalField || "arrival"] || null; null;
const arrival =
dbArrival || this.trackingContext?.formData?.[this.trackingConfig?.trackingArrivalField || "arrival"] || null;
const departureName = this.trackingContext?.formData?.["departure_name"] || null; const departureName = this.trackingContext?.formData?.["departure_name"] || null;
const destinationName = this.trackingContext?.formData?.["destination_name"] || null; const destinationName = this.trackingContext?.formData?.["destination_name"] || null;
const vehicleId = dbVehicleId || const vehicleId =
this.trackingContext?.formData?.[this.trackingConfig?.trackingVehicleIdField || "vehicle_id"] || null; dbVehicleId ||
this.trackingContext?.formData?.[this.trackingConfig?.trackingVehicleIdField || "vehicle_id"] ||
null;
await this.saveLocationToHistory( await this.saveLocationToHistory(
tripId, tripId,