From 6d11849dae914b590af9a39816bd5daa70f4e94c Mon Sep 17 00:00:00 2001 From: Cindy Chang Date: Tue, 25 Jun 2024 12:08:53 +0800 Subject: [PATCH] duplicate account check --- src/components/Header.vue | 2 +- src/i18n/en.json | 3 +- src/stores/acctMgmt.js | 4 + .../AccountManagement/ModalAccountEdit.vue | 104 +++++++++++++----- 4 files changed, 82 insertions(+), 31 deletions(-) diff --git a/src/components/Header.vue b/src/components/Header.vue index aa14a46..f520194 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -10,7 +10,7 @@ - diff --git a/src/i18n/en.json b/src/i18n/en.json index a893908..7d6f9ef 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -36,7 +36,8 @@ "DeleteFirstClause": "deletion is irreversible !", "DeleteSecondClause": "You will delete all data and content on this account.", "MsgAccountAdded": "Account added.", - "MsgAccountDeleteSuccess": "Account deleted." + "MsgAccountDeleteSuccess": "Account deleted.", + "AccountNotUnique": "Account has already been registered." }, "Compare": { "timeUsage": "Time Usage", diff --git a/src/stores/acctMgmt.js b/src/stores/acctMgmt.js index 940c4e5..407a0b4 100644 --- a/src/stores/acctMgmt.js +++ b/src/stores/acctMgmt.js @@ -125,9 +125,13 @@ export default defineStore('acctMgmtStore', { try{ const response = await this.$axios.get(apiUserDetail); this.currentViewingUser.detail = response.data; + if(response.status === 200) { + return true; + } } catch(error) { apiError(error, 'Failed to get user detail.'); + return false; }; }, /** diff --git a/src/views/AccountManagement/ModalAccountEdit.vue b/src/views/AccountManagement/ModalAccountEdit.vue index 52eb825..cb49b03 100644 --- a/src/views/AccountManagement/ModalAccountEdit.vue +++ b/src/views/AccountManagement/ModalAccountEdit.vue @@ -11,9 +11,27 @@ {{ i18next.t("AcctMgmt.Account") }} - +
+ +
+
+ ! + + {{ i18next.t("AcctMgmt.AccountNotUnique") }} + +
+
+ +
@@ -138,6 +156,7 @@ export default defineComponent({ const isPwdEyeOn = ref(false); const isPwdConfirmEyeOn = ref(false); const isPwdMatched = ref(true); + const isConfirmDisabled = ref(true); const isSetAsAdminChecked = ref(false); const isSetActivedChecked = ref(true); @@ -157,6 +176,8 @@ export default defineComponent({ const inputPwd = ref(""); const inputConfirmPwd = ref(""); + const isAccountUnique = ref(true); + // 自從加入這段 watch 之後,填寫密碼欄位之時,就不會胡亂清空掉 account 或是 full name 蘭為了。 watch(whichCurrentModal, (newVal) => { if (newVal === MODAL_CREATE_NEW) { @@ -172,9 +193,26 @@ export default defineComponent({ return modalStore.whichModal === MODAL_CREATE_NEW ? i18next.t('AcctMgmt.CreateNew') : i18next.t('AcctMgmt.AccountEdit'); }); - const isConfirmDisabled = computed(() => { - return inputPwd.length && inputConfirmPwd.length; - }); + + watch( + [inputUserAccount, inputName, inputPwd, inputConfirmPwd, isAccountUnique, + isPwdMatched, + ], + ([newAccount, newName, newPwd, newConfirmPwd, newIsAccountUnique, + newPwdMatched, + ]) => { + if (!newAccount.length || !newName.length || !newPwd.length + || !newConfirmPwd.length || !newIsAccountUnique + || !newPwdMatched + ) { + isConfirmDisabled.value = true; + } else { + isConfirmDisabled.value = false; + } + }, + { immediate: true } + ); + const togglePwdEyeBtn = () => { isPwdEyeOn.value = !isPwdEyeOn.value; @@ -184,31 +222,31 @@ export default defineComponent({ }; const validateConfirmPwd = () => { - let validateResult = true; - isPwdMatched.value = inputPwd.value === inputConfirmPwd.value; - return validateResult && isPwdMatched.value; + isPwdMatched.value = inputPwd.value.length > 0 && inputPwd.value === inputConfirmPwd.value; } const onConfirmBtnClick = async () => { + validateConfirmPwd(); + if(!isPwdMatched.value){ + return; + } switch(whichCurrentModal.value) { - case MODAL_CREATE_NEW: - const validateResult = validateConfirmPwd(); - if(!validateResult){ - return; - } - //TODO: 這邊要記得回來加一個判斷帳號是否已經存在的邏輯 - checkAccountIsUnique(); - await acctMgmtStore.createNewAccount({ - username: inputUserAccount.value, - password: inputPwd.value, - name: inputName.value, - is_admin: isSetAsAdminChecked.value, - is_active: isSetActivedChecked.value, - }); - await toast.success(i18next.t("AcctMgmt.MsgAccountAdded")); - await modalStore.closeModal(); - await router.push('/account/account-admin'); + case MODAL_CREATE_NEW: + await checkAccountIsUnique(); + if(!isAccountUnique.value) { + return; + } + await acctMgmtStore.createNewAccount({ + username: inputUserAccount.value, + password: inputPwd.value, + name: inputName.value, + is_admin: isSetAsAdminChecked.value, + is_active: isSetActivedChecked.value, + }); + await toast.success(i18next.t("AcctMgmt.MsgAccountAdded")); + await modalStore.closeModal(); + await router.push('/account/account-admin'); break; default: break; @@ -217,9 +255,9 @@ export default defineComponent({ } const checkAccountIsUnique = async() => { - let isAccountUnique = false; - //TODO: call pinia store to call backend API - return isAccountUnique; + const isAccountAlreadyExistAPISuccess = await acctMgmtStore.getUserDetail(inputUserAccount.value); + isAccountUnique.value = !isAccountAlreadyExistAPISuccess; + return isAccountUnique.value; }; const toggleIsAdmin = () => { @@ -229,6 +267,12 @@ export default defineComponent({ const toggleIsActivated = () => { isSetActivedChecked.value = !isSetActivedChecked.value; } + const onInputAccountFocus = () => { + if(!isAccountUnique.value) { + // 之所以要轉回true,是為了讓使用者可以繼續填寫不被阻擋 + isAccountUnique.value = true; + } + } return { isConfirmDisabled, username, @@ -252,6 +296,8 @@ export default defineComponent({ whichCurrentModal, MODAL_CREATE_NEW, modalTitle, + isAccountUnique, + onInputAccountFocus, }; }, data() {