รวมข้อมูลสมัคึรสอบไว้หน้าเดียว

This commit is contained in:
Kittapath 2023-03-28 14:51:48 +07:00
parent a95c2fcbb4
commit 05d19419e7
11 changed files with 341 additions and 285 deletions

View file

@ -0,0 +1,600 @@
<!-- card อมลสวนต -->
<template>
<q-card flat bordered class="col-12 q-px-lg q-py-md">
<HeaderTop
v-model:edit="edit"
header="ข้อมูลส่วนตัว"
icon="mdi-account"
:save="saveData"
:addData="true"
:editOnly="false"
:cancel="cancelData"
:editData="status == 'register' || status == 'rejectRegister'"
:disable="statusEdit"
/>
<!-- :changeBtn="changeBtn" -->
<q-form ref="myform" class="col-12 row">
<div class="row col-10 items-center q-col-gutter-x-sm q-col-gutter-y-sm">
<div class="col-xs-6 col-sm-2 col-md-2">
<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="informaData.prefixId"
emit-value
map-options
option-label="name"
:options="prefixOptions"
option-value="id"
:label="`${'คำนำหน้า'}`"
/>
</div>
<div class="col-xs-6 col-sm-5 col-md-5">
<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="informaData.firstname"
:rules="[(val) => !!val || `${'กรุณากรอก ชื่อ'}`]"
:label="`${'ชื่อ'}`"
/>
</div>
<div class="col-xs-6 col-sm-5 col-md-5">
<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="informaData.lastname"
:rules="[(val) => !!val || `${'กรุณากรอก นามสกุล'}`]"
:label="`${'นามสกุล'}`"
/>
</div>
<div class="col-xs-6 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="informaData.nationality"
:rules="[(val) => !!val || `${'กรุณากรอก สัญชาติ'}`]"
:label="`${'สัญชาติ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<datepicker
v-model="informaData.birthDate"
:locale="'th'"
autoApply
:enableTimePicker="false"
week-start="0"
:max-date="new Date()"
:disabled="!(status == 'register' || status == 'rejectRegister')"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<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')"
:model-value="
informaData.birthDate == null ? null : date2Thai(informaData.birthDate)
"
:rules="[(val) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`]"
:label="`${'วัน/เดือน/ปี เกิด'}`"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
:style="
status == 'register' || status == 'rejectRegister'
? 'color: var(--q-primary)'
: 'color: var(--q-grey)'
"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
dense
lazy-rules
readonly
borderless
:style="!(status == 'register' || status == 'rejectRegister') ? '' : 'padding:0 12px;'"
:model-value="informaData.birthDate == null ? null : calAge(informaData.birthDate)"
:label="`${'อายุ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<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="informaData.relationship"
emit-value
map-options
option-label="name"
:options="relationshipOptions"
option-value="id"
:label="`${'สถานภาพ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:class="getClass(status == 'register' || status == 'rejectRegister')"
:outlined="status == 'register' || status == 'rejectRegister'"
dense
counter
lazy-rules
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="informaData.cardid"
maxlength="13"
:rules="[
(val) => !!val || `${'กรุณากรอก เลขบัตรประจำตัวประชาชน'}`,
(val) => val.length >= 13 || `${'กรุณากรอกเลขบัตรประจำตัวประชาชนให้ครบ'}`
]"
label="เลขบัตรประจำตัวประชาชน"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<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="informaData.provinceId"
emit-value
map-options
option-label="name"
:options="provinceOptions"
option-value="id"
:label="`${'ออกให้ ณ จังหวัด'}`"
@update:model-value="(value) => selectProvince(value)"
/>
</div>
<div class="col-xs-6 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="informaData.cardid"
:rules="[(val) => !!val || `${'กรุณากรอก ออกให้ ณ อำเภอ'}`]"
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="informaData.districtId"
emit-value
map-options
option-label="name"
:options="districtOptions"
option-value="id"
:label="`${'ออกให้ ณ อำเภอ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<datepicker
v-model="informaData.cardIdDate"
:locale="'th'"
autoApply
:enableTimePicker="false"
week-start="0"
:max-date="new Date()"
:disabled="!(status == 'register' || status == 'rejectRegister')"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<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')"
:model-value="
informaData.cardIdDate == null ? null : date2Thai(informaData.cardIdDate)
"
:rules="[(val) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี ที่ออกบัตร'}`]"
:label="`${'วัน/เดือน/ปี ที่ออกบัตร'}`"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
:style="
status == 'register' || status == 'rejectRegister'
? 'color: var(--q-primary)'
: 'color: var(--q-grey)'
"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:outlined="status == 'register' || status == 'rejectRegister'"
dense
counter
lazy-rules
type="tel"
maxlength="10"
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="informaData.tel"
:rules="[
(val) => !!val || `${'กรุณากรอก โทรศัพท์'}`,
(val) => val.length >= 9 || `${'กรุณากรอกข้อมูลโทรศัพท์ให้ครบ'}`
]"
:label="`${'โทรศัพท์'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:outlined="status == 'register' || status == 'rejectRegister'"
dense
counter
lazy-rules
type="tel"
maxlength="10"
:class="getClass(status == 'register' || status == 'rejectRegister')"
:readonly="!(status == 'register' || status == 'rejectRegister')"
:borderless="!(status == 'register' || status == 'rejectRegister')"
v-model="informaData.phone"
:rules="[
(val) => !!val || `${'กรุณากรอก โทรศัพท์มือถือ'}`,
(val) => val.length >= 10 || `${'กรุณากรอกข้อมูลโทรศัพท์มือถือให้ครบ'}`
]"
:label="`${'โทรศัพท์มือถือ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:class="getClass(false)"
:outlined="false"
dense
lazy-rules
:readonly="true"
:borderless="true"
v-model="informaData.email"
label="E-mail address"
/>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<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="informaData.knowledge"
label="ความรู้ความสามารถพิเศษ"
type="textarea"
/>
</div>
</div>
<div class="row col-2 justify-center q-pt-md">
<div class="containerimage row justify-center">
<q-file
borderless
v-model="fileData"
stack-label
:readonly="!(status == 'register' || status == 'rejectRegister')"
@update:model-value="pickFile"
>
<q-img src="@/assets/avatar_user.jpg" class="col-12">
<div class="overlay" v-if="status == 'register' || status == 'rejectRegister'">
<q-icon name="mdi-camera" />
<br />ปเดต
</div>
</q-img>
</q-file>
</div>
<div class="col-12 text-center" v-if="disabledPic">
<q-btn outline dense color="black" icon="mdi-content-save-outline" @click="savePic">
<q-tooltip content-class="bg-grey-2 text-black">นทกร</q-tooltip>
</q-btn>
</div>
</div>
</q-form>
</q-card>
<!-- <q-dialog :model-value="modalConsend" persistent>
<q-card style="min-width: 800px">
<Conference :ok="consendOk" :close="consenClose" />
</q-card>
</q-dialog> -->
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useQuasar } from 'quasar'
import { useCounterMixin } from '@/stores/mixin'
import http from '@/plugins/http'
import config from '@/app.config'
import { useExamDataStore } from '@/modules/01_exam/store'
import type { PropType } from 'vue'
import type { Information, DataOption } from '@/modules/01_exam/interface/index/Main'
import { defaultInformation } from '@/modules/01_exam/interface/index/Main'
import HeaderTop from '@/components/top.vue'
import Conference from '@/modules/01_exam/components/Conference.vue'
const props = defineProps({
prefixOptions: {
type: Array as PropType<DataOption[]>,
required: true
},
relationshipOptions: {
type: Array as PropType<DataOption[]>,
required: true
},
provinceOptions: {
type: Array as PropType<DataOption[]>,
required: true
},
statusEdit: {
type: Boolean,
required: true
},
notiNoEdit: {
type: Function,
default: () => console.log('not function')
},
status: {
type: String,
required: true
}
})
const $q = useQuasar()
const mixin = useCounterMixin()
const store = useExamDataStore()
const { date2Thai, calAge, success, dateToISO } = mixin
const districtOptions = ref<DataOption[]>([])
const candidateId = ref<string>('2223ba53-2fb2-470b-8dc1-27e5471b0331')
const edit = ref<boolean>(true)
const informaData = ref<Information>(defaultInformation)
const myform = ref<any>()
const imageUrl = ref<string | null>(null)
const disabledPic = ref<boolean>(false)
// const modalConsend = ref<boolean>(false)
const fileData = ref<File | null>()
const loader = ref<boolean>(false)
const emit = defineEmits(['update:statusEdit'])
onMounted(async () => {
await fetchData()
if (informaData.value.provinceId != null) await fetchDistrict(informaData.value.provinceId)
})
const fetchData = async () => {
loader.value = true
await http
.get(config.API.candidateInformation(candidateId.value))
.then((res) => {
const data = res.data.result
informaData.value.prefixId = data.prefixId
informaData.value.lastname = data.lastName
informaData.value.provinceId = data.citizenProvinceId
informaData.value.districtId = data.citizenDistrictId
informaData.value.birthDate = data.dateOfBirth == null ? null : new Date(data.dateOfBirth)
informaData.value.cardIdDate = data.citizenDate == null ? null : new Date(data.citizenDate)
informaData.value.cardid = data.citizenId
informaData.value.firstname = data.firstName
informaData.value.relationship = data.relationshipId
informaData.value.nationality = data.nationality
informaData.value.email = data.email
informaData.value.phone = data.mobilePhone
informaData.value.tel = data.telephone
informaData.value.knowledge = data.knowledge
})
.catch(() => {})
.finally(() => {
loader.value = false
})
}
const selectProvince = (val: string) => {
informaData.value.districtId = ''
myform.value.resetValidation()
fetchDistrict(val)
}
const saveData = async () => {
await myform.value.validate().then(async (suc: boolean) => {
if (suc) {
// if (store.consend == true) {
loader.value = true
await http
.post(config.API.candidateInformation(candidateId.value), {
prefixId: informaData.value.prefixId,
lastName: informaData.value.lastname,
citizenProvinceId: informaData.value.provinceId,
citizenDistrictId: informaData.value.districtId,
dateOfBirth:
informaData.value.birthDate == null ? null : dateToISO(informaData.value.birthDate),
citizenDate:
informaData.value.cardIdDate == null ? null : dateToISO(informaData.value.cardIdDate),
citizenId: informaData.value.cardid,
firstName: informaData.value.firstname,
relationshipId: informaData.value.relationship,
nationality: informaData.value.nationality,
email: informaData.value.email,
mobilePhone: informaData.value.phone,
telephone: informaData.value.tel,
knowledge: informaData.value.knowledge
})
.then(() => {
success($q, 'บันทึกข้อมูลส่วนตัวสำเร็จ')
// edit.value = false
emit('update:statusEdit', false)
})
.catch(() => {
// modalError.value = true
// modalErrorTittle.value = ''
// modalErrorDetail.value = e.response.data.message
// statusCode.value = e.response.data.status
})
.finally(async () => {
loader.value = false
await fetchData()
})
// } else {
// modalConsend.value = true
// }
}
})
}
// const changeBtn = async () => {
// if (edit.value == true) {
// if (props.statusEdit === true) {
// edit.value = false
// props.notiNoEdit()
// } else {
// emit('update:statusEdit', true)
// }
// } else {
// emit('update:statusEdit', false)
// }
// }
const fetchDistrict = async (id: string) => {
loader.value = true
await http
.get(config.API.listDistrict(id))
.then((res) => {
const data = res.data.result
let option: DataOption[] = []
data.map((r: DataOption) => {
option.push({ id: r.id.toString(), name: r.name.toString() })
})
districtOptions.value = option
})
.catch(() => {})
.finally(() => {
loader.value = false
})
}
const savePic = () => {
disabledPic.value = false
}
const onFilePicked = () => {}
const pickFile = () => {
disabledPic.value = true
}
// const consenClose = () => {
// modalConsend.value = false
// }
// const consendOk = () => {
// modalConsend.value = false
// store.consend = true
// saveData()
// }
const cancelData = () => {
fileData.value = null
disabledPic.value = false
}
const getClass = (val: boolean) => {
return {
'full-width inputgreen cursor-pointer': val,
'full-width cursor-pointer': !val
}
}
</script>
<style>
.containerimage {
position: relative;
width: 100%;
}
.q-img {
display: block;
width: 160px;
height: 170px;
padding: 1%;
border-radius: 3px;
border: solid 2px rgba(168, 168, 168, 0.055) !important;
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.048), 0 3px 6px 0 rgba(0, 0, 0, 0.19);
}
.overlay {
position: absolute;
bottom: 0;
background: rgb(0, 0, 0);
background: rgba(0, 0, 0, 0.7);
color: #f1f1f1;
transition: 0.5s ease;
width: 160px;
height: 70px;
opacity: 0;
color: white;
text-align: center;
cursor: pointer;
padding: 5% 0 5% 0;
}
.containerimage:hover .overlay {
opacity: 1;
}
</style>