hrms-mgt/src/modules/03_recruiting/views/02_qualify/PeriodAdd.vue

2528 lines
103 KiB
Vue
Raw Normal View History

2023-06-01 12:54:58 +07:00
<!-- page:ดการรอบการสอบ สรรหา -->
<script setup lang="ts">
import type { QTableProps } from "quasar";
2025-11-20 13:37:29 +07:00
import { onMounted, ref, watch, computed } from "vue";
2023-06-01 12:54:58 +07:00
import { useQuasar, QForm } from "quasar";
import { useRouter, useRoute } from "vue-router";
2024-09-17 15:56:06 +07:00
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
2023-06-01 12:54:58 +07:00
import type {
RequestPosition,
RequestPayment,
} from "@/modules/03_recruiting/interface/request/Period";
import type {
ResponsePosition,
ResponsePayment,
} from "@/modules/03_recruiting/interface/response/Period";
import type {
2024-11-21 16:58:49 +07:00
DataOption2,
2023-06-01 12:54:58 +07:00
UploadType,
2024-11-21 16:58:49 +07:00
} from "@/modules/02_organization/interface/index/Main";
2025-01-08 10:24:40 +07:00
import type {
ResponesePosType,
DataPosLevel,
ResponesePosition,
} from "@/modules/03_recruiting/interface/response/Main";
2023-08-04 10:04:59 +07:00
import ProfileTable from "@/modules/03_recruiting/components/Table1.vue";
2023-06-01 12:54:58 +07:00
const $q = useQuasar(); // show dialog
const mixin = useCounterMixin();
const router = useRouter();
const route = useRoute();
const {
date2Thai,
success,
2025-11-17 10:41:29 +07:00
convertDatetimeToAPI,
messageError,
showLoader,
hideLoader,
convertDateToAPI,
2025-08-21 12:57:16 +07:00
notifyWarring,
} = mixin;
2024-09-17 15:56:06 +07:00
2024-09-23 13:40:03 +07:00
const checkRoutePermisson = ref<boolean>(
route.name == "qualifyPeriodEditDetail"
); //เช็คชื่อ route
2023-06-01 12:54:58 +07:00
const myForm = ref<QForm | null>(null); //form data input
const name = ref<string>("");
const note = ref<string>("");
const editor = ref<string>("");
const editorCondition = ref<string>(
`<div style="text-align: center;"><span style="color: rgb(193, 0, 21); font-weight: 700; letter-spacing: 0.14992px;">ข้อกำหนดและเงื่อนไขฉบับนี้ ถือเป็นข้อตกลงในการเก็บข้อมูล</span><br></div><div style="text-align: center;"><span style="color: rgb(193, 0, 21); font-weight: 700; letter-spacing: 0.14992px;"><br></span></div><div><p style="margin-bottom: 16px;"><span style="font-size: 14px;">&nbsp; &nbsp;&nbsp;ข้าพเจ้าได้ศึกษาและทำความเข้าใจพระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 ตลอดจนประกาศและระเบียบที่เกี่ยวข้องโดยละเอียดครบถ้วนแล้ว ข้าพเจ้ายินยอมให้หน่วยงานหรือบุคคลที่เกี่ยวข้องกับการดำเนินการสรรหา สามารถเก็บ รวบรวม ใช้และเปิดเผยข้อมูลส่วนบุคคลที่เกี่ยวข้องกับข้าพเจ้า เพื่อประโยชน์ของทางราชการตามกฎหมายที่เกี่ยวข้อง</span></p></div>`
);
const editorConfirm = ref<string>(
2024-11-28 13:44:28 +07:00
`<div style="text-align: center;"><span style="color: rgb(93, 190, 21); font-weight: 700; letter-spacing: 0.14992px;">คำรับรอง</span><br></div><div><div style=""><div style=""><font color="#35473c"><span style="font-size: 14px;"><br></span></font></div><div style=""><font color="#35473c"><span style="font-size: 14px;">1.<span style="white-space: pre;"> </span>ข้าพเจ้าขอให้คำรับรองว่า ข้อความดังกล่าวข้างต้นเป็นจริงทุกประการ และข้าพเจ้ามีคุณสมบัติทั่วไปและไม่มีลักษณะต้องห้ามตามมาตรา 43 แห่งพระราชบัญญัติระเบียบข้าราชการกรุงเทพมหานครและบุคลากรกรุงเทพมหานคร พ.ศ. 2554 และมีคุณสมบัติเฉพาะสำหรับตำแหน่งที่สมัครตรงตามประกาศรับสมัคร</span></font></div><div style=""><font color="#35473c"><span style="font-size: 14px;">2.<span style="white-space:pre"> </span>กรณีข้าพเจ้ามีลักษณะต้องห้าม ตามมาตรา 43 ข. แห่งพระราชบัญญัติระเบียบข้าราชการกรุงเทพมหานครและบุคลากรกรุงเทพมหานคร พ.ศ. 2554 และประสงค์จะยื่นคำขอยกเว้นเข้ารับราชการฯ ต่อสำนักงาน ก.ก. ตามระเบียบ ก.ก. ว่าด้วยการยกเว้นให้ผู้มีลักษณะต้องห้ามเข้ารับราชการเป็นข้าราชการกรุงเทพมหานคร พ.ศ. 2556 ตามมติ ก.ก. ครั้งที่ 7/2556 เมื่อวันที่ 15 สิงหาคม 2556 ข้าพเจ้าจะยื่นคำขอยกเว้นฯ ภายในวันปิดรับสมัคร ทั้งนี้ หากยื่นภายหลังกำหนด สำนักงาน ก.ก. จะไม่รับคำขอดังกล่าว</span></font></div><div style=""><font color="#35473c"><span style="font-size: 14px;">3.<span style="white-space:pre"> </span>ข้าพเจ้าจะยื่นหลักฐานและเอกสารที่แสดงว่า เป็นผู้มีคุณสมบัติทั่วไปและมีคุณสมบัติเฉพาะสำหรับตำแหน่งที่สมัครตรงตามประกาศรับสมัครภายในระยะเวลาที่กำหนดตามประกาศฯ หากมีการตรวจสอบหลักฐานและเอกสาร และหรือคุณวุฒิการศึกษาของข้าพเจ้าในภายหลังปรากฏว่าข้าพเจ้ามีคุณสมบัติไม่ตรงหรือมีลักษณะต้องห้ามตามประกาศรับสมัครหรือไม่ได้รับการยกเว้นให้ถือว่า ข้าพเจ้าเป็นผู้ขาดคุณสมบัติในการสมัครครั้งนี้มาตั้งแต่ต้น และไม่มีสิทธิได้รับการบรรจุและแต่งตั้งให้ดำรงตำแหน่ง และข้าพเจ้าจะไม่มีสิทธิเรียกร้องใดๆ ทั้งสิ้น และหา<E0B8AB><E0B8B2>
);
const fee = ref<number>(0);
const remark = ref<string>("");
const companyCode = ref<string>("");
const reason = ref<string>("");
const refNo1 = ref<string>("");
const qrCodes = ref<File | any>(null);
const barCodes = ref<File | any>(null);
const qrCodesFile = ref<UploadType[]>([]);
const barCodesFile = ref<UploadType[]>([]);
2023-06-01 12:54:58 +07:00
const checkDocument = ref<boolean>(false);
const checkDisability = ref<boolean>(false);
const announcementExam = ref<boolean>(true);
const round = ref<number>(1);
2025-11-17 10:02:00 +07:00
const yearly = ref<number>(new Date().getFullYear());
2023-06-01 12:54:58 +07:00
const nameRaw = ref<number | null>(null);
const roundRaw = ref<number | null>(null);
const yearlyRaw = ref<number | null>(null);
2023-06-19 15:50:50 +07:00
const dateRegister = ref<[Date, Date] | null>(null); //วันที่สมัคร
const datePayment = ref<[Date, Date] | null>(null); //วันที่จ่ายเงิน
const dateAnnouncement = ref<[Date, Date] | null>(null); //วันที่ประกาศ
const dateAnnounce = ref<Date | null>(null); //วันประกาศผลสอบ
const dateExam = ref<Date | null>(null); //วันที่สอบ
2025-11-17 17:08:32 +07:00
const graduationYearLock = ref<number>(3); //ล็อกวันที่สำเร็จการศึกษา (ปี)
2023-06-01 12:54:58 +07:00
const myFormPayment = ref<any>();
const myFormPosition = ref<any>();
2024-11-21 16:58:49 +07:00
const organizationShortName = ref<DataOption2>();
const organizationName = ref<DataOption2>();
2023-06-01 12:54:58 +07:00
const examTypeOptions = [
{ name: "ทั่วไป", id: "normol" },
{ name: "แพทย์", id: "docter" },
];
const category = ref<string>("");
2024-09-17 15:56:06 +07:00
2023-06-01 12:54:58 +07:00
const fileDocDataUpload = ref<File[]>([]);
const fileDocs = ref<UploadType[]>([]);
const fileImgDataUpload = ref<File[]>([]);
const fileImgs = ref<UploadType[]>([]);
const id = ref<string>("");
const pay = ref<string>("payment1");
const filterPayment = ref<string>(""); //search data table
const filterPosition = ref<string>(""); //search data table
const edit = ref<boolean>(false);
const rowsPayment = ref<ResponsePayment[]>([]);
const rowsPosition = ref<any>([]);
2023-06-01 12:54:58 +07:00
const visibleColumnsPayment = ref<String[]>([
"accountNumber",
"bankName",
"accountName",
]);
const columnsPayment = ref<QTableProps["columns"]>([
{
name: "accountNumber",
align: "left",
label: "เลขบัญชี",
sortable: true,
field: "accountNumber",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "bankName",
align: "left",
label: "ธนาคาร",
sortable: true,
field: "bankName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "accountName",
align: "left",
label: "ชื่อบัญชี",
sortable: true,
field: "accountName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
2023-06-19 15:50:50 +07:00
const visibleColumnsPosition = ref<String[]>([
"code",
2023-06-19 15:50:50 +07:00
"position",
2023-09-29 17:39:23 +07:00
"level",
2023-06-19 15:50:50 +07:00
"type",
2025-11-17 17:08:32 +07:00
"educational",
2023-06-19 15:50:50 +07:00
"highDegree",
]);
2023-06-01 12:54:58 +07:00
const columnsPosition = ref<QTableProps["columns"]>([
{
name: "code",
align: "left",
label: "รหัสประจำตำแหน่งที่สอบ",
sortable: true,
field: "code",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
2023-06-01 12:54:58 +07:00
{
name: "highDegree",
2023-06-01 12:54:58 +07:00
align: "left",
label: "ประเภทตำแหน่ง",
2023-06-01 12:54:58 +07:00
sortable: true,
field: "highDegree",
2023-06-01 12:54:58 +07:00
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
2023-09-29 17:39:23 +07:00
{
name: "level",
align: "left",
label: "ระดับ",
sortable: true,
field: "level",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
2023-06-19 15:50:50 +07:00
{
name: "position",
2023-06-19 15:50:50 +07:00
align: "left",
label: "ตำแหน่ง",
2023-06-19 15:50:50 +07:00
sortable: true,
field: "position",
2023-06-19 15:50:50 +07:00
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
2025-11-17 17:08:32 +07:00
{
name: "educational",
align: "left",
label: "กำหนดขีดจำกัดวุฒิการศึกษา",
sortable: true,
field: "educational",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
2023-06-01 12:54:58 +07:00
{
name: "type",
align: "left",
label: "ประเภทแบบฟอร์ม",
sortable: true,
field: "type",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
2025-11-20 13:37:29 +07:00
const shouldShowPaymentFields = computed(() => {
return announcementExam.value && fee.value > 0;
});
2024-09-17 15:56:06 +07:00
/** ย้อนกลับไปหน้าหลัก */
function clickBack() {
2023-06-01 12:54:58 +07:00
router.push({ name: "qualifyPeriod" });
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** ดึงข้อมูล */
async function fetchData() {
2023-08-04 10:04:59 +07:00
showLoader();
2023-06-01 12:54:58 +07:00
await http
.get(config.API.periodExamId(id.value))
.then((res) => {
const data = res.data.result;
const positionData: ResponsePosition[] = [];
data.positionExam.map((r: RequestPosition) => {
positionData.push({
id: r.id,
position: {
id: r.positionId,
name: r.positionName,
},
2023-09-29 17:39:23 +07:00
level: {
id: r.positionLevelId,
name: r.positionLevelName,
},
2023-06-01 12:54:58 +07:00
type: {
id: r.typeId,
name: r.typeName,
},
code: r.code,
2023-09-29 17:39:23 +07:00
highDegree: r.highDegree == true ? "1" : "0",
2025-11-17 17:08:32 +07:00
educationLevel: r.educationLevel,
2023-06-01 12:54:58 +07:00
});
});
const bankData: ResponsePayment[] = [];
data.bankExam.map((r: RequestPayment) => {
bankData.push({
id: r.id,
accountNumber: r.accountNumber,
bankName: r.bankName,
accountName: r.accountName,
});
});
id.value = data.id;
name.value = data.name;
nameRaw.value = data.name;
checkDocument.value = data.checkDocument;
checkDisability.value = data.checkDisability;
announcementExam.value = data.announcementExam;
round.value = data.round;
yearly.value = data.year;
roundRaw.value = data.round;
yearlyRaw.value = data.year;
fee.value = data.fee;
2023-06-19 15:50:50 +07:00
dateAnnounce.value =
data.announcementDate != null ? new Date(data.announcementDate) : null;
dateAnnouncement.value =
data.announcementStartDate != null && data.announcementEndDate != null
? [
new Date(data.announcementStartDate),
new Date(data.announcementEndDate),
]
: null;
dateExam.value = data.examDate != null ? new Date(data.examDate) : null;
dateRegister.value =
data.registerStartDate != null && data.registerEndDate != null
2025-11-17 10:41:29 +07:00
? [data.registerStartDate, data.registerEndDate]
2023-06-19 15:50:50 +07:00
: null;
2023-09-29 17:39:23 +07:00
if (data.fee == 0) {
data.paymentStartDate = null;
data.paymentEndDate = null;
}
2023-06-19 15:50:50 +07:00
datePayment.value =
data.paymentStartDate != null && data.paymentEndDate != null
? [new Date(data.paymentStartDate), new Date(data.paymentEndDate)]
: null;
if (data.organizationCodeId != null) {
organizationShortName.value = {
id: data.organizationCodeId,
name: data.organizationCodeName,
};
}
if (data.organizationId != null) {
organizationName.value = {
id: data.organizationId,
name: data.organizationName,
};
}
2023-06-01 12:54:58 +07:00
rowsPosition.value = positionData;
pay.value = data.paymentKrungThai;
rowsPayment.value = bankData;
editor.value = data.detail;
2023-09-29 17:39:23 +07:00
editorCondition.value = data.editorCondition;
editorConfirm.value = data.editorConfirm;
2023-06-01 12:54:58 +07:00
note.value = data.note;
fileDocs.value = data.documents;
fileImgs.value = data.images;
qrCodesFile.value = data.qrCodes;
barCodesFile.value = data.barCodes;
2023-06-01 12:54:58 +07:00
category.value = data.category;
remark.value = data.remark;
companyCode.value = data.companyCode;
refNo1.value = data.refNo1;
reason.value = data.reason;
2025-11-17 17:08:32 +07:00
graduationYearLock.value = data.graduationYearLock;
2023-06-01 12:54:58 +07:00
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
2023-08-04 10:04:59 +07:00
hideLoader();
2023-06-01 12:54:58 +07:00
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
* งช filter
* @param val input
* @param update Function #quasar
* @param refData เเยก case
*/
function filterSelector(val: string, update: Function, refData: string) {
2023-09-29 17:39:23 +07:00
switch (refData) {
case "positionLevel1":
2023-09-29 17:39:23 +07:00
update(() => {
optionPosLevel1.value = filterOptionPosLevel1.value.filter(
2024-11-21 16:58:49 +07:00
(v: DataOption2) => v.name.indexOf(val) > -1
2023-09-29 17:39:23 +07:00
);
});
break;
case "positionLevel2":
2023-09-29 17:39:23 +07:00
update(() => {
optionPosLevel2.value = filterOptionPosLevel2.value.filter(
(v: DataOption2) => v.name.indexOf(val) > -1
);
});
break;
case "position1":
update(() => {
optionPosType1.value = filterOptionPosType1.value.filter(
(v: DataOption2) => v.name.indexOf(val) > -1
);
});
break;
case "position2":
update(() => {
optionPosType2.value = filterOptionPosType2.value.filter(
2024-11-21 16:58:49 +07:00
(v: DataOption2) => v.name.indexOf(val) > -1
2023-09-29 17:39:23 +07:00
);
});
break;
default:
break;
}
2024-09-17 15:56:06 +07:00
}
2023-09-29 17:39:23 +07:00
2024-09-17 15:56:06 +07:00
/**
* update
2024-09-23 13:40:03 +07:00
* @param e
2024-09-17 15:56:06 +07:00
*/
async function updateYear(e: number) {
2023-06-01 12:54:58 +07:00
yearly.value = e;
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** saveข้อมูล เพิ่ม แก้ไข */
async function checkSave() {
2025-11-20 10:14:39 +07:00
try {
// เช็ค validation form หลัก
const isMainFormValid = await myForm.value?.validate();
if (!isMainFormValid) return;
// เช็ค validation form ตำแหน่ง
const isPositionFormValid = await myFormPosition.value?.validate();
if (!isPositionFormValid) return;
// เช็คการเพิ่มตำแหน่ง
if (announcementExam.value && rowsPosition.value.length === 0) {
notifyWarring($q, "กรุณาเพิ่มตำแหน่ง");
return;
}
// เช็คการเลือกวิธีการชำระเงิน
2025-11-20 13:37:29 +07:00
if (shouldShowPaymentFields.value && pay.value === "") {
2025-11-20 10:14:39 +07:00
notifyWarring($q, "กรุณาเลือกวิธีการชำระเงิน");
return;
}
// เช็ค validation form วิธีการชำระเงิน ชำระเงินค่าสมัครสอบผ่านสำนัก/หน่วยงาน
if (pay.value === "payment2") {
const isPaymentFormValid = await myFormPayment.value?.validate();
if (!isPaymentFormValid) return;
if (rowsPayment.value.length === 0) {
notifyWarring($q, "กรุณาเพิ่มวิธีการชำระเงิน");
return;
2023-06-01 12:54:58 +07:00
}
2025-11-20 10:14:39 +07:00
}
if (edit.value) {
await editData(id.value);
} else {
await addData();
}
} catch (error) {
messageError($q, error);
2023-06-01 12:54:58 +07:00
}
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** body สำหรับ save ข้อมูล */
function sendData() {
2023-06-01 12:54:58 +07:00
const positionData: RequestPosition[] = [];
rowsPosition.value.map((r: ResponsePosition) => {
positionData.push({
id: r.id,
2025-11-19 17:23:27 +07:00
positionId: r.position ? r.position.id : "",
positionName: r.position ? r.position.name : "",
positionLevelId: r.level ? r.level.id : "",
positionLevelName: r.level ? r.level.name : "",
typeId: r.type ? r.type.id : "",
typeName: r.type ? r.type.name : "",
code: r.code,
2023-09-29 17:39:23 +07:00
highDegree: r.highDegree == "1" ? true : false,
2025-11-17 17:08:32 +07:00
educationLevel: r.educationLevel,
2023-06-01 12:54:58 +07:00
});
});
2025-11-19 17:23:27 +07:00
if (fee.value == 0) {
datePayment.value = null;
}
const valueData: any = {
2023-06-19 15:50:50 +07:00
announcementDate:
dateAnnounce.value != null ? convertDateToAPI(dateAnnounce.value) : null,
2023-06-19 15:50:50 +07:00
announcementEndDate:
dateAnnouncement.value != null
? convertDateToAPI(dateAnnouncement.value[1])
2023-06-19 15:50:50 +07:00
: null,
announcementStartDate:
dateAnnouncement.value != null
? convertDateToAPI(dateAnnouncement.value[0])
2023-06-19 15:50:50 +07:00
: null,
examDate: dateExam.value != null ? convertDateToAPI(dateExam.value) : null,
2023-06-01 12:54:58 +07:00
bankExam: rowsPayment.value,
checkDisability: checkDisability.value,
announcementExam: announcementExam.value,
checkDocument: checkDocument.value,
detail: editor.value,
2023-09-29 17:39:23 +07:00
editorCondition: editorCondition.value,
editorConfirm: editorConfirm.value,
2023-06-01 12:54:58 +07:00
fee: fee.value,
id: "",
isActive: true,
name: name.value,
note: note.value,
organizationCodeId: organizationShortName.value?.id,
organizationCodeName: organizationShortName.value?.name,
organizationId: organizationName.value?.id,
organizationName: organizationName.value?.name,
2023-06-19 15:50:50 +07:00
paymentEndDate:
datePayment.value != null ? convertDateToAPI(datePayment.value[1]) : null,
2023-06-01 12:54:58 +07:00
paymentKrungThai: pay.value,
2023-06-19 15:50:50 +07:00
paymentStartDate:
datePayment.value != null ? convertDateToAPI(datePayment.value[0]) : null,
2023-06-01 12:54:58 +07:00
positionExam: positionData,
2023-06-19 15:50:50 +07:00
registerEndDate:
dateRegister.value != null
2025-11-17 10:41:29 +07:00
? convertDatetimeToAPI(dateRegister.value[1])
: null,
2023-06-19 15:50:50 +07:00
registerStartDate:
dateRegister.value != null
2025-11-17 10:41:29 +07:00
? convertDatetimeToAPI(dateRegister.value[0])
: null,
2023-06-01 12:54:58 +07:00
round: round.value,
year: yearly.value,
category: category.value,
remark: remark.value,
companyCode: companyCode.value,
refNo1: refNo1.value,
reason: reason.value,
2025-11-17 17:08:32 +07:00
graduationYearLock: Number(graduationYearLock.value),
2023-06-01 12:54:58 +07:00
};
return valueData;
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** เพิ่มข้อมูล */
async function addData() {
2023-08-04 10:04:59 +07:00
showLoader();
2023-06-01 12:54:58 +07:00
await http
.post(config.API.periodExam, sendData())
.then(async (res) => {
const data = res.data.result;
id.value = data;
const uploadImg = await uploadImgData();
const uploadDoc = await uploadDocData();
const uploadBarCode = await uploadBarCodes();
const uploadQrCode = await uploadQrCodes();
2025-07-07 15:18:37 +07:00
if (uploadImg && uploadDoc && uploadBarCode && uploadQrCode) {
success($q, "บันทึกรอบคัดเลือกสำเร็จ");
2025-07-08 13:52:02 +07:00
clickBack();
}
2023-06-01 12:54:58 +07:00
})
.catch((e) => {
messageError($q, e);
2025-07-07 15:18:37 +07:00
})
2025-11-17 10:41:29 +07:00
.finally(async () => {
hideLoader();
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
* แกไข อม
* @param id id ดการรอบคดเลอก
*/
async function editData(id: string) {
2023-08-04 10:04:59 +07:00
showLoader();
2023-06-01 12:54:58 +07:00
await http
.put(config.API.periodExamId(id), sendData())
.then(async () => {
const uploadImg = await uploadImgData();
const uploadDoc = await uploadDocData();
const uploadBarCode = await uploadBarCodes();
const uploadQrCode = await uploadQrCodes();
if (uploadImg && uploadDoc && uploadBarCode && uploadQrCode) {
success($q, "แก้ไขรอบคัดเลือกสำเร็จ");
2025-11-17 10:41:29 +07:00
clickBack();
}
2023-06-01 12:54:58 +07:00
})
.catch((e) => {
messageError($q, e);
2025-07-07 15:18:37 +07:00
})
2025-11-17 10:41:29 +07:00
.finally(() => {
hideLoader();
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
* เกบไฟลเปนอาเรย
* @param files ไฟล
*/
async function fileUploadDoc(files: any) {
2023-06-01 12:54:58 +07:00
files.forEach((file: any) => {
fileDocDataUpload.value.push(file);
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
2024-09-23 13:40:03 +07:00
* ลบไฟลจาก array
2024-09-17 15:56:06 +07:00
* @param files ไฟล
*/
async function fileRemoveDoc(files: any) {
2023-06-01 12:54:58 +07:00
files.forEach((file: any) => {
const index = fileDocDataUpload.value.findIndex(
(x: any) => x.__key == file.__key
);
if (index > -1) {
fileDocDataUpload.value.splice(index, 1);
}
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** อัปโหลดไฟล์เอกสาร */
async function uploadDocData() {
2023-06-01 12:54:58 +07:00
if (fileDocDataUpload.value.length > 0) {
const formData = new FormData();
2023-06-01 12:54:58 +07:00
fileDocDataUpload.value.forEach((file: any) => {
formData.append("", file);
});
await http
.put(config.API.periodExamDoc(id.value), formData)
.then(() => {
return true;
})
.catch((e) => {
messageError($q, e);
return false;
2023-06-01 12:54:58 +07:00
});
}
return true;
}
/** อัปโหลดไฟล์เอกสาร */
async function uploadBarCodes() {
if (barCodes.value !== null) {
const formData = new FormData();
formData.append("", barCodes.value);
await http
.put(config.API.periodExambarcode(id.value), formData)
.then(() => {
return true;
})
.catch((e) => {
messageError($q, e);
return false;
});
}
return true;
}
/** อัปโหลดไฟล์เอกสาร */
async function uploadQrCodes() {
if (qrCodes.value !== null) {
const formData = new FormData();
formData.append("", qrCodes.value);
await http
.put(config.API.periodExamqrcode(id.value), formData)
.then(() => {
return true;
})
.catch((e) => {
messageError($q, e);
return false;
});
}
return true;
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
* งชนเก ปเป array
* @param files ไฟล
*/
async function fileUploadImg(files: any) {
2023-06-01 12:54:58 +07:00
files.forEach((file: any) => {
fileImgDataUpload.value.push(file);
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
2024-09-23 13:40:03 +07:00
* ลบไฟลปจาก array
2024-09-17 15:56:06 +07:00
* @param files
*/
async function fileRemoveImg(files: any) {
2023-06-01 12:54:58 +07:00
files.forEach((file: any) => {
const index = fileImgDataUpload.value.findIndex(
(x: any) => x.__key == file.__key
);
if (index > -1) {
fileImgDataUpload.value.splice(index, 1);
}
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** อัปโหลดรูป */
async function uploadImgData() {
2023-06-01 12:54:58 +07:00
if (fileImgDataUpload.value.length > 0) {
const formData = new FormData();
fileImgDataUpload.value.forEach((file: any) => {
formData.append("", file);
});
await http
.put(config.API.periodExamImg(id.value), formData)
.then(() => {
return true;
})
.catch((e) => {
messageError($q, e);
return false;
2023-06-01 12:54:58 +07:00
});
}
return true;
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
* ลบไฟล
* @param docId ไฟล id
*/
async function deleteDocData(docId: string) {
2023-06-01 12:54:58 +07:00
const params = {
documentId: docId,
};
2023-08-04 10:04:59 +07:00
showLoader();
2023-06-01 12:54:58 +07:00
await http
.delete(config.API.periodExamDoc(id.value.toString()), {
params,
})
.then((res) => {})
.catch((e) => {})
.finally(async () => {
await fetchData();
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/**
* ดาวหโหลดไฟล
* @param path งก
*/
async function downloadData(path: string) {
2023-06-01 12:54:58 +07:00
window.open(path);
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** เพิ่มวิธีการชำระเงิน */
function clickAddPayment() {
2023-06-01 12:54:58 +07:00
myFormPayment.value.validate().then(async (result: boolean) => {
if (result) {
rowsPayment.value.push({
id: "00000000-0000-0000-0000-000000000000",
accountNumber: "",
bankName: "",
accountName: "",
});
}
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** ลบวิธีการชำระ */
function clickDeletePayment(row: any) {
2023-06-01 12:54:58 +07:00
const index = rowsPayment.value.indexOf(row);
if (index > -1) {
rowsPayment.value.splice(index, 1);
}
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** เพิ่มตำแหน่ง */
function clickAddPosition() {
2023-06-01 12:54:58 +07:00
myFormPosition.value.validate().then(async (result: boolean) => {
if (result) {
rowsPosition.value.push({
id: "00000000-0000-0000-0000-000000000000",
position: null,
2023-06-01 12:54:58 +07:00
type: { id: "normol", name: "ทั่วไป" },
code: null,
highDegree: "",
2023-06-01 12:54:58 +07:00
});
}
});
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
2024-09-17 15:56:06 +07:00
/** ลบตำแหน่ง */
function clickDeletePosition(row: any) {
2023-06-01 12:54:58 +07:00
const index = rowsPosition.value.indexOf(row);
if (index > -1) {
rowsPosition.value.splice(index, 1);
}
2024-09-17 15:56:06 +07:00
}
2023-06-01 12:54:58 +07:00
/**
* แปลงชวงวนทา2คาเปนวนเดยวกนจะโชววนเดยวแตาไมเทากนจะแสดงเปนชวง
* @param val วงวนท
*/
2024-09-17 15:56:06 +07:00
function dateThaiRange(val: [Date, Date] | null) {
2023-06-01 12:54:58 +07:00
if (val === null) {
return "";
} else if (date2Thai(val[0], true) === date2Thai(val[1], true)) {
return `${date2Thai(val[0], true)}`;
} else {
return `${date2Thai(val[0], true)} - ${date2Thai(val[1], true)}`;
}
2024-09-17 15:56:06 +07:00
}
2023-06-19 15:50:50 +07:00
2024-09-17 15:56:06 +07:00
/** clear วันที่สอบ*/
function clearDateExam() {
2023-06-19 15:50:50 +07:00
dateExam.value = null;
2024-09-17 15:56:06 +07:00
}
/** clear วันที่สมัคร*/
function clearDateRegister() {
dateRegister.value = null;
}
/** clear วันที่ชำระเงิน*/
function clearDatePayment() {
datePayment.value = null;
}
/** clear วันประกาศผลสอบ*/
function clearDateAnnounce() {
dateAnnounce.value = null;
}
2025-01-08 10:24:40 +07:00
const mainDataPosLevel = ref<ResponesePosType[]>([]); //ข้อมูลรายการประเภทตำแหน่ง
const optionPosLevel1 = ref<DataOption2[]>([]); // ตัวเลือกระดับประเภททั่วไป
const filterOptionPosLevel1 = ref<DataOption2[]>([]); //ข้อมูลตัวเลือกระดับประเภททั่วไป
const optionPosLevel2 = ref<DataOption2[]>([]); //ตัวเลือกระดับประเภทวิชาการ
const filterOptionPosLevel2 = ref<DataOption2[]>([]); //ข้อมูลตัวเลือกระดับประเภทวิชาการ
const optionPosType1 = ref<DataOption2[]>([]); //ตัวเลือกตำแหน่งของระดับปฏิบัติงาน
const filterOptionPosType1 = ref<DataOption2[]>([]); //ข้อมูลตัวเลือกตำแหน่งของระดับปฏิบัติงาน
const optionPosType2 = ref<DataOption2[]>([]); //ตัวเลือกตำแหน่งของระดับปฏิบัติการ
const filterOptionPosType2 = ref<DataOption2[]>([]); //ข้อมูลตัวเลือกตำแหน่งของระดับปฏิบัติการ
/** ฟังก์ชันเรียกข้อมูล ประเภทตำแหน่ง*/
async function fetchPositionType() {
http
.get(config.API.orgPosType)
.then((res) => {
mainDataPosLevel.value = res.data.result.filter(
2025-01-08 10:24:40 +07:00
(e: ResponesePosType) => e.posTypeRank <= 2
);
const getDataByRank = (rank: number) => {
const data =
2025-01-08 10:24:40 +07:00
res.data.result.find((e: ResponesePosType) => e.posTypeRank === rank)
?.posLevels || [];
return data
2025-01-08 10:24:40 +07:00
.filter((e: DataPosLevel) => e.posLevelRank === 1)
.map((e: DataPosLevel) => ({
id: e.id.toString(),
name: e.posLevelName.toString(),
level: e.posLevelRank,
}));
};
optionPosLevel1.value = getDataByRank(1);
filterOptionPosLevel1.value = getDataByRank(1);
optionPosLevel2.value = getDataByRank(2);
filterOptionPosLevel2.value = getDataByRank(2);
fetchPosition(1);
fetchPosition(2);
})
.catch((err) => {
messageError($q, err);
});
}
2025-01-08 10:24:40 +07:00
/**
* งกนเรยกขอมลตำแหน
* @param level ระดบของประเภทตำแหน
*/
function fetchPosition(level: number) {
http
.post(config.API.orgPosTypeSearch, {
2025-01-08 10:24:40 +07:00
posType:
mainDataPosLevel.value?.find(
(e: ResponesePosType) => e.posTypeRank === level
)?.id ?? null,
posLevel:
level === 1 ? optionPosLevel1.value[0].id : optionPosLevel2.value[0].id,
})
.then((res) => {
2025-01-08 10:24:40 +07:00
const option: DataOption2[] = res.data.result.map(
(r: ResponesePosition) => ({
id: r.id.toString(),
name: r.positionName.toString(),
})
);
if (level === 1) {
optionPosType1.value = option;
filterOptionPosType1.value = option;
} else if (level === 2) {
optionPosType2.value = option;
filterOptionPosType2.value = option;
}
})
.catch((err) => {
messageError($q, err);
});
}
2025-01-08 10:24:40 +07:00
/**
* งกนเปลยนประเภทตำแหน
* @param val าประเภทตำแหน 0 = ประเภททวไป ,1 = ประเภทวชาการ
* @param index ตำแหนงของขอม
*/
function onUpdateHighDegree(val: string, index: string) {
rowsPosition.value[index].position = null;
rowsPosition.value[index].level =
val === "0" ? optionPosLevel1.value[0] : optionPosLevel2.value[0];
2025-11-17 17:08:32 +07:00
rowsPosition.value[index].educationLevel =
val === "0" ? "LOW_BACHELOR" : "BACHELOR";
}
2024-09-17 15:56:06 +07:00
watch(fee, () => {
if (fee.value <= 0) {
pay.value = "";
remark.value = "";
} else if (fee.value > 0) {
remark.value = `*ค่าธรรมเนียมการสมัครคัดเลือก จำนวน ${
fee.value
} บาท ประกอบไปดวย าธรรมเนยมสอบ จำนวน ${
fee.value > 30 ? fee.value - 30 : "..."
} บาท และคาธรรมเนยมธนาคารรวมคาบรการอนเทอรเนตจำนวน ${
fee.value > 30 ? "30" : "..."
} บาท โดยคาธรรมเนยมดงกลาวจะไมายคนใหไมากรณใดๆ งส`;
2024-09-17 15:56:06 +07:00
}
});
pay.value;
watch(
() => ({ datePayment: datePayment.value, pay: pay.value }),
({ datePayment, pay }) => {
if (datePayment) {
reason.value = `โปรดนำแบบฟอร์มการชำระเงินฉบับนี้ พร้อมเงินสดไปยื่นขำระเงินที่เคาน์เตอร์ บมจ.ธนาคารกรุงไทย
ไดกสาขาทวประเทศ งแตนท ${dateThaiRange(
datePayment
)} ภายในวนเวลาทำการของธนาคาร
หรอผานระบบ Internet payment (Krungthai NEXT/เปาต) ตลอด 24 วโมง
งแตนท ${date2Thai(
datePayment[0]
)} เปดชำระเง เวลา 08.30 . ${date2Thai(
datePayment[1]
)} ดชำระเงนเวลา 22.00 .
`;
}
if (pay == "payment1" && datePayment == null) {
reason.value = `โปรดนำแบบฟอร์มการชำระเงินฉบับนี้ พร้อมเงินสดไปยื่นขำระเงินที่เคาน์เตอร์ บมจ.ธนาคารกรุงไทย
ไดกสาขาทวประเทศ งแตนท ... ... ภายในวนเวลาทำการของธนาคาร
หรอผานระบบ Internet payment (Krungthai NEXT/เปาต) ตลอด 24 วโมง
งแตนท ... เปดชำระเง เวลา ... . ... ดชำระเงนเวลา ... .
`;
}
}
);
2024-09-17 15:56:06 +07:00
onMounted(async () => {
hideLoader();
if (route.params.id != undefined) {
edit.value = true;
id.value = route.params.id.toString();
await fetchData();
} else {
pay.value = "";
edit.value = false;
}
await fetchPositionType();
2024-09-17 15:56:06 +07:00
});
</script>
<template>
<div class="toptitle text-dark col-12 row items-center">
<q-btn
icon="mdi-arrow-left"
unelevated
round
dense
flat
color="primary"
class="q-mr-sm"
@click="clickBack"
/>
2024-09-23 13:40:03 +07:00
{{
checkRoutePermisson
? "รายละเอียด"
: edit
? `แก้ไขรอบ`
: "เพิ่มรอบคัดเลือก"
}}
2024-09-17 15:56:06 +07:00
{{
edit && announcementExam
? `${name} ครั้งที่ ${roundRaw}/${
yearlyRaw == null ? "" : yearlyRaw + 543
}`
: ""
}}
</div>
<q-card flat bordered class="col-12 q-my-sm q-pt-sm">
<q-form ref="myForm">
<q-card-section class="q-pa-md">
<div class="col-xs-12 col-sm-8 items-top q-pb-md">
<q-toggle
v-model="announcementExam"
:false-value="true"
:true-value="false"
color="primary"
label="ประกาศข่าวทั่วไป"
v-if="!edit"
/>
</div>
<div class="col-12 row items-top q-col-gutter-x-sm">
<div class="col-xs-12 col-sm-6 col-sm-5">
<q-input
outlined
v-model="name"
label="ชื่อรอบคัดเลือก/ชื่อประกาศ"
dense
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
lazy-rules
:rules="[
2024-11-21 16:58:49 +07:00
(val:string) => !!val || `${'กรุณากรอกชื่อรอบคัดเลือก/ชื่อประกาศ'}`,
2024-09-17 15:56:06 +07:00
]"
></q-input>
</div>
<div class="col-xs-12 col-sm-4 col-md-1" v-if="announcementExam">
<q-input
outlined
v-model="round"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
type="number"
label="รอบการสอบ(ครั้ง)"
dense
lazy-rules
2024-09-20 15:23:06 +07:00
:rules="[(val:number) => val > 0 || `${'กรุณากรอกรอบการสอบให้ถูกต้อง'}`]"
2024-09-17 15:56:06 +07:00
></q-input>
</div>
<div class="col-xs-12 col-sm-4 col-md-1" v-if="announcementExam">
<q-input
outlined
v-model="fee"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
type="number"
label="ค่าธรรมเนียม"
dense
lazy-rules
input-class="text-right"
:rules="[
2024-09-20 15:23:06 +07:00
(val:number) => val >= 0 || `${'กรุณากรอกค่าธรรมเนียมให้ถูกต้อง'}`,
2024-09-17 15:56:06 +07:00
]"
></q-input>
</div>
<div class="col-xs-12 col-sm-4 col-md-1" v-if="announcementExam">
<datepicker
v-model="yearly"
:locale="'th'"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
autoApply
year-picker
:enableTimePicker="false"
@update:modelValue="updateYear"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
outlined
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
:model-value="yearly + 543"
2025-11-14 15:41:25 +07:00
:rules="[(val:string) => !!val || `${'กรุณาเลือกปี พ.ศ.'}`]"
:label="`${'ปี พ.ศ.'}`"
2024-09-17 15:56:06 +07:00
>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-12 col-sm-3 col-md-3" v-if="announcementExam">
<datepicker
v-model="dateExam"
:locale="'th'"
autoApply
borderless
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
:enableTimePicker="false"
week-start="0"
2025-11-17 17:08:32 +07:00
hide-bottom-space
2024-09-17 15:56:06 +07:00
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
dense
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
class="full-width datepicker q-mb-md"
:model-value="dateExam != null ? date2Thai(dateExam) : null"
:label="`${'วันที่สอบ'}`"
clearable
@clear="clearDateExam"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-12 col-sm-3 col-md-3">
<datepicker
v-model="dateAnnouncement"
:locale="'th'"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
autoApply
borderless
range
:enableTimePicker="false"
week-start="0"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
dense
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
class="full-width datepicker q-mb-md"
:model-value="dateThaiRange(dateAnnouncement)"
:label="`${'วันที่ประกาศ'}`"
2024-09-20 15:23:06 +07:00
:rules="[(val:string) => !!val || `${'กรุณาเลือกวันที่ประกาศ'}`]"
2025-11-17 17:08:32 +07:00
hide-bottom-space
2024-09-17 15:56:06 +07:00
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-12 col-sm-3 col-md-3" v-if="announcementExam">
<datepicker
v-model="dateRegister"
:locale="'th'"
autoApply
clearValue
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
borderless
range
week-start="0"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
dense
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
class="full-width datepicker q-mb-md"
:model-value="dateThaiRange(dateRegister)"
:label="`${'วันที่สมัคร'}`"
clearable
@clear="clearDateRegister"
2025-11-17 17:08:32 +07:00
hide-bottom-space
2024-09-17 15:56:06 +07:00
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div
class="col-xs-12 col-sm-3 col-md-3"
2025-11-20 13:37:29 +07:00
v-if="shouldShowPaymentFields"
2024-09-17 15:56:06 +07:00
>
<datepicker
v-model="datePayment"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
:locale="'th'"
autoApply
borderless
range
:enableTimePicker="false"
week-start="0"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
outlined
dense
class="full-width datepicker q-mb-md"
:model-value="dateThaiRange(datePayment)"
2025-11-06 14:43:52 +07:00
:rules="[(val:string) => !!val || `${'กรุณาเลือกวันที่ชำระเงิน'}`]"
2024-09-17 15:56:06 +07:00
:label="`${'วันที่ชำระเงิน'}`"
clearable
@clear="clearDatePayment"
2025-11-17 17:08:32 +07:00
hide-bottom-space
2024-09-17 15:56:06 +07:00
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-12 col-sm-3 col-md-3" v-if="announcementExam">
<datepicker
v-model="dateAnnounce"
:locale="'th'"
autoApply
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
borderless
:enableTimePicker="false"
week-start="0"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
dense
class="full-width datepicker q-mb-md"
:model-value="
dateAnnounce != null ? date2Thai(dateAnnounce) : null
"
:label="`${'วันประกาศผลสอบ'}`"
clearable
@clear="clearDateAnnounce"
2025-11-17 17:08:32 +07:00
hide-bottom-space
2024-09-17 15:56:06 +07:00
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
2025-11-17 17:08:32 +07:00
<div class="row col-12" v-if="announcementExam">
<div class="col-xs-12 col-md-2">
<q-input
outlined
v-model="graduationYearLock"
label="ล็อกวันที่สำเร็จการศึกษา (ปี)"
dense
:readonly="checkRoutePermisson"
lazy-rules
:rules="[
(val:string) => !!val || `${'กรุณากรอกล็อกวันที่สำเร็จการศึกษา (ปี)'}`,
]"
type="number"
></q-input>
</div>
</div>
2025-11-07 10:48:42 +07:00
2024-09-17 15:56:06 +07:00
<div class="col-12" v-if="announcementExam">
<div class="col-12 q-mb-sm">
<q-separator size="5px" color="grey-2" />
</div>
<q-form ref="myFormPosition">
<ProfileTable
:rows="rowsPosition"
:columns="columnsPosition"
:filter="filterPosition"
:visible-columns="visibleColumnsPosition"
v-model:inputfilter="filterPosition"
v-model:inputvisible="visibleColumnsPosition"
:add="clickAddPosition"
name="ตำแหน่ง"
icon=""
:statusEdit="false"
:headerShow="false"
:icon-left="true"
>
<template #columns="props">
<q-tr :props="props">
<q-td auto-width>
<q-btn
color="red"
flat
2024-09-23 13:40:03 +07:00
v-if="!checkRoutePermisson"
2024-09-17 15:56:06 +07:00
dense
round
size="14px"
icon="mdi-delete"
@click="clickDeletePosition(props.row)"
/>
</q-td>
<q-td key="code" :props="props">
<q-input
outlined
dense
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
lazy-rules
v-model="props.row.code"
:rules="[
(val:string) => !!val || `${'กรุณากรอกรหัสประจำตำแหน่งที่สอบ'}`,
(val:any) =>
val.length >= 3 ||
`${'กรุณากรอกรหัสประจำตำแหน่งที่สอบ'}`,
]"
:label="`${'รหัสประจำตำแหน่งที่สอบ'}`"
hide-bottom-space
mask="###"
/>
</q-td>
2025-11-19 15:57:22 +07:00
<q-td
key="highDegree"
:props="props"
class="q-col-gutter-sm"
>
2025-11-17 17:08:32 +07:00
<div class="col-12">
<q-radio
2025-11-19 11:55:43 +07:00
dense
2025-11-17 17:08:32 +07:00
v-model="props.row.highDegree"
label="ประเภททั่วไป"
color="teal"
:disable="checkRoutePermisson"
val="0"
@update:model-value="
onUpdateHighDegree(
props.row.highDegree,
props.rowIndex
)
"
/>
</div>
<div class="col-12">
<q-radio
2025-11-19 11:55:43 +07:00
dense
2025-11-17 17:08:32 +07:00
v-model="props.row.highDegree"
label="ประเภทวิชาการ"
color="teal"
:disable="checkRoutePermisson"
val="1"
@update:model-value="
onUpdateHighDegree(
props.row.highDegree,
props.rowIndex
)
"
/>
</div>
</q-td>
<q-td key="level" :props="props">
2024-09-17 15:56:06 +07:00
<selector
:disable="props.row.highDegree === ''"
2024-09-17 15:56:06 +07:00
class=""
outlined
use-input
v-model="props.row.level"
:readonly="checkRoutePermisson"
:options="
props.row.highDegree === '0'
? optionPosLevel1
: optionPosLevel2
"
2024-09-17 15:56:06 +07:00
option-value="id"
option-label="name"
input-debounce="0"
dense
hide-bottom-space
lazy-rules
:rules="[(val:any) => !!val || `${'กรุณาเลือกระดับ'}`]"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn, props.row.highDegree === '0' ? 'positionLevel1':'positionLevel2'
2024-09-17 15:56:06 +07:00
) "
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section>
<q-item-label>{{ scope.opt.name }}</q-item-label>
</q-item-section>
</q-item>
</template>
</selector>
</q-td>
<q-td key="position" :props="props">
2024-09-17 15:56:06 +07:00
<selector
:disable="props.row.highDegree === ''"
2024-09-17 15:56:06 +07:00
class=""
outlined
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
use-input
v-model="props.row.position"
:options="
props.row.highDegree === '0'
? optionPosType1
: optionPosType2
"
2024-09-17 15:56:06 +07:00
option-value="id"
option-label="name"
input-debounce="0"
dense
hide-bottom-space
lazy-rules
:rules="[(val:any) => !!val || `${'กรุณาเลือกตำแหน่ง'}`]"
@filter="(inputValue:string,
doneFn:Function) => filterSelector(inputValue, doneFn, props.row.highDegree === '0' ? 'position1' :'position2'
2024-09-17 15:56:06 +07:00
) "
>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section>
<q-item-label>{{ scope.opt.name }}</q-item-label>
</q-item-section>
</q-item>
</template>
</selector>
</q-td>
2025-11-19 15:57:22 +07:00
<q-td
key="educational"
:props="props"
class="q-col-gutter-sm"
>
2025-11-17 17:08:32 +07:00
<div class="col-12">
<q-radio
2025-11-19 11:55:43 +07:00
dense
2025-11-17 17:08:32 +07:00
v-model="props.row.educationLevel"
label="วุฒิปริญญาตรี"
color="teal"
:disable="checkRoutePermisson"
val="BACHELOR"
/>
</div>
<div class="col-12">
<q-radio
2025-11-19 11:55:43 +07:00
dense
2025-11-17 17:08:32 +07:00
v-model="props.row.educationLevel"
label="ต่ำกว่าปริญญาตรี"
color="teal"
:disable="checkRoutePermisson"
val="LOW_BACHELOR"
/>
</div>
</q-td>
2024-09-17 15:56:06 +07:00
<q-td key="type" :props="props">
<selector
class=""
outlined
v-model="props.row.type"
:options="examTypeOptions"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
option-value="id"
option-label="name"
dense
hide-bottom-space
lazy-rules
:rules="[(val:any) => !!val || `${'กรุณาเลือกประเภทแบบฟอร์ม'}`]"
></selector>
</q-td>
</q-tr>
</template>
</ProfileTable>
</q-form>
</div>
2025-11-20 13:37:29 +07:00
<div class="col-12" v-if="shouldShowPaymentFields">
2024-09-17 15:56:06 +07:00
<q-separator size="5px" color="grey-2" class="q-mt-lg" />
</div>
2025-11-20 10:14:39 +07:00
2025-11-20 13:37:29 +07:00
<div
class="col-12 q-mt-lg"
v-if="shouldShowPaymentFields"
>
2024-09-17 15:56:06 +07:00
<div class="text-bold text-subtitle2 q-pb-md">
เลอกวการชำระเง
</div>
<div class="row col-12 q-gutter-y-md q-mb-md">
<q-list dense bordered class="col-12 rounded-borders">
<q-item tag="label" v-ripple class="q-pa-md">
<q-radio
v-model="pay"
val="payment1"
color="blue"
class="q-mr-md"
2024-09-23 13:40:03 +07:00
:disable="fee <= 0 || checkRoutePermisson"
2024-09-17 15:56:06 +07:00
/>
<q-item-section avatar>
<q-avatar size="28px">
<q-img src="@/assets/krungthai.png" class="col-12" />
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label class="text-weight-medium text-subtitle1"
>ชำระเงนคาสมครสอบผานธนาคารกรงไทย</q-item-label
>
</q-item-section>
</q-item>
<q-slide-transition :duration="100">
<div v-show="pay == 'payment1'" class="q-py-sm bg-grey-1">
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-separator />
</div>
<div
class="col-12 text-weight-medium text-subtitle1 q-px-md"
>
รายละเอยดการชำระ
</div>
<div class="col-12">
<q-separator />
</div>
<div class="col-12">
<div class="row q-col-gutter-sm q-pa-sm">
<div class="col-12">
<q-input
label="ข้อความส่วนหัว"
outlined
dense
type="textarea"
rows="2"
:readonly="checkRoutePermisson"
bg-color="white"
v-model="remark"
:rules="[(val:string) => !!val || `${'กรุณากรอกข้อความส่วนหัว'}`]"
hide-bottom-space
>
</q-input>
</div>
<div class="col-6">
<q-input
label="Company Code"
outlined
dense
bg-color="white"
:readonly="checkRoutePermisson"
v-model="companyCode"
2025-11-07 11:17:24 +07:00
:rules="pay === 'payment1'?[(val:string) => !!val || `${'กรุณากรอก Company Code'}`]:[]"
hide-bottom-space
>
</q-input>
</div>
<div class="col-6">
<q-input
label="refNo1."
outlined
dense
bg-color="white"
:readonly="checkRoutePermisson"
v-model="refNo1"
2025-11-07 11:17:24 +07:00
:rules="pay === 'payment1' ? [(val:string) => !!val || `${'กรุณากรอก refNo1.'}`]:[]"
hide-bottom-space
>
</q-input>
</div>
<div class="col-12">
<q-input
label="หมายเหตุ"
outlined
dense
:readonly="checkRoutePermisson"
bg-color="white"
v-model="reason"
type="textarea"
rows="4"
>
</q-input>
</div>
<div class="row col-12 items-top q-col-gutter-x-sm">
<div class="col-xs-12 col-sm-6">
<div class="text-bold text-subtitle2 q-pb-sm">
ปโหลดบารโค
</div>
<div class="row justify-center row col-12">
<q-uploader
v-model="qrCodes"
color="gray"
type="file"
flat
:readonly="checkRoutePermisson"
ref="uploader"
class="full-width"
text-color="dark"
:max-size="10000000"
accept=".jpg,.png"
bordered
label="[ไฟล์ jpg,png ขนาดไม่เกิน 10MB]"
@removed="qrCodes = null"
@added="(v:any) => (qrCodes = v[0])"
>
<template v-slot:header="scope">
<div
class="row no-wrap items-center q-pa-sm q-gutter-xs text-white"
>
<q-btn
v-if="
scope.queuedFiles.length > 0 &&
!checkRoutePermisson
"
icon="clear_all"
@click="scope.removeQueuedFiles"
round
dense
flat
>
<q-tooltip>ลบทงหมด</q-tooltip>
</q-btn>
<q-btn
v-if="
scope.uploadedFiles.length > 0 &&
!checkRoutePermisson
"
icon="done_all"
@click="scope.removeUploadedFiles"
round
dense
flat
>
<q-tooltip>ลบไฟลปโหลด</q-tooltip>
</q-btn>
<q-spinner
v-if="scope.isUploading"
class="q-uploader__spinner"
/>
<div class="col">
<div class="q-uploader__title">
{{
"[ไฟล์ jpg,png ขนาดไม่เกิน 10MB]"
}}
</div>
<div class="q-uploader__subtitle">
{{ scope.uploadSizeLabel }}
/
{{ scope.uploadProgressLabel }}
</div>
</div>
<q-btn
v-if="
scope.canAddFiles &&
!checkRoutePermisson
"
type="a"
icon="add_box"
@click="scope.pickFiles"
round
dense
flat
>
<q-uploader-add-trigger />
<q-tooltip>เลอกไฟล</q-tooltip>
</q-btn>
<q-btn
v-if="
scope.isUploading &&
!checkRoutePermisson
"
icon="clear"
@click="scope.abort"
round
dense
flat
>
<q-tooltip>ยกเลกการอปโหลด</q-tooltip>
</q-btn>
</div>
</template>
</q-uploader>
</div>
<q-card
bordered
flat
class="full-width q-my-md"
v-if="qrCodesFile.length != 0"
>
<q-list separator>
<q-item
v-for="file in qrCodesFile"
:key="file.id"
class="q-my-xs"
>
<q-item-section>
<q-item-label class="full-width ellipsis">
{{ file.fileName }}
</q-item-label>
<q-item-label caption>
สถานะ: {{ file.fileType }} /
{{ file.fileSize }}
</q-item-label>
</q-item-section>
<q-item-section top side>
<div class="q-gutter-sm">
<q-btn
size="12px"
flat
dense
round
color="blue"
icon="mdi-download-outline"
@click="downloadData(file.detail)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
<q-btn
size="12px"
flat
dense
round
color="red"
icon="mdi-delete-outline"
v-if="edit && !checkRoutePermisson"
@click="deleteDocData(file.id)"
>
<q-tooltip>ลบไฟล</q-tooltip>
</q-btn>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
<div class="col-xs-12 col-sm-6">
<div class="text-bold text-subtitle2 q-pb-sm">
ปโหลดควอารโค
</div>
<div class="row justify-center row col-12">
<q-uploader
color="gray"
type="file"
flat
ref="uploader"
class="full-width"
:readonly="checkRoutePermisson"
text-color="dark"
:max-size="10000000"
accept=".jpg,.png"
bordered
label="[ไฟล์ jpg,png ขนาดไม่เกิน 10MB]"
@removed="barCodes = null"
@added="(v:any) => (barCodes = v[0])"
>
<template v-slot:header="scope">
<div
class="row no-wrap items-center q-pa-sm q-gutter-xs text-white"
>
<q-btn
v-if="
scope.queuedFiles.length > 0 &&
!checkRoutePermisson
"
icon="clear_all"
@click="scope.removeQueuedFiles"
round
dense
flat
>
<q-tooltip>ลบทงหมด</q-tooltip>
</q-btn>
<q-btn
v-if="
scope.uploadedFiles.length > 0 &&
!checkRoutePermisson
"
icon="done_all"
@click="scope.removeUploadedFiles"
round
dense
flat
>
<q-tooltip>ลบไฟลปโหลด</q-tooltip>
</q-btn>
<q-spinner
v-if="scope.isUploading"
class="q-uploader__spinner"
/>
<div class="col">
<div class="q-uploader__title">
{{
"[ไฟล์ jpg,png ขนาดไม่เกิน 10MB]"
}}
</div>
<div class="q-uploader__subtitle">
{{ scope.uploadSizeLabel }}
/
{{ scope.uploadProgressLabel }}
</div>
</div>
<q-btn
v-if="
scope.canAddFiles &&
!checkRoutePermisson
"
type="a"
icon="add_box"
@click="scope.pickFiles"
round
dense
flat
>
<q-uploader-add-trigger />
<q-tooltip>เลอกไฟล</q-tooltip>
</q-btn>
<q-btn
v-if="
scope.isUploading &&
!checkRoutePermisson
"
icon="clear"
@click="scope.abort"
round
dense
flat
>
<q-tooltip>ยกเลกการอปโหลด</q-tooltip>
</q-btn>
</div>
</template>
</q-uploader>
</div>
<q-card
bordered
flat
class="full-width q-my-md"
v-if="barCodesFile.length != 0"
>
<q-list separator>
<q-item
v-for="file in barCodesFile"
:key="file.id"
class="q-my-xs"
>
<q-item-section>
<q-item-label class="full-width ellipsis">
{{ file.fileName }}
</q-item-label>
<q-item-label caption>
สถานะ: {{ file.fileType }} /
{{ file.fileSize }}
</q-item-label>
</q-item-section>
<q-item-section top side>
<div class="q-gutter-sm">
<q-btn
size="12px"
flat
dense
round
color="blue"
icon="mdi-download-outline"
@click="downloadData(file.detail)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
<q-btn
size="12px"
flat
dense
round
color="red"
icon="mdi-delete-outline"
v-if="edit && !checkRoutePermisson"
@click="deleteDocData(file.id)"
>
<q-tooltip>ลบไฟล</q-tooltip>
</q-btn>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</div>
</div>
</div>
</div>
</q-slide-transition>
2024-09-17 15:56:06 +07:00
</q-list>
2023-06-19 15:50:50 +07:00
2024-09-17 15:56:06 +07:00
<q-list dense bordered class="col-12 rounded-borders">
<q-item tag="label" v-ripple class="q-py-lg">
<q-radio
v-model="pay"
val="payment2"
color="blue"
class="q-mr-md"
2024-09-23 13:40:03 +07:00
:disable="fee <= 0 || checkRoutePermisson"
2024-09-17 15:56:06 +07:00
/>
<q-item-section avatar>
<q-icon name="mdi-cash" color="positive" size="33px" />
</q-item-section>
<q-item-section>
<q-item-label class="text-weight-medium text-subtitle1"
>ชำระเงนคาสมครสอบผานสำน/หนวยงาน</q-item-label
>
</q-item-section>
</q-item>
<q-slide-transition :duration="100">
<div v-show="pay == 'payment2'" class="q-pa-sm bg-grey-1">
<q-form ref="myFormPayment">
<ProfileTable
:rows="rowsPayment"
:columns="columnsPayment"
:filter="filterPayment"
:visible-columns="visibleColumnsPayment"
v-model:inputfilter="filterPayment"
v-model:inputvisible="visibleColumnsPayment"
:add="clickAddPayment"
2024-09-23 13:40:03 +07:00
name="วิธีการชำระ"
2024-09-17 15:56:06 +07:00
icon=""
:statusEdit="false"
:headerShow="false"
>
<template #columns="props">
<q-tr :props="props">
<q-td key="accountNumber" :props="props">
<q-input
class=""
outlined
hide-bottom-space
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
v-model="props.row.accountNumber"
dense
lazy-rules
mask="###-#-#####-#"
:rules="[
2024-11-21 16:58:49 +07:00
(val:any) =>
2024-09-17 15:56:06 +07:00
(val && val.length > 0) ||
'กรุณากรอกข้อมูลให้ครบ',
]"
></q-input>
</q-td>
<q-td key="bankName" :props="props">
<q-input
class=""
outlined
hide-bottom-space
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
v-model="props.row.bankName"
dense
lazy-rules
:rules="[
2024-11-21 16:58:49 +07:00
(val:any) =>
2024-09-17 15:56:06 +07:00
(val && val.length > 0) ||
'กรุณากรอกข้อมูลให้ครบ',
]"
></q-input>
</q-td>
<q-td key="accountName" :props="props">
<q-input
class=""
outlined
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
hide-bottom-space
v-model="props.row.accountName"
dense
lazy-rules
:rules="[
2024-11-21 16:58:49 +07:00
(val:any) =>
2024-09-17 15:56:06 +07:00
(val && val.length > 0) ||
'กรุณากรอกข้อมูลให้ครบ',
]"
></q-input>
</q-td>
<q-td auto-width>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="!checkRoutePermisson"
2024-09-17 15:56:06 +07:00
color="red"
flat
dense
round
size="14px"
icon="mdi-delete"
@click="clickDeletePayment(props.row)"
/>
</q-td>
</q-tr>
</template>
</ProfileTable>
</q-form>
</div>
</q-slide-transition>
</q-list>
</div>
</div>
<div class="col-12" v-if="announcementExam">
<q-separator size="5px" color="grey-2" class="q-mt-md q-mb-lg" />
</div>
<div class="row col-12 items-top q-col-gutter-x-sm">
<div class="col-xs-12 col-sm-6">
<div class="text-bold text-subtitle2 q-pb-sm">ปภาพประกอบ</div>
<div class="row justify-center row col-12">
<q-uploader
color="gray"
type="file"
flat
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
ref="uploader"
class="full-width"
text-color="dark"
:max-size="10000000"
accept=".jpg,.png,.pdf,.csv,.doc,.docx"
bordered
label="[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
multiple
@added="fileUploadImg"
@removed="fileRemoveImg"
>
<template v-slot:header="scope">
<div
class="row no-wrap items-center q-pa-sm q-gutter-xs text-white"
>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="
scope.queuedFiles.length > 0 && !checkRoutePermisson
"
2024-09-17 15:56:06 +07:00
icon="clear_all"
@click="scope.removeQueuedFiles"
round
dense
flat
>
<q-tooltip>ลบทงหมด</q-tooltip>
</q-btn>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="
scope.uploadedFiles.length > 0 && !checkRoutePermisson
"
2024-09-17 15:56:06 +07:00
icon="done_all"
@click="scope.removeUploadedFiles"
round
dense
flat
>
<q-tooltip>ลบไฟลปโหลด</q-tooltip>
</q-btn>
<q-spinner
v-if="scope.isUploading"
class="q-uploader__spinner"
/>
<div class="col">
<div class="q-uploader__title">
{{
"[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
}}
</div>
<div class="q-uploader__subtitle">
{{ scope.uploadSizeLabel }}
/
{{ scope.uploadProgressLabel }}
</div>
</div>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="scope.canAddFiles && !checkRoutePermisson"
2024-09-17 15:56:06 +07:00
type="a"
icon="add_box"
@click="scope.pickFiles"
round
dense
flat
>
<q-uploader-add-trigger />
<q-tooltip>เลอกไฟล</q-tooltip>
</q-btn>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="scope.isUploading && !checkRoutePermisson"
2024-09-17 15:56:06 +07:00
icon="clear"
@click="scope.abort"
round
dense
flat
>
<q-tooltip>ยกเลกการอปโหลด</q-tooltip>
</q-btn>
</div>
</template>
</q-uploader>
</div>
<q-card
bordered
flat
class="full-width q-my-md"
v-if="fileImgs.length != 0"
>
<q-list separator>
<q-item
v-for="file in fileImgs"
:key="file.id"
class="q-my-xs"
>
<q-item-section>
<q-item-label class="full-width ellipsis">
{{ file.fileName }}
</q-item-label>
2023-06-19 15:50:50 +07:00
2024-09-17 15:56:06 +07:00
<q-item-label caption>
สถานะ: {{ file.fileType }} /
{{ file.fileSize }}
</q-item-label>
</q-item-section>
<q-item-section top side>
<div class="q-gutter-sm">
<q-btn
size="12px"
flat
dense
round
color="blue"
icon="mdi-download-outline"
@click="downloadData(file.detail)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
<q-btn
size="12px"
flat
dense
round
color="red"
icon="mdi-delete-outline"
2024-09-23 13:40:03 +07:00
v-if="edit && !checkRoutePermisson"
2024-09-17 15:56:06 +07:00
@click="deleteDocData(file.id)"
>
<q-tooltip>ลบไฟล</q-tooltip>
</q-btn>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
<div class="col-xs-12 col-sm-6">
<div class="text-bold text-subtitle2 q-pb-sm">เอกสารประกอบ</div>
<div class="row justify-center row col-12">
<q-uploader
color="gray"
type="file"
flat
ref="uploader"
class="full-width"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
text-color="dark"
:max-size="10000000"
accept=".jpg,.png,.pdf,.csv,.doc,.docx"
bordered
label="[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
multiple
@added="fileUploadDoc"
@removed="fileRemoveDoc"
>
<template v-slot:header="scope">
<div
class="row no-wrap items-center q-pa-sm q-gutter-xs text-white"
>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="
scope.queuedFiles.length > 0 && !checkRoutePermisson
"
2024-09-17 15:56:06 +07:00
icon="clear_all"
@click="scope.removeQueuedFiles"
round
dense
flat
>
<q-tooltip>ลบทงหมด</q-tooltip>
</q-btn>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="
scope.uploadedFiles.length > 0 && !checkRoutePermisson
"
2024-09-17 15:56:06 +07:00
icon="done_all"
@click="scope.removeUploadedFiles"
round
dense
flat
>
<q-tooltip>ลบไฟลปโหลด</q-tooltip>
</q-btn>
<q-spinner
v-if="scope.isUploading"
class="q-uploader__spinner"
/>
<div class="col">
<div class="q-uploader__title">
{{
"[ไฟล์ jpg,png,pdf,csv,doc,docx ขนาดไม่เกิน 10MB]"
}}
</div>
<div class="q-uploader__subtitle">
{{ scope.uploadSizeLabel }}
/
{{ scope.uploadProgressLabel }}
</div>
</div>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="scope.canAddFiles && !checkRoutePermisson"
2024-09-17 15:56:06 +07:00
type="a"
icon="add_box"
@click="scope.pickFiles"
round
dense
flat
>
<q-uploader-add-trigger />
<q-tooltip>เลอกไฟล</q-tooltip>
</q-btn>
<q-btn
2024-09-23 13:40:03 +07:00
v-if="scope.isUploading && !checkRoutePermisson"
2024-09-17 15:56:06 +07:00
icon="clear"
@click="scope.abort"
round
dense
flat
>
<q-tooltip>ยกเลกการอปโหลด</q-tooltip>
</q-btn>
</div>
</template>
</q-uploader>
</div>
<q-card
bordered
flat
class="full-width q-my-md"
v-if="fileDocs.length != 0"
>
<q-list separator>
<q-item
v-for="file in fileDocs"
:key="file.id"
class="q-my-xs"
>
<q-item-section>
<q-item-label class="full-width ellipsis">
{{ file.fileName }}
</q-item-label>
2023-06-19 15:50:50 +07:00
2024-09-17 15:56:06 +07:00
<q-item-label caption>
สถานะ: {{ file.fileType }} /
{{ file.fileSize }}
</q-item-label>
</q-item-section>
<q-item-section top side>
<div class="q-gutter-sm">
<q-btn
size="12px"
flat
dense
round
color="blue"
icon="mdi-download-outline"
@click="downloadData(file.detail)"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
<q-btn
size="12px"
flat
dense
round
color="red"
icon="mdi-delete-outline"
2024-09-23 13:40:03 +07:00
v-if="edit && !checkRoutePermisson"
2024-09-17 15:56:06 +07:00
@click="deleteDocData(file.id)"
>
<q-tooltip>ลบไฟล</q-tooltip>
</q-btn>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
<div class="col-12">
<q-separator size="5px" color="grey-2" class="q-my-lg" />
</div>
<div class="col-12">
<div class="text-bold text-subtitle2 q-pb-sm">รายละเอยด</div>
<q-editor
v-model="editor"
:dense="$q.screen.lt.md"
toolbar-text-color="blue-grey-10"
toolbar-bg="blue-grey-2"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
toolbar-toggle-color="blue-grey-8"
class="editor"
:toolbar="[
['left', 'center', 'right', 'justify'],
[
'bold',
'italic',
'strike',
'underline',
'subscript',
'superscript',
],
['token', 'hr', 'link', 'custom_btn'],
['print', 'fullscreen'],
[
{
label: $q.lang.editor.formatting,
icon: $q.iconSet.editor.formatting,
list: 'no-icons',
options: ['p', 'h1', 'h2', 'h3'],
},
{
label: $q.lang.editor.defaultFont,
icon: $q.iconSet.editor.font,
fixedIcon: true,
list: 'no-icons',
options: [
'default_font',
'arial',
'arial_black',
'comic_sans',
'courier_new',
'impact',
'lucida_grande',
'times_new_roman',
'verdana',
],
},
'removeFormat',
],
['undo', 'redo'],
['viewsource'],
]"
:fonts="{
arial: 'Arial',
arial_black: 'Arial Black',
comic_sans: 'Comic Sans MS',
courier_new: 'Courier New',
impact: 'Impact',
lucida_grande: 'Lucida Grande',
times_new_roman: 'Times New Roman',
verdana: 'Verdana',
}"
/>
</div>
<div class="col-12 q-mt-md">
<q-input
outlined
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
v-model="note"
label="หมายเหตุ"
dense
lazy-rules
type="textarea"
/>
</div>
<div class="col-12" v-if="announcementExam">
<q-separator size="5px" color="grey-2" class="q-my-lg" />
</div>
<div class="col-12" v-if="announcementExam">
<div class="text-bold text-subtitle2 q-pb-sm">
อกำหนดและเงอนไข
</div>
<q-editor
v-model="editorCondition"
:dense="$q.screen.lt.md"
toolbar-text-color="blue-grey-10"
toolbar-bg="blue-grey-2"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
toolbar-toggle-color="blue-grey-8"
class="editor"
:toolbar="[
['left', 'center', 'right', 'justify'],
[
'bold',
'italic',
'strike',
'underline',
'subscript',
'superscript',
],
['token', 'hr', 'link', 'custom_btn'],
['print', 'fullscreen'],
[
{
label: $q.lang.editor.formatting,
icon: $q.iconSet.editor.formatting,
list: 'no-icons',
options: ['p', 'h1', 'h2', 'h3'],
},
{
label: $q.lang.editor.defaultFont,
icon: $q.iconSet.editor.font,
fixedIcon: true,
list: 'no-icons',
options: [
'default_font',
'arial',
'arial_black',
'comic_sans',
'courier_new',
'impact',
'lucida_grande',
'times_new_roman',
'verdana',
],
},
'removeFormat',
],
['undo', 'redo'],
['viewsource'],
]"
:fonts="{
arial: 'Arial',
arial_black: 'Arial Black',
comic_sans: 'Comic Sans MS',
courier_new: 'Courier New',
impact: 'Impact',
lucida_grande: 'Lucida Grande',
times_new_roman: 'Times New Roman',
verdana: 'Verdana',
}"
/>
</div>
<div class="col-12" v-if="announcementExam">
<q-separator size="5px" color="grey-2" class="q-my-lg" />
</div>
<div class="col-12" v-if="announcementExam">
<div class="text-bold text-subtitle2 q-pb-sm">คำรบรอง</div>
<q-editor
v-model="editorConfirm"
:dense="$q.screen.lt.md"
toolbar-text-color="blue-grey-10"
2024-09-23 13:40:03 +07:00
:readonly="checkRoutePermisson"
2024-09-17 15:56:06 +07:00
toolbar-bg="blue-grey-2"
toolbar-toggle-color="blue-grey-8"
class="editor"
:toolbar="[
['left', 'center', 'right', 'justify'],
[
'bold',
'italic',
'strike',
'underline',
'subscript',
'superscript',
],
['token', 'hr', 'link', 'custom_btn'],
['print', 'fullscreen'],
[
{
label: $q.lang.editor.formatting,
icon: $q.iconSet.editor.formatting,
list: 'no-icons',
options: ['p', 'h1', 'h2', 'h3'],
},
{
label: $q.lang.editor.defaultFont,
icon: $q.iconSet.editor.font,
fixedIcon: true,
list: 'no-icons',
options: [
'default_font',
'arial',
'arial_black',
'comic_sans',
'courier_new',
'impact',
'lucida_grande',
'times_new_roman',
'verdana',
],
},
'removeFormat',
],
['undo', 'redo'],
['viewsource'],
]"
:fonts="{
arial: 'Arial',
arial_black: 'Arial Black',
comic_sans: 'Comic Sans MS',
courier_new: 'Courier New',
impact: 'Impact',
lucida_grande: 'Lucida Grande',
times_new_roman: 'Times New Roman',
verdana: 'Verdana',
}"
/>
</div>
</div>
</q-card-section>
2024-09-23 13:40:03 +07:00
<q-separator v-if="!checkRoutePermisson" />
2024-09-17 15:56:06 +07:00
<q-card-actions class="text-primary q-py-sm">
<q-space />
<q-btn
2024-09-23 13:40:03 +07:00
v-if="!checkRoutePermisson"
2024-09-17 15:56:06 +07:00
flat
round
color="public"
@click="checkSave"
icon="mdi-content-save-outline"
>
<q-tooltip>{{ edit ? "แก้ไขข้อมูล" : "บันทึกข้อมูล" }}</q-tooltip>
</q-btn>
</q-card-actions>
</q-form>
</q-card>
</template>
2023-06-01 12:54:58 +07:00
<style></style>