From 7065391525c29c8dd8289d742e9e3368986a24c5 Mon Sep 17 00:00:00 2001 From: Kritkhanin Anantakul <65160144@go.buu.ac.th> Date: Mon, 24 Mar 2025 16:40:05 +0700 Subject: [PATCH] fix targettable --- src/components/ProductionTargetTable.vue | 113 ++++++++++++++--------- src/services/productionTarget.ts | 7 ++ src/stores/productionTarget.ts | 22 ++++- 3 files changed, 98 insertions(+), 44 deletions(-) diff --git a/src/components/ProductionTargetTable.vue b/src/components/ProductionTargetTable.vue index 75fbc1a..0ea5b0f 100644 --- a/src/components/ProductionTargetTable.vue +++ b/src/components/ProductionTargetTable.vue @@ -2,20 +2,18 @@ import { ref, onMounted, computed } from 'vue' import { useProductionTargetStore } from '@/stores/productionTarget' import { usePageContextStore } from '@/stores/pageContext' - -// ⬇️ ใช้ dateStore แทน props import { useDateStore } from '@/stores/dateStore' import { storeToRefs } from 'pinia' const productionTargetStore = useProductionTargetStore() const pageContext = usePageContextStore() -const { currentDate: selectedDate } = storeToRefs(useDateStore()) // ✅ ใช้จาก store +const { currentDate: selectedDate } = storeToRefs(useDateStore()) const currentPage = computed(() => pageContext.currentPage) const headers = ref([ { title: "รหัส", key: "id" }, - { title: "ชื่อ", key: "name" }, + { title: "ชื่อ", key: "name" }, { title: "ขนาด", key: "size" }, { title: "แบรนด์", key: "brand" }, { title: "ชนิด", key: "type" }, @@ -29,12 +27,15 @@ const groupBy = [{ key: 'customerGroup' }] const savingRowIds = ref<number[]>([]) const recentlySavedIds = ref<number[]>([]) +// ตั้งค่า delay (ms) หลังจากเรียก edit function ก่อน re-fetch data +const UPDATE_DELAY = 500 + onMounted(async () => { await productionTargetStore.fetchProductionTargets() }) -// ✅ กรองตาม PageID + selectedDate จาก store const productionData = computed(() => { + // map rawData ให้มี field ที่จำเป็นสำหรับ UI และ API const rawData = productionTargetStore.productionTargets .filter((target) => target.page?.PageID === currentPage.value && @@ -44,6 +45,10 @@ const productionData = computed(() => { const customerName = target.order?.customer?.name || 'ไม่ระบุลูกค้า' return { id: target.ProductionTargetID, + // เปลี่ยน field จาก target.item?.ItemID เป็น target.item?.id + // ให้แน่ใจว่าฟิลด์นี้ตรงกับ structure ที่ backend ส่งมา + itemID: target.item?.id, + itemType: target.itemType, name: target.item?.name || target.item?.brand || 'ไม่พบข้อมูล', size: target.item?.size || '-', brand: target.item?.brand || '-', @@ -57,11 +62,13 @@ const productionData = computed(() => { } }) - // 🔄 รวมรายการซ้ำในกลุ่ม "วันนี้" - const todayGroupMap = new Map<string, any>() + console.log('✅ rawData:', rawData) + // รวมรายการซ้ำในกลุ่ม "วันนี้" + const todayGroupMap = new Map<string, any>() rawData.forEach(item => { - const key = `${item.name}|${item.size}|${item.brand}|${item.type}` + // key รวม itemID เพื่อให้แน่ใจว่า itemID ไม่หาย + const key = `${item.itemID}|${item.name}|${item.size}|${item.brand}|${item.type}` if (todayGroupMap.has(key)) { const existing = todayGroupMap.get(key) existing.target += item.target @@ -69,14 +76,18 @@ const productionData = computed(() => { } else { todayGroupMap.set(key, { ...item, - customerGroup: '0-รวมทั้งหมด', // กลุ่ม "วันนี้" + // force ให้แน่ใจว่า itemID กับ itemType ถูกเก็บไว้ + itemID: item.itemID, + itemType: item.itemType, + customerGroup: '0-รวมทั้งหมด', }) } }) const todayItems = Array.from(todayGroupMap.values()) + console.log('✅ todayItems:', todayItems) - // ✅ กลุ่มรายลูกค้า (ไม่ยุบ) + // กลุ่มรายลูกค้า (ไม่รวมกัน) const customerItems = rawData.map(item => ({ ...item, customerGroup: `1-${item.customer}`, @@ -85,10 +96,6 @@ const productionData = computed(() => { return [...todayItems, ...customerItems] }) - - - - async function saveActualProduced(item: any) { const id = item.id const produced = Number(item.produced) @@ -98,22 +105,34 @@ async function saveActualProduced(item: any) { savingRowIds.value.push(id) try { - await productionTargetStore.editProductionTarget(id, { - ActualProduced: produced, - }) - await productionTargetStore.fetchProductionTargets() + if (item.customerGroup?.startsWith('0-')) { + await productionTargetStore.editTodayTarget({ + itemID: item.itemID, + itemType: item.itemType, + date: selectedDate.value.split('-').reverse().join('/'), + actualProduced: produced, + }) + // ✅ optional: อาจต้อง fetch ใหม่ เพราะรวม target หลายรายการ + await productionTargetStore.fetchProductionTargets() + } else { + await productionTargetStore.editProductionTarget(id, { + ActualProduced: produced, + }) + // ❌ ไม่ต้อง fetch + } recentlySavedIds.value.push(id) setTimeout(() => { - recentlySavedIds.value = recentlySavedIds.value.filter(rowId => rowId !== id) + recentlySavedIds.value = recentlySavedIds.value.filter((rowId) => rowId !== id) }, 1000) } catch (e) { console.error('❌ Save failed:', e) } finally { - savingRowIds.value = savingRowIds.value.filter(rowId => rowId !== id) + savingRowIds.value = savingRowIds.value.filter((rowId) => rowId !== id) } } + function blockInvalidKeys(event: KeyboardEvent) { const invalidKeys = ['e', 'E', '+', '-', '.', ','] if (invalidKeys.includes(event.key)) { @@ -132,25 +151,24 @@ function blockInvalidKeys(event: KeyboardEvent) { item-value="name" hide-default-footer > - <template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }"> - <tr> - <td :colspan="columns.length"> - <div class="d-flex align-center"> - <v-btn - :icon="isGroupOpen(item) ? '$expand' : '$next'" - density="comfortable" - size="x-small" - variant="outlined" - @click="toggleGroup(item)" - /> - <span class="ms-2 text-caption"> - {{ item.value.startsWith('0-') ? 'วันนี้' : 'ลูกค้า: ' + item.value.slice(2) }} - </span> - </div> - </td> - </tr> - </template> - + <template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }"> + <tr> + <td :colspan="columns.length"> + <div class="d-flex align-center"> + <v-btn + :icon="isGroupOpen(item) ? '$expand' : '$next'" + density="comfortable" + size="x-small" + variant="outlined" + @click="toggleGroup(item)" + /> + <span class="ms-2 text-caption"> + {{ item.value.startsWith('0-') ? 'วันนี้' : 'ลูกค้า: ' + item.value.slice(2) }} + </span> + </div> + </td> + </tr> + </template> <template v-slot:item.produced="{ item }"> <div class="save-cell-wrapper" style="position: relative; display: inline-block;"> @@ -190,10 +208,19 @@ function blockInvalidKeys(event: KeyboardEvent) { .fade-check { animation: fadeOut 1s ease-out forwards; } + @keyframes fadeOut { - 0% { opacity: 1; transform: scale(1); } - 80% { opacity: 1; transform: scale(1.2); } - 100% { opacity: 0; transform: scale(1); } + 0% { + opacity: 1; + transform: scale(1); + } + 80% { + opacity: 1; + transform: scale(1.2); + } + 100% { + opacity: 0; + transform: scale(1); + } } - </style> diff --git a/src/services/productionTarget.ts b/src/services/productionTarget.ts index 7772012..a839ab6 100644 --- a/src/services/productionTarget.ts +++ b/src/services/productionTarget.ts @@ -29,3 +29,10 @@ export async function updateProductionTarget( export async function deleteProductionTarget(id: number): Promise<void> { await http.delete(`/production-targets/${id}`); } + +export async function editTodayTarget(payload: { + ProductionTargetID: number; + ActualProduced: number; +}): Promise<void> { + await http.post('/production-targets/edit-today', payload); +} \ No newline at end of file diff --git a/src/stores/productionTarget.ts b/src/stores/productionTarget.ts index 2246d0b..8515a91 100644 --- a/src/stores/productionTarget.ts +++ b/src/stores/productionTarget.ts @@ -53,7 +53,11 @@ export const useProductionTargetStore = defineStore('productionTarget', () => { const updated = await productionTargetService.updateProductionTarget(id, payload); const index = productionTargets.value.findIndex(p => p.ProductionTargetID === id); if (index !== -1) { - productionTargets.value[index] = updated; + // ✅ อัปเดตค่าจริงใน local state เพื่อให้ computed re-render + productionTargets.value[index] = { + ...productionTargets.value[index], + ...payload, // ใช้ payload (เช่น ActualProduced) ทับของเดิม + }; } } catch (e: any) { error.value = e.message || 'Unknown Error'; @@ -61,6 +65,21 @@ export const useProductionTargetStore = defineStore('productionTarget', () => { loading.value = false; } } + + + async function editTodayTarget(payload: { ProductionTargetID: number, ActualProduced: number }) { + loading.value = true; + error.value = null; + try { + await productionTargetService.editTodayTarget(payload); + } catch (e: any) { + error.value = e.message || 'Unknown Error'; + throw e; // เพื่อให้ caller เช่นหน้า UI จับ error ได้ + } finally { + loading.value = false; + } + } + async function removeProductionTarget(id: number) { loading.value = true; @@ -82,6 +101,7 @@ export const useProductionTargetStore = defineStore('productionTarget', () => { fetchProductionTargets, fetchProductionTarget, addProductionTarget, + editTodayTarget, editProductionTarget, removeProductionTarget, }; -- GitLab