| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617 |
- <template>
- <div class="login-wrap type--join">
- <!-- header -->
- <div class="login--header">
- <div class="login--header--l">
- <div class="logo">
- <!-- prettier-ignore -->
- SHOPDELI
- </div>
- </div>
- <div class="login--header--r"></div>
- </div>
- <!-- login -->
- <div class="login-box type--join">
- <div class="login-r">
- <!-- <h2 class="mk--title"></h2> -->
- <div class="tit-login">
- <strong>{{ titleh }} 회원가입</strong>
- <!-- <span><i>*</i>필수입력 항목</span> -->
- </div>
- <div v-show="form.formValue0 === 'Y'" class="login-input-wrap">
- <div class="txt-field-box">
- <v-text-field
- :disabled="useStore.getSnsTempData?.ID ? true : false"
- v-model="form.formValue1"
- placeholder="아이디를 입력해주세요"
- class="custom-input"
- @blur="checkId"
- ></v-text-field>
- <v-btn v-if="!useStore.getSnsTempData?.ID" small class="ml-2" @click="checkId"
- >중복확인</v-btn
- >
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="form.formValue2"
- :type="visible ? 'text' : 'password'"
- placeholder="패스워드를 입력해주세요."
- class="custom-input"
- id="password"
- ></v-text-field>
- <i
- class="ico-eye"
- @click.stop="toggleVisibility"
- :class="visible ? 'eye-on' : 'eye-off'"
- ></i>
- <i class="ico"></i>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="form.formValue3"
- :type="visible ? 'text' : 'password'"
- placeholder="패스워드 확인"
- class="custom-input"
- ></v-text-field>
- <i
- class="ico-eye"
- @click.stop="toggleVisibility"
- :class="visible ? 'eye-on' : 'eye-off'"
- ></i>
- <i class="ico"></i>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="form.formValue4"
- :maxlength="20"
- :counter="20"
- :placeholder="'닉네임을 입력해주세요.'"
- class="custom-input"
- ></v-text-field>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="form.formValue5"
- :disabled="useStore.getSnsTempData?.NAME ? true : false"
- :maxlength="20"
- :counter="20"
- placeholder="이름을 입력해주세요"
- class="custom-input"
- ></v-text-field>
- </div>
- <div class="txt-field-box">
- <v-select
- v-model="form.formValue6"
- :items="form.formValueItems6"
- item-title="text"
- item-value="value"
- class="custom-select"
- ></v-select>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="form.formValue7"
- placeholder="소셜 ID 또는 주소를 입력해주세요."
- class="custom-input"
- ></v-text-field>
- </div>
- <div class="txt-field-box phone">
- <v-text-field
- placeholder=""
- class="custom-input"
- v-model="form.formValue8"
- ></v-text-field>
- -
- <v-text-field
- placeholder="1234"
- class="custom-input"
- v-model="form.formValue9"
- ></v-text-field>
- -
- <v-text-field
- placeholder="5678"
- class="custom-input"
- v-model="form.formValue10"
- ></v-text-field>
- </div>
- <div class="txt-field-box email">
- <v-text-field
- v-model="form.formValue12"
- :disabled="useStore.getSnsTempData?.EMAIL"
- class="custom-input"
- placeholder=""
- ></v-text-field>
- <span v-if="form.formValue11 != 'direct'">@</span>
- <v-select
- :disabled="useStore.getSnsTempData?.EMAIL ? true : false"
- v-model="form.formValue11"
- :items="form.formValueItems11"
- item-title="text"
- item-value="value"
- class="custom-select"
- ></v-select>
- </div>
- <div class="txt-field-box">
- <v-textarea
- v-model="form.formValue13"
- placeholder="자기소개를 입력해주세요. 벤더사들이 참고할 수 있도록 작성해주세요."
- class="custom-textarea"
- rows="3"
- ></v-textarea>
- </div>
- </div>
- <div v-show="form.formValue0 === 'N'" class="login-input-wrap">
- <div class="txt-field-box">
- <v-text-field
- v-model="formVendor.formValue1"
- placeholder="아이디를 입력해주세요"
- class="custom-input"
- ></v-text-field>
- <v-btn
- v-if="!useStore.getSnsTempData?.ID"
- class="ml-2 custom-btn mini btn-white"
- @click="checkIdVendor"
- >중복확인</v-btn
- >
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="formVendor.formValue2"
- :type="visible ? 'text' : 'password'"
- placeholder="패스워드를 입력해주세요."
- class="custom-input"
- id="password"
- ></v-text-field>
- <i
- class="ico-eye"
- @click.stop="toggleVisibility"
- :class="visible ? 'eye-on' : 'eye-off'"
- ></i>
- <i class="ico"></i>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="formVendor.formValue3"
- :type="visible ? 'text' : 'password'"
- placeholder="패스워드 확인"
- class="custom-input"
- ></v-text-field>
- <i
- class="ico-eye"
- @click.stop="toggleVisibility"
- :class="visible ? 'eye-on' : 'eye-off'"
- ></i>
- <i class="ico"></i>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="formVendor.formValue4"
- :maxlength="20"
- :counter="20"
- placeholder="회사명"
- class="custom-input"
- ></v-text-field>
- </div>
- <div class="txt-field-box">
- <v-text-field
- v-model="formVendor.formValue5"
- :maxlength="20"
- :counter="20"
- placeholder="담당자 명"
- class="custom-input"
- ></v-text-field>
- </div>
- <div class="txt-field-box phone">
- <v-text-field
- placeholder=""
- class="custom-input"
- v-model="formVendor.formValue8"
- ></v-text-field>
- -
- <v-text-field
- placeholder="1234"
- class="custom-input"
- v-model="formVendor.formValue9"
- ></v-text-field>
- -
- <v-text-field
- placeholder="5678"
- class="custom-input"
- v-model="formVendor.formValue10"
- ></v-text-field>
- </div>
- <div class="txt-field-box email">
- <v-text-field
- v-model="formVendor.formValue12"
- class="custom-input"
- placeholder=""
- ></v-text-field>
- <span v-if="formVendor.formValue11 != 'direct'">@</span>
- <v-select
- v-model="formVendor.formValue11"
- :items="formVendor.formValueItems11"
- item-title="text"
- item-value="value"
- class="custom-select"
- ></v-select>
- </div>
- <div class="mt-5 d-flex agree--box">
- <v-checkbox class="custom-check type2" v-model="formVendor.formValue13">
- <template v-slot:label>개인정보약관동의</template>
- </v-checkbox>
- <v-checkbox class="custom-check type2" v-model="formVendor.formValue14">
- <template v-slot:label>제3자 정보동의</template>
- </v-checkbox>
- </div>
- </div>
- <div class="login-btn-wrap">
- <v-btn
- v-show="form.formValue0 === 'Y'"
- class="custom-btn btn-blue"
- @click.stop="joinMember('influence')"
- >회원가입</v-btn
- >
- <v-btn
- v-show="typeParam === 'vendor'"
- class="custom-btn btn-blue"
- @click.stop="joinMember('vendor')"
- >회원가입</v-btn
- >
- <v-btn
- v-show="typeParam === 'brand'"
- class="custom-btn btn-blue"
- @click.stop="joinMember('brand')"
- >회원가입</v-btn
- >
- </div>
- </div>
- </div>
- <!-- footer -->
- <div class="login-footer">
- <div class="login--footer--l">
- <p>COPYRIGHT@2025 SHOPDELI INC. ALL RIGHTS RESERVED.</p>
- <p>마포구 합정동</p>
- </div>
- </div>
- </div>
- </template>
- <script setup>
- /************************
- * import
- ************************/
- const { $log, $toast } = useNuxtApp();
- /************************
- * layout setting
- ************************/
- definePageMeta({
- layout: "loginlayout",
- });
- /************************
- * 전역
- ************************/
- const titleh = ref("인플루언서");
- const useStore = useAuthStore();
- const randomString = ref("");
- //인플루언서 폼
- const form = ref({
- formValue0: "Y",
- formValue1: useStore.getSnsTempData?.ID || "", // 아이디
- formValue2: "", // 패스워드
- formValue3: "", // 패스워드 확인
- formValue4: "", // 닉네임
- formValue5: useStore.getSnsTempData?.NAME || "", // 이름
- formValue6: "소셜채널 선택", // 소셜 채널
- formValueItems6: [
- {
- text: "유튜브",
- value: "youtube",
- },
- {
- text: "인스타",
- value: "instagram",
- },
- {
- text: "네이버 블로그",
- value: "naverblog",
- },
- {
- text: "네이버 카페",
- value: "navercafe",
- },
- {
- text: "스마트스토어",
- value: "smartstore",
- },
- ], // 소셜 채널 아이템
- formValue7: "", // 소셜 ID 또는 주소
- formValue8: "010", // 휴대폰1
- formValue9: "", // 휴대폰2
- formValue10: "", // 휴대폰3
- formValue11: "email", // 이메일1
- formValueItems11: [
- {
- text: "이메일 선택",
- value: "email",
- },
- {
- text: "직접입력",
- value: "direct",
- },
- {
- text: "naver.com",
- value: "naver",
- },
- {
- text: "gmail.com",
- value: "gmail",
- },
- {
- text: "daum.net",
- value: "daum",
- },
- ], // 이메일 아이템
- formValue12: "", // 이메일2
- formValue13: "", // 자기소개
- });
- //밴더 폼
- const formVendor = ref({
- formValue0: "",
- formValue1: "", // 아이디
- formValue2: "", // 패스워드
- formValue3: "", // 패스워드 확인
- formValue4: "", // 닉네임
- formValue5: "", // 이름
- formValue6: "소셜채널 선택", // 소셜 채널
- formValue7: "", // 소셜 ID 또는 주소
- formValue8: "010", // 휴대폰1
- formValue9: "", // 휴대폰2
- formValue10: "", // 휴대폰3
- formValue11: "email", // 이메일1
- formValueItems11: [
- {
- text: "이메일 선택",
- value: "email",
- },
- {
- text: "직접입력",
- value: "direct",
- },
- {
- text: "naver.com",
- value: "naver",
- },
- {
- text: "gmail.com",
- value: "gmail",
- },
- {
- text: "daum.net",
- value: "daum",
- },
- ], // 이메일 아이템
- formValue12: "",
- formValue13: "", // 개인정보약관동의
- formValue14: "", // 제3자 정보동의
- });
- /************************
- * 함수
- ************************/
- const generateRandomAlphanumeric = (length) => {
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- let result = "";
- const charsLength = chars.length;
- for (let i = 0; i < length; i++) {
- result += chars.charAt(Math.floor(Math.random() * charsLength));
- }
- return result;
- };
- const checkId = async () => {
- if (!form.value.formValue1) {
- $toast.error("아이디를 입력해주세요.");
- return;
- }
- // 아이디 형식 검사 (영문, 숫자 조합 6~20자)
- const idRegex = /^[a-zA-Z0-9]{6,20}$/;
- if (!idRegex.test(form.value.formValue1)) {
- $toast.error("아이디는 영문, 숫자 조합 6~20자로 입력해주세요.");
- return;
- }
- try {
- const response = await useAxios().post("/auth/checkId", {
- ID: form.value.formValue1,
- TYPE: "influence",
- });
- if (response.data.isDuplicate) {
- $toast.error("이미 사용중인 아이디입니다.");
- } else {
- $toast.success("사용 가능한 아이디입니다.");
- }
- } catch (error) {
- console.error("ID check error:", error);
- $toast.error("아이디 중복 확인 중 오류가 발생했습니다.");
- }
- };
- const checkIdVendor = async () => {
- if (!formVendor.value.formValue1) {
- $toast.error("아이디를 입력해주세요.");
- return;
- }
- // 아이디 형식 검사 (영문, 숫자 조합 6~20자)
- const idRegex = /^[a-zA-Z0-9]{6,20}$/;
- if (!idRegex.test(formVendor.value.formValue1)) {
- $toast.error("아이디는 영문, 숫자 조합 6~20자로 입력해주세요.");
- return;
- }
- try {
- const response = await useAxios().post("/auth/checkId", {
- ID: formVendor.value.formValue1,
- TYPE: typeParam.value,
- });
- if (response.data.isDuplicate) {
- $toast.error("이미 사용중인 아이디입니다.");
- } else {
- $toast.success("사용 가능한 아이디입니다.");
- }
- } catch (error) {
- console.error("ID check error:", error);
- $toast.error("아이디 중복 확인 중 오류가 발생했습니다.");
- }
- };
- // 회원가입 전에 아이디 유효성 검사 추가
- const joinMember = async (id_type) => {
- if (!useStore.getSnsTempData?.ID) {
- if (id_type === "vendor") {
- if (!formVendor.value.formValue1) {
- $toast.error("아이디를 입력해주세요.");
- return;
- }
- // const idRegex = /^[a-zA-Z0-9]{6,20}$/;
- // if (!idRegex.test(form.value.formValue1)) {
- // $toast.error("아이디는 영문, 숫자 조합 6~20자로 입력해주세요.");
- // return;
- // }
- } else {
- if (!formVendor.value.formValue1) {
- $toast.error("아이디를 입력해주세요.");
- return;
- }
- }
- }
- let _req = "";
- let _api = "";
- if (id_type === "influence") {
- _api = "/auth/joinmember";
- _req = {
- ID: form.value.formValue1,
- PASSWORD: form.value.formValue2,
- NAME: form.value.formValue5,
- NICK_NAME: form.value.formValue4 || "", //닉네임 없으면 빈문자
- PHONE: `${form.value.formValue8}-${form.value.formValue9}-${form.value.formValue10}`,
- EMAIL: form.value.formValue12,
- SNS_TYPE: form.value.formValue6,
- SNS_LINK_ID: form.value.formValue7,
- ADD_INFO1: form.value.formValue13,
- GOOGLE_REFRESH_TOKEN: useStore.getSnsTempData?.GOOGLE_REFRESH_TOKEN || "",
- TYPE: useStore.getSnsTempData ? "1" : "0", // SNS 가입일경우 1, 일반회원 가입일경우 0
- };
- } else if (id_type === "vendor") {
- _api = "/auth/joinvendor";
- _req = {
- ID: formVendor.value.formValue1,
- PASSWORD: formVendor.value.formValue3,
- COMPANY_NAME: formVendor.value.formValue4,
- COMPANY_NUMBER: (randomString.value = generateRandomAlphanumeric(100)),
- NAME: formVendor.value.formValue5,
- HP: `${formVendor.value.formValue8}-${formVendor.value.formValue9}-${formVendor.value.formValue10}`,
- EMAIL: formVendor.value.formValue12,
- }
- } else {
- _api = "/auth/joinbrand";
- _req = {
- ID: formVendor.value.formValue1,
- PASSWORD: formVendor.value.formValue3,
- COMPANY_NAME: formVendor.value.formValue4,
- COMPANY_NUMBER: (randomString.value = generateRandomAlphanumeric(100)),
- NAME: formVendor.value.formValue5,
- HP: `${formVendor.value.formValue8}-${formVendor.value.formValue9}-${formVendor.value.formValue10}`,
- EMAIL: formVendor.value.formValue12,
- };
- }
- useAxios()
- .post(_api, _req)
- .then((res) => {
- if (_req.TYPE === "1") {
- // SNS 가입일 경우
- useStore.setTempData("");
- useUtil.setPageMove("/?type=influence");
- return;
- }
- if (form.value.formValue0 === "Y") {
- useUtil.setPageMove("/?type=influence");
- } else {
- useUtil.setPageMove("/?type=vendor");
- }
- })
- .catch((error) => {
- if (error.response) {
- console.log("status:", error.response.status, "data:", error.response.data);
- // 안전하게 errCode, message 접근
- const errData = error.response.data || {};
- const errCode = errData.errCode || errData.errorCode || errData.code || "";
- const errMsg = errData.message || "알 수 없는 오류가 발생했습니다.";
- console.log("errCode:", errCode, "message:", errMsg);
- } else {
- console.log("error:", error.message, error.code);
- }
- if (error.response?.status) {
- fnLoginSet(error.response.data.messages.message);
- }
- $log.debug("[join][fnIdPwCheck][error]");
- })
- .finally(() => {
- $log.debug("[join][fnIdPwCheck][finished]");
- });
- };
- /************************
- * 반응형 변수
- ************************/
- const route = useRoute();
- const typeParam = ref(route.query.type);
- /************************
- * 마운트
- ************************/
- onMounted(() => {
- if(typeParam.value === "influence"){
- (form.value.formValue0 = "Y");
- titleh.value = "인플루언서"
- } else if(typeParam.value === "vendor"){
- (form.value.formValue0 = "N") ;
- titleh.value = "벤더사"
- } else {
- (form.value.formValue0 = "N") ;
- titleh.value = "브랜드사"
- }
- if (useStore.getSnsTempData?.EMAIL) {
- form.value.formValue12 = useStore.getSnsTempData.EMAIL;
- form.value.formValue11 = "direct"; // 이메일 직접입력으로 설정
- }
- });
- </script>
|