Gitlab@Informatics
Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
PQS-Frontend
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
65160206
PQS-Frontend
Commits
70653915
Commit
70653915
authored
1 month ago
by
Kritkhanin Anantakul
Browse files
Options
Downloads
Patches
Plain Diff
fix targettable
parent
238f40c9
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/components/ProductionTargetTable.vue
+70
-43
70 additions, 43 deletions
src/components/ProductionTargetTable.vue
src/services/productionTarget.ts
+7
-0
7 additions, 0 deletions
src/services/productionTarget.ts
src/stores/productionTarget.ts
+21
-1
21 additions, 1 deletion
src/stores/productionTarget.ts
with
98 additions
and
44 deletions
src/components/ProductionTargetTable.vue
+
70
−
43
View file @
70653915
...
@@ -2,20 +2,18 @@
...
@@ -2,20 +2,18 @@
import
{
ref
,
onMounted
,
computed
}
from
'
vue
'
import
{
ref
,
onMounted
,
computed
}
from
'
vue
'
import
{
useProductionTargetStore
}
from
'
@/stores/productionTarget
'
import
{
useProductionTargetStore
}
from
'
@/stores/productionTarget
'
import
{
usePageContextStore
}
from
'
@/stores/pageContext
'
import
{
usePageContextStore
}
from
'
@/stores/pageContext
'
// ⬇️ ใช้ dateStore แทน props
import
{
useDateStore
}
from
'
@/stores/dateStore
'
import
{
useDateStore
}
from
'
@/stores/dateStore
'
import
{
storeToRefs
}
from
'
pinia
'
import
{
storeToRefs
}
from
'
pinia
'
const
productionTargetStore
=
useProductionTargetStore
()
const
productionTargetStore
=
useProductionTargetStore
()
const
pageContext
=
usePageContextStore
()
const
pageContext
=
usePageContextStore
()
const
{
currentDate
:
selectedDate
}
=
storeToRefs
(
useDateStore
())
// ✅ ใช้จาก store
const
{
currentDate
:
selectedDate
}
=
storeToRefs
(
useDateStore
())
const
currentPage
=
computed
(()
=>
pageContext
.
currentPage
)
const
currentPage
=
computed
(()
=>
pageContext
.
currentPage
)
const
headers
=
ref
([
const
headers
=
ref
([
{
title
:
"
รหัส
"
,
key
:
"
id
"
},
{
title
:
"
รหัส
"
,
key
:
"
id
"
},
{
title
:
"
ชื่อ
"
,
key
:
"
name
"
},
{
title
:
"
ชื่อ
"
,
key
:
"
name
"
},
{
title
:
"
ขนาด
"
,
key
:
"
size
"
},
{
title
:
"
ขนาด
"
,
key
:
"
size
"
},
{
title
:
"
แบรนด์
"
,
key
:
"
brand
"
},
{
title
:
"
แบรนด์
"
,
key
:
"
brand
"
},
{
title
:
"
ชนิด
"
,
key
:
"
type
"
},
{
title
:
"
ชนิด
"
,
key
:
"
type
"
},
...
@@ -29,12 +27,15 @@ const groupBy = [{ key: 'customerGroup' }]
...
@@ -29,12 +27,15 @@ const groupBy = [{ key: 'customerGroup' }]
const
savingRowIds
=
ref
<
number
[]
>
([])
const
savingRowIds
=
ref
<
number
[]
>
([])
const
recentlySavedIds
=
ref
<
number
[]
>
([])
const
recentlySavedIds
=
ref
<
number
[]
>
([])
// ตั้งค่า delay (ms) หลังจากเรียก edit function ก่อน re-fetch data
const
UPDATE_DELAY
=
500
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
await
productionTargetStore
.
fetchProductionTargets
()
await
productionTargetStore
.
fetchProductionTargets
()
})
})
// ✅ กรองตาม PageID + selectedDate จาก store
const
productionData
=
computed
(()
=>
{
const
productionData
=
computed
(()
=>
{
// map rawData ให้มี field ที่จำเป็นสำหรับ UI และ API
const
rawData
=
productionTargetStore
.
productionTargets
const
rawData
=
productionTargetStore
.
productionTargets
.
filter
((
target
)
=>
.
filter
((
target
)
=>
target
.
page
?.
PageID
===
currentPage
.
value
&&
target
.
page
?.
PageID
===
currentPage
.
value
&&
...
@@ -44,6 +45,10 @@ const productionData = computed(() => {
...
@@ -44,6 +45,10 @@ const productionData = computed(() => {
const
customerName
=
target
.
order
?.
customer
?.
name
||
'
ไม่ระบุลูกค้า
'
const
customerName
=
target
.
order
?.
customer
?.
name
||
'
ไม่ระบุลูกค้า
'
return
{
return
{
id
:
target
.
ProductionTargetID
,
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
||
'
ไม่พบข้อมูล
'
,
name
:
target
.
item
?.
name
||
target
.
item
?.
brand
||
'
ไม่พบข้อมูล
'
,
size
:
target
.
item
?.
size
||
'
-
'
,
size
:
target
.
item
?.
size
||
'
-
'
,
brand
:
target
.
item
?.
brand
||
'
-
'
,
brand
:
target
.
item
?.
brand
||
'
-
'
,
...
@@ -57,11 +62,13 @@ const productionData = computed(() => {
...
@@ -57,11 +62,13 @@ const productionData = computed(() => {
}
}
})
})
// 🔄 รวมรายการซ้ำในกลุ่ม "วันนี้"
console
.
log
(
'
✅ rawData:
'
,
rawData
)
const
todayGroupMap
=
new
Map
<
string
,
any
>
()
// รวมรายการซ้ำในกลุ่ม "วันนี้"
const
todayGroupMap
=
new
Map
<
string
,
any
>
()
rawData
.
forEach
(
item
=>
{
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
))
{
if
(
todayGroupMap
.
has
(
key
))
{
const
existing
=
todayGroupMap
.
get
(
key
)
const
existing
=
todayGroupMap
.
get
(
key
)
existing
.
target
+=
item
.
target
existing
.
target
+=
item
.
target
...
@@ -69,14 +76,18 @@ const productionData = computed(() => {
...
@@ -69,14 +76,18 @@ const productionData = computed(() => {
}
else
{
}
else
{
todayGroupMap
.
set
(
key
,
{
todayGroupMap
.
set
(
key
,
{
...
item
,
...
item
,
customerGroup
:
'
0-รวมทั้งหมด
'
,
// กลุ่ม "วันนี้"
// force ให้แน่ใจว่า itemID กับ itemType ถูกเก็บไว้
itemID
:
item
.
itemID
,
itemType
:
item
.
itemType
,
customerGroup
:
'
0-รวมทั้งหมด
'
,
})
})
}
}
})
})
const
todayItems
=
Array
.
from
(
todayGroupMap
.
values
())
const
todayItems
=
Array
.
from
(
todayGroupMap
.
values
())
console
.
log
(
'
✅ todayItems:
'
,
todayItems
)
//
✅
กลุ่มรายลูกค้า (ไม่
ยุบ
)
// กลุ่มรายลูกค้า (ไม่
รวมกัน
)
const
customerItems
=
rawData
.
map
(
item
=>
({
const
customerItems
=
rawData
.
map
(
item
=>
({
...
item
,
...
item
,
customerGroup
:
`1-
${
item
.
customer
}
`
,
customerGroup
:
`1-
${
item
.
customer
}
`
,
...
@@ -85,10 +96,6 @@ const productionData = computed(() => {
...
@@ -85,10 +96,6 @@ const productionData = computed(() => {
return
[...
todayItems
,
...
customerItems
]
return
[...
todayItems
,
...
customerItems
]
})
})
async
function
saveActualProduced
(
item
:
any
)
{
async
function
saveActualProduced
(
item
:
any
)
{
const
id
=
item
.
id
const
id
=
item
.
id
const
produced
=
Number
(
item
.
produced
)
const
produced
=
Number
(
item
.
produced
)
...
@@ -98,22 +105,34 @@ async function saveActualProduced(item: any) {
...
@@ -98,22 +105,34 @@ async function saveActualProduced(item: any) {
savingRowIds
.
value
.
push
(
id
)
savingRowIds
.
value
.
push
(
id
)
try
{
try
{
await
productionTargetStore
.
editProductionTarget
(
id
,
{
if
(
item
.
customerGroup
?.
startsWith
(
'
0-
'
))
{
ActualProduced
:
produced
,
await
productionTargetStore
.
editTodayTarget
({
})
itemID
:
item
.
itemID
,
await
productionTargetStore
.
fetchProductionTargets
()
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
)
recentlySavedIds
.
value
.
push
(
id
)
setTimeout
(()
=>
{
setTimeout
(()
=>
{
recentlySavedIds
.
value
=
recentlySavedIds
.
value
.
filter
(
rowId
=>
rowId
!==
id
)
recentlySavedIds
.
value
=
recentlySavedIds
.
value
.
filter
(
(
rowId
)
=>
rowId
!==
id
)
},
1000
)
},
1000
)
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
'
❌ Save failed:
'
,
e
)
console
.
error
(
'
❌ Save failed:
'
,
e
)
}
finally
{
}
finally
{
savingRowIds
.
value
=
savingRowIds
.
value
.
filter
(
rowId
=>
rowId
!==
id
)
savingRowIds
.
value
=
savingRowIds
.
value
.
filter
(
(
rowId
)
=>
rowId
!==
id
)
}
}
}
}
function
blockInvalidKeys
(
event
:
KeyboardEvent
)
{
function
blockInvalidKeys
(
event
:
KeyboardEvent
)
{
const
invalidKeys
=
[
'
e
'
,
'
E
'
,
'
+
'
,
'
-
'
,
'
.
'
,
'
,
'
]
const
invalidKeys
=
[
'
e
'
,
'
E
'
,
'
+
'
,
'
-
'
,
'
.
'
,
'
,
'
]
if
(
invalidKeys
.
includes
(
event
.
key
))
{
if
(
invalidKeys
.
includes
(
event
.
key
))
{
...
@@ -132,25 +151,24 @@ function blockInvalidKeys(event: KeyboardEvent) {
...
@@ -132,25 +151,24 @@ function blockInvalidKeys(event: KeyboardEvent) {
item-value=
"name"
item-value=
"name"
hide-default-footer
hide-default-footer
>
>
<template
v-slot:group-header=
"
{ item, columns, toggleGroup, isGroupOpen }">
<template
v-slot:group-header=
"
{ item, columns, toggleGroup, isGroupOpen }">
<tr>
<tr>
<td
:colspan=
"columns.length"
>
<td
:colspan=
"columns.length"
>
<div
class=
"d-flex align-center"
>
<div
class=
"d-flex align-center"
>
<v-btn
<v-btn
:icon=
"isGroupOpen(item) ? '$expand' : '$next'"
:icon=
"isGroupOpen(item) ? '$expand' : '$next'"
density=
"comfortable"
density=
"comfortable"
size=
"x-small"
size=
"x-small"
variant=
"outlined"
variant=
"outlined"
@
click=
"toggleGroup(item)"
@
click=
"toggleGroup(item)"
/>
/>
<span
class=
"ms-2 text-caption"
>
<span
class=
"ms-2 text-caption"
>
{{
item
.
value
.
startsWith
(
'
0-
'
)
?
'
วันนี้
'
:
'
ลูกค้า:
'
+
item
.
value
.
slice
(
2
)
}}
{{
item
.
value
.
startsWith
(
'
0-
'
)
?
'
วันนี้
'
:
'
ลูกค้า:
'
+
item
.
value
.
slice
(
2
)
}}
</span>
</span>
</div>
</div>
</td>
</td>
</tr>
</tr>
</
template
>
</
template
>
<
template
v-slot:item.produced=
"{ item }"
>
<
template
v-slot:item.produced=
"{ item }"
>
<div
class=
"save-cell-wrapper"
style=
"position: relative; display: inline-block;"
>
<div
class=
"save-cell-wrapper"
style=
"position: relative; display: inline-block;"
>
...
@@ -190,10 +208,19 @@ function blockInvalidKeys(event: KeyboardEvent) {
...
@@ -190,10 +208,19 @@ function blockInvalidKeys(event: KeyboardEvent) {
.fade-check
{
.fade-check
{
animation
:
fadeOut
1s
ease-out
forwards
;
animation
:
fadeOut
1s
ease-out
forwards
;
}
}
@keyframes
fadeOut
{
@keyframes
fadeOut
{
0
%
{
opacity
:
1
;
transform
:
scale
(
1
);
}
0
%
{
80
%
{
opacity
:
1
;
transform
:
scale
(
1.2
);
}
opacity
:
1
;
100
%
{
opacity
:
0
;
transform
:
scale
(
1
);
}
transform
:
scale
(
1
);
}
80
%
{
opacity
:
1
;
transform
:
scale
(
1.2
);
}
100
%
{
opacity
:
0
;
transform
:
scale
(
1
);
}
}
}
</
style
>
</
style
>
This diff is collapsed.
Click to expand it.
src/services/productionTarget.ts
+
7
−
0
View file @
70653915
...
@@ -29,3 +29,10 @@ export async function updateProductionTarget(
...
@@ -29,3 +29,10 @@ export async function updateProductionTarget(
export
async
function
deleteProductionTarget
(
id
:
number
):
Promise
<
void
>
{
export
async
function
deleteProductionTarget
(
id
:
number
):
Promise
<
void
>
{
await
http
.
delete
(
`/production-targets/
${
id
}
`
);
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
This diff is collapsed.
Click to expand it.
src/stores/productionTarget.ts
+
21
−
1
View file @
70653915
...
@@ -53,7 +53,11 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
...
@@ -53,7 +53,11 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
const
updated
=
await
productionTargetService
.
updateProductionTarget
(
id
,
payload
);
const
updated
=
await
productionTargetService
.
updateProductionTarget
(
id
,
payload
);
const
index
=
productionTargets
.
value
.
findIndex
(
p
=>
p
.
ProductionTargetID
===
id
);
const
index
=
productionTargets
.
value
.
findIndex
(
p
=>
p
.
ProductionTargetID
===
id
);
if
(
index
!==
-
1
)
{
if
(
index
!==
-
1
)
{
productionTargets
.
value
[
index
]
=
updated
;
// ✅ อัปเดตค่าจริงใน local state เพื่อให้ computed re-render
productionTargets
.
value
[
index
]
=
{
...
productionTargets
.
value
[
index
],
...
payload
,
// ใช้ payload (เช่น ActualProduced) ทับของเดิม
};
}
}
}
catch
(
e
:
any
)
{
}
catch
(
e
:
any
)
{
error
.
value
=
e
.
message
||
'
Unknown Error
'
;
error
.
value
=
e
.
message
||
'
Unknown Error
'
;
...
@@ -61,6 +65,21 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
...
@@ -61,6 +65,21 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
loading
.
value
=
false
;
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
)
{
async
function
removeProductionTarget
(
id
:
number
)
{
loading
.
value
=
true
;
loading
.
value
=
true
;
...
@@ -82,6 +101,7 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
...
@@ -82,6 +101,7 @@ export const useProductionTargetStore = defineStore('productionTarget', () => {
fetchProductionTargets
,
fetchProductionTargets
,
fetchProductionTarget
,
fetchProductionTarget
,
addProductionTarget
,
addProductionTarget
,
editTodayTarget
,
editProductionTarget
,
editProductionTarget
,
removeProductionTarget
,
removeProductionTarget
,
};
};
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment