join.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. <template>
  2. <div class="login-wrap type--join">
  3. <!-- header -->
  4. <div class="login--header">
  5. <div class="login--header--l">
  6. <div class="logo">
  7. <!-- prettier-ignore -->
  8. SHOPDELI
  9. </div>
  10. </div>
  11. <div class="login--header--r"></div>
  12. </div>
  13. <!-- login -->
  14. <div class="login-box type--join">
  15. <div class="login-r">
  16. <h2 class="mk--title">{{ titleh }}</h2>
  17. <!-- <div class="join--type">
  18. <v-radio-group v-model="form.formValue0" row inline class="custom-radio type2">
  19. <v-radio value="Y" label="인플루언스"></v-radio>
  20. <v-radio value="N" label="벤더"></v-radio>
  21. </v-radio-group>
  22. </div> -->
  23. <div class="tit-login">
  24. <strong>회원가입</strong>
  25. <span><i>*</i>필수입력 항목</span>
  26. </div>
  27. <div v-show="form.formValue0 === 'Y'" class="login-input-wrap">
  28. <div class="txt-field-box">
  29. <v-text-field
  30. :disabled="useStore.getSnsTempData?.ID ? true : false"
  31. v-model="form.formValue1"
  32. placeholder="아이디를 입력해주세요"
  33. class="custom-input"
  34. ></v-text-field>
  35. </div>
  36. <div class="txt-field-box">
  37. <v-text-field
  38. v-model="form.formValue2"
  39. :type="visible ? 'text' : 'password'"
  40. placeholder="패스워드를 입력해주세요."
  41. class="custom-input"
  42. id="password"
  43. ></v-text-field>
  44. <i
  45. class="ico-eye"
  46. @click.stop="toggleVisibility"
  47. :class="visible ? 'eye-on' : 'eye-off'"
  48. ></i>
  49. <i class="ico"></i>
  50. </div>
  51. <div class="txt-field-box">
  52. <v-text-field
  53. v-model="form.formValue3"
  54. :type="visible ? 'text' : 'password'"
  55. placeholder="패스워드 확인"
  56. class="custom-input"
  57. ></v-text-field>
  58. <i
  59. class="ico-eye"
  60. @click.stop="toggleVisibility"
  61. :class="visible ? 'eye-on' : 'eye-off'"
  62. ></i>
  63. <i class="ico"></i>
  64. </div>
  65. <div class="txt-field-box">
  66. <v-text-field
  67. v-model="form.formValue4"
  68. :maxlength="20"
  69. :counter="20"
  70. :placeholder="'닉네임을 입력해주세요.'"
  71. class="custom-input"
  72. ></v-text-field>
  73. </div>
  74. <div class="txt-field-box">
  75. <v-text-field
  76. v-model="form.formValue5"
  77. :disabled="useStore.getSnsTempData?.NAME ? true : false"
  78. :maxlength="20"
  79. :counter="20"
  80. placeholder="이름을 입력해주세요"
  81. class="custom-input"
  82. ></v-text-field>
  83. </div>
  84. <div class="txt-field-box">
  85. <v-select
  86. v-model="form.formValue6"
  87. :items="form.formValueItems6"
  88. item-title="text"
  89. item-value="value"
  90. class="custom-select"
  91. ></v-select>
  92. </div>
  93. <div class="txt-field-box">
  94. <v-text-field
  95. v-model="form.formValue7"
  96. placeholder="소셜 ID 또는 주소를 입력해주세요."
  97. class="custom-input"
  98. ></v-text-field>
  99. </div>
  100. <div class="txt-field-box phone">
  101. <v-text-field
  102. placeholder=""
  103. class="custom-input"
  104. v-model="form.formValue8"
  105. ></v-text-field>
  106. -
  107. <v-text-field
  108. placeholder="1234"
  109. class="custom-input"
  110. v-model="form.formValue9"
  111. ></v-text-field>
  112. -
  113. <v-text-field
  114. placeholder="5678"
  115. class="custom-input"
  116. v-model="form.formValue10"
  117. ></v-text-field>
  118. </div>
  119. <div class="txt-field-box email">
  120. <v-text-field
  121. v-model="form.formValue12"
  122. :disabled="useStore.getSnsTempData?.EMAIL"
  123. class="custom-input"
  124. placeholder=""
  125. ></v-text-field>
  126. <span v-if="form.formValue11 != 'direct'">@</span>
  127. <v-select
  128. :disabled="useStore.getSnsTempData?.EMAIL ? true : false"
  129. v-model="form.formValue11"
  130. :items="form.formValueItems11"
  131. item-title="text"
  132. item-value="value"
  133. class="custom-select"
  134. ></v-select>
  135. </div>
  136. <div class="txt-field-box">
  137. <v-textarea
  138. v-model="form.formValue13"
  139. placeholder="자기소개를 입력해주세요. 벤더사들이 참고할 수 있도록 작성해주세요."
  140. class="custom-textarea"
  141. rows="3"
  142. ></v-textarea>
  143. </div>
  144. </div>
  145. <div v-show="form.formValue0 === 'N'" class="login-input-wrap">
  146. <div class="txt-field-box">
  147. <v-text-field
  148. v-model="formVendor.formValue1"
  149. placeholder="아이디를 입력해주세요"
  150. class="custom-input"
  151. ></v-text-field>
  152. </div>
  153. <div class="txt-field-box">
  154. <v-text-field
  155. v-model="formVendor.formValue2"
  156. :type="visible ? 'text' : 'password'"
  157. placeholder="패스워드를 입력해주세요."
  158. class="custom-input"
  159. id="password"
  160. ></v-text-field>
  161. <i
  162. class="ico-eye"
  163. @click.stop="toggleVisibility"
  164. :class="visible ? 'eye-on' : 'eye-off'"
  165. ></i>
  166. <i class="ico"></i>
  167. </div>
  168. <div class="txt-field-box">
  169. <v-text-field
  170. v-model="formVendor.formValue3"
  171. :type="visible ? 'text' : 'password'"
  172. placeholder="패스워드 확인"
  173. class="custom-input"
  174. ></v-text-field>
  175. <i
  176. class="ico-eye"
  177. @click.stop="toggleVisibility"
  178. :class="visible ? 'eye-on' : 'eye-off'"
  179. ></i>
  180. <i class="ico"></i>
  181. </div>
  182. <div class="txt-field-box">
  183. <v-text-field
  184. v-model="formVendor.formValue4"
  185. :maxlength="20"
  186. :counter="20"
  187. placeholder="회사명"
  188. class="custom-input"
  189. ></v-text-field>
  190. </div>
  191. <div class="txt-field-box">
  192. <v-text-field
  193. v-model="formVendor.formValue5"
  194. :maxlength="20"
  195. :counter="20"
  196. placeholder="담당자 명"
  197. class="custom-input"
  198. ></v-text-field>
  199. </div>
  200. <div class="txt-field-box phone">
  201. <v-text-field
  202. placeholder=""
  203. class="custom-input"
  204. v-model="formVendor.formValue8"
  205. ></v-text-field>
  206. -
  207. <v-text-field
  208. placeholder="1234"
  209. class="custom-input"
  210. v-model="formVendor.formValue9"
  211. ></v-text-field>
  212. -
  213. <v-text-field
  214. placeholder="5678"
  215. class="custom-input"
  216. v-model="formVendor.formValue10"
  217. ></v-text-field>
  218. </div>
  219. <div class="txt-field-box email">
  220. <v-text-field
  221. v-model="formVendor.formValue12"
  222. class="custom-input"
  223. placeholder=""
  224. ></v-text-field>
  225. <span v-if="formVendor.formValue11 != 'direct'">@</span>
  226. <v-select
  227. v-model="formVendor.formValue11"
  228. :items="formVendor.formValueItems11"
  229. item-title="text"
  230. item-value="value"
  231. class="custom-select"
  232. ></v-select>
  233. </div>
  234. <div class="mt-5 d-flex agree--box">
  235. <v-checkbox class="custom-check type2" v-model="formVendor.formValue13">
  236. <template v-slot:label>개인정보약관동의</template>
  237. </v-checkbox>
  238. <v-checkbox class="custom-check type2" v-model="formVendor.formValue14">
  239. <template v-slot:label>제3자 정보동의</template>
  240. </v-checkbox>
  241. </div>
  242. </div>
  243. <div class="login-btn-wrap">
  244. <v-btn
  245. v-show="form.formValue0 === 'Y'"
  246. class="custom-btn btn-blue"
  247. @click.stop="joinMember('influence')"
  248. >회원가입</v-btn
  249. >
  250. <v-btn
  251. v-show="form.formValue0 === 'N'"
  252. class="custom-btn btn-blue"
  253. @click.stop="joinMember('vendor')"
  254. >회원가입</v-btn
  255. >
  256. </div>
  257. </div>
  258. </div>
  259. <!-- footer -->
  260. <div class="login-footer">
  261. <div class="login--footer--l">
  262. <p>COPYRIGHT@2025 SHOPDELI INC. ALL RIGHTS RESERVED.</p>
  263. <p>마포구 합정동</p>
  264. </div>
  265. </div>
  266. </div>
  267. </template>
  268. <script setup>
  269. /************************
  270. * import
  271. ************************/
  272. import apiUrl from "@/composables/useApi";
  273. import { useI18n } from "vue-i18n";
  274. /************************
  275. * layout setting
  276. ************************/
  277. definePageMeta({
  278. layout: "loginlayout",
  279. });
  280. /************************
  281. * 전역
  282. ************************/
  283. const titleh = ref("인플루언스");
  284. const useStore = useAuthStore();
  285. const randomString = ref("");
  286. //인플루언서 폼
  287. const form = ref({
  288. formValue0: "Y",
  289. formValue1: useStore.getSnsTempData?.ID || "", // 아이디
  290. formValue2: "", // 패스워드
  291. formValue3: "", // 패스워드 확인
  292. formValue4: "", // 닉네임
  293. formValue5: useStore.getSnsTempData?.NAME || "", // 이름
  294. formValue6: "소셜채널 선택", // 소셜 채널
  295. formValueItems6: [
  296. {
  297. text: "유튜브",
  298. value: "youtube",
  299. },
  300. {
  301. text: "인스타",
  302. value: "instagram",
  303. },
  304. {
  305. text: "네이버 블로그",
  306. value: "naverblog",
  307. },
  308. {
  309. text: "네이버 카페",
  310. value: "navercafe",
  311. },
  312. {
  313. text: "스마트스토어",
  314. value: "smartstore",
  315. },
  316. ], // 소셜 채널 아이템
  317. formValue7: "", // 소셜 ID 또는 주소
  318. formValue8: "010", // 휴대폰1
  319. formValue9: "", // 휴대폰2
  320. formValue10: "", // 휴대폰3
  321. formValue11: "email", // 이메일1
  322. formValueItems11: [
  323. {
  324. text: "이메일 선택",
  325. value: "email",
  326. },
  327. {
  328. text: "직접입력",
  329. value: "direct",
  330. },
  331. {
  332. text: "naver.com",
  333. value: "naver",
  334. },
  335. {
  336. text: "gmail.com",
  337. value: "gmail",
  338. },
  339. {
  340. text: "daum.net",
  341. value: "daum",
  342. },
  343. ], // 이메일 아이템
  344. formValue12: "", // 이메일2
  345. formValue13: "", // 자기소개
  346. });
  347. //밴더 폼
  348. const formVendor = ref({
  349. formValue0: "",
  350. formValue1: "", // 아이디
  351. formValue2: "", // 패스워드
  352. formValue3: "", // 패스워드 확인
  353. formValue4: "", // 닉네임
  354. formValue5: "", // 이름
  355. formValue6: "소셜채널 선택", // 소셜 채널
  356. formValue7: "", // 소셜 ID 또는 주소
  357. formValue8: "010", // 휴대폰1
  358. formValue9: "", // 휴대폰2
  359. formValue10: "", // 휴대폰3
  360. formValue11: "email", // 이메일1
  361. formValueItems11: [
  362. {
  363. text: "이메일 선택",
  364. value: "email",
  365. },
  366. {
  367. text: "직접입력",
  368. value: "direct",
  369. },
  370. {
  371. text: "naver.com",
  372. value: "naver",
  373. },
  374. {
  375. text: "gmail.com",
  376. value: "gmail",
  377. },
  378. {
  379. text: "daum.net",
  380. value: "daum",
  381. },
  382. ], // 이메일 아이템
  383. formValue12: "",
  384. formValue13: "", // 개인정보약관동의
  385. formValue14: "", // 제3자 정보동의
  386. });
  387. /************************
  388. * 함수
  389. ************************/
  390. const generateRandomAlphanumeric = (length) => {
  391. const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  392. let result = "";
  393. const charsLength = chars.length;
  394. for (let i = 0; i < length; i++) {
  395. result += chars.charAt(Math.floor(Math.random() * charsLength));
  396. }
  397. return result;
  398. };
  399. const joinMember = (id_type) => {
  400. let _req = "";
  401. let _api = "";
  402. if (id_type === "influence") {
  403. _api = "/auth/joinmember";
  404. _req = {
  405. ID: form.value.formValue1,
  406. PASSWORD: form.value.formValue2,
  407. NAME: form.value.formValue5,
  408. NICK_NAME: form.value.formValue4 || "", //닉네임 없으면 빈문자
  409. PHONE: `${form.value.formValue8}-${form.value.formValue9}-${form.value.formValue10}`,
  410. EMAIL: form.value.formValue12,
  411. SNS_TYPE: form.value.formValue6,
  412. SNS_LINK_ID: form.value.formValue7,
  413. ADD_INFO1: form.value.formValue13,
  414. GOOGLE_REFRESH_TOKEN: useStore.getSnsTempData?.GOOGLE_REFRESH_TOKEN || "",
  415. TYPE: useStore.getSnsTempData ? "1" : "0", // SNS 가입일경우 1, 일반회원 가입일경우 0
  416. };
  417. } else {
  418. _api = "/auth/joinvendor";
  419. _req = {
  420. ID: formVendor.value.formValue1,
  421. PASSWORD: formVendor.value.formValue3,
  422. COMPANY_NAME: formVendor.value.formValue4,
  423. COMPANY_NUMBER: (randomString.value = generateRandomAlphanumeric(100)),
  424. NAME: formVendor.value.formValue5,
  425. HP: `${formVendor.value.formValue8}-${formVendor.value.formValue9}-${formVendor.value.formValue10}`,
  426. EMAIL: formVendor.value.formValue12,
  427. };
  428. }
  429. useAxios()
  430. .post(_api, _req)
  431. .then((res) => {
  432. if (_req.TYPE === "1") {
  433. // SNS 가입일 경우
  434. useStore.setTempData("");
  435. }
  436. //useUtil.setPageMove("/");
  437. })
  438. .catch((error) => {
  439. if (error.response) {
  440. console.log("status:", error.response.status, "data:", error.response.data);
  441. // 안전하게 errCode, message 접근
  442. const errData = error.response.data || {};
  443. const errCode = errData.errCode || errData.errorCode || errData.code || "";
  444. const errMsg = errData.message || "알 수 없는 오류가 발생했습니다.";
  445. console.log("errCode:", errCode, "message:", errMsg);
  446. } else {
  447. console.log("error:", error.message, error.code);
  448. }
  449. if (error.response?.status) {
  450. fnLoginSet(error.response.data.messages.message);
  451. }
  452. $log.debug("[join][fnIdPwCheck][error]");
  453. })
  454. .finally(() => {
  455. $log.debug("[join][fnIdPwCheck][finished]");
  456. });
  457. };
  458. /************************
  459. * 마운트
  460. ************************/
  461. onMounted(() => {
  462. const route = useRoute();
  463. const typeParam = route.query.type;
  464. typeParam === "influence"
  465. ? (form.value.formValue0 = "Y")
  466. : (form.value.formValue0 = "N");
  467. if (useStore.getSnsTempData?.EMAIL) {
  468. form.value.formValue12 = useStore.getSnsTempData.EMAIL;
  469. form.value.formValue11 = "direct"; // 이메일 직접입력으로 설정
  470. }
  471. });
  472. watch(
  473. () => form.value.formValue0,
  474. (newValue) => {
  475. if (newValue === "Y") {
  476. titleh.value = "인플루언서";
  477. } else {
  478. titleh.value = "벤더";
  479. }
  480. }
  481. );
  482. </script>