From f07cf2548995aa2456e6da01047069c12f1f4b33 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Fri, 8 May 2026 17:39:01 +0700 Subject: [PATCH] refactor(registry): downloadBlobFile --- .../01_Information/02_ChangeName.vue | 43 ++------------ .../10_registry/01_Information/06_Ability.vue | 17 ++---- .../02_Government/02_Discipline.vue | 18 ++---- .../10_registry/02_Government/04_Duty.vue | 18 ++---- .../02_Government/06_Assistance.vue | 17 ++---- .../10_registry/03_Salary/02_Nopaid.vue | 17 ++---- .../04_Achievement/01_Certificate.vue | 18 ++---- .../04_Achievement/03_Insignia.vue | 17 ++---- .../10_registry/04_Achievement/04_Honor.vue | 17 ++---- src/modules/10_registry/utils/downloadFile.ts | 59 +++++++++++++++++++ 10 files changed, 103 insertions(+), 138 deletions(-) create mode 100644 src/modules/10_registry/utils/downloadFile.ts diff --git a/src/modules/10_registry/01_Information/02_ChangeName.vue b/src/modules/10_registry/01_Information/02_ChangeName.vue index dc2b645..165f95a 100644 --- a/src/modules/10_registry/01_Information/02_ChangeName.vue +++ b/src/modules/10_registry/01_Information/02_ChangeName.vue @@ -3,6 +3,7 @@ import { ref, onMounted } from "vue"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import http from "@/plugins/http"; import config from "@/app.config"; @@ -137,46 +138,10 @@ async function onDownloadFile(id: string, profileId: string) { ) .then(async (res) => { const downloadUrl = res.data.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - - const contentType: string | null = response.headers.get("Content-Type"); - - // 2. สร้างตัวแปลง MIME Type เป็นนามสกุลไฟล์ - const extensionMap: Record = { - "application/pdf": "pdf", - "image/jpeg": "jpg", - "image/png": "png", - "image/gif": "gif", - "application/zip": "zip", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document": - "docx", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": - "xlsx", - }; - - let extension = contentType ? extensionMap[contentType] : undefined; - - if (!extension) { - const urlWithoutQuery = downloadUrl.split("?")[0]; - extension = urlWithoutQuery.includes(".") - ? urlWithoutQuery.split(".").pop() - : "pdf"; - } - - const blobForDownload = new Blob([blob], { - type: "application/octet-stream", + await downloadBlobFile({ + downloadUrl: downloadUrl, + fileName: `ประวัติการเปลี่ยนชื่อ-นามสกุล`, }); - const url = URL.createObjectURL(blobForDownload); - const link = document.createElement("a"); - link.href = url; - link.download = `ประวัติการเปลี่ยนชื่อ-นามสกุล.${extension}`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); }) .catch((err) => { messageError($q, err); diff --git a/src/modules/10_registry/01_Information/06_Ability.vue b/src/modules/10_registry/01_Information/06_Ability.vue index 5254633..ffcb8e0 100644 --- a/src/modules/10_registry/01_Information/06_Ability.vue +++ b/src/modules/10_registry/01_Information/06_Ability.vue @@ -6,6 +6,7 @@ import http from "@/plugins/http"; import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; /** import type */ import type { AbilityRows } from "@/modules/10_registry/interface/index/Main"; @@ -263,18 +264,10 @@ async function onDownloadFile(id: string, profileId: string) { ) .then(async (res) => { const downloadUrl = res.data.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารความสามารถพิเศษ_`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: downloadUrl, + fileName: `เอกสารความสามารถพิเศษ`, + }); }) .catch((err) => { messageError($q, err); diff --git a/src/modules/10_registry/02_Government/02_Discipline.vue b/src/modules/10_registry/02_Government/02_Discipline.vue index 21dc522..2d6b4d0 100644 --- a/src/modules/10_registry/02_Government/02_Discipline.vue +++ b/src/modules/10_registry/02_Government/02_Discipline.vue @@ -7,6 +7,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; import { useRegistryDataStore } from "@/modules/10_registry/store/Main"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { DisciplineDetail } from "@/modules/10_registry/interface/index/Main"; @@ -195,19 +196,10 @@ async function onDownloadFile(id: string, profileId: string) { showLoader(); try { const res = await getPathUploadFlie(fileGroup.value, profileId, id); - const downloadUrl = res.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารวินัย`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: res.downloadUrl, + fileName: `เอกสารวินัย`, + }); } catch (e) { messageError($q, e); } finally { diff --git a/src/modules/10_registry/02_Government/04_Duty.vue b/src/modules/10_registry/02_Government/04_Duty.vue index 7b2c1e7..a64dc34 100644 --- a/src/modules/10_registry/02_Government/04_Duty.vue +++ b/src/modules/10_registry/02_Government/04_Duty.vue @@ -7,6 +7,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; import { useRegistryDataStore } from "@/modules/10_registry/store/Main"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { DutyFormType } from "@/modules/10_registry/interface/index/Main"; @@ -298,19 +299,10 @@ async function onDownloadFile(id: string, profileId: string) { showLoader(); try { const res = await getPathUploadFlie(fileGroup.value, profileId, id); - const downloadUrl = res.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารปฏิบัติราชการพิเศษ`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: res.downloadUrl, + fileName: `เอกสารปฏิบัติราชการพิเศษ`, + }); } catch (e) { messageError($q, e); } finally { diff --git a/src/modules/10_registry/02_Government/06_Assistance.vue b/src/modules/10_registry/02_Government/06_Assistance.vue index 02ad925..69d5184 100644 --- a/src/modules/10_registry/02_Government/06_Assistance.vue +++ b/src/modules/10_registry/02_Government/06_Assistance.vue @@ -6,6 +6,7 @@ import http from "@/plugins/http"; import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { DutyFormType } from "@/modules/10_registry/interface/index/Main"; @@ -307,18 +308,10 @@ async function onDownloadFile(id: string, profileId: string) { ) .then(async (res) => { const downloadUrl = res.data.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารช่วยราชการ`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: downloadUrl, + fileName: `เอกสารช่วยราชการ`, + }); }) .catch((err) => { messageError($q, err); diff --git a/src/modules/10_registry/03_Salary/02_Nopaid.vue b/src/modules/10_registry/03_Salary/02_Nopaid.vue index 8d81c30..271d3d9 100644 --- a/src/modules/10_registry/03_Salary/02_Nopaid.vue +++ b/src/modules/10_registry/03_Salary/02_Nopaid.vue @@ -7,6 +7,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; import { useRegistryDataStore } from "@/modules/10_registry/store/Main"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { NopaidFormType } from "@/modules/10_registry/interface/index/Main"; @@ -280,18 +281,10 @@ async function onDownloadFile(id: string, profileId: string) { try { const res = await getPathUploadFlie(fileGroup.value, profileId, id); const downloadUrl = res.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `บันทึกวันที่ไม่ได้รับ${salaryText.value}ฯ`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: downloadUrl, + fileName: `บันทึกวันที่ไม่ได้รับ${salaryText.value}ฯ`, + }); } catch (e) { messageError($q, e); } finally { diff --git a/src/modules/10_registry/04_Achievement/01_Certificate.vue b/src/modules/10_registry/04_Achievement/01_Certificate.vue index 21a6eeb..5e0b4c7 100644 --- a/src/modules/10_registry/04_Achievement/01_Certificate.vue +++ b/src/modules/10_registry/04_Achievement/01_Certificate.vue @@ -7,6 +7,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; import { useRegistryDataStore } from "@/modules/10_registry/store/Main"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { CertificateDetail } from "@/modules/10_registry/interface/index/Main"; @@ -278,19 +279,10 @@ async function onDownloadFile(id: string, profileId: string) { showLoader(); try { const data = await getPathUploadFlie(fileGroup.value, profileId, id); - const downloadUrl = data.downloadUrl; - const response = await fetch(downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารใบอนุญาตประกอบวิชาชีพ`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: data.downloadUrl, + fileName: `เอกสารใบอนุญาตประกอบวิชาชีพ`, + }); } catch (error) { messageError($q, error); } finally { diff --git a/src/modules/10_registry/04_Achievement/03_Insignia.vue b/src/modules/10_registry/04_Achievement/03_Insignia.vue index 8db5851..2acb679 100644 --- a/src/modules/10_registry/04_Achievement/03_Insignia.vue +++ b/src/modules/10_registry/04_Achievement/03_Insignia.vue @@ -7,6 +7,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; import { useRegistryDataStore } from "@/modules/10_registry/store/Main"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { InsigniaFormType } from "@/modules/10_registry/interface/index/Main"; @@ -494,18 +495,10 @@ async function onDownloadFile(id: string, profileId: string) { showLoader(); try { const data = await getPathUploadFlie(fileGroup.value, profileId, id); - const response = await fetch(data.downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารเครื่องราชอิสริยาภรณ์`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: data.downloadUrl, + fileName: `เอกสารเครื่องราชอิสริยาภรณ์`, + }); } catch (error) { messageError($q, error); } finally { diff --git a/src/modules/10_registry/04_Achievement/04_Honor.vue b/src/modules/10_registry/04_Achievement/04_Honor.vue index dee78b9..a142ad7 100644 --- a/src/modules/10_registry/04_Achievement/04_Honor.vue +++ b/src/modules/10_registry/04_Achievement/04_Honor.vue @@ -7,6 +7,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useDataStore } from "@/stores/data"; import { useRegistryDataStore } from "@/modules/10_registry/store/Main"; +import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile"; import type { HonorFormData } from "@/modules/10_registry/interface/index/Main"; @@ -278,18 +279,10 @@ async function onDownloadFile(id: string, profileId: string) { showLoader(); try { const data = await getPathUploadFlie(fileGroup.value, profileId, id); - const response = await fetch(data.downloadUrl); - const blob = await response.blob(); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `เอกสารประกาศเกียรติคุณ`; - document.body.appendChild(link); - link.click(); - setTimeout(() => { - document.body.removeChild(link); - URL.revokeObjectURL(url); - }, 100); + await downloadBlobFile({ + downloadUrl: data.downloadUrl, + fileName: `เอกสารประกาศเกียรติคุณ`, + }); } catch (error) { messageError($q, error); } finally { diff --git a/src/modules/10_registry/utils/downloadFile.ts b/src/modules/10_registry/utils/downloadFile.ts new file mode 100644 index 0000000..341b7f9 --- /dev/null +++ b/src/modules/10_registry/utils/downloadFile.ts @@ -0,0 +1,59 @@ +export interface DownloadFileOptions { + downloadUrl: string; + fileName: string; +} + +const isMobile = + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + navigator.userAgent, + ); + +export async function downloadBlobFile({ + downloadUrl, + fileName, +}: DownloadFileOptions): Promise { + // Use window.open for desktop, blob download for mobile + if (!isMobile) { + window.open(downloadUrl, "_blank"); + return; + } + + const response = await fetch(downloadUrl); + const blob = await response.blob(); + + const contentType: string | null = response.headers.get("Content-Type"); + + const extensionMap: Record = { + "application/pdf": "pdf", + "image/jpeg": "jpg", + "image/png": "png", + "image/gif": "gif", + "application/zip": "zip", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + "docx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx", + }; + + let extension = contentType ? extensionMap[contentType] : undefined; + + if (!extension) { + const urlWithoutQuery = downloadUrl.split("?")[0]; + extension = urlWithoutQuery.includes(".") + ? urlWithoutQuery.split(".").pop() + : "pdf"; + } + + const blobForDownload = new Blob([blob], { + type: "application/octet-stream", + }); + const url = URL.createObjectURL(blobForDownload); + const link = document.createElement("a"); + link.href = url; + link.download = `${fileName}.${extension}`; + document.body.appendChild(link); + link.click(); + setTimeout(() => { + document.body.removeChild(link); + URL.revokeObjectURL(url); + }, 100); +}