Merge branch 'develop' into dev

* develop:
  fix:status
  fix
This commit is contained in:
Warunee Tamkoo 2025-11-19 17:12:37 +07:00
commit e15d8b030e
9 changed files with 201 additions and 27 deletions

View file

@ -91,4 +91,6 @@ export default {
exportExamCandidateList: (id: string) => `${exam_report}candidate-exam/${id}`, exportExamCandidateList: (id: string) => `${exam_report}candidate-exam/${id}`,
exportExamPassExamList: (id: string) => `${exam_report}pass-exam/${id}`, exportExamPassExamList: (id: string) => `${exam_report}pass-exam/${id}`,
periodExamToPlacement: (examId: string) => `${periodExam}placement/${examId}`, periodExamToPlacement: (examId: string) => `${periodExam}placement/${examId}`,
checkShowExaminfo: `${candidate}check-showExamInfo`,
}; };

View file

@ -60,6 +60,7 @@ const fetchData = async () => {
const data = res.data.result; const data = res.data.result;
if (data != null) { if (data != null) {
defaultContact.value.contactPrefixId = data.contactPrefixId; defaultContact.value.contactPrefixId = data.contactPrefixId;
defaultContact.value.contactPrefixName = data.contactPrefix;
defaultContact.value.contactFirstname = data.contactFirstname; defaultContact.value.contactFirstname = data.contactFirstname;
defaultContact.value.contactLastname = data.contactLastname; defaultContact.value.contactLastname = data.contactLastname;
defaultContact.value.contactRelations = data.contactRelations; defaultContact.value.contactRelations = data.contactRelations;
@ -78,6 +79,25 @@ const getClass = (val: boolean) => {
"full-width cursor-pointer": !val, "full-width cursor-pointer": !val,
}; };
}; };
const filteredPrefixOptions = ref<string[]>([]);
const filterPrefix = (val: string, update: (fn: () => void) => void) => {
update(() => {
if (val === "") {
filteredPrefixOptions.value = [];
} else {
const needle = val.toLowerCase();
filteredPrefixOptions.value = props.prefixOptions
.filter((v) => v.name.toLowerCase().indexOf(needle) > -1)
.map((v) => v.name);
}
});
};
const setModel = (val: string) => {
defaultContact.value.contactPrefixName = val;
};
</script> </script>
<template> <template>
@ -92,7 +112,7 @@ const getClass = (val: boolean) => {
<q-form ref="myform"> <q-form ref="myform">
<div class="row col-12 items-center q-col-gutter-x-sm q-col-gutter-y-xs"> <div class="row col-12 items-center q-col-gutter-x-sm q-col-gutter-y-xs">
<div class="col-xs-12 col-sm-3 col-md-2"> <div class="col-xs-12 col-sm-3 col-md-2">
<q-select <!-- <q-select
:class="getClass(status == 'checkRegister' || status == 'payment')" :class="getClass(status == 'checkRegister' || status == 'payment')"
:readonly="!(status == 'checkRegister' || status == 'payment')" :readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')" :borderless="!(status == 'checkRegister' || status == 'payment')"
@ -107,6 +127,25 @@ const getClass = (val: boolean) => {
:options="prefixOptions" :options="prefixOptions"
option-value="id" option-value="id"
:label="`${'คำนำหน้า'}`" :label="`${'คำนำหน้า'}`"
/> -->
<q-select
:class="getClass(status == 'checkRegister' || status == 'payment')"
:readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')"
:rules="[(val:string) => !!val || `${'กรุณาเลือก คำนำหน้า'}`]"
:outlined="status == 'checkRegister' || status == 'payment'"
dense
lazy-rules
v-model="defaultContact.contactPrefixName"
:label="`${'คำนำหน้า'}`"
:options="filteredPrefixOptions"
use-input
fill-input
input-debounce="0"
@filter="filterPrefix"
@input-value="setModel"
hide-selected
hide-dropdown-icon
/> />
</div> </div>
<div class="col-xs-12 col-sm-3 col-md-3"> <div class="col-xs-12 col-sm-3 col-md-3">
@ -165,8 +204,8 @@ const getClass = (val: boolean) => {
v-model="defaultContact.contactTel" v-model="defaultContact.contactTel"
:label="`${'โทรศัพท์'}`" :label="`${'โทรศัพท์'}`"
:rules="[ :rules="[
(val) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์', (val: string) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์',
(val) => (val: string) =>
(val.length >= 9 && val.length <= 10 && val.startsWith('0')) || (val.length >= 9 && val.length <= 10 && val.startsWith('0')) ||
'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง', 'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง',
]" ]"

View file

@ -67,6 +67,7 @@ async function fetchData() {
.get(config.API.candidateInformation(candidateId.value)) .get(config.API.candidateInformation(candidateId.value))
.then((res) => { .then((res) => {
const data = res.data.result; const data = res.data.result;
defaultInformation.value.prefix = data.prefix;
defaultInformation.value.prefixId = data.prefixId; defaultInformation.value.prefixId = data.prefixId;
defaultInformation.value.lastname = data.lastName; defaultInformation.value.lastname = data.lastName;
defaultInformation.value.provinceId = data.citizenProvinceId; defaultInformation.value.provinceId = data.citizenProvinceId;
@ -78,6 +79,7 @@ async function fetchData() {
defaultInformation.value.cardid = data.citizenId; defaultInformation.value.cardid = data.citizenId;
defaultInformation.value.firstname = data.firstName; defaultInformation.value.firstname = data.firstName;
defaultInformation.value.religionId = data.religionId; defaultInformation.value.religionId = data.religionId;
defaultInformation.value.religionName = data.religion;
defaultInformation.value.nationality = data.nationality; defaultInformation.value.nationality = data.nationality;
defaultInformation.value.email = data.email; defaultInformation.value.email = data.email;
defaultInformation.value.phone = data.mobilePhone; defaultInformation.value.phone = data.mobilePhone;
@ -164,6 +166,44 @@ function getClass(val: boolean) {
}; };
} }
const filteredPrefixOptions = ref<string[]>([]);
const filterPrefix = (val: string, update: (fn: () => void) => void) => {
update(() => {
if (val === "") {
filteredPrefixOptions.value = [];
} else {
const needle = val.toLowerCase();
filteredPrefixOptions.value = props.prefixOptions
.filter((v) => v.name.toLowerCase().indexOf(needle) > -1)
.map((v) => v.name);
}
});
};
const setModel = (val: string) => {
defaultInformation.value.prefix = val;
};
const filteredReligionOptions = ref<string[]>([]);
const filterReligion = (val: string, update: (fn: () => void) => void) => {
update(() => {
if (val === "") {
filteredReligionOptions.value = [];
} else {
const needle = val.toLowerCase();
filteredReligionOptions.value = props.religionOptions
.filter((v) => v.name.toLowerCase().indexOf(needle) > -1)
.map((v) => v.name);
}
});
};
const setModelReligionId = (val: string) => {
defaultInformation.value.religionName = val;
};
watch(myform, async (count: any) => { watch(myform, async (count: any) => {
emit("update:form", count); emit("update:form", count);
}); });
@ -222,7 +262,7 @@ onMounted(async () => {
/> />
</div> </div>
<div class="col-xs-12 col-sm-2 col-md-2"> <div class="col-xs-12 col-sm-2 col-md-2">
<q-select <!-- <q-select
:class="getClass(status == 'checkRegister' || status == 'payment')" :class="getClass(status == 'checkRegister' || status == 'payment')"
:readonly="!(status == 'checkRegister' || status == 'payment')" :readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')" :borderless="!(status == 'checkRegister' || status == 'payment')"
@ -237,6 +277,25 @@ onMounted(async () => {
:options="prefixOptions" :options="prefixOptions"
option-value="id" option-value="id"
:label="`${'คำนำหน้าชื่อ'}`" :label="`${'คำนำหน้าชื่อ'}`"
/> -->
<q-select
:class="getClass(status == 'checkRegister' || status == 'payment')"
:readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')"
:rules="[(val:string) => !!val || `${'กรุณากรอก คำนำหน้าชื่อ'}`]"
:outlined="status == 'checkRegister' || status == 'payment'"
dense
lazy-rules
v-model="defaultInformation.prefix"
:label="`${'คำนำหน้า'}`"
:options="filteredPrefixOptions"
use-input
fill-input
input-debounce="0"
@filter="filterPrefix"
@input-value="setModel"
hide-selected
hide-dropdown-icon
/> />
</div> </div>
<div class="col-xs-12 col-sm-3 col-md-3"> <div class="col-xs-12 col-sm-3 col-md-3">
@ -280,7 +339,7 @@ onMounted(async () => {
/> />
</div> </div>
<div class="col-xs-12 col-sm-3 col-md-3"> <div class="col-xs-12 col-sm-3 col-md-3">
<q-select <!-- <q-select
:class="getClass(status == 'checkRegister' || status == 'payment')" :class="getClass(status == 'checkRegister' || status == 'payment')"
:readonly="!(status == 'checkRegister' || status == 'payment')" :readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')" :borderless="!(status == 'checkRegister' || status == 'payment')"
@ -295,6 +354,25 @@ onMounted(async () => {
:options="religionOptions" :options="religionOptions"
option-value="id" option-value="id"
:label="`${'ศาสนา'}`" :label="`${'ศาสนา'}`"
/> -->
<q-select
:class="getClass(status == 'checkRegister' || status == 'payment')"
:readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')"
:rules="[(val:string) => !!val || `${'กรุณากรอก ศาสนา'}`]"
:outlined="status == 'checkRegister' || status == 'payment'"
dense
lazy-rules
v-model="defaultInformation.religionName"
:label="`${'ศาสนา'}`"
:options="filteredReligionOptions"
use-input
fill-input
input-debounce="0"
@filter="filterReligion"
@input-value="setModelReligionId"
hide-selected
hide-dropdown-icon
/> />
</div> </div>
<div class="col-xs-12 col-sm-3 col-md-3"> <div class="col-xs-12 col-sm-3 col-md-3">

View file

@ -191,25 +191,24 @@ onMounted(async () => {
:class="getClass(status == 'checkRegister' || status == 'payment')" :class="getClass(status == 'checkRegister' || status == 'payment')"
:outlined="status == 'checkRegister' || status == 'payment'" :outlined="status == 'checkRegister' || status == 'payment'"
dense dense
:counter="
status == 'checkRegister' || status == 'payment' ? true : false
"
maxlength="10"
lazy-rules lazy-rules
type="tel"
mask="##########"
autogrow autogrow
:readonly="!(status == 'checkRegister' || status == 'payment')" :readonly="!(status == 'checkRegister' || status == 'payment')"
:borderless="!(status == 'checkRegister' || status == 'payment')" :borderless="!(status == 'checkRegister' || status == 'payment')"
v-model="defaultOccupation.tel" v-model="defaultOccupation.tel"
:rules="[ :rules="[(val:string) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์']"
(val) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์',
(val) =>
(val.length >= 9 && val.length <= 10 && val.startsWith('0')) ||
'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง',
]"
:label="`${'เบอร์โทรที่ทำงาน'}`" :label="`${'เบอร์โทรที่ทำงาน'}`"
maxlength="20"
/> />
<!-- (val) => (val.length >= 9 && val.length <= 10 && val.startsWith('0'))
|| 'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง', -->
<!-- :counter="
status == 'checkRegister' || status == 'payment' ? true : false
" -->
<!-- maxlength="10" -->
<!-- type="tel" -->
<!-- mask="##########" -->
</div> </div>
</div> </div>
</div> </div>

View file

@ -27,6 +27,7 @@ const selected = ref<string[]>([]);
const { messageError, showLoader, hideLoader } = mixin; const { messageError, showLoader, hideLoader } = mixin;
const dateFilter = ref<[Date, Date]>([new Date(), new Date()]); // const dateFilter = ref<[Date, Date]>([new Date(), new Date()]); //
const isFee = defineModel<boolean>("isFee");
const props = defineProps({ const props = defineProps({
inputfilter: String, inputfilter: String,
inputvisible: Array, inputvisible: Array,
@ -393,6 +394,20 @@ async function clickCandidateList() {
}); });
} }
async function onCheckShowExaminfo() {
try {
showLoader();
await http.post(config.API.checkShowExaminfo, {
examId: examId.value,
});
await props.fetchData();
} catch (error) {
messageError($q, error);
} finally {
hideLoader();
}
}
// Pagination - page & change page & get new data // Pagination - page & change page & get new data
const currentPage = ref<number>(1); const currentPage = ref<number>(1);
watch( watch(
@ -479,7 +494,7 @@ watch(
v-if="optionsFilter != undefined && optionsFilter.length > 0" v-if="optionsFilter != undefined && optionsFilter.length > 0"
/> />
</div> </div>
<div> <div v-if="isFee">
<q-btn <q-btn
v-if="checkPermission($route)?.attrIsUpdate" v-if="checkPermission($route)?.attrIsUpdate"
size="md" size="md"
@ -495,6 +510,21 @@ watch(
<q-tooltip>ตรวจสอบขอม/ไดบใบสมครแล</q-tooltip> <q-tooltip>ตรวจสอบขอม/ไดบใบสมครแล</q-tooltip>
</q-btn> </q-btn>
</div> </div>
<div>
<q-btn
v-if="checkPermission($route)?.attrIsUpdate"
size="md"
icon="mdi-eye-check"
round
flat
color="info"
@click="onCheckShowExaminfo"
>
<q-tooltip
>เปดใหดาวนโหลดใบสมคร แสดงสถานทสอบ และเลขประจำตวสอบ</q-tooltip
>
</q-btn>
</div>
<div> <div>
<q-btn icon="mdi-download" round color="green-6" flat> <q-btn icon="mdi-download" round color="green-6" flat>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip> <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
@ -623,7 +653,10 @@ watch(
</template> </template>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th auto-width v-if="checkPermission($route)?.attrIsUpdate"> <q-th
auto-width
v-if="checkPermission($route)?.attrIsUpdate && isFee"
>
<q-checkbox v-model="props.selected" /> <q-checkbox v-model="props.selected" />
</q-th> </q-th>
<q-th auto-width v-if="boss == true" /> <q-th auto-width v-if="boss == true" />

View file

@ -44,6 +44,8 @@ interface Information {
statusId: string | null; statusId: string | null;
knowledge: string | null; knowledge: string | null;
profileImg: string | null; profileImg: string | null;
prefixName: string | null;
religionName: string | null;
} }
interface Family { interface Family {
@ -80,6 +82,7 @@ interface Occupation {
interface Contact { interface Contact {
contactPrefixId: string | null; contactPrefixId: string | null;
contactPrefixName: string | null;
contactFirstname: string | null; contactFirstname: string | null;
contactLastname: string | null; contactLastname: string | null;
contactRelations: string | null; contactRelations: string | null;
@ -208,6 +211,8 @@ const defaultInformation = ref<Information>({
provinceId: null, provinceId: null,
statusId: null, statusId: null,
profileImg: null, profileImg: null,
religionName: null,
prefixName: null,
}); });
const defaultFamily = ref<Family>({ const defaultFamily = ref<Family>({
@ -248,6 +253,7 @@ const defaultContact = ref<Contact>({
contactLastname: null, contactLastname: null,
contactRelations: null, contactRelations: null,
contactTel: null, contactTel: null,
contactPrefixName: null,
}); });
const defaultEducation = ref<Education>({ const defaultEducation = ref<Education>({

View file

@ -53,7 +53,6 @@ async function fetchStatus() {
const data = res.data.result; const data = res.data.result;
status.value = data.status; status.value = data.status;
rejectDetail.value = data.rejectDetail; rejectDetail.value = data.rejectDetail;
console.log(rejectDetail.value);
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -171,7 +170,7 @@ async function clickSave() {
showLoader(); showLoader();
await http await http
.post(config.API.candidateId(candidateId.value), { .post(config.API.candidateId(candidateId.value), {
prefixId: defaultInformation.value.prefixId, // prefixId: defaultInformation.value.prefixId,
lastName: defaultInformation.value.lastname, lastName: defaultInformation.value.lastname,
dateOfBirth: dateOfBirth:
defaultInformation.value.birthDate == null defaultInformation.value.birthDate == null
@ -181,7 +180,7 @@ async function clickSave() {
), ),
citizenId: defaultInformation.value.cardid, citizenId: defaultInformation.value.cardid,
firstName: defaultInformation.value.firstname, firstName: defaultInformation.value.firstname,
religionId: defaultInformation.value.religionId, // religionId: defaultInformation.value.religionId,
nationality: defaultInformation.value.nationality, nationality: defaultInformation.value.nationality,
email: defaultInformation.value.email, email: defaultInformation.value.email,
mobilePhone: defaultInformation.value.phone, mobilePhone: defaultInformation.value.phone,
@ -236,8 +235,8 @@ async function clickSave() {
defaultEducation.value.educationScores, defaultEducation.value.educationScores,
educationLevelHighId: educationLevelHighId:
defaultEducation.value.educationLevelHighId, defaultEducation.value.educationLevelHighId,
contactPrefixId: // contactPrefixId:
defaultContact.value.contactPrefixId, // defaultContact.value.contactPrefixId,
contactFirstname: contactFirstname:
defaultContact.value.contactFirstname, defaultContact.value.contactFirstname,
contactLastname: contactLastname:
@ -245,6 +244,12 @@ async function clickSave() {
contactRelations: contactRelations:
defaultContact.value.contactRelations, defaultContact.value.contactRelations,
contactTel: defaultContact.value.contactTel, contactTel: defaultContact.value.contactTel,
contactPrefixName:
defaultContact.value.contactPrefixName,
prefixName: defaultInformation.value.prefix,
religionName:
defaultInformation.value.religionName,
}) })
.then(async () => { .then(async () => {
success($q, "บันทึกข้อมูลส่วนตัวสำเร็จ"); success($q, "บันทึกข้อมูลส่วนตัวสำเร็จ");
@ -331,10 +336,11 @@ onMounted(async () => {
icon="refresh" icon="refresh"
class="bg-red-1" class="bg-red-1"
@click="modalReverse" @click="modalReverse"
v-if="status == 'payment' || status == 'checkSeat'" v-if="status == 'payment'"
> >
<q-tooltip>อนกลบใหเจาหนาทตรวจสอบ</q-tooltip> <q-tooltip>อนกลบใหเจาหนาทตรวจสอบ</q-tooltip>
</q-btn> </q-btn>
<!-- || status == 'checkSeat' -->
</div> </div>
<q-card class="q-pa-md"> <q-card class="q-pa-md">
<div> <div>

View file

@ -1309,6 +1309,7 @@ onMounted(async () => {
> >
<div class="col-12"> <div class="col-12">
<q-radio <q-radio
dense
v-model="props.row.highDegree" v-model="props.row.highDegree"
label="ประเภททั่วไป" label="ประเภททั่วไป"
color="teal" color="teal"
@ -1324,6 +1325,7 @@ onMounted(async () => {
</div> </div>
<div class="col-12"> <div class="col-12">
<q-radio <q-radio
dense
v-model="props.row.highDegree" v-model="props.row.highDegree"
label="ประเภทวิชาการ" label="ประเภทวิชาการ"
color="teal" color="teal"
@ -1412,6 +1414,7 @@ onMounted(async () => {
> >
<div class="col-12"> <div class="col-12">
<q-radio <q-radio
dense
v-model="props.row.educationLevel" v-model="props.row.educationLevel"
label="วุฒิปริญญาตรี" label="วุฒิปริญญาตรี"
color="teal" color="teal"
@ -1421,6 +1424,7 @@ onMounted(async () => {
</div> </div>
<div class="col-12"> <div class="col-12">
<q-radio <q-radio
dense
v-model="props.row.educationLevel" v-model="props.row.educationLevel"
label="ต่ำกว่าปริญญาตรี" label="ต่ำกว่าปริญญาตรี"
color="teal" color="teal"

View file

@ -32,6 +32,7 @@ const yearly = ref<number | null>(null);
const examId = ref<string>(route.params.examId.toString()); const examId = ref<string>(route.params.examId.toString());
const visible = ref<boolean>(false); // card const visible = ref<boolean>(false); // card
const dataNum = ref<DataNumObject[]>([]); // const dataNum = ref<DataNumObject[]>([]); //
const isFee = ref<boolean>(false);
const rows = ref<any[]>([]); const rows = ref<any[]>([]);
const visibleColumns = ref<String[]>([ const visibleColumns = ref<String[]>([
"no", "no",
@ -279,6 +280,7 @@ async function fetchData(loading: boolean = true) {
position: `${r.positionName}${r.positionLevelName}`, position: `${r.positionName}${r.positionLevelName}`,
positionLevel: r.positionLevelName, positionLevel: r.positionLevelName,
check: false, check: false,
isShowExamInfo: r.isShowExamInfo,
}); });
}); });
} }
@ -303,6 +305,7 @@ async function fetchPeriodExam() {
yearly.value = data.year; yearly.value = data.year;
statusPayment.value = data.status; statusPayment.value = data.status;
setSeat.value = data.setSeat; setSeat.value = data.setSeat;
isFee.value = data.fee === 0 ? false : true;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -489,10 +492,14 @@ onMounted(async () => {
:page="page" :page="page"
@update:change-page="changePage" @update:change-page="changePage"
:max-page="maxPage" :max-page="maxPage"
:is-fee="isFee"
> >
<template #columns="props"> <template #columns="props">
<q-tr :props="props" class="cursor-pointer"> <q-tr :props="props" class="cursor-pointer">
<q-td auto-width v-if="checkPermission($route)?.attrIsUpdate"> <q-td
auto-width
v-if="checkPermission($route)?.attrIsUpdate && isFee"
>
<q-checkbox v-model="props.selected" /> <q-checkbox v-model="props.selected" />
</q-td> </q-td>
<q-td <q-td