Refactoring code module 03_recruiting

This commit is contained in:
STW_TTTY\stwtt 2024-09-17 15:56:06 +07:00
parent b223c2433e
commit 87e2e3b080
36 changed files with 6139 additions and 6335 deletions

View file

@ -1,3 +1,420 @@
<script setup lang="ts">
import { ref, useAttrs, watch } from "vue";
import { checkPermission } from "@/utils/permissions";
import { useRoute, useRouter } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import { useQuasar } from "quasar";
const route = useRoute();
const router = useRouter();
const $q = useQuasar();
const mixin = useCounterMixin();
const { dateToISO, success, modalError, dialogMessage } = mixin;
const attrs = ref<any>(useAttrs());
const table = ref<any>(null);
const files = ref<File[]>([]);
const filterRef = ref<any>(null);
const examId = ref<string>(route.params.examId.toString());
const selected = ref<string[]>([]);
const { messageError, showLoader, hideLoader } = mixin;
const dateFilter = ref<[Date, Date]>([new Date(), new Date()]); //
const props = defineProps({
inputfilter: String,
inputvisible: Array,
inputvisibleFilter: String,
editvisible: Boolean,
titleText: String,
optionsFilter: {
type: Array,
defualt: [],
},
selected: {
type: Array,
defualt: [],
},
boss: {
type: Boolean,
defualt: false,
},
saveNoDraft: {
type: Boolean,
defualt: false,
},
history: {
type: Boolean,
defualt: false,
},
paging: {
type: Boolean,
defualt: false,
},
pageSize: {
type: Number,
defualt: 25,
},
page: {
type: Number,
defualt: 1,
},
maxPage: {
type: Number,
defualt: 1,
},
total: {
type: Number,
defualt: 0,
},
nornmalData: {
type: Boolean,
defualt: false,
},
nextPageVisible: {
type: Boolean,
defualt: false,
},
publicData: {
type: Boolean,
defualt: true,
required: false,
},
updateData: {
type: Boolean,
defualt: true,
required: false,
},
statusPayment: {
type: Boolean,
required: false,
},
setSeat: {
type: Boolean,
required: false,
},
publicNoBtn: {
type: Boolean,
defualt: false,
},
save: {
type: Function,
default: () => console.log("not function"),
},
cancel: {
type: Function,
default: () => console.log("not function"),
},
publish: {
type: Function,
default: () => console.log("not function"),
},
validate: {
type: Function,
default: () => console.log("not function"),
},
fetchData: {
type: Function,
default: () => console.log("not function"),
},
});
// Pagination - initial pagination
const initialPagination = ref<any>({
sortBy: null,
descending: false,
page: 1,
rowsPerPage: props.pageSize,
});
// Pagination - update rowsPerPage
async function updatePagination(newPagination: any) {
initialPagination.value = newPagination;
currentPage.value = 1;
}
const emit = defineEmits([
"update:inputfilter",
"update:inputvisible",
"update:editvisible",
"update:titleText",
"update:inputvisibleFilter",
"update:change-page",
]);
const updateInput = async (value: any) => {
await emit("update:inputfilter", value);
};
// search & get new data by keyword
const submitInput = () => {
setTimeout(() => {
emit("update:change-page", 1, initialPagination.value.rowsPerPage);
currentPage.value = 1;
}, 500);
};
const updateVisible = (value: any) => {
emit("update:inputvisible", value);
};
const updateVisibleFilter = (value: any) => {
emit("update:inputvisibleFilter", value);
};
async function uploadFile() {
if (files.value.length > 0) {
if (props.setSeat == false) {
uploadDataSeat();
} else {
uploadDataPoint();
}
} else {
modalError(
$q,
"ไม่สามารถอัปโหลดไฟล์ได้",
"กรุณาเลือกไฟล์ที่ต้องการอัปโหลด"
);
}
}
async function candidateToPlacement() {
$q.dialog({
title: "ยืนยันการนำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุ",
message: "ต้องการนำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุใช่หรือไม่?",
cancel: {
flat: true,
color: "negative",
},
persistent: true,
})
.onOk(async () => {
await http
.get(config.API.periodExamToPlacement(examId.value))
.then((res) => {
success($q, "นำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
router.go(-1);
});
})
.onCancel(() => {})
.onDismiss(() => {});
}
async function uploadDataSeat() {
showLoader();
const formData = new FormData();
formData.append("", files.value[0]);
await http
.put(config.API.periodExamUploadSeat(examId.value), formData)
.then((res) => {
success($q, "อัพเดทที่นั่งสอบสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
files.value = [];
props.fetchData();
});
}
async function uploadDataPoint() {
showLoader();
const formData = new FormData();
formData.append("", files.value[0]);
await http
.put(config.API.periodExamUploadPoint(examId.value), formData)
.then((res) => {
success($q, "อัพเดทคะแนนสอบสำเร็จ");
files.value = [];
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
files.value = [];
props.fetchData();
});
}
async function downloadFile() {
showLoader();
await http
.get(config.API.periodExamDownload(examId.value), {
responseType: "blob",
})
.then((res) => {
const data = res.data;
downloadFilePDF(data, `Candidate__${dateToISO(new Date())}.xlsx`);
})
.catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text()));
})
.finally(() => {
hideLoader();
});
}
async function downloadFileDetail() {
showLoader();
await http
.get(config.API.periodExamDownloadDetail(examId.value), {
responseType: "blob",
})
.then((res) => {
const data = res.data;
downloadFilePDF(data, `Candidate_Detail_${dateToISO(new Date())}.xlsx`);
})
.catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text()));
})
.finally(() => {
hideLoader();
});
}
async function checkCandidates() {
var _selected: any[] = [];
selected.value.map((r: any) => {
_selected.push(r.id.toString());
});
showLoader();
await http
.post(config.API.candidateCheckRegisters, {
candidateId: _selected,
})
.then((res) => {
success($q, "ตรวจสอบข้อมูลสำเร็จ");
selected.value = [];
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
props.fetchData();
});
}
async function downloadFilePDF(res: string, fileName: string) {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(
new Blob([res], {
type: "application/vnd.ms-excel",
})
);
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
}
async function candidateCheckProfileDialog() {
dialogMessage(
$q,
"ยืนยันการตรวจสอบข้อมูลนี้หรือไม่?",
"ยืนยันการตรวจสอบข้อมูล",
"mdi-email-check-outline",
"ยืนยัน",
"public",
checkCandidates,
undefined
);
}
function resetFilter() {
// reset X
emit("update:inputfilter", "");
filterRef.value.focus();
// clear keyword & get new data
emit("update:change-page", 1, initialPagination.value.rowsPerPage);
currentPage.value = 1;
}
async function downloadFileDashboard() {
showLoader();
await http
.put(
config.API.periodExamDownloadDashboard(examId.value),
{
dateStart: dateToISO(dateFilter.value[0]),
dateEnd: dateToISO(dateFilter.value[1]),
responseType: "blob",
},
{
responseType: "blob",
}
)
.then((res) => {
const data = res.data;
downloadFilePDF(
data,
`Candidate_Dashboard_${dateToISO(new Date())}.xlsx`
);
})
.catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text()));
})
.finally(() => {
hideLoader();
});
}
async function clickPassExam() {
showLoader();
await http
.get(config.API.exportExamPassExamList(examId.value))
.then((res) => {
window.open(config.API.exportExamPassExamList(examId.value));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
async function clickCandidateList() {
showLoader();
await http
.get(config.API.exportExamCandidateList(examId.value))
.then((res) => {
window.open(config.API.exportExamCandidateList(examId.value));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
// Pagination - page & change page & get new data
const currentPage = ref<number>(1);
watch(
[() => currentPage.value, () => initialPagination.value.rowsPerPage],
() => {
emit(
"update:change-page",
currentPage.value,
initialPagination.value.rowsPerPage,
true
);
}
);
</script>
<template>
<div class="q-px-md q-pb-md">
<q-card
@ -235,453 +652,7 @@
</q-table>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, watch, watchEffect } from "vue";
import { checkPermission } from "@/utils/permissions";
import { useRoute, useRouter } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import { useQuasar } from "quasar";
const route = useRoute();
const router = useRouter();
const mixin = useCounterMixin();
const { dateToISO, success, modalError, dialogMessage } = mixin;
const $q = useQuasar(); // show dialog
const attrs = ref<any>(useAttrs());
const table = ref<any>(null);
const files = ref<File[]>([]);
const filterRef = ref<any>(null);
const examId = ref<string>(route.params.examId.toString());
const candidateId = ref<string[]>([]);
const selected = ref<string[]>([]);
const { messageError, showLoader, hideLoader } = mixin;
const dateFilter = ref<[Date, Date]>([new Date(), new Date()]); //
const props = defineProps({
inputfilter: String,
inputvisible: Array,
inputvisibleFilter: String,
editvisible: Boolean,
titleText: String,
optionsFilter: {
type: Array,
defualt: [],
},
selected: {
type: Array,
defualt: [],
},
boss: {
type: Boolean,
defualt: false,
},
saveNoDraft: {
type: Boolean,
defualt: false,
},
history: {
type: Boolean,
defualt: false,
},
paging: {
type: Boolean,
defualt: false,
},
pageSize: {
type: Number,
defualt: 25,
},
page: {
type: Number,
defualt: 1,
},
maxPage: {
type: Number,
defualt: 1,
},
total: {
type: Number,
defualt: 0,
},
nornmalData: {
type: Boolean,
defualt: false,
},
nextPageVisible: {
type: Boolean,
defualt: false,
},
publicData: {
type: Boolean,
defualt: true,
required: false,
},
updateData: {
type: Boolean,
defualt: true,
required: false,
},
statusPayment: {
type: Boolean,
required: false,
},
setSeat: {
type: Boolean,
required: false,
},
publicNoBtn: {
type: Boolean,
defualt: false,
},
save: {
type: Function,
default: () => console.log("not function"),
},
cancel: {
type: Function,
default: () => console.log("not function"),
},
publish: {
type: Function,
default: () => console.log("not function"),
},
validate: {
type: Function,
default: () => console.log("not function"),
},
fetchData: {
type: Function,
default: () => console.log("not function"),
},
});
// Pagination - initial pagination
const initialPagination = ref<any>({
sortBy: null,
descending: false,
page: 1,
rowsPerPage: props.pageSize,
});
// Pagination - page & change page & get new data
const currentPage = ref<number>(1);
watch(
[() => currentPage.value, () => initialPagination.value.rowsPerPage],
() => {
emit(
"update:change-page",
currentPage.value,
initialPagination.value.rowsPerPage,
true
);
}
);
// Pagination - update rowsPerPage
async function updatePagination(newPagination: any) {
initialPagination.value = newPagination;
currentPage.value = 1;
}
const emit = defineEmits([
"update:inputfilter",
"update:inputvisible",
"update:editvisible",
"update:titleText",
"update:inputvisibleFilter",
"update:change-page",
]);
const updateInput = async (value: any) => {
await emit("update:inputfilter", value);
};
// search & get new data by keyword
const submitInput = () => {
setTimeout(() => {
emit("update:change-page", 1, initialPagination.value.rowsPerPage);
currentPage.value = 1;
}, 500);
};
const updateVisible = (value: any) => {
emit("update:inputvisible", value);
};
const updateVisibleFilter = (value: any) => {
emit("update:inputvisibleFilter", value);
};
const uploadFile = async () => {
if (files.value.length > 0) {
if (props.setSeat == false) {
uploadDataSeat();
} else {
uploadDataPoint();
}
} else {
modalError(
$q,
"ไม่สามารถอัปโหลดไฟล์ได้",
"กรุณาเลือกไฟล์ที่ต้องการอัปโหลด"
);
}
};
const candidateToPlacement = async () => {
$q.dialog({
title: "ยืนยันการนำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุ",
message: "ต้องการนำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุใช่หรือไม่?",
cancel: {
flat: true,
color: "negative",
},
persistent: true,
})
.onOk(async () => {
await http
.get(config.API.periodExamToPlacement(examId.value))
.then((res) => {
success($q, "นำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
router.go(-1);
});
})
.onCancel(() => {})
.onDismiss(() => {});
};
const uploadDataSeat = async () => {
showLoader();
const formData = new FormData();
formData.append("", files.value[0]);
await http
.put(config.API.periodExamUploadSeat(examId.value), formData)
.then((res) => {
success($q, "อัพเดทที่นั่งสอบสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
files.value = [];
props.fetchData();
});
};
const uploadDataPoint = async () => {
showLoader();
const formData = new FormData();
formData.append("", files.value[0]);
await http
.put(config.API.periodExamUploadPoint(examId.value), formData)
.then((res) => {
success($q, "อัพเดทคะแนนสอบสำเร็จ");
files.value = [];
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
files.value = [];
props.fetchData();
});
};
const downloadFile = async () => {
showLoader();
await http
.get(config.API.periodExamDownload(examId.value), {
responseType: "blob",
})
.then((res) => {
const data = res.data;
downloadFilePDF(data, `Candidate__${dateToISO(new Date())}.xlsx`);
})
.catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text()));
})
.finally(() => {
hideLoader();
});
};
const downloadFileDetail = async () => {
showLoader();
await http
.get(config.API.periodExamDownloadDetail(examId.value), {
responseType: "blob",
})
.then((res) => {
const data = res.data;
downloadFilePDF(data, `Candidate_Detail_${dateToISO(new Date())}.xlsx`);
})
.catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text()));
})
.finally(() => {
hideLoader();
});
};
const checkCandidates = async () => {
var _selected: any[] = [];
selected.value.map((r: any) => {
_selected.push(r.id.toString());
});
showLoader();
await http
.post(config.API.candidateCheckRegisters, {
candidateId: _selected,
})
.then((res) => {
success($q, "ตรวจสอบข้อมูลสำเร็จ");
selected.value = [];
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
props.fetchData();
});
};
const downloadFilePDF = async (res: string, fileName: string) => {
const link = document.createElement("a");
link.href = window.URL.createObjectURL(
new Blob([res], {
type: "application/vnd.ms-excel",
})
);
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
};
const checkSave = () => {
props.validate();
props.save();
};
const publishModal = () => {
props.validate();
const filter = attrs.value.rows.filter((r: any) => r.name == "");
if (filter.length == 0 || attrs.value.rows.length == 0) {
dialogMessage(
$q,
"ต้องการเผยแพร่ข้อมูลนี้หรือไม่?",
"ข้อมูลที่กำลังถูกเผยแพร่นี้จะมีผลใช้งานทันที",
"public",
"เผยแพร่",
"public",
props.publish,
undefined
);
}
};
const candidateCheckProfileDialog = async () => {
dialogMessage(
$q,
"ยืนยันการตรวจสอบข้อมูลนี้หรือไม่?",
"ยืนยันการตรวจสอบข้อมูล",
"mdi-email-check-outline",
"ยืนยัน",
"public",
checkCandidates,
undefined
);
};
// const candidateCheckProfile = async () => {
// const filter = attrs.value.rows.filter((r: any) => r.check == true);
// filter.map((r: any) => {
// candidateId.value.push(r.id.toString());
// });
// await checkCandidates();
// };
const resetFilter = () => {
// reset X
emit("update:inputfilter", "");
filterRef.value.focus();
// clear keyword & get new data
emit("update:change-page", 1, initialPagination.value.rowsPerPage);
currentPage.value = 1;
};
const downloadFileDashboard = async () => {
showLoader();
await http
.put(
config.API.periodExamDownloadDashboard(examId.value),
{
dateStart: dateToISO(dateFilter.value[0]),
dateEnd: dateToISO(dateFilter.value[1]),
responseType: "blob",
},
{
responseType: "blob",
}
)
.then((res) => {
const data = res.data;
downloadFilePDF(
data,
`Candidate_Dashboard_${dateToISO(new Date())}.xlsx`
);
})
.catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text()));
})
.finally(() => {
hideLoader();
});
};
const clickPassExam = async () => {
showLoader();
await http
.get(config.API.exportExamPassExamList(examId.value))
.then((res) => {
window.open(config.API.exportExamPassExamList(examId.value));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
const clickCandidateList = async () => {
showLoader();
await http
.get(config.API.exportExamCandidateList(examId.value))
.then((res) => {
window.open(config.API.exportExamCandidateList(examId.value));
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
</script>
<style lang="scss">
.icon-color {
color: #4154b3;