Compare commits
18 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89801e787f | ||
|
|
a0f0443a55 | ||
|
|
d022ae189c | ||
|
|
650de029f3 | ||
|
|
423b9f5fe3 | ||
|
|
54c7855b61 | ||
|
|
2a27dadff7 | ||
|
|
0092133ba6 | ||
|
|
b845cdaeab | ||
|
|
9bee07eb7c | ||
|
|
0a68951571 | ||
|
|
ebd514a33a | ||
|
|
58c6150ef8 | ||
|
|
f07cf25489 | ||
|
|
814c17d4c9 | ||
|
|
9eaa28711d | ||
|
|
d00d4ac692 | ||
|
|
780a815a24 |
20 changed files with 319 additions and 223 deletions
|
|
@ -6,7 +6,7 @@ import http from "@/plugins/http";
|
|||
import config from "@/app.config";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useLeaveStore } from "@/modules/05_leave/store";
|
||||
import { useDataStore } from "@/stores/data";
|
||||
import genReport from "@/plugins/genreport";
|
||||
|
||||
/** import type*/
|
||||
import type {
|
||||
|
|
@ -16,8 +16,6 @@ import type {
|
|||
FromCancelDetail,
|
||||
} from "@/modules/05_leave/interface/response/leave";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import Workflow from "@/components/Workflow/Main.vue";
|
||||
import FormLeave from "@/modules/05_leave/components/formDetail/01_SickForm.vue";
|
||||
import FormChildbirth from "@/modules/05_leave/components/formDetail/04_HelpWifeBirthForm.vue";
|
||||
import FormHoliday from "@/modules/05_leave/components/formDetail/05_VacationForm.vue";
|
||||
|
|
@ -33,7 +31,6 @@ import FormCancel from "@/modules/05_leave/components/formDetail/formCancel.vue"
|
|||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useLeaveStore();
|
||||
const mainStore = useDataStore();
|
||||
const { convertStatud } = dataStore;
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
|
|
@ -411,6 +408,28 @@ async function onSubmit() {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังก์ชันดาวน์โหลดไฟล์
|
||||
* @param id รหัสการลา
|
||||
* @param fileName ชื่อไฟล์
|
||||
* @param type ประเภทไฟล์
|
||||
*/
|
||||
async function onClickDownloadFile(id: string, fileName: string, type: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.leaveReport(id))
|
||||
.then(async (res) => {
|
||||
const data = res.data.result;
|
||||
await genReport(data, fileName, type);
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาแล้วเปิด modal */
|
||||
watch(
|
||||
() => props.modal,
|
||||
|
|
@ -434,10 +453,62 @@ watch(
|
|||
v-if="props.leaveStatus != 'DELETE'"
|
||||
style="width: 900px; max-width: 80vw"
|
||||
>
|
||||
<DialogHeader
|
||||
:tittle="`${titleMain} ${titleName}`"
|
||||
:close="props.onClickClose"
|
||||
<q-toolbar>
|
||||
<q-toolbar-title class="text-subtitle2 text-bold">
|
||||
{{ ` ${titleMain} ${titleName}` }}
|
||||
<q-btn class="q-mr-sm" icon="mdi-download" round color="primary" flat>
|
||||
<q-tooltip>ดาวน์โหลดไฟล์</q-tooltip>
|
||||
<q-menu>
|
||||
<q-list style="min-width: 100px">
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="
|
||||
onClickDownloadFile(
|
||||
formData.id,
|
||||
formData.leaveSubTypeName
|
||||
? formData.leaveSubTypeName
|
||||
: formData.leaveTypeName,
|
||||
'docx',
|
||||
)
|
||||
"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon color="blue" name="mdi-file-word" />
|
||||
</q-item-section>
|
||||
<q-item-section>ไฟล์ .DOCX</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="
|
||||
onClickDownloadFile(
|
||||
formData.id,
|
||||
formData.leaveSubTypeName
|
||||
? formData.leaveSubTypeName
|
||||
: formData.leaveTypeName,
|
||||
'pdf',
|
||||
)
|
||||
"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon color="red" name="mdi-file-pdf" />
|
||||
</q-item-section>
|
||||
<q-item-section>ไฟล์ .pdf</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</q-toolbar-title>
|
||||
<q-btn
|
||||
icon="close"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
@click="props.onClickClose?.()"
|
||||
style="color: #ff8080; background-color: #ffdede"
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<q-separator />
|
||||
<q-card-section v-if="isLoading">
|
||||
|
|
@ -580,10 +651,62 @@ watch(
|
|||
</q-card>
|
||||
|
||||
<q-card v-if="props.leaveStatus === 'DELETE'" style="min-width: 40vw">
|
||||
<DialogHeader
|
||||
:tittle="`${titleMainCancle} ${titleName}`"
|
||||
:close="props.onClickClose"
|
||||
<q-toolbar>
|
||||
<q-toolbar-title class="text-subtitle2 text-bold">
|
||||
{{ ` ${titleMainCancle} ${titleName}` }}
|
||||
<q-btn class="q-mr-sm" icon="mdi-download" round color="primary" flat>
|
||||
<q-tooltip>ดาวน์โหลดไฟล์</q-tooltip>
|
||||
<q-menu>
|
||||
<q-list style="min-width: 100px">
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="
|
||||
onClickDownloadFile(
|
||||
formData.id,
|
||||
formData.leaveSubTypeName
|
||||
? formData.leaveSubTypeName
|
||||
: formData.leaveTypeName,
|
||||
'docx',
|
||||
)
|
||||
"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon color="blue" name="mdi-file-word" />
|
||||
</q-item-section>
|
||||
<q-item-section>ไฟล์ .DOCX</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="
|
||||
onClickDownloadFile(
|
||||
formData.id,
|
||||
formData.leaveSubTypeName
|
||||
? formData.leaveSubTypeName
|
||||
: formData.leaveTypeName,
|
||||
'pdf',
|
||||
)
|
||||
"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon color="red" name="mdi-file-pdf" />
|
||||
</q-item-section>
|
||||
<q-item-section>ไฟล์ .pdf</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</q-toolbar-title>
|
||||
<q-btn
|
||||
icon="close"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
@click="props.onClickClose?.()"
|
||||
style="color: #ff8080; background-color: #ffdede"
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<q-separator />
|
||||
<q-card-section v-if="isLoading">
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ interface LeaveItem {
|
|||
all: number;
|
||||
use: number;
|
||||
remain: number;
|
||||
leaveCountApproveCount: number;
|
||||
}
|
||||
|
||||
interface MainList {
|
||||
|
|
|
|||
|
|
@ -141,12 +141,14 @@ async function fetchStatsTable() {
|
|||
value:
|
||||
el.leaveLimit > 0
|
||||
? Math.round(
|
||||
(Number(el.leaveCountApprove) / Number(el.leaveLimit)) * 100
|
||||
(Number(el.leaveCountApprove) / Number(el.leaveLimit)) *
|
||||
100,
|
||||
)
|
||||
: 0,
|
||||
all: Number(el.leaveLimit),
|
||||
use: el.leaveCountApprove,
|
||||
remain: Number(el.leaveLimit) - Number(el.leaveCountApprove),
|
||||
leaveCountApproveCount: el.leaveCountApproveCount,
|
||||
}));
|
||||
});
|
||||
stat.forEach((item) => itemPie.value.push(...item));
|
||||
|
|
@ -254,7 +256,7 @@ onMounted(async () => {
|
|||
</q-knob>
|
||||
</div>
|
||||
<div class="col-12 text-center text-weight-medium">
|
||||
ลาพักผ่อน
|
||||
{{ item.text }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gt-xs"><q-separator vertical /></div>
|
||||
|
|
@ -262,17 +264,19 @@ onMounted(async () => {
|
|||
<div class="col-12 row text-dark text-body2 items-center">
|
||||
<div class="col-12 row q-pa-xs q-px-md row">
|
||||
<span class="text-grey-7 col-6">ได้รับ</span>
|
||||
<span class="text-weight-bold">{{ item.all }}</span>
|
||||
<span class="text-weight-bold">{{ item.all }} วัน</span>
|
||||
</div>
|
||||
<div class="col-12"><q-separator /></div>
|
||||
<div class="col-12 row q-pa-xs q-px-md">
|
||||
<span class="text-grey-7 col-6">ใช้ไป</span>
|
||||
<span class="text-weight-bold">{{ item.use }}</span>
|
||||
<span class="text-weight-bold">{{ item.use }} วัน </span>
|
||||
</div>
|
||||
<div class="col-12"><q-separator /></div>
|
||||
<div class="col-12 row q-pa-xs q-px-md">
|
||||
<span class="text-grey-7 col-6">คงเหลือ</span>
|
||||
<span class="text-weight-bold">{{ item.remain }}</span>
|
||||
<span class="text-weight-bold"
|
||||
>{{ item.remain }} วัน</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -294,11 +298,11 @@ onMounted(async () => {
|
|||
flat
|
||||
class="shadow-0 col-12 fit row items-center q-px-lg"
|
||||
>
|
||||
<div class="text-subtitle2 col-4">ลาป่วย</div>
|
||||
<div class="text-subtitle2 col-4">{{ item.text }}</div>
|
||||
<div class="text-subtitle2 col-8">
|
||||
<span class="text-grey-7 q-pr-md">ใช้ไป</span>
|
||||
<span class="text-weight-bold">{{ item.use }}</span>
|
||||
<!-- <span class="text-grey-7 q-pl-md">ลา</span> -->
|
||||
<span class="text-weight-bold">{{ item.use }} วัน </span>
|
||||
({{ item.leaveCountApproveCount }} ครั้ง)
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
@ -317,11 +321,11 @@ onMounted(async () => {
|
|||
flat
|
||||
class="shadow-0 col-12 fit row items-center q-px-lg"
|
||||
>
|
||||
<div class="text-subtitle2 col-4">ลากิจส่วนตัว</div>
|
||||
<div class="text-subtitle2 col-4">{{ item.text }}</div>
|
||||
<div class="text-subtitle2 col-8">
|
||||
<span class="text-grey-7 q-pr-md">ใช้ไป</span>
|
||||
<span class="text-weight-bold">{{ item.use }}</span>
|
||||
<!-- <span class="text-grey-7 q-pl-md">ลา</span> -->
|
||||
<span class="text-weight-bold">{{ item.use }} วัน </span>
|
||||
({{ item.leaveCountApproveCount }} ครั้ง)
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import http from "@/plugins/http";
|
|||
import config from "@/app.config";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useKpiDataStore } from "@/modules/08_KPI/store";
|
||||
import avatar from "@/assets/avatar_user.jpg";
|
||||
|
||||
import type { FormProfile } from "@/modules/08_KPI/interface/request/index";
|
||||
import type {
|
||||
|
|
@ -107,11 +108,13 @@ async function getAvatar(id: string) {
|
|||
.then(async (res) => {
|
||||
const data = await res.data.result;
|
||||
if (data.avatarName) {
|
||||
await fetchProfile(id, data.avatarName);
|
||||
fetchProfile(id, data.avatarName);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
imgProfile.value = avatar;
|
||||
store.dataEvaluation.avartar = avatar;
|
||||
})
|
||||
.finally(() => {
|
||||
isLoadAvatar.value = false;
|
||||
|
|
@ -119,12 +122,16 @@ async function getAvatar(id: string) {
|
|||
}
|
||||
|
||||
/** ดึงข้อมูล เพื่อเก็บรูปโปรไฟล์ */
|
||||
async function fetchProfile(id: string, avatarName: string) {
|
||||
await http
|
||||
function fetchProfile(id: string, avatarName: string) {
|
||||
http
|
||||
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, avatarName))
|
||||
.then(async (res) => {
|
||||
.then((res) => {
|
||||
store.dataEvaluation.avartar = res.data.downloadUrl;
|
||||
imgProfile.value = res.data.downloadUrl;
|
||||
})
|
||||
.catch(() => {
|
||||
imgProfile.value = avatar;
|
||||
store.dataEvaluation.avartar = avatar;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +215,7 @@ async function getOrgOp() {
|
|||
name: `${i.prefix}${i.firstName} ${i.lastName}`,
|
||||
}))
|
||||
.find(
|
||||
(i: EvaOptionType) => i.id == store.dataEvaluation.commanderHighId
|
||||
(i: EvaOptionType) => i.id == store.dataEvaluation.commanderHighId,
|
||||
);
|
||||
isLoadCommander.value = false;
|
||||
})
|
||||
|
|
@ -225,21 +232,21 @@ function filterOption(val: string, update: Function, refData: string) {
|
|||
case "evaluatorIdOp":
|
||||
update(() => {
|
||||
evaluatorIdOp.value = evaluatorIdMainOp.value.filter(
|
||||
(v: DataOptions) => v.name.indexOf(val) > -1
|
||||
(v: DataOptions) => v.name.indexOf(val) > -1,
|
||||
);
|
||||
});
|
||||
break;
|
||||
case "commanderIdOp":
|
||||
update(() => {
|
||||
commanderIdOp.value = commanderIdMainOp.value.filter(
|
||||
(v: DataOptions) => v.name.indexOf(val) > -1
|
||||
(v: DataOptions) => v.name.indexOf(val) > -1,
|
||||
);
|
||||
});
|
||||
break;
|
||||
case "commanderHighOp":
|
||||
update(() => {
|
||||
commanderHighOp.value = commanderHighMainOp.value.filter(
|
||||
(v: DataOptions) => v.name.indexOf(val) > -1
|
||||
(v: DataOptions) => v.name.indexOf(val) > -1,
|
||||
);
|
||||
});
|
||||
break;
|
||||
|
|
@ -278,7 +285,7 @@ function sendToEvaluatore() {
|
|||
}
|
||||
},
|
||||
"ยืนยันการส่งข้อตกลงให้ผู้ประเมินอนุมัติ",
|
||||
"ต้องการยืนยันส่งข้อตกลงนี้ให้ผู้ประเมินอนุมัติใช่หรือไม่?"
|
||||
"ต้องการยืนยันส่งข้อตกลงนี้ให้ผู้ประเมินอนุมัติใช่หรือไม่?",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +315,7 @@ function sendToEvaluateEvaluatore() {
|
|||
}
|
||||
},
|
||||
"ยืนยันการส่งให้ผู้ประเมินรายงานผลสำเร็จของงาน",
|
||||
"ต้องการยืนยันส่งให้ผู้ประเมินรายงานผลสำเร็จของงานใช่หรือไม่?"
|
||||
"ต้องการยืนยันส่งให้ผู้ประเมินรายงานผลสำเร็จของงานใช่หรือไม่?",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +345,7 @@ function requireEdit() {
|
|||
}
|
||||
},
|
||||
"ยืนยันการขอแก้ไขข้อตกลง",
|
||||
"ต้องการยืนยันการขอแก้ไขข้อตกลงนี้ใช่หรือไม่?"
|
||||
"ต้องการยืนยันการขอแก้ไขข้อตกลงนี้ใช่หรือไม่?",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -411,7 +418,7 @@ async function goToSummary() {
|
|||
store.excusiveIndicator2ScoreVal +
|
||||
store.competencyScoreVal
|
||||
).toFixed(2),
|
||||
}
|
||||
},
|
||||
)
|
||||
.then((res) => {});
|
||||
|
||||
|
|
@ -427,7 +434,7 @@ async function goToSummary() {
|
|||
});
|
||||
},
|
||||
"ยืนยันการส่งไปสรุปผลการประเมิน",
|
||||
"ต้องการยืนยันส่งไปสรุปผลการประเมินใช่หรือไม่?"
|
||||
"ต้องการยืนยันส่งไปสรุปผลการประเมินใช่หรือไม่?",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +524,7 @@ async function downloadReport() {
|
|||
store.dataEvaluation.prefix +
|
||||
store.dataEvaluation.firstName +
|
||||
" " +
|
||||
store.dataEvaluation.lastName
|
||||
store.dataEvaluation.lastName,
|
||||
);
|
||||
})
|
||||
.catch((e) => {
|
||||
|
|
@ -556,7 +563,7 @@ async function clickUpload(file: any) {
|
|||
const foundKey: string | undefined = Object.keys(res.data).find(
|
||||
(key) =>
|
||||
res.data[key]?.fileName !== undefined &&
|
||||
res.data[key]?.fileName !== ""
|
||||
res.data[key]?.fileName !== "",
|
||||
);
|
||||
foundKey &&
|
||||
uploadFileDoc(res.data[foundKey]?.uploadUrl, fileUpload.value);
|
||||
|
|
@ -566,7 +573,7 @@ async function clickUpload(file: any) {
|
|||
});
|
||||
},
|
||||
"ยืนยันการอัปโหลดไฟล์",
|
||||
"ต้องการยืนยันการอัปโหลดไฟล์นี้หรือไม่ ?"
|
||||
"ต้องการยืนยันการอัปโหลดไฟล์นี้หรือไม่ ?",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +630,7 @@ function deleteFile(fileName: string) {
|
|||
showLoader();
|
||||
http
|
||||
.delete(
|
||||
config.API.file("แบบกำหนดข้อตกลง", "KPI", id.value) + `/${fileName}`
|
||||
config.API.file("แบบกำหนดข้อตกลง", "KPI", id.value) + `/${fileName}`,
|
||||
)
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
|
|||
|
|
@ -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<string, string> = {
|
||||
"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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { ref, onMounted, watch } from "vue";
|
|||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
|
||||
import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile";
|
||||
|
||||
import type { FileFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
|
|
@ -57,18 +58,10 @@ async function downloadFile(fileName: 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 = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
await downloadBlobFile({
|
||||
downloadUrl: downloadUrl,
|
||||
fileName: fileName,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { useQuasar } from "quasar";
|
|||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import { useRegistryInFormationStore } from "@/modules/10_registry/store/registry";
|
||||
import { downloadBlobFile } from "@/modules/10_registry/utils/downloadFile";
|
||||
|
||||
import type { FileFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
|
|
@ -57,18 +58,10 @@ async function downloadFile(fileName: 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 = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
await downloadBlobFile({
|
||||
downloadUrl: downloadUrl,
|
||||
fileName: fileName,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
|
|||
60
src/modules/10_registry/utils/downloadFile.ts
Normal file
60
src/modules/10_registry/utils/downloadFile.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
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<void> {
|
||||
// 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<string, string> = {
|
||||
"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;
|
||||
const downloadFileName = fileName.includes(".") ? fileName : `${fileName}.${extension}`;
|
||||
link.download = downloadFileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
}
|
||||
|
|
@ -151,6 +151,7 @@ async function getAvatar(id: string) {
|
|||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
profileImg.value = avatar;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -168,14 +169,15 @@ function getList(id: string) {
|
|||
});
|
||||
}
|
||||
|
||||
async function getImg(id: string, pathName: string) {
|
||||
await http
|
||||
function getImg(id: string, pathName: string) {
|
||||
http
|
||||
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, pathName))
|
||||
.then((res) => {
|
||||
profileImg.value = res.data.downloadUrl;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
profileImg.value = avatar;
|
||||
// messageError($q, e);
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
|
@ -188,7 +190,7 @@ function onSearch() {
|
|||
rows.value = onSearchDataTable(
|
||||
filter.value,
|
||||
rowsData.value,
|
||||
columns.value ? columns.value : []
|
||||
columns.value ? columns.value : [],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ async function genReport(data: any, fileName: string, type: string = "docx") {
|
|||
},
|
||||
responseType: "arraybuffer",
|
||||
})
|
||||
.then((res) => {
|
||||
.then(async (res) => {
|
||||
const responseData = res.data;
|
||||
if (responseData) {
|
||||
const mimeType =
|
||||
|
|
@ -32,13 +32,11 @@ async function genReport(data: any, fileName: string, type: string = "docx") {
|
|||
|
||||
const baseName = fileName.trim();
|
||||
const extension = type === "docx" ? "docx" : "pdf";
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = `${baseName}.${extension}`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
const calAge = (
|
||||
srcDate: Date,
|
||||
birthCal: Date = new Date(),
|
||||
eng: boolean = false
|
||||
eng: boolean = false,
|
||||
) => {
|
||||
const year = eng ? "years" : "ปี";
|
||||
const month = eng ? "months" : "เดือน";
|
||||
|
|
@ -82,7 +82,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
function date2Thai(
|
||||
srcDate: Date | null,
|
||||
isFullMonth: boolean = false,
|
||||
isTime: boolean = false
|
||||
isTime: boolean = false,
|
||||
) {
|
||||
if (srcDate == null || !moment(srcDate).isValid()) return "";
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
function dateThai(
|
||||
srcDate: Date,
|
||||
isFullMonth: boolean = true,
|
||||
isTime: boolean = false
|
||||
isTime: boolean = false,
|
||||
) {
|
||||
if (srcDate == null) {
|
||||
return null;
|
||||
|
|
@ -490,7 +490,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
color: string | undefined,
|
||||
ok?: Function | undefined,
|
||||
cancel?: Function | undefined,
|
||||
onlycancel: Boolean = false
|
||||
onlycancel: Boolean = false,
|
||||
) => {
|
||||
q.dialog({
|
||||
component: CustomComponent,
|
||||
|
|
@ -529,7 +529,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
title: string,
|
||||
message: string,
|
||||
ok: Function,
|
||||
cancel?: Function
|
||||
cancel?: Function,
|
||||
) {
|
||||
q.dialog({
|
||||
title: `<span class="text-red">${title}</span>`,
|
||||
|
|
@ -559,7 +559,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
title: string,
|
||||
message: string,
|
||||
ok: Function,
|
||||
cancel?: Function
|
||||
cancel?: Function,
|
||||
) {
|
||||
q.dialog({
|
||||
title: `<span class="text-primary">${title}</span>`,
|
||||
|
|
@ -795,7 +795,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
ok?: Function,
|
||||
title?: string, // ถ้ามี cancel action ใส่เป็น null
|
||||
desc?: string, // ถ้ามี cancel action ใส่เป็น null
|
||||
cancel?: Function
|
||||
cancel?: Function,
|
||||
) => {
|
||||
q.dialog({
|
||||
component: CustomComponent,
|
||||
|
|
@ -824,7 +824,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
ok?: Function,
|
||||
title?: string, // ถ้ามี cancel action ใส่เป็น null
|
||||
desc?: string, // ถ้ามี cancel action ใส่เป็น null
|
||||
cancel?: Function
|
||||
cancel?: Function,
|
||||
) => {
|
||||
q.dialog({
|
||||
component: CustomComponent,
|
||||
|
|
@ -851,7 +851,7 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
const dialogMessageNotify = (
|
||||
q: any,
|
||||
desc?: string, // ถ้ามี cancel action ใส่เป็น null
|
||||
cancel?: Function
|
||||
cancel?: Function,
|
||||
) => {
|
||||
q.dialog({
|
||||
component: CustomComponent,
|
||||
|
|
@ -1252,9 +1252,15 @@ export const useCounterMixin = defineStore("mixin", () => {
|
|||
|
||||
// กรณีมีเฉพาะ date
|
||||
function convertDateToAPI(date: Date | null) {
|
||||
return date
|
||||
? format(utcToZonedTime(date, "Asia/Bangkok"), "yyyy-MM-dd")
|
||||
: null;
|
||||
if (!date) return null;
|
||||
|
||||
const parsedDate = new Date(date);
|
||||
|
||||
if (parsedDate) {
|
||||
return format(parsedDate, "yyyy-MM-dd");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// กรณี datetime
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ async function checkUser() {
|
|||
await dataStore.getProFileType();
|
||||
kpiDataStore.dataProfile = data; // Set dataProfile in kpiDataStore
|
||||
if (data.avatarName) {
|
||||
await getImg(data.profileId, data.avatarName);
|
||||
getImg(data.profileId, data.avatarName);
|
||||
} else {
|
||||
dataStore.profileImg = avatar;
|
||||
}
|
||||
|
|
@ -106,6 +106,9 @@ function getImg(id: string, pathName: string) {
|
|||
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, pathName))
|
||||
.then((res) => {
|
||||
dataStore.profileImg = res.data.downloadUrl;
|
||||
})
|
||||
.catch(() => {
|
||||
dataStore.profileImg = avatar;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue