| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- <template>
- <!-- 내 정보 수정 -->
- <v-dialog v-model="props.isMyInfoUpdateModal" persistent width="50rem">
- <div class="v-common-dialog-wrapper custom-dialog">
- <div class="modal-tit">
- <strong>{{$t('common.header.myInfoUpdateModal.title')}}</strong>
- <button class="btn-close" @click="fnMyInfoClose()"></button>
- </div>
- <div class="v-common-dialog-content">
- <div class="form-style1 col4 shadow--type">
- <table>
- <colgroup>
- <col style="width:9.375rem;">
- <col style="width: 9.5rem">
- <col style="width:7.375rem;">
- <col style="width: calc(50% - 0.375rem)">
- </colgroup>
- <tbody>
- <tr>
- <th>{{$t('common.header.myInfoUpdateModal.id')}}</th>
- <td>{{ myInfo.id }}</td>
- <th>{{$t('common.header.myInfoUpdateModal.name')}}</th>
- <td>{{ myInfo.name }}</td>
- </tr>
- <tr>
- <th>{{$t('common.header.myInfoUpdateModal.tenantName')}}</th>
- <td>{{ myInfo.tenantName }}</td>
- <th>{{$t('common.header.myInfoUpdateModal.priority')}}</th>
- <td>{{ myInfo.accountRole }}</td>
- </tr>
- <tr>
- <th>{{$t('common.header.myInfoUpdateModal.alarmMsgType')}}</th>
- <td>{{ myInfo.emailRecvYN === 'Y' ? $t('common.header.myInfoUpdateModal.alarmEmail') : '' }}{{ myInfo.smsRecvYN === 'Y' ? ' / '+$t('common.header.myInfoUpdateModal.alarmMobile') : '' }}</td>
- <th>{{$t('common.header.myInfoUpdateModal.alarmMsgTime')}}</th>
- <td>{{ myInfo.recvSdate }} ~ {{ myInfo.recvEdate }}</td>
- </tr>
- <tr v-if="!errorCheck.pwdChg">
- <th>{{$t('common.header.myInfoUpdateModal.password')}}</th>
- <td>
- <v-btn class="custom-btn btn-password" style="width: 7.875rem;" @click="errorCheck.pwdChg = true">{{$t('common.header.myInfoUpdateModal.passwordChange')}}</v-btn>
- </td>
- </tr>
- <tr v-if="errorCheck.pwdChg">
- <th>{{$t('common.header.myInfoUpdateModal.newPassword')}}<span class="cir"></span></th>
- <td colspan="3">
- <div class="txt-field-box" :class="errorCheck.newPassword1Error ? 'error' : ''">
- <v-text-field type="password" :placeholder="$t('common.header.myInfoUpdateModal.newPasswordDesc')" class="custom-input mini2" v-model="myInfo.newPassword1" style="width:100%;" @input="setInputField('newPassword1')"></v-text-field>
- <i class="ico"></i>
- </div>
- </td>
- </tr>
- <tr v-if="errorCheck.pwdChg">
- <th class="align-top">{{$t('common.header.myInfoUpdateModal.newPassword2')}}<span class="cir"></span></th>
- <td colspan="3">
- <div class="txt-field-box" :class="errorCheck.newPassword2Error ? 'error' : ''">
- <v-text-field type="password" :placeholder="$t('common.header.myInfoUpdateModal.newPasswordDesc2')" class="custom-input mini2" style="width:100%;" v-model="myInfo.newPassword2" @input="setInputField('newPassword2')"></v-text-field>
- <i class="ico"></i>
- </div>
- <p class="error-txt" v-if="errorCheck.newPassword1Error || errorCheck.newPassword2Error">{{ errorCheck.inputValidPasswordTxt }}</p>
- </td>
- </tr>
- <tr>
- <th class="align-top">{{$t('common.header.myInfoUpdateModal.email')}}<span class="cir"></span></th>
- <td colspan="3" class="pr--0">
- <div class="input-wrap">
- <div class="txt-field-box" :class="errorCheck.isEmailErr ? 'error' : ''">
- <v-text-field placeholder="admin@test.com" class="custom-input mini2" v-model="myInfo.email" style="width: 100%" @input="setInputField('email')"></v-text-field>
- <i class="ico"></i>
- </div>
- <v-btn class="custom-btn btn-black mini2" style="width:5.1875rem; height:2.25rem;" @click="fnDupCheck('EMAIL')" :disabled="!errorCheck.isEmailBtn">{{$t('common.header.myInfoUpdateModal.dupCheck')}}</v-btn>
- </div>
- <p class="error-txt" v-if="errorCheck.isEmailErr">{{errorCheck.emailErrText}}</p>
- <p class="success-txt" v-if="errorCheck.isEmailDupCheck">{{$t('common.header.myInfoUpdateModal.valid.dupSuccessEmail')}}</p>
- </td>
- </tr>
- <tr>
- <th>{{$t('common.header.myInfoUpdateModal.phone')}}<span class="cir"></span></th>
- <td colspan="3" class="pr--0">
- <div class="input-wrap">
- <div class="txt-field-box" :class="errorCheck.isPhoneErr ? 'error' : ''">
- <v-text-field placeholder="010-1234-5678" class="custom-input mini2" v-model="myInfo.phone" @input="setInputField('phone')"></v-text-field>
- <i class="ico"></i>
- </div>
- <v-btn class="custom-btn btn-black mini2" style="width:5.1875rem; height: 2.25rem;" @click="fnDupCheck('PHONE_NUMBER')" :disabled="!errorCheck.isPhoneBtn">{{$t('common.header.myInfoUpdateModal.dupCheck')}}</v-btn>
- </div>
- <p class="error-txt" v-if="errorCheck.isPhoneErr">{{errorCheck.phoneErrText}}</p>
- <p class="success-txt" v-if="errorCheck.isPhoneDupCheck">{{$t('common.header.myInfoUpdateModal.valid.dupSuccessPhone')}}</p>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="btn-wrap">
- <v-btn class="custom-btn btn-white mini" @click="fnMyInfoClose()"><i class="ico"></i>
- {{$t('common.cancel')}}
- </v-btn>
- <v-btn class="custom-btn btn-blue2 btn-mod mini" @click="fnUpdate" :disabled="!errorCheck.isUpdateBtn"><i class="ico"></i> 수정 </v-btn>
- </div>
- </div>
- </v-dialog>
- </template>
- <script setup>
- /***********************
- * import
- ************************/
- import apiUrl from '@/composables/useApi';
- import useUtil from '@/composables/useUtil';
- import useValid from '@/composables/useValid';
- import { useI18n } from 'vue-i18n';
- /***********************
- * plugins inject
- ************************/
- const { $toast, $log, $dayjs, $eventBus } = useNuxtApp()
- // 현재 입력 중인 필드를 설정하는 함수
- const setInputField = (name) => {
- fnValidCheck(name)
- }
- // props
- const props = defineProps({
- isMyInfoUpdateModal: Boolean,
- })
- // 참조가능 데이터 설정
- defineExpose({
- fnInit
- })
- // 발신 이벤트 선언
- const emit = defineEmits(['closeModal'])
- const i18n = useI18n()
- /***********************
- * data & created
- ************************/
- const errorCheck = ref({
- pwdChg: false, // 비밀번호 활성화 YN
- newPassword1Error: false, // 신규비밀번호 입력 에러
- newPassword2Error: false, // 변경비밀번호 체크 입력 에러
- inputValidPasswordTxt: '', // 비밀번호 validation 문구
- isEmailErr: false, // 이메일 에러
- emailErrText: 'success', // 이메일 중복체크 문구
- isEmailBtn: false,
- isPhoneErr: false, // 전화번호 에러
- phoneErrText: 'success', // 전화번호 중복체크 문구
- isPhoneBtn: false,
- isEmailDupCheck: false, //
- isPhoneDupCheck: false,
- isUpdateBtn: false,
- })
- const myInfo = ref({
- id: '',
- name: '',
- newPassword1: '',
- newPassword2: '',
- tenantName: '',
- accountRole: '',
- email: '',
- phone: ''
- })
- const myInfoClone = ref({})
- const errorCheckClone = ref({})
-
- /*********************
- * computed
- *********************/
- // 변경사항 여부 체크
- const isUpdateContents = computed(() => {
- const isUpdate = JSON.stringify(myInfo.value) != JSON.stringify(myInfoClone.value)
- return isUpdate
- })
- watch(() => errorCheck.value, (newV, oldV) => {
- let isEmailDupCheck = true
- let isPhoneDupCheck = true
- // 비밀번호 입력 란이 활성화 되어있을 경우
- if(errorCheck.value.pwdChg) {
- if(errorCheck.value.inputValidPasswordTxt === 'success') {
- if(errorCheck.value.emailErrText != 'success') isEmailDupCheck = false
- else isEmailDupCheck = true
- if(errorCheck.value.phoneErrText != 'success') isPhoneDupCheck = false
- else isPhoneDupCheck = true
- if(isEmailDupCheck && isPhoneDupCheck) {
- errorCheck.value.isUpdateBtn = true
- } else {
- errorCheck.value.isUpdateBtn = false
- }
- } else {
- errorCheck.value.isUpdateBtn = false
- }
- } else {
- if(errorCheck.value.emailErrText != 'success') isEmailDupCheck = false
- else isEmailDupCheck = true
- if(errorCheck.value.phoneErrText != 'success') isPhoneDupCheck = false
- else isPhoneDupCheck = true
- if(isEmailDupCheck && isPhoneDupCheck) {
- errorCheck.value.isUpdateBtn = true
- } else {
- errorCheck.value.isUpdateBtn = false
- }
- }
- },{ deep: true, immediate: false })
-
- /***********************
- * Methods
- ************************/
- function fnInit(){
- // 데이터 초기화
- errorCheckClone.value = _cloneDeep(errorCheck.value)
- fnGetMyInfo()
- }
- /**
- * @SCRIPT
- * 내 정보 조회
- */
- function fnGetMyInfo(){
- useAxios().get(apiUrl.myInfo).then((res) => {
- let dataObj = {}
- dataObj = res.data.data
- dataObj.accessToken = useAuthStore().getAccessToken
- dataObj.refreshToken = useAuthStore().getRefreshToken
- useAuthStore().setAuth(dataObj)
-
- myInfo.value = {
- id: dataObj.accountId,
- name: dataObj.accountName,
- newPassword1: '',
- newPassword2: '',
- tenantName: dataObj.tenantName,
- accountRole: dataObj.accountRole,
- emailRecvYN: dataObj.emailRecvYN,
- smsRecvYN: dataObj.smsRecvYN,
- recvSdate: $dayjs(dataObj.recvSdate).format('YYYY-MM-DD HH:mm:ss'),
- recvEdate: $dayjs(dataObj.recvEdate).format('YYYY-MM-DD HH:mm:ss'),
- email: dataObj.email,
- phone: dataObj.phoneNumber
- }
- myInfoClone.value = _cloneDeep(myInfo.value)
- $log.debug("[myInfoUpdate][fnGetMyInfo][success]")
- }).catch((error)=>{
- $log.debug("[myInfoUpdate][fnGetMyInfo][error]")
- useErrorHandler().fnSetCommErrorHandle(error, fnGetMyInfo)
- }).finally(()=>{
- $log.debug("[myInfoUpdate][fnGetMyInfo][finished]")
- })
- }
- /**
- * @SCRIPT
- * 이메일 validation 검사 및 중복확인 처리
- */
- function fnDupCheck(type){
- if(type === 'EMAIL') {
- if(myInfo.value.email === myInfoClone.value.email) {
- errorCheck.value.isEmailErr = true
- errorCheck.value.isEmailDupCheck = false
- errorCheck.value.emailErrText = i18n.t('common.header.myInfoUpdateModal.valid.dupEmail')
- } else {
- fnDupCheckProc('EMAIL')
- }
- } else {
- if(myInfo.value.phone.replace(/\D/g, '') === myInfoClone.value.phone.replace(/\D/g, '')) {
- errorCheck.value.isPhoneErr = true
- errorCheck.value.isPhoneDupCheck = false
- errorCheck.value.phoneErrText = i18n.t('common.header.myInfoUpdateModal.valid.dupPhone')
- } else {
- fnDupCheckProc('PHONE_NUMBER')
- }
- }
- }
- function fnMyInfoClose() {
- errorCheck.value = _cloneDeep(errorCheckClone.value)
- emit('closeModal')
- }
- /**
- * @API
- * 이메일 & 전화번호 중복체크
- */
- function fnDupCheckProc(type){
- let _req = {
- checkType: type
- }
- if(type === 'EMAIL') {
- _req.checkValue = myInfo.value.email
- } else {
- _req.checkValue = myInfo.value.phone
- }
- useAxios().get(apiUrl.accountDupChk, {params: _req}).then((res) => {
- if(type === 'EMAIL') {
- errorCheck.value.isEmailDupCheck = true
- errorCheck.value.emailErrText = 'success'
- } else {
- errorCheck.value.isPhoneDupCheck = true
- errorCheck.value.phoneErrText = 'success'
- }
- $log.debug("[myInfoUpdate][fnDupCheckProc][success]")
- }).catch((error)=>{
- $log.debug("[myInfoUpdate][fnDupCheckProc][error]")
- // 에러 메시지 체크
- let errData = error.response.data
- let errorMessage = ''
- if(errData.message === 'DUPLICATE_ERROR') {
- if(type === 'EMAIL') {
- errorMessage = i18n.t('common.header.myInfoUpdateModal.valid.dupFailEmail')
- errorCheck.value.isEmailBtn = false
- errorCheck.value.isEmailErr = true
- errorCheck.value.emailErrText = errorMessage
- } else {
- errorMessage = i18n.t('common.header.myInfoUpdateModal.valid.dupFailPhone')
- errorCheck.value.isPhoneBtn = false
- errorCheck.value.isPhoneErr = true
- errorCheck.value.phoneErrText = errorMessage
- }
- }
- //$toast.error(errorMessage)
- }).finally(()=>{
- $log.debug("[myInfoUpdate][fnDupCheckProc][finished]")
- })
- }
- /**
- * @API
- * 수정API
- */
- function fnUpdate(){
- // // 1. 변경사항 체크 2. 필수입력값 체크 3. validation 검사
- if(isUpdateContents.value){
- let _req = {
- newPassword: btoa(myInfo.value.newPassword2),
- email: myInfo.value.email,
- phoneNumber: myInfo.value.phone
- }
-
- useAxios().post(apiUrl.myInfoUpdate, _req).then((res) => {
- useAuthStore().setHeaderMyInfo(_req)
- console.log('%c 내 정보가 수정되었습니다.' ,'color:#bada55','')
- $toast.success(i18n.t('common.header.myInfoUpdateModal.successMyInfo'))
- emit('closeModal')
- $log.debug("[myInfoUpdate][fnUpdate][success]")
- }).catch((error)=>{
- $log.debug("[myInfoUpdate][fnUpdate][error]")
- useErrorHandler().fnSetCommErrorHandle(error, fnUpdate)
- }).finally(()=>{
- $log.debug("[myInfoUpdate][fnUpdate][finished]")
- })
- }
- }
- /**
- * @SCRIPT
- * 비밀번호확인 validation
- */
- function fnValidCheck(type) {
- if(type === 'newPassword1') {
- let digits1 = myInfo.value.phone.replace(/\D/g, '')
- let digits2 = myInfo.value.newPassword1.replace(/\D/g, '')
- let lastEightDigits1 = digits1.slice(-8)
- let lastEightDigits2 = digits2.slice(-8)
- if(_includes(myInfo.value.newPassword1 , myInfo.value.id)) {
- // 아이디는 비밀번호로 사용할 수 없습니다.
- errorCheck.value.newPassword1Error = true
- errorCheck.value.inputValidPasswordTxt = i18n.t('common.header.myInfoUpdateModal.valid.includeId')
- } else if(lastEightDigits1 === lastEightDigits2) {
- // 연락처와 유사한 비밀번호는 사용할 수 없습니다.
- errorCheck.value.newPassword1Error = true
- errorCheck.value.inputValidPasswordTxt = i18n.t('common.header.myInfoUpdateModal.valid.includePhone')
- } else if(/(.)\1{2,}/.test(myInfo.value.newPassword1)) {
- // 3자리 이상 연속 숫자, 문자는 사용 불가합니다.
- errorCheck.value.newPassword1Error = true
- errorCheck.value.inputValidPasswordTxt = i18n.t('common.header.myInfoUpdateModal.valid.continuousUse')
- } else if(!/^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,30}$/i.test(myInfo.value.newPassword1)) {
- // 비밀번호는 문자,숫자,특수문자 조합 8~30자리로입력
- errorCheck.value.newPassword1Error = true
- errorCheck.value.inputValidPasswordTxt = i18n.t('common.header.myInfoUpdateModal.valid.validPassword')
- } else {
- errorCheck.value.newPassword1Error = false
- }
- } else if(type === 'newPassword2') {
- if(myInfo.value.newPassword1 != myInfo.value.newPassword2) {
- // 신규비밀번호가 일치 하지 않습니다.
- errorCheck.value.newPassword2Error = true
- errorCheck.value.inputValidPasswordTxt = i18n.t('common.header.myInfoUpdateModal.valid.missmatchPassword')
- } else if(!/^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,30}$/i.test(myInfo.value.newPassword1)) {
- errorCheck.value.newPassword2Error = true
- errorCheck.value.inputValidPasswordTxt = i18n.t('common.header.myInfoUpdateModal.valid.validPassword')
- } else {
- if(!errorCheck.value.newPassword1Error) {
- errorCheck.value.newPassword2Error = false
- errorCheck.value.inputValidPasswordTxt = 'success'
- }
- }
- } else if(type === 'email') {
- let isValid = useValid.emailStrChk(myInfo.value.email)
- if(useUtil.isNull(myInfo.value.email)) {
- errorCheck.value.isEmailErr = true
- errorCheck.value.isEmailBtn = false
- errorCheck.value.isEmailDupCheck = false
- errorCheck.value.emailErrText = i18n.t('login.findId.valid.isNullEmail')
- } else if(!isValid) {
- errorCheck.value.isEmailErr = true
- errorCheck.value.isEmailBtn = false
- errorCheck.value.isEmailDupCheck = false
- errorCheck.value.emailErrText = i18n.t('login.findId.valid.isTypeEmail')
- } else {
- errorCheck.value.isEmailErr = false
- errorCheck.value.isEmailBtn = true
- }
- }else {
- // phone
- //let isValid = useValid.phoneStrChk(myInfo.value.phone)
- myInfo.value.phone = useValid.p5gNumCheck(myInfo.value.phone, 'phone')
- if(useUtil.isNull(myInfo.value.phone) || myInfo.value.phone.length <= 10) {
- errorCheck.value.isPhoneErr = true
- errorCheck.value.isPhoneBtn = false
- errorCheck.value.isPhoneDupCheck = false
- errorCheck.value.phoneErrText = i18n.t('common.header.myInfoUpdateModal.valid.validPhone')
- } else {
- errorCheck.value.isPhoneErr = false
- errorCheck.value.isPhoneBtn = true
- }
- }
- }
- </script>
|