fix
All checks were successful
Build & Deploy on Dev / build (push) Successful in 52s

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-11-18 14:38:44 +07:00
parent 7982bd9c97
commit 647c9d5b9f
13 changed files with 383 additions and 174 deletions

View file

@ -68,7 +68,7 @@
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
:rules="[(val) => !!val || `${'กรุณาเลือก ตำบล / แขวง'}`]"
:rules="[(val) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
@ -78,7 +78,7 @@
option-label="name"
:options="subdistrictOptions"
option-value="id"
:label="`${'ตำบล / แขวง'}`"
:label="`${'แขวง / ตำบล'}`"
@update:model-value="(value) => selectSubDistrict(value, '1')"
/>
</div>
@ -180,7 +180,7 @@
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
:rules="[(val) => !!val || `${'กรุณาเลือก ตำบล / แขวง'}`]"
:rules="[(val) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
@ -190,7 +190,7 @@
option-label="name"
:options="subdistrictCOptions"
option-value="id"
:label="`${'ตำบล / แขวง'}`"
:label="`${'แขวง / ตำบล'}`"
@update:model-value="(value) => selectSubDistrict(value, '2')"
/>
</div>

View file

@ -18,6 +18,7 @@
:editData="status == 'register' || status == 'rejectRegister'"
name="ประวัติการทำงาน (ตั้งแต่เริ่มปฏิบัติงานกับกรุงเทพมหานคร - ปัจจุบัน)"
icon="mdi-briefcase"
:is-showfilter="false"
>
<template #columns="props">
<q-tr :props="props">
@ -80,8 +81,8 @@
:readonly="!edit"
:borderless="!edit"
v-model="position"
:rules="[(val) => !!val || `${'กรุณากรอกตำแหน่ง/ลักษณะงาน'}`]"
:label="`${'ตำแหน่ง/ลักษณะงาน'}`"
:rules="[(val) => !!val || `${'กรุณากรอกตำแหน่ง'}`]"
:label="`${'ตำแหน่ง'}`"
@update:modelValue="clickEditRowPosition"
hide-bottom-space
/>

View file

@ -1,17 +1,17 @@
<!-- card คคลทสามารถตดตอได -->
<template>
<HeaderTop
v-model:edit="edit"
header="บุคคลที่สามารถติดต่อได้"
icon="mdi-account-circle"
:addData="true"
:editOnly="false"
:editData="false"
/>
<q-form ref="myform">
<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">
<q-select
<HeaderTop
v-model:edit="edit"
header="บุคคลที่สามารถติดต่อได้"
icon="mdi-account-circle"
:addData="true"
:editOnly="false"
:editData="false"
/>
<q-form ref="myform">
<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">
<!-- <q-select
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
@ -26,71 +26,88 @@
:options="prefixOptions"
option-value="id"
:label="`${'คำนำหน้า'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-3">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contactfirstname"
:rules="[(val) => !!val || `${'กรุณากรอก ชื่อ'}`]"
:label="`${'ชื่อ'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-3">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contactlastname"
:rules="[(val) => !!val || `${'กรุณากรอก นามสกุล'}`]"
:label="`${'นามสกุล'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-4">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contactrelations"
:rules="[(val) => !!val || `${'กรุณากรอกความสัมพันธ์'}`]"
:label="`${'เกี่ยวข้องเป็น'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-4">
<q-input
:outlined="status == 'register' || status == 'rejectRegister'"
dense
:counter="status == 'register' || status == 'rejectRegister' ? true : false"
lazy-rules
type="tel"
mask="##########"
maxlength="10"
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contacttel"
:label="`${'โทรศัพท์'}`"
:rules="[
(val) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์',
(val) =>
(val.length >= 9 && val.length <= 10 && val.startsWith('0')) ||
'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง'
]"
/>
</div>
</div>
</q-form>
/> -->
<q-select
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
:rules="[(val) => !!val || `${'กรุณาเลือก คำนำหน้า'}`]"
:outlined="status == 'register' || status == 'rejectRegister'"
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 class="col-xs-12 col-sm-3 col-md-3">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contactfirstname"
:rules="[(val) => !!val || `${'กรุณากรอก ชื่อ'}`]"
:label="`${'ชื่อ'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-3">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contactlastname"
:rules="[(val) => !!val || `${'กรุณากรอก นามสกุล'}`]"
:label="`${'นามสกุล'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-4">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contactrelations"
:rules="[(val) => !!val || `${'กรุณากรอกความสัมพันธ์'}`]"
:label="`${'เกี่ยวข้องเป็น'}`"
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-4">
<q-input
:outlined="status == 'register' || status == 'rejectRegister'"
dense
lazy-rules
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultContact.contacttel"
:label="`${'โทรศัพท์'}`"
:rules="[(val) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์']"
/>
<!-- (val) =>
(val.length >= 9 && val.length <= 10 && val.startsWith('0')) ||
'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง' -->
<!-- type="tel" -->
<!-- mask="##########" -->
<!-- maxlength="10" -->
<!-- :counter="status == 'register' || status == 'rejectRegister' ? true : false" -->
</div>
</div>
</q-form>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, PropType } from 'vue'
@ -106,18 +123,18 @@ import HeaderTop from '@/components/top.vue'
import { DataOption } from '../../interface/index/Main'
const props = defineProps({
status: {
type: String,
required: true
},
form: {
type: Object,
required: true
},
prefixOptions: {
type: Array as PropType<DataOption[]>,
required: true
}
status: {
type: String,
required: true
},
form: {
type: Object,
required: true
},
prefixOptions: {
type: Array as PropType<DataOption[]>,
required: true
}
})
const emit = defineEmits(['update:form'])
@ -133,43 +150,63 @@ const examId = ref<string>(route.params.id.toString())
const positionId = ref<string>(route.params.positionId.toString())
watch(myform, async (count: any, prevCount: any) => {
emit('update:form', count)
emit('update:form', count)
})
watch(defaultContact, async (count: Contact, prevCount: Contact) => {
await changeData('contact', count)
await changeData('contact', count)
})
onMounted(async () => {
await fetchData()
await fetchData()
})
const fetchData = async () => {
loaderPage(true)
await http
.get(config.API.candidateContact(examId.value, positionId.value))
.then((res) => {
const data = res.data.result
if (data != null) {
defaultContact.value.contactprefixId = data.contactPrefixId
defaultContact.value.contactfirstname = data.contactFirstname
defaultContact.value.contactlastname = data.contactLastname
defaultContact.value.contactrelations = data.contactRelations
defaultContact.value.contacttel = data.contactTel
}
})
.catch((e) => {
// messageError($q, e)
})
.finally(() => {
loaderPage(false)
})
loaderPage(true)
await http
.get(config.API.candidateContact(examId.value, positionId.value))
.then((res) => {
const data = res.data.result
if (data != null) {
defaultContact.value.contactprefixId = data.contactPrefixId
defaultContact.value.contactfirstname = data.contactFirstname
defaultContact.value.contactlastname = data.contactLastname
defaultContact.value.contactrelations = data.contactRelations
defaultContact.value.contacttel = data.contactTel
defaultContact.value.contactprefixName = data.contactPrefixName
}
})
.catch((e) => {
// messageError($q, e)
})
.finally(() => {
loaderPage(false)
})
}
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
}
const getClass = (val: boolean) => {
return {
'full-width inputgreen cursor-pointer': val,
'full-width cursor-pointer': !val
}
return {
'full-width inputgreen cursor-pointer': val,
'full-width cursor-pointer': !val
}
}
</script>

View file

@ -98,7 +98,7 @@
autoApply
:enableTimePicker="false"
week-start="0"
:max-date="new Date()"
:max-date="dateCondition"
:disabled="!(status == 'register' || status == 'rejectRegister')"
>
<template #year="{ year }">
@ -176,7 +176,7 @@
</q-form>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, PropType } from 'vue'
import { ref, onMounted, watch, PropType, computed } from 'vue'
import http from '@/plugins/http'
import config from '@/app.config'
import type { DataOption, Education } from '@/modules/01_exam/interface/index/Main'
@ -184,10 +184,13 @@ import { defaultEducation, changeData } from '@/modules/01_exam/interface/index/
import HeaderTop from '@/components/top.vue'
import { useRoute } from 'vue-router'
import { useExamDataStore } from '@/modules/01_exam/store'
import { useCounterMixin } from '@/stores/mixin'
import { useDataStore } from '@/stores/data'
import { useQuasar } from 'quasar'
const storeExam = useExamDataStore()
const props = defineProps({
status: {
type: String,
@ -258,7 +261,7 @@ const fetchData = async () => {
checkInputName()
})
.catch((e) => {
// messageError($q, e)
// messageError($q, e)
})
.finally(() => {
loaderPage(false)
@ -282,4 +285,16 @@ const getClass = (val: boolean) => {
'full-width cursor-pointer': !val
}
}
const dateCondition = computed(() => {
const date =
storeExam.examInfo?.registerEndDate == null
? new Date()
: new Date(storeExam.examInfo.registerEndDate)
if (date === null) {
return null
}
date.setFullYear(date.getFullYear() - (Number(storeExam.examInfo?.graduationYearLock) || 0))
return date
})
</script>

View file

@ -67,7 +67,7 @@
/> -->
</div>
<div class="col-xs-12 col-sm-3 col-md-2">
<q-select
<!-- <q-select
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
@ -83,6 +83,26 @@
option-value="id"
:label="`${'คำนำหน้า'}`"
@update:model-value="(value) => selectPrefix()"
/> -->
<q-select
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
:rules="[(val) => !!val || `${'กรุณาเลือก คำนำหน้า'}`]"
:outlined="status == 'register' || status == 'rejectRegister'"
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 class="col-xs-12 col-sm-3 col-md-3">
@ -127,7 +147,7 @@
/>
</div>
<div class="col-xs-12 col-sm-3 col-md-3">
<q-select
<!-- <q-select
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
@ -142,6 +162,25 @@
:options="religionOptions"
option-value="id"
:label="`${'ศาสนา'}`"
/> -->
<q-select
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
:rules="[(val) => !!val || `${'กรุณาเลือก ศาสนา'}`]"
:outlined="status == 'register' || status == 'rejectRegister'"
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 class="col-xs-12 col-sm-3 col-md-3">
@ -214,23 +253,21 @@
<q-input
:outlined="status == 'register' || status == 'rejectRegister'"
dense
:counter="status == 'register' || status == 'rejectRegister' ? true : false"
lazy-rules
type="tel"
mask="##########"
maxlength="10"
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="defaultInformation.tel"
:label="`${'โทรศัพท์'}`"
:rules="[
(val) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์',
(val) =>
(val.length >= 9 && val.length <= 10 && val.startsWith('0')) ||
'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง'
]"
:rules="[(val) => !!val || '* กรุณากรอกข้อมูลหมายเลขโทรศัพท์']"
/>
<!-- :counter="status == 'register' || status == 'rejectRegister' ? true : false" -->
<!-- type="tel" -->
<!-- mask="##########" -->
<!-- maxlength="10" -->
<!-- (val) =>
(val.length >= 9 && val.length <= 10 && val.startsWith('0')) ||
'กรุณากรอกข้อมูลหมายเลขโทรศัพท์ให้ถูกต้อง' -->
</div>
<!-- <div class="col-xs-12 col-sm-3 col-md-3">
<q-input
@ -374,9 +411,10 @@
</q-dialog>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { ref, onMounted, watch, computed } from 'vue'
import { useCounterMixin } from '@/stores/mixin'
import { useDataStore } from '@/stores/data'
import { useExamDataStore } from '@/modules/01_exam/store'
import http from '@/plugins/http'
import config from '@/app.config'
import type { PropType } from 'vue'
@ -387,6 +425,8 @@ import type { Information, DataOption } from '@/modules/01_exam/interface/index/
import { defaultInformation, changeData } from '@/modules/01_exam/interface/index/Main'
import HeaderTop from '@/components/top.vue'
const storeExam = useExamDataStore()
const props = defineProps({
prefixOptions: {
type: Array as PropType<DataOption[]>,
@ -427,7 +467,7 @@ const img = ref<string>('')
const fileProfile = ref<File[]>([])
const cardid1 = ref<string | null>('')
const cardid2 = ref<string | null>('')
const registerEndDate = ref<Date>(new Date())
// const registerEndDate = ref<Date>(new Date())
const opNat = ref(['ไทย'])
const idModel = ref<boolean>(false)
@ -445,7 +485,7 @@ onMounted(async () => {
await fetchImgData()
if (defaultInformation.value.provinceId != null)
await fetchDistrict(defaultInformation.value.provinceId)
candidateCheck()
// candidateCheck()
})
const fetchData = async () => {
@ -480,6 +520,8 @@ const fetchData = async () => {
defaultInformation.value.phone = data.mobilePhone
defaultInformation.value.tel = data.telephone
defaultInformation.value.knowledge = data.knowledge
defaultInformation.value.prefix = data.prefixName
defaultInformation.value.religionName = data.religionName
})
.catch(() => {
defaultInformation.value.email =
@ -536,22 +578,28 @@ const selectBirthDate = async () => {
}
}
const candidateCheck = async () => {
loaderPage(true)
await http
.get(config.API.candidateCheckCreate(examId.value, positionId.value))
.then(async (res) => {
const data = res.data.result
registerEndDate.value =
data.registerEndDate == null ? new Date() : new Date(data.registerEndDate)
})
.catch((e) => {
messageError($q, e)
})
.finally(() => {
loaderPage(false)
})
}
const registerEndDate = computed<Date>(() => {
return storeExam.examInfo?.registerEndDate == null
? new Date()
: new Date(storeExam.examInfo?.registerEndDate)
})
// const candidateCheck = async () => {
// loaderPage(true)
// await http
// .get(config.API.candidateCheckCreate(examId.value, positionId.value))
// .then(async (res) => {
// const data = res.data.result
// registerEndDate.value =
// data.registerEndDate == null ? new Date() : new Date(data.registerEndDate)
// })
// .catch((e) => {
// messageError($q, e)
// })
// .finally(() => {
// loaderPage(false)
// })
// }
const fetchImgData = async () => {
loaderPage(true)
@ -636,6 +684,44 @@ function getMaxBirthDate(registerEndDate: Date | string): Date {
date.setFullYear(date.getFullYear() - 18)
return date
}
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
}
</script>
<style>

View file

@ -55,6 +55,7 @@ import http from '@/plugins/http'
import config from '@/app.config'
import { useCounterMixin } from '@/stores/mixin'
import { useDataStore } from '@/stores/data'
import { useExamDataStore } from '@/modules/01_exam/store'
import { useQuasar } from 'quasar'
import type { DataOption } from '@/modules/01_exam/interface/index/Main'
import Information from '@/modules/01_exam/components/Form/Information.vue'
@ -102,6 +103,7 @@ const emit = defineEmits([
const $q = useQuasar()
const dataStore = useDataStore()
const examStore = useExamDataStore()
const { loaderPage } = dataStore
const mixin = useCounterMixin()
const { messageError } = mixin
@ -164,7 +166,17 @@ const fetchPerson = async () => {
provinceOptions.value = optionProvince
let optionEducationLevel: DataOption[] = []
data.educationLevels.map((r: any) => {
let filterEducationLevels = data.educationLevels
if (examStore.educationLevel === 'BACHELOR') {
filterEducationLevels = data.educationLevels.filter((level: any) => level.rank === 7)
} else if (examStore.educationLevel === 'LOW_BACHELOR') {
filterEducationLevels = data.educationLevels.filter(
(level: any) => level.rank >= 4 && level.rank <= 6
)
}
filterEducationLevels.map((r: any) => {
optionEducationLevel.push({ id: r.id.toString(), name: r.name.toString() })
})
educationLevelOptions.value = optionEducationLevel