From e87f441c00c697d83ecad9ff0d16259c39398d51 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Fri, 17 Apr 2026 14:38:31 +0700 Subject: [PATCH 01/19] refactor:(position-review) add Call API profileSalaryTemp /done --- .../components/PositionReview/Table.vue | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/modules/10_registry/components/PositionReview/Table.vue b/src/modules/10_registry/components/PositionReview/Table.vue index d2b7712..3d20dd6 100644 --- a/src/modules/10_registry/components/PositionReview/Table.vue +++ b/src/modules/10_registry/components/PositionReview/Table.vue @@ -323,20 +323,23 @@ async function fetchData() { // .get( // `${config.API.profileSalaryTemp}/${empType.value}/done/${profileId.value}`, // ) - http - .get(`${config.API.profileSalaryTemp}/${empType.value}/${profileId.value}`) - .then((res) => { - const data = res.data.result; - rowsMain.value = data; - rows.value = data; - serchDataTable(); - }) - .catch((err) => { - messageError($q, err); - }) - .finally(() => { - isLoad.value = false; - }); + try { + await http.get( + `${config.API.profileSalaryTemp}/${empType.value}/${profileId.value}`, + ); + + const res = await http.get( + `${config.API.profileSalaryTemp}/${empType.value}/done/${profileId.value}`, + ); + const data = res.data.result; + rowsMain.value = data; + rows.value = data; + serchDataTable(); + } catch (err) { + messageError($q, err); + } finally { + isLoad.value = false; + } } /** function ค้นหาข้อมูลรายการในตาราง*/ From 3cedcddbacc964469d9a89bb5d08c783b25aeea9 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Mon, 20 Apr 2026 10:08:02 +0700 Subject: [PATCH 02/19] =?UTF-8?q?fixed=20=E0=B8=9F=E0=B8=AD=E0=B8=A3?= =?UTF-8?q?=E0=B9=8C=E0=B8=A1=E0=B9=81=E0=B8=88=E0=B9=89=E0=B8=87=E0=B8=9B?= =?UTF-8?q?=E0=B8=B1=E0=B8=8D=E0=B8=AB=E0=B8=B2=E0=B8=9A=E0=B8=B1=E0=B8=87?= =?UTF-8?q?=E0=B8=84=E0=B8=B1=E0=B8=9A=E0=B8=AD=E0=B8=B5=E0=B9=80=E0=B8=A1?= =?UTF-8?q?=E0=B8=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DialogDebug.vue | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/DialogDebug.vue b/src/components/DialogDebug.vue index d51100e..401d641 100644 --- a/src/components/DialogDebug.vue +++ b/src/components/DialogDebug.vue @@ -316,6 +316,9 @@ function onClose() {
+
+ ผู้ดูแลระบบจะติดต่อกลับผ่านทางอีเมลที่ท่านระบุ กรุณาตรวจสอบอีเมลของท่านเป็นระยะ +
@@ -341,12 +345,6 @@ function onClose() { v-model="formData.phone" class="inputgreen" hide-bottom-space - :rules="[ - () => - !!formData.email || - !!formData.phone || - 'กรุณากรอกอีเมลหรือเบอร์โทรติดต่อกลับ', - ]" />
From 573a76448ea2dab7432a1ec0ff1a54c1dd342595 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 23 Apr 2026 09:13:05 +0700 Subject: [PATCH 03/19] refactor(registry): exportToExcelPosition --- package.json | 1 + .../components/PositionReview/Table.vue | 113 ++++++------- .../10_registry/interface/review/Edit.ts | 1 + .../10_registry/utils/exportPosition.ts | 148 ++++++++++++++++++ 4 files changed, 208 insertions(+), 55 deletions(-) create mode 100644 src/modules/10_registry/utils/exportPosition.ts diff --git a/package.json b/package.json index fc5a6bd..d84d6c4 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@tato30/vue-pdf": "^1.5.1", "@vuepic/vue-datepicker": "^3.6.3", "bma-org-chart": "^0.0.7", + "exceljs": "^4.4.0", "html-to-image": "^1.11.13", "keycloak-js": "^20.0.2", "moment": "^2.29.4", diff --git a/src/modules/10_registry/components/PositionReview/Table.vue b/src/modules/10_registry/components/PositionReview/Table.vue index 3d20dd6..a79e32f 100644 --- a/src/modules/10_registry/components/PositionReview/Table.vue +++ b/src/modules/10_registry/components/PositionReview/Table.vue @@ -24,6 +24,8 @@ import type { DataPosition } from "@/modules/10_registry/interface/review/Edit"; // import DialogSort from "@/modules/04_registryPerson/views/edit/components/DialogSort.vue"; // import CurruncyInput from "@/components/CurruncyInput.vue"; +import { exportToExcelPosition } from "@/modules/10_registry/utils/exportPosition"; + const dataStore = useDataStore(); const store = useGovernmentPosDataStore(); const $q = useQuasar(); @@ -445,67 +447,68 @@ function classColorRow(isDelete: boolean, isEdit: boolean, isEntry: boolean) { /** ฟังก์ชันดาวน์โหลดไฟล Excel */ function exportToExcel() { - const newData = rows.value.map((e: DataPosition, index: number) => { - return { - no: index + 1, - commandDateAffect: date2Thai(e.commandDateAffect), - positionName: e.positionName, - positionType: e.positionType, - positionLevel: e.positionLevel - ? e.positionLevel - : e.positionCee - ? e.positionCee - : "", - positionExecutive: e.positionExecutive, - amount: e.amount, - mouthSalaryAmount: e.mouthSalaryAmount, - positionSalaryAmount: e.positionSalaryAmount, - organization: findOrgName({ - root: e.orgRoot, - child1: e.orgChild1, - child2: e.orgChild2, - child3: e.orgChild3, - child4: e.orgChild4, - }), - posNo: - e.posNoAbb && e.posNo - ? `${e.posNoAbb} ${e.posNo}` - : e.posNo - ? e.posNo - : "", - posNumCodeSit: - e.posNumCodeSitAbb && e.posNumCodeSit - ? `${e.posNumCodeSit} (${e.posNumCodeSitAbb})` - : e.posNumCodeSit - ? e.posNumCodeSit - : "", - commandNo: - e.commandNo && e.commandYear - ? `${e.commandNo}/${Number(e.commandYear) + 543}` - : "", - commandDateSign: date2Thai(e.commandDateSign), - commandCode: store.convertCommandCodeName(e.commandCode), - remark: e.remark, - }; - }); + exportToExcelPosition(rows.value); + // const newData = rows.value.map((e: DataPosition, index: number) => { + // return { + // no: index + 1, + // commandDateAffect: date2Thai(e.commandDateAffect), + // positionName: e.positionName, + // positionType: e.positionType, + // positionLevel: e.positionLevel + // ? e.positionLevel + // : e.positionCee + // ? e.positionCee + // : "", + // positionExecutive: e.positionExecutive, + // amount: e.amount, + // mouthSalaryAmount: e.mouthSalaryAmount, + // positionSalaryAmount: e.positionSalaryAmount, + // organization: findOrgName({ + // root: e.orgRoot, + // child1: e.orgChild1, + // child2: e.orgChild2, + // child3: e.orgChild3, + // child4: e.orgChild4, + // }), + // posNo: + // e.posNoAbb && e.posNo + // ? `${e.posNoAbb} ${e.posNo}` + // : e.posNo + // ? e.posNo + // : "", + // posNumCodeSit: + // e.posNumCodeSitAbb && e.posNumCodeSit + // ? `${e.posNumCodeSit} (${e.posNumCodeSitAbb})` + // : e.posNumCodeSit + // ? e.posNumCodeSit + // : "", + // commandNo: + // e.commandNo && e.commandYear + // ? `${e.commandNo}/${Number(e.commandYear) + 543}` + // : "", + // commandDateSign: date2Thai(e.commandDateSign), + // commandCode: store.convertCommandCodeName(e.commandCode), + // remark: e.remark, + // }; + // }); - const headers = columns.value.map((item: any) => item.label) || []; // หัวคอลัมน์ภาษาไทย - const worksheet = XLSX.utils.json_to_sheet(newData, { - header: visibleColumns.value, - }); + // const headers = columns.value.map((item: any) => item.label) || []; // หัวคอลัมน์ภาษาไทย + // const worksheet = XLSX.utils.json_to_sheet(newData, { + // header: visibleColumns.value, + // }); //แทรกหัวคอลัมน์ภาษาไทย (ใช้ A1, B1, C1 แทน) - XLSX.utils.sheet_add_aoa(worksheet, [headers], { origin: "A1" }); + // XLSX.utils.sheet_add_aoa(worksheet, [headers], { origin: "A1" }); // Create a new workbook and append the worksheet - const workbook = XLSX.utils.book_new(); + // const workbook = XLSX.utils.book_new(); - XLSX.utils.book_append_sheet( - workbook, - worksheet, - `รายการประวัติตำแหน่งเงินเดือน`, - ); - XLSX.writeFile(workbook, "รายการประวัติตำแหน่งเงินเดือน.xlsx"); + // XLSX.utils.book_append_sheet( + // workbook, + // worksheet, + // `รายการประวัติตำแหน่งเงินเดือน`, + // ); + // XLSX.writeFile(workbook, "รายการประวัติตำแหน่งเงินเดือน.xlsx"); } // const commandCodeOptions = ref(store.commandCodeData); //รายการปรเภทคำสั่ง diff --git a/src/modules/10_registry/interface/review/Edit.ts b/src/modules/10_registry/interface/review/Edit.ts index 04041b2..545dc35 100644 --- a/src/modules/10_registry/interface/review/Edit.ts +++ b/src/modules/10_registry/interface/review/Edit.ts @@ -71,6 +71,7 @@ interface DataPosition { status: string; posNumCodeSitAbb: string; posNumCodeSit: string; + positionExecutiveField: string; } export type { DataSalaryPos, DataPosition }; diff --git a/src/modules/10_registry/utils/exportPosition.ts b/src/modules/10_registry/utils/exportPosition.ts new file mode 100644 index 0000000..ccd1dbf --- /dev/null +++ b/src/modules/10_registry/utils/exportPosition.ts @@ -0,0 +1,148 @@ +import ExcelJS from "exceljs"; +import { useCounterMixin } from "@/stores/mixin"; +import { useGovernmentPosDataStore } from "@/modules/10_registry/store/Position"; + +import type { DataPosition } from "@/modules/10_registry/interface/review/Edit"; + +const { date2Thai } = useCounterMixin(); +const store = useGovernmentPosDataStore(); + +export async function exportToExcelPosition(data: DataPosition[]) { + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet("รายการประวัติตำแหน่งเงินเดือน"); + + // --- ส่วนที่ 1: สร้าง Master Data Sheet สำหรับอ้างอิง ID --- + // เราจะซ่อนแผ่นงานนี้ไว้ (hidden) เพื่อใช้ทำ Dropdown และ VLOOKUP + const masterSheet = workbook.addWorksheet("MasterData", { state: "hidden" }); + const masterData = store.commandCodeData; // [{id: 1, name: "ย้าย"}, ...] + + masterData.forEach((item, index) => { + masterSheet.getCell(`A${index + 1}`).value = item.name; + masterSheet.getCell(`B${index + 1}`).value = item.id; + }); + + // --- ส่วนที่ 2: กำหนด Columns --- + worksheet.columns = [ + { header: "ลำดับ", key: "no", width: 8 }, + { header: "วันที่คำสั่งมีผล", key: "commandDateAffect", width: 18 }, + { header: "ตำแหน่งในสายงาน", key: "positionName", width: 25 }, + { header: "ตำแหน่งประเภท", key: "positionType", width: 18 }, + { header: "ระดับ", key: "positionLevel", width: 12 }, + { header: "ระดับซี", key: "positionCee", width: 12 }, + { header: "สายงาน", key: "positionLine", width: 20 }, + { header: "ด้าน/สาขา", key: "positionPathSide", width: 15 }, + { header: "ตำแหน่งทางการบริหาร", key: "positionExecutive", width: 20 }, + { header: "ด้านทางการบริหาร", key: "positionExecutiveField", width: 20 }, + { header: "เงินเดือน", key: "amount", width: 15 }, + { header: "เงินค่าตอบแทนรายเดือน", key: "mouthSalaryAmount", width: 15 }, + { header: "เงินประจำตำแหน่ง", key: "positionSalaryAmount", width: 15 }, + { header: "เงินค่าตอบแทนพิเศษ", key: "amountSpecial", width: 15 }, + { header: "หน่วยงาน", key: "organization", width: 30 }, + { header: "ส่วนราชการระดับ 1", key: "orgChild1", width: 20 }, + { header: "ส่วนราชการระดับ 2", key: "orgChild2", width: 20 }, + { header: "ส่วนราชการระดับ 3", key: "orgChild3", width: 20 }, + { header: "ส่วนราชการระดับ 4", key: "orgChild4", width: 20 }, + { header: "ตัวย่อเลขที่ตำแหน่ง", key: "posNoAbb", width: 15 }, + { header: "เลขที่ตำแหน่ง", key: "posNo", width: 15 }, + { header: "หน่วยงานที่ออกคำสั่ง", key: "posNumCodeSit", width: 20 }, + { + header: "ตัวย่อหน่วยงานที่ออกคำสั่ง", + key: "posNumCodeSitAbb", + width: 15, + }, + { header: "เลขที่คำสั่ง", key: "commandNo", width: 15 }, + { header: "ปีเลขที่คำสั่ง", key: "commandYear", width: 12 }, + { header: "วันที่ลงนาม", key: "commandDateSign", width: 18 }, + { header: "ประเภทคำสั่ง", key: "commandCode", width: 25 }, // AA + { header: "หมายเหตุ", key: "remark", width: 20 }, + { header: "commandId", key: "commandId", width: 20 }, // AC (ลำดับที่ 29) + ]; + + // 3. Map ข้อมูล + const newData = data.map((e, index) => ({ + no: index + 1, + commandDateAffect: date2Thai(e.commandDateAffect), + positionName: e.positionName, + positionType: e.positionType, + positionLevel: e.positionLevel, + positionCee: e.positionCee, + positionLine: e.positionLine || "", + positionPathSide: e.positionPathSide || "", + positionExecutive: e.positionExecutive, + positionExecutiveField: e.positionExecutiveField || "", + amount: e.amount, + mouthSalaryAmount: e.mouthSalaryAmount || 0, + positionSalaryAmount: e.positionSalaryAmount, + amountSpecial: e.amountSpecial || 0, + organization: e.orgRoot, + orgChild1: e.orgChild1, + orgChild2: e.orgChild2, + orgChild3: e.orgChild3, + orgChild4: e.orgChild4, + posNoAbb: e.posNoAbb, + posNo: e.posNo, + posNumCodeSit: e.posNumCodeSit, + posNumCodeSitAbb: e.posNumCodeSitAbb, + commandNo: e.commandNo, + commandYear: e.commandYear ? Number(e.commandYear) + 543 : "", + commandDateSign: date2Thai(e.commandDateSign), + commandCode: store.convertCommandCodeName(e.commandCode), + remark: e.remark, + commandId: e.commandCode, // ใส่ค่าเริ่มต้นไว้ + })); + + worksheet.addRows(newData); + + // 4. ตกแต่งสี, Dropdown และ สูตร VLOOKUP + newData.forEach((_, index) => { + const rowIndex = index + 2; + + // --- ระบายสีเหลืองเข้ม (ถอด # ออกจาก ARGB) --- + ["B", "O", "U", "V", "X", "Z"].forEach((col) => { + worksheet.getCell(`${col}${rowIndex}`).fill = { + type: "pattern", + pattern: "solid", + fgColor: { argb: "FFBF00" }, // ลบ # ออก + }; + }); + + // --- ระบายสีเหลืองอ่อน --- + ["F", "G", "H", "N", "P", "Q", "R", "S", "T", "W", "Y"].forEach((col) => { + worksheet.getCell(`${col}${rowIndex}`).fill = { + type: "pattern", + pattern: "solid", + fgColor: { argb: "FFFFD7" }, // ลบ # ออก + }; + }); + + // --- ทำ Dropdown คอลัมน์ AA --- + // อ้างอิงรายการจาก MasterData Sheet จะทำให้ Excel ทำงานได้เสถียรกว่า (กรณีรายการเยอะ) + worksheet.getCell(`AA${rowIndex}`).dataValidation = { + type: "list", + allowBlank: true, + formulae: [`MasterData!$A$1:$A$${masterData.length}`], + }; + + // --- ผูกสูตรให้ commandId (AC) เปลี่ยนตามการเลือกใน AA --- + // AA คือประเภทคำสั่ง, AB คือหมายเหตุ, AC คือ commandId + worksheet.getCell(`AC${rowIndex}`).value = { + formula: `=IFERROR(VLOOKUP(AA${rowIndex}, MasterData!$A$1:$B$${masterData.length}, 2, FALSE), "")`, + }; + }); + + // 5. สไตล์ Header + worksheet.getRow(1).font = { bold: true }; + worksheet.getRow(1).alignment = { vertical: "middle", horizontal: "center" }; + + // 6. เขียนไฟล์ + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "รายการประวัติตำแหน่งเงินเดือน.xlsx"; + a.click(); + window.URL.revokeObjectURL(url); +} From 803ba41a79686c2a3d08b3f7f9f5ba0a372c8290 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 23 Apr 2026 10:00:20 +0700 Subject: [PATCH 04/19] refactor: add column commandCode --- .../10_registry/utils/exportPosition.ts | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/modules/10_registry/utils/exportPosition.ts b/src/modules/10_registry/utils/exportPosition.ts index ccd1dbf..4c77019 100644 --- a/src/modules/10_registry/utils/exportPosition.ts +++ b/src/modules/10_registry/utils/exportPosition.ts @@ -53,9 +53,10 @@ export async function exportToExcelPosition(data: DataPosition[]) { { header: "เลขที่คำสั่ง", key: "commandNo", width: 15 }, { header: "ปีเลขที่คำสั่ง", key: "commandYear", width: 12 }, { header: "วันที่ลงนาม", key: "commandDateSign", width: 18 }, - { header: "ประเภทคำสั่ง", key: "commandCode", width: 25 }, // AA + { header: "ประเภทคำสั่ง", key: "commandCodeName", width: 25 }, // AA { header: "หมายเหตุ", key: "remark", width: 20 }, { header: "commandId", key: "commandId", width: 20 }, // AC (ลำดับที่ 29) + { header: "commandCode", key: "commandCode", width: 20 }, // AD (ลำดับที่ 30) ]; // 3. Map ข้อมูล @@ -86,9 +87,10 @@ export async function exportToExcelPosition(data: DataPosition[]) { commandNo: e.commandNo, commandYear: e.commandYear ? Number(e.commandYear) + 543 : "", commandDateSign: date2Thai(e.commandDateSign), - commandCode: store.convertCommandCodeName(e.commandCode), + commandCodeName: store.convertCommandCodeName(e.commandCode), remark: e.remark, - commandId: e.commandCode, // ใส่ค่าเริ่มต้นไว้ + commandId: e.commandId, + commandCode: e.commandCode, // ใส่ค่าเริ่มต้นไว้ })); worksheet.addRows(newData); @@ -97,24 +99,6 @@ export async function exportToExcelPosition(data: DataPosition[]) { newData.forEach((_, index) => { const rowIndex = index + 2; - // --- ระบายสีเหลืองเข้ม (ถอด # ออกจาก ARGB) --- - ["B", "O", "U", "V", "X", "Z"].forEach((col) => { - worksheet.getCell(`${col}${rowIndex}`).fill = { - type: "pattern", - pattern: "solid", - fgColor: { argb: "FFBF00" }, // ลบ # ออก - }; - }); - - // --- ระบายสีเหลืองอ่อน --- - ["F", "G", "H", "N", "P", "Q", "R", "S", "T", "W", "Y"].forEach((col) => { - worksheet.getCell(`${col}${rowIndex}`).fill = { - type: "pattern", - pattern: "solid", - fgColor: { argb: "FFFFD7" }, // ลบ # ออก - }; - }); - // --- ทำ Dropdown คอลัมน์ AA --- // อ้างอิงรายการจาก MasterData Sheet จะทำให้ Excel ทำงานได้เสถียรกว่า (กรณีรายการเยอะ) worksheet.getCell(`AA${rowIndex}`).dataValidation = { @@ -123,9 +107,9 @@ export async function exportToExcelPosition(data: DataPosition[]) { formulae: [`MasterData!$A$1:$A$${masterData.length}`], }; - // --- ผูกสูตรให้ commandId (AC) เปลี่ยนตามการเลือกใน AA --- - // AA คือประเภทคำสั่ง, AB คือหมายเหตุ, AC คือ commandId - worksheet.getCell(`AC${rowIndex}`).value = { + // --- ผูกสูตรให้ commandCode (AD) เปลี่ยนตามการเลือกใน AA --- + // AA คือประเภทคำสั่ง, AD คือ commandCode + worksheet.getCell(`AD${rowIndex}`).value = { formula: `=IFERROR(VLOOKUP(AA${rowIndex}, MasterData!$A$1:$B$${masterData.length}, 2, FALSE), "")`, }; }); From 87f091f15b4c4c796575dfab4918b32f2b21b88c Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 23 Apr 2026 10:11:14 +0700 Subject: [PATCH 05/19] fix: formatDate --- src/modules/10_registry/utils/exportPosition.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/modules/10_registry/utils/exportPosition.ts b/src/modules/10_registry/utils/exportPosition.ts index 4c77019..7745306 100644 --- a/src/modules/10_registry/utils/exportPosition.ts +++ b/src/modules/10_registry/utils/exportPosition.ts @@ -62,7 +62,7 @@ export async function exportToExcelPosition(data: DataPosition[]) { // 3. Map ข้อมูล const newData = data.map((e, index) => ({ no: index + 1, - commandDateAffect: date2Thai(e.commandDateAffect), + commandDateAffect: e.commandDateAffect, positionName: e.positionName, positionType: e.positionType, positionLevel: e.positionLevel, @@ -86,7 +86,7 @@ export async function exportToExcelPosition(data: DataPosition[]) { posNumCodeSitAbb: e.posNumCodeSitAbb, commandNo: e.commandNo, commandYear: e.commandYear ? Number(e.commandYear) + 543 : "", - commandDateSign: date2Thai(e.commandDateSign), + commandDateSign: e.commandDateSign, commandCodeName: store.convertCommandCodeName(e.commandCode), remark: e.remark, commandId: e.commandId, @@ -99,6 +99,15 @@ export async function exportToExcelPosition(data: DataPosition[]) { newData.forEach((_, index) => { const rowIndex = index + 2; + const dateAffectCell = worksheet.getCell(`B${rowIndex}`); + const dateSignCell = worksheet.getCell(`Z${rowIndex}`); + + [dateAffectCell, dateSignCell].forEach((cell) => { + // ใช้ Custom Format: วัน/เดือน/ปี(4หลัก) + // โดยบังคับให้เลขวันและเดือนมี 2 หลักเสมอ (dd/mm) + cell.numFmt = "dd/mm/yyyy"; + }); + // --- ทำ Dropdown คอลัมน์ AA --- // อ้างอิงรายการจาก MasterData Sheet จะทำให้ Excel ทำงานได้เสถียรกว่า (กรณีรายการเยอะ) worksheet.getCell(`AA${rowIndex}`).dataValidation = { From 3da965dc0e35c8766f328d12590bd3b7e9af3002 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 23 Apr 2026 15:22:33 +0700 Subject: [PATCH 06/19] fix: formatDateToDDMMYYYY --- .../10_registry/utils/exportPosition.ts | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/modules/10_registry/utils/exportPosition.ts b/src/modules/10_registry/utils/exportPosition.ts index 7745306..1761408 100644 --- a/src/modules/10_registry/utils/exportPosition.ts +++ b/src/modules/10_registry/utils/exportPosition.ts @@ -1,12 +1,24 @@ import ExcelJS from "exceljs"; -import { useCounterMixin } from "@/stores/mixin"; import { useGovernmentPosDataStore } from "@/modules/10_registry/store/Position"; import type { DataPosition } from "@/modules/10_registry/interface/review/Edit"; -const { date2Thai } = useCounterMixin(); const store = useGovernmentPosDataStore(); +// ฟังก์ชันแปลงวันที่จาก ISO format เป็นรูปแบบ dd/mm/yyyy (เช่น 18/05/2564) +function formatDateToDDMMYYYY(dateString: string | null | Date): string { + if (!dateString) return ""; + + const date = new Date(dateString); + if (isNaN(date.getTime())) return ""; + + const day = String(date.getDate()).padStart(2, "0"); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const year = date.getFullYear() + 543; // แปลงเป็นปีพุทธศักราช + + return `${day}/${month}/${year}`; +} + export async function exportToExcelPosition(data: DataPosition[]) { const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet("รายการประวัติตำแหน่งเงินเดือน"); @@ -62,7 +74,9 @@ export async function exportToExcelPosition(data: DataPosition[]) { // 3. Map ข้อมูล const newData = data.map((e, index) => ({ no: index + 1, - commandDateAffect: e.commandDateAffect, + commandDateAffect: e.commandDateAffect + ? formatDateToDDMMYYYY(e.commandDateAffect) + : "", positionName: e.positionName, positionType: e.positionType, positionLevel: e.positionLevel, @@ -71,9 +85,9 @@ export async function exportToExcelPosition(data: DataPosition[]) { positionPathSide: e.positionPathSide || "", positionExecutive: e.positionExecutive, positionExecutiveField: e.positionExecutiveField || "", - amount: e.amount, + amount: e.amount || 0, mouthSalaryAmount: e.mouthSalaryAmount || 0, - positionSalaryAmount: e.positionSalaryAmount, + positionSalaryAmount: e.positionSalaryAmount || 0, amountSpecial: e.amountSpecial || 0, organization: e.orgRoot, orgChild1: e.orgChild1, @@ -86,11 +100,13 @@ export async function exportToExcelPosition(data: DataPosition[]) { posNumCodeSitAbb: e.posNumCodeSitAbb, commandNo: e.commandNo, commandYear: e.commandYear ? Number(e.commandYear) + 543 : "", - commandDateSign: e.commandDateSign, + commandDateSign: e.commandDateSign + ? formatDateToDDMMYYYY(e.commandDateSign) + : "", commandCodeName: store.convertCommandCodeName(e.commandCode), remark: e.remark, - commandId: e.commandId, - commandCode: e.commandCode, // ใส่ค่าเริ่มต้นไว้ + commandId: e.commandId || "", + commandCode: e.commandCode || "", // ใส่ค่าเริ่มต้นไว้ })); worksheet.addRows(newData); @@ -99,12 +115,12 @@ export async function exportToExcelPosition(data: DataPosition[]) { newData.forEach((_, index) => { const rowIndex = index + 2; + // --- ตั้งค่า Format สำหรับเซลล์วันที่ --- + // เซลล์ B (commandDateAffect) และ Z (commandDateSign) const dateAffectCell = worksheet.getCell(`B${rowIndex}`); const dateSignCell = worksheet.getCell(`Z${rowIndex}`); [dateAffectCell, dateSignCell].forEach((cell) => { - // ใช้ Custom Format: วัน/เดือน/ปี(4หลัก) - // โดยบังคับให้เลขวันและเดือนมี 2 หลักเสมอ (dd/mm) cell.numFmt = "dd/mm/yyyy"; }); From ab1ea1f614ee2a7ce9447747341912a2820cef30 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 23 Apr 2026 18:09:48 +0700 Subject: [PATCH 07/19] fix: fetchData position review --- .../10_registry/components/PositionReview/Table.vue | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/modules/10_registry/components/PositionReview/Table.vue b/src/modules/10_registry/components/PositionReview/Table.vue index a79e32f..4523be3 100644 --- a/src/modules/10_registry/components/PositionReview/Table.vue +++ b/src/modules/10_registry/components/PositionReview/Table.vue @@ -886,12 +886,20 @@ async function fetchDataCommandCode() { // } onMounted(async () => { - // เพิ่ม delay เล็กน้อยเพื่อรอให้ dataStore fetch ข้อมูล position เสร็จก่อน - await new Promise((resolve) => setTimeout(resolve, 800)); if (dataStore.officerType && dataStore.profileId) { await Promise.all([fetchData(), fetchDataCommandCode()]); } }); + +watch( + () => [dataStore.officerType, dataStore.profileId], + async ([officerType, profileId]) => { + if (officerType && profileId) { + await Promise.all([fetchData(), fetchDataCommandCode()]); + } + }, + { immediate: true }, +);