WinWin‐join - jung-so-e/winwin GitHub Wiki

📌Join

✔️회원가입

  • 모달창 여러개를 활용해 마지막 버튼을 눌렀을 때 회원가입이 완료됨
  • SMS API를 이용해 회원의 번호로 인증 번호를 전송하고, 회원이 입력한 번호와 인증 번호가 일치하면 다음으로 넘어감
  • 관심 태그 최소 1개에서 최대 3개까지 생성/삭제 할 수 있음
  • 첨부파일 올리기/삭제하기
  • 유효성 검사를 통해 데이터의 중복 또는 잘못된 형식을 막음

🖥️ code

UserRestController.java
@Controller
@RequiredArgsConstructor
@RequestMapping("/main/*")
public class MainController {

    private final UserService userService;
    private final StudyService studyService;
    

    @PostMapping("/main")
    public RedirectView header(UserDto userDto, @RequestParam("subNumber") List<Integer> subNumbers,  Integer certificationNumber){
        userService.userRegister(userDto);

        CategoryBridgeVo categoryBridgeVo = new CategoryBridgeVo();
        categoryBridgeVo.setUserNumber(userDto.getUserNumber());


        for(int i : subNumbers){
            categoryBridgeVo.setSubNumber(i);
            userService.categoryBridge(categoryBridgeVo);
        }


        if(userDto.getUserPosition().equals("mentor")){
            MentorDto mentorDto = new MentorDto();
            mentorDto.setUserNumber(userDto.getUserNumber());
            mentorDto.setCertificationNumber(certificationNumber.intValue());

            userService.joinMentor(mentorDto);
        }
        
        return new RedirectView("/main/main");
    }
UserService.java
//    회원 등록
    public void userRegister(UserDto userDto){
        if(userDto == null){ throw new IllegalArgumentException("회원 정보 xxxxxxxxxxxxxx");}
        userMapper.join(userDto);
    }
//    아이디 중복 검사
    public int checkId(String userId){
        if(userId == null){
            throw new IllegalArgumentException("아이디가 없습니다.");
        }
        return userMapper.checkId(userId);
    }

    //    닉네임 중복 검사
    public int checkNickname(String userNickname){
        if(userNickname == null){
            throw new IllegalArgumentException("닉네임 없음");
        }
        return userMapper.checkNickname(userNickname);
    }

    // 관심분야 카테고리
    public List<CategoryVo> findCategoryJ(){
        List<CategoryVo> categoryJ = userMapper.categoryJ();

        for (int i=0; i<categoryJ.size(); i++){
            categoryJ.get(i).getMainCode();
            categoryJ.get(i).getMainName();
        }

        return categoryJ;
    }

    public List<CategoryVo> findCategoryH(){
        List<CategoryVo> categoryH = userMapper.categoryH();

        for (int i=0; i<categoryH.size(); i++){
            categoryH.get(i).getSubNumber();
            categoryH.get(i).getSubName();
        }

        return categoryH;
    }

    public List<CategoryVo> findSubCategory(String maindCode){
        List<CategoryVo> subCategory = userMapper.subCategory(maindCode);
        return subCategory;
    }

    public void categoryBridge(CategoryBridgeVo categoryBridgeVo){
        if(categoryBridgeVo == null){throw new IllegalArgumentException("존재하지 않는 카테고리 번호");};
        userMapper.categoryBridge(categoryBridgeVo);

    }

    public void joinMentor(MentorDto mentorDto){
        if(mentorDto == null){throw new IllegalArgumentException("존재하지 않는 회원");};
        userMapper.joinMentor(mentorDto);
    }

    public void joinPfp(UserPfpDto userPfpDto){
        userMapper.joinPfp(userPfpDto);
    }

    // 인증 태그 카테고리
    public List<UserCategoryVo> certificationH(){
        List<UserCategoryVo> categoryH = userMapper.certificationH();

        for (int i=0; i<categoryH.size(); i++){
            categoryH.get(i).getMainCode();
            categoryH.get(i).getMainName();
        }

        return categoryH;
    }

    public List<UserCategoryVo> certificationJ(){
        List<UserCategoryVo> categoryJ = userMapper.certificationJ();

        for(int i=0; i<categoryJ.size(); i++){
            categoryJ.get(i).getSubNumber();
            categoryJ.get(i).getSubName();
        }

        return categoryJ;
    }

    public List<UserCategoryVo> certificationSub(String mainCode){
        List<UserCategoryVo> subCategory = userMapper.certificationSub(mainCode);
        System.out.println(subCategory);
        return subCategory;
    }
UserMapper.xml
    <!--회원가입-->
    <insert id="join">
        <selectKey keyProperty="userNumber" order="BEFORE" resultType="Long">
            SELECT SEQ_WWUSER.NEXTVAL FROM DUAL
        </selectKey>
        INSERT INTO WW_USER (USER_NUMBER, USER_NAME, USER_ID, USER_PASSWORD, USER_EMAIL, USER_RRNUMBER, USER_NICKNAME,
        USER_PHONE_NUMBER, USER_BELONG, USER_GENDER, USER_IDENTITY, USER_POSITION)
        VALUES (#{userNumber}, #{userName}, #{userId}, #{userPassword}, #{userEmail}, #{userRrnumber}, #{userNickname},
        #{userPhoneNumber}, #{userBelong},
        <trim suffix=",">
            <if test="userGender == 1 or userGender == 3">
                ''
            </if>
            <if test="userGender == 2 or userGender == 4">
                ''
            </if>
        </trim>
        <trim suffix=",">
            <if test="userIdentity.equals('identity-worker')">
                '직장인'
            </if>
            <if test="userIdentity.equals('identity-un-student')">
                '대학생'
            </if>
            <if test="userIdentity.equals('identity-high-student')">
                '고등학생'
            </if>
        </trim>
        <trim suffix=")">
            <if test="userPosition.equals('mentor')">
                '멘토'
            </if>
            <if test="userPosition.equals('mentee')">
                '멘티'
            </if>
        </trim>
    </insert>

    <!--회원번호로 이름, 윙 갯수, 상태 조회-->
    <select id="findUserInfo" resultType="userDto">
        SELECT USER_NICKNAME, USER_WING, USER_STATUS , USER_POSITION
        FROM WW_USER
        WHERE USER_NUMBER = #{userNumber}
    </select>

    <!-- 아이디 중복 체크 -->
    <select id="checkId" resultType="_int">
        SELECT COUNT (*)
        FROM WW_USER
        WHERE USER_ID = #{userId}
    </select>

    <!-- 닉네임 중복 체크 -->
    <select id="checkNickname" resultType="_int">
        SELECT COUNT (*)
        FROM WW_USER
        WHERE USER_NICKNAME = #{userNickname}
    </select>
    
    <!-- 관심분야 카테고리 -->
    <select id="categoryH" resultType="categoryVo">
        SELECT *
        FROM MAIN_CATEGORY mc
        WHERE MAIN_CODE LIKE '1__'
    </select>

    <select id="categoryJ" resultType="categoryVo">
        SELECT *
        FROM MAIN_CATEGORY mc
        WHERE MAIN_CODE LIKE '2__'
    </select>

    <select id="subCategory" resultType="categoryVo">
        SELECT *
        FROM SUB_CATEGORY sc
        WHERE main_code = #{mainCode}
    </select>

    <!-- 관심분야 태그 bridge -->
    <insert id="categoryBridge">
        <selectKey keyProperty="bridgeNumber" order="BEFORE" resultType="Long">
            SELECT SEQ_BRIDGE.NEXTVAL FROM DUAL
        </selectKey>
        INSERT INTO SU_BRIDGE (BRIDGE_NUMBER, SUB_NUMBER, USER_NUMBER)
        VALUES (#{bridgeNumber}, #{subNumber}, #{userNumber})
    </insert>

    <!-- 회원가입 시 멘토테이블 등록 -->
    <insert id="joinMentor">
        <selectKey keyProperty="mentorNumber" order="BEFORE" resultType="Long">
            SELECT SEQ_MENTOR.NEXTVAL FROM DUAL
        </selectKey>
        INSERT INTO MENTOR (MENTOR_NUMBER, USER_NUMBER, SUB_NUMBER)
        VALUES (#{mentorNumber}, #{userNumber}, #{certificationNumber})
    </insert>

    <!-- 인증 태그 -->
    <select id="certificationH" resultType="userCategoryVo">
        SELECT *
        FROM MAIN_CATEGORY
        WHERE MAIN_CODE LIKE '1__'
    </select>
join.js
let $current = $('.login-box'); // 첫 번째 모달창 (처음에는 로그인 고정, 이후 변경)
let $next = null; // 다음 모달창 (항시 변경)
let $checkIdMsg = $('#join-check-id-msg');
let $checkPwMsg = $("#join-check-pw-msg");
let $checkPwMsg2 = $("#join-check-pw-msg2");
let $checkEmailMsg = $('#join-check-email-msg');

// 아이디 정규식
// 영문/숫자만 입력 가능 || 전체 길이 = 2-15자
let $idPattern = RegExp("^[a-zA-Z][0-9a-zA-Z]{2,14}$");

// 닉네임 정규식
// 특수문자 절대 못 씀
let nicknamePattern = /[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/ ]/gim;

// 이메일 정규식
// @, . 무조건 들어가야 함 || @를 제외한 특수문자 입력 안 됨
let $emailPattern = RegExp("^[0-9a-zA-Z]([-_\\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\\.]?[0-9a-zA-Z])*\\.[a-zA-Z]{2,3}$");

// 비밀번호 정규식
//영어, 숫자, 특수문자 입력 || 최소 8자 이상 || 영어 대소문자를 구분 안 함
const regex = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[a-zA-Z\d!@#$%^&*()_+]{8,}$/;

// 이름 정규식
// 한글 또는 영문만 가능 (혼용x)
let namePattern = /^[-]{2,4}|[a-zA-Z]{2,10}\s[a-zA-Z]{2,10}$/;

// 주민번호, 핸드폰번호, 인증번호
// 숫자만 입력할 수 있음
let numberPattern = /^[0-9]+$/;




// 모달창 이동처리
$('.modal-next').on('click', function(){

    if($current.hasClass('login-box')){

        return;
    }


    if($current.hasClass('message-box')){
        console.log('메세지 이후 처리');

    }

    if($current.hasClass('find-id-box')){
        $('.modal-next').addClass('none');
        $('.home-btn').addClass('none');
        $('.home-btn-2').removeClass('none');
        $next = $('.result-id-box');
    }

    if($current.hasClass('find-pw-box')){
        $('.modal-next').addClass('none');
        $('.home-btn').addClass('none');
        $('.home-btn-2').removeClass('none');
        $next = $('.result-pw-box');
    }

    if($current.hasClass('result-id-box')){
        // $next = $('.result-id-box');
        $('.modal-next').addClass('none');
        $('.home-btn').addClass('none');
        $('.home-btn-2').removeClass('none');
    }

    if($current.hasClass('result-pw-box')){
        // $next = $('.result-id-box');
        $('.modal-next').addClass('none');
        $('.home-btn').addClass('none');
        $('.home-btn-2').removeClass('none');
    }

    if($current.hasClass('agreement-box')){
        //약관 확인
        if (!$("#agreement-check2").is(":checked") || !$("#agreement-check3").is(":checked")) {
            console.log('약관 확인 처리!')
            return;
        }
        $next = $('.self-box');
    }



    if($current.hasClass('self-box')){

        console.log($('.radioInput').val());

        if($('#user-name').val() == '') {
            return;
        }else if(!namePattern.test($('#user-name').val())){
            return;
        }else if($('#self-number').val() == '' || $('#self-gender').val() == ''){
            return;
        }else if($('#self-gender').val() >= 5){
            return;
        }else if(!numberPattern.test($('#self-number').val()) || !numberPattern.test($('#self-gender').val())){
            return;
        }else if($('#userPhoneNumber').val() == ''){
            return;
        }else if(!numberPattern.test($('#userPhoneNumber').val()) || !numberPattern.test($('#userVerification').val())){
            return;
        }else if($('#userVerification').val() == ''){
            return;
        }
        $next = $('.join-box');

    }

    if($current.hasClass('join-box')){

        if($('#join-id-input').val() == ''){
            return;
        }else if($('#userNickname').val() == ''){
            return;
        }else if($('#join-pw-input').val() == ''){
            return;
        }else if(!regex.test($('#join-pw-input').val())){
            return;
        }else if($("#join-pw-input2").val() != "" && $("#join-pw-input").val() != $("#join-pw-input2").val()){
            return;
        }else if($('#userEmail').val() == ''){
            return;
        } else if(!$emailPattern.test($('#userEmail').val())){
            return;
        }

        $next = $('.job-dep-box');
    }

    if($current.hasClass('job-dep-box')){

        if($('.job-tag').val() == null){
            $('.job-dep-text').html("최소 1개 이상의 태그를 선택해 주세요.");
            return;
        }

        $next = $('.goal-box');
    }


    if ($current.hasClass('identity-belong-box')){

            $next = $('.mentor-goal-box');
    }



    if ($current.hasClass('mentor-goal-box')){

        if($('.userBelong').val() == ''){
            $('#com-check-msg').html("회사명/학교명을 입력해 주세요.");
            return;
        }
        $next = $('.certification-box');
    }


    if ($current.hasClass('certification-box')){
        $next = $('.sign-box');

        $('.modal-next').addClass('none');
        $('.home-btn').removeClass('none');
    }

    if ($next.hasClass('sign-box')){
        $('.modal-next').addClass('none');
        $('.home-btn').removeClass('none');
    }


    changeModal($current, $next);

});

/**
 * 모달창 변경하는 함수
 *
 * @param $currentParam 현재 페이지를 jquery객체로 넘겨주기
 * @param $nextParam 다음 페이지를 jquery객체로 넘겨주기
 */
function changeModal($currentParam, $nextParam){
    //현재 페이지 화면에서 사라지기
    $currentParam.addClass('disappear');
    $currentParam.removeClass('appear');
    $currentParam.addClass('none');

    //다음 페이지 화면에 보이기
    $nextParam.removeClass('none');
    $nextParam.addClass('appear');

    $current = $nextParam;
}


// 회원가입 (첫 페이지 : 약관 동의)
$('.login-kakao').on('click', function(e){
    e.preventDefault();
    $next = $('.agreement-box');
    changeModal($current, $next);
    $('.login-end').addClass('none');
    $('.modal-next').removeClass('none');
})

// 가입 목적 버튼에 따라 다음페이지가 달라짐
$('.btn1').on('click', function(){

    $('.goal-mm-value').val('mentor');

    $next = $('.identity-belong-box');

})

$('.btn3').on('click', function (){

    $('.goal-mm-value').val('mentorMentee');

    $next = $('.identity-belong-box');
})

$('.btn2').on('click', function (){

    $('.goal-mm-value').val('mentee');

    $next = $('.sign-box');
})



// 회원가입 처리
$('.home-btn').on('click', function (){

    console.log("드러와따 ~~~")
    let form = document.createElement("form");
    form.setAttribute("charset", "UTF-8");
    form.setAttribute("method", "Post");  //Post 방식
    form.setAttribute("action", "/main/main"); //요청 보낼 주소

    let hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userName");
    hiddenField.setAttribute("value", $('#user-name').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userRrnumber");
    hiddenField.setAttribute("value", $('#self-number').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userPhoneNumber");
    hiddenField.setAttribute("value", $('#userPhoneNumber').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userId");
    hiddenField.setAttribute("value", $('#join-id-input').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userPassword");
    hiddenField.setAttribute("value", $('#join-pw-input').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userEmail");
    hiddenField.setAttribute("value", $('#userEmail').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userGender");
    hiddenField.setAttribute("value", $('#self-gender').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userNickname");
    hiddenField.setAttribute("value", $('#userNickname').val());
    form.appendChild(hiddenField);

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userIdentity");
    hiddenField.setAttribute("value", $('.radioInput:checked').val());
    form.appendChild(hiddenField);


    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userBelong");
    hiddenField.setAttribute("value", $('.userBelong').val());
    form.appendChild(hiddenField);
    
    $('.job-tag>input').each((i, obj) => {
        let value = $(obj).val();

        hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", "subNumber");
        hiddenField.setAttribute("value", value);
        form.appendChild(hiddenField);
    })

    hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", "userPosition");
    hiddenField.setAttribute("value", $('.goal-mm-value').val());
    form.appendChild(hiddenField);

    if($('#certi-input').val()){
        hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", "certificationNumber");
        hiddenField.setAttribute("value", $('#certi-input').val());
        form.appendChild(hiddenField);
    }


    document.body.appendChild(form);
    form.submit();
});



// 아이디 중복 검사
$('#join-id-input').on('blur', function() {
    if ($(this).val() == '') {
        $checkIdMsg.text('아이디를 입력하세요.');
    }else if(!$idPattern.test($(this).val())){
        $checkIdMsg.text('아이디는 영문/숫자만 가능하며 3-15자 이내로 작성해 주세요.');
    }
    else {
        console.log($(this).val());
        let id = $(this).val();
        $.ajax({
            url: '/users/checkId',
            type: 'post',
            data : {'userId' : id},
            success : function(result) {
                //서버와 통신성공시 실행할 내용 작성.
                console.log('통신 성공!');
                if (result === 0) {
                    $checkIdMsg.html('사용 가능한 아이디 입니다.');
                } else {
                    $checkIdMsg.html('중복된 아이디 입니다.');
                }
            }
        });
    }
});

let $checkNicknameMsg = $('#join-check-nickname-msg');

// 닉네임 중복 검사
$('#userNickname').on('blur', function() {
    if ($(this).val() == '') {
        $checkNicknameMsg.text('닉네임을 입력하세요.');
    }else if(nicknamePattern.test($(this).val())){
        $checkNicknameMsg.text('특수문자는 사용이 불가능 합니다.');
    }
    else {
        console.log($(this).val());
        let nickname = $(this).val();
        $.ajax({
            url: '/users/checkNickname',
            type: 'post',
            data : {'userNickname' : nickname},
            success : function(result) {
                //서버와 통신성공시 실행할 내용 작성.
                console.log('통신 성공!');
                if (result === 0) {
                    $checkNicknameMsg.html('사용 가능한 닉네임 입니다.');
                } else {
                    $checkNicknameMsg.html('중복된 닉네임 입니다.');
                }
            }
        });
    }
});



// 비밀번호 조건
$("#join-pw-input").on("blur", function () {
    if($(this).val() == ''){
        $checkPwMsg.text("비밀번호를 입력해 주세요.");
    }else if (regex.test($(this).val())) {
        $checkPwMsg.text("사용가능한 비밀번호 입니다.");
    } else {
        $checkPwMsg.html("사용 불가능한 비밀번호입니다.<br>영어, 숫자, 특수문자를 포함한 8글자 이상으로 작성해주세요.");
    }
    if ($("#join-pw-input2").val() != "" && $("#join-pw-input").val() == $("#join-pw-input2").val()) {
        $checkPwMsg2.html("비밀번호가 일치합니다.");
    } else if ($("#join-pw-input2").val() != "" && $("#join-pw-input").val() != $("#join-pw-input2").val()) {
        $checkPwMsg2.text("비밀번호가 일치하지 않습니다.");
    }
});

// 비밀번호 동일확인
$("#join-pw-input2").on("blur", function () {
    console.log($("#join-pw-input").val());
    if ($("#join-pw-input").val() != $("#join-pw-input2").val()) {
        $checkPwMsg2.text("비밀번호가 일치하지 않습니다.");
    } else {
        $checkPwMsg2.html("비밀번호가 일치합니다.");
    }
});

// 이메일 조건
$("#userEmail").on("blur", function () {
    if($(this).val() == ''){
        $checkEmailMsg.text("이메일을 입력해 주세요.");
    }else if ($emailPattern.test($(this).val())) {
        $checkEmailMsg.text("사용가능한 이메일 입니다.");
    } else {
        $checkEmailMsg.html("올바른 형식의 이메일이 아닙니다.");
    }

});

// 이름 조건
$('#user-name').on('blur', function (){
    if(!namePattern.test($('#user-name').val())){
        $('#user-name-msg').text('잘못된 형식의 이름입니다.');
    }else {
        $('#user-name-msg').text('');
    }
});

// 주민번호 조건
$('#self-number').on('blur', function (){
    if(!numberPattern.test($('#self-number').val())){
        $('#user-rrnumber-msg').text('올바른 형식의 주민등록번호가 아닙니다.');
    }else{
        $('#user-rrnumber-msg').text('');
    }
});

$('#self-gender').on('blur', function (){
    if(!numberPattern.test($('#self-gender').val())){
        $('#user-rrnumber-msg').text('올바른 형식의 주민등록번호가 아닙니다.');
    }else if ($('#self-gender').val() >= 5){
        $('#user-rrnumber-msg').text('올바른 형식의 주민등록번호가 아닙니다.');
    }else{
        $('#user-rrnumber-msg').text('');
    }
});

// 전화번호, 인증번호 조건
$('#userPhoneNumber').on('blur', function (){
    if(!numberPattern.test($('#userPhoneNumber').val())){
        $('#user-phone-msg').text('올바른 형식의 번호가 아닙니다.')
    }else{
        $('#user-phone-msg').text('')
    }
});

$('#userVerification').on('blur', function (){
    if(!numberPattern.test($('#userVerification').val())){
        $('#user-phone-msg').text('올바른 형식의 번호가 아닙니다.')
    }else{
        $('#user-phone-msg').text('')
    }
});



// ========================================
// 약관 동의 js
//체크박스 전체선택
$("#agreement-check1").on("click", function () {
    if ($(this).is(":checked")) {
        $(".agreement-check").prop("checked", true);
    } else {
        $(".agreement-check").prop("checked", false);
    }
});

$(".agreement-input-btn").on("click", ".check", function () {
    console.log("check");
    $("#agreement-check1").prop("checked", false);
});

$(".agreement-check").on("change", function () {
    if ($("#agreement-check2").is(":checked") && $("#agreement-check3").is(":checked") && $("#agreement-check4").is(":checked")) {
        $("#agreement-check1").prop("checked", true);
    }
});

$(".check").on("change", function () {

    if ($("#check2").is(":checked") && $("#check3").is(":checked") && $("#check4").is(":checked")) {
        $("#check1").prop("checked", true);
    }
});

// ========================================
// 관심분야 태그 js

// 1,2,3차 카테고리 선택

const selectBoxElements = document.querySelectorAll(".job-select");

function toggleSelectBox(selectBox) {
    selectBox.classList.toggle("job-active");
}

function selectOption(optionElement) {
    const selectBox = optionElement.closest(".job-select");
    const selectedElement = selectBox.querySelector(".job-selected-value");
    selectedElement.textContent = optionElement.textContent;
}

selectBoxElements.forEach((selectBoxElement) => {
    selectBoxElement.addEventListener("click", function (e) {
        const targetElement = e.target;
        const isOptionElement = targetElement.classList.contains("job-option");

        if (isOptionElement) {
            selectOption(targetElement);
        }

        toggleSelectBox(selectBoxElement);
        if (e.target.classList.contains("job-option")) {
            $(e.target).closest(".job-select").find(".job-arrow").removeClass("job-arrow-after");
        }

        e.preventDefault();
    });
});

document.addEventListener("click", function (e) {
    const targetElement = e.target;
    const isSelect = targetElement.classList.contains("job-select") || targetElement.closest(".job-select");

    if (isSelect) {
        return;
    }

    const allSelectBoxElements = document.querySelectorAll(".job-select");

    allSelectBoxElements.forEach((boxElement) => {
        boxElement.classList.remove("job-active");
        $(boxElement).find(".job-arrow").removeClass("job-arrow-after");
    });
});

$(".job-third-job-box").on("click", ".job-option2", function () {
    let text = $(this).text();

    let tagHtml = `<div class="job-tag">@${text}</div>`;

    $(".job-select-tag").append(tagHtml);
});

$(".job-select-tag").on("click", ".job-tag", function () {
    $(this).detach();
});

// 나의 관심분야 3가지 카테고리 박스
let $boxes = $('.job-select');

//클릭하면 리스트 div 보기,닫기
$boxes.on('click', function(){
    if($(this).closest('.job-select').find('.job-option-box').hasClass('none')){
        $('.job-option-box').addClass('none');
        $(this).closest('.job-select').find('.job-option-box').toggleClass('none');
    }else{
        $('.job-option-box').addClass('none');
    }
});

//고른 항목 텍스트 상위로 복사
$('.job-select').on('click', '.option', function(){
    $(this).closest('.job-select').find('.job-selected-value').text($(this).text());
});

//다른 곳 클릭 시 리스트 div 닫기
$("body").on('click', function(e){
    if(!$(e.target).closest('.job-select').hasClass('job-select')){
        $boxes.each((i, box) => {$(box).find('.job-option-box').addClass('none');});
    }
});

//3차 카테고리 선택 시 태그 추가(최대 3개)
$(".job-third-job-box").on("click", ".job-option", function () {
    let text = $(this).text();
    let val = $(this).val();

    let existingTags = $(".job-select-tag .job-tag");
    if (existingTags.length >= 3) { return; }

    for(let i=0; i<existingTags.length; i++){
        if(existingTags.eq(i).text() == '@' + text){
            return;
        }
    }

    let tagHtml = `<div class="job-tag" name="subNumber" value="${val}">@${text}
                                <input type="hidden" name="subNumber" value="${val}"/>
                            </div>
                            `;

    $(".job-select-tag").append(tagHtml);
});

// 태그 눌렀을 때 삭제
$(".job-select-tag").on("click", ".job-tag", function () {
    $(this).detach();
});

// 1, 2, 3차 카테고리 별 항목 띄우기

// 1차 카테고리
let $category = $(".job-first-option-box");
// 2차 카테고리
let $jobBox = $(".job-second-job-box");
// 3차 카테고리
let $depBox = $(".job-third-job-box");

$(".job-option").on("click", function () {
    let text = "";
    $jobBox.html(text);
    // 직무일때
    let ss = $(this).val();
    if ($(this).val() == "1") {
        // 백엔드 작업시 비동기 통신 사용해서 꽂기
        $.ajax({
          url: "/users/categoryJ",
          type: "get",
          data: { mainCode: ss },
          dataType : 'json',
          success: function (result) {
            makeMiddleCate(result);
          },
        });

    }

    // 학과일때
    if ($(this).val() == "2") {
        // 백엔드 작업시 비동기 통신 사용해서 꽂기
        $.ajax({
          url: "/users/categoryH",
          type: "get",
            data: { mainCode: ss },
            dataType : 'json',
          success: function (result) {
            makeMiddleCate(result);
          },
        });
    }

    $jobBox.html(text);
});

$(".job-second-job-box").on("click", ".job-option", function () {
    let text = "";

    $depBox.html(text)
    let ss = $(this).val();
    $.ajax({
        url : '/users/subCategory',
        type : 'get',
        data : { mainCode : ss },
        dataType : 'json',
        success : function (result) {
            let text2 = '';
            result.forEach(r => {
                text2 +=`
                    <li class="job-option" value="${r.subNumber}">${r.subName}</li>
                    `;
            });
            $('.job-third-job-box').html(text2);
        }
    });
    $depBox.html(text);

});

// 2, 3차 카테고리 선택 시 항목 띄어주는 함수

function makeMiddleCate(result) {
    let text2 = '';

    result.forEach((r) => {
        text2 += `<li class="job-option" value="${r.mainCode}">${r.mainName}</li>`;
    });

    $('.job-second-job-box').html(text2);

    return text2;
}


// ========================================
// 직장인 인증 js
$("#mentor-goal-file").on("change", function () {
    let files = [...this.files];

    if (files.length == 1) {
        $(this).closest(".mentor-goal-box").find(".mentor-goal-file-name1").text(files[0].name);
        $(this).closest(".mentor-goal-box").find(".mentor-goal-name1").removeClass("mentor-goal-none");
        $(this).closest(".mentor-goal-box").find(".mentor-goal-file-name2").text("");
        $(this).closest(".mentor-goal-box").find(".mentor-goal-name2").addClass("mentor-goal-none");
    } else if (files.length == 2) {
        $(this).closest(".mentor-goal-box").find(".mentor-goal-file-name1").text(files[0].name);
        $(this).closest(".mentor-goal-box").find(".mentor-goal-name1").removeClass("mentor-goal-none");
        $(this).closest(".mentor-goal-box").find(".mentor-goal-file-name2").text(files[1].name);
        $(this).closest(".mentor-goal-box").find(".mentor-goal-name2").removeClass("mentor-goal-none");
    } else {
        alert("파일은 최대 2개까지 업로드 가능합니다.");
    }
});

$(".bi-trash3").on("click", function () {
    let targetName = $(this).closest(".mentor-goal-name-box").find(".mentor-goal-file-name1").text();
    $(this).closest(".mentor-goal-name-box").find(".mentor-goal-file-name1").text("");
    $(this).closest(".mentor-goal-name-box").find(".mentor-goal-name1").addClass("mentor-goal-none");
    $(this).closest(".mentor-goal-name-box").find(".mentor-goal-file-name2").text("");
    $(this).closest(".mentor-goal-name-box").find(".mentor-goal-name2").addClass("mentor-goal-none");

    let $input = $("#mentor-goal-file");
    let oldFiles = $input[0].files;
    console.log($input[0].files);

    let dt = new DataTransfer();

    for (let i = 0; i < 2; i++) {
        if ($input[0].files[i].name != targetName) {
            dt.items.add(oldFiles[i]);
        }
    }
    let newFiles = dt.files;

    $input[0].files = newFiles;

    console.log($input[0].files);
});

// ========================================
// 대학생 인증 js
$("#mentor-goal-2-file").on("change", function () {
    let files = [...this.files];

    if (files.length == 1) {
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-file-name1").text(files[0].name);
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-name1").removeClass("mentor-goal-2-none");
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-file-name2").text("");
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-name2").addClass("mentor-goal-2-none");
    } else if (files.length == 2) {
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-file-name1").text(files[0].name);
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-name1").removeClass("mentor-goal-2-none");
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-file-name2").text(files[1].name);
        $(this).closest(".mentor-goal-2-box").find(".mentor-goal-2-name2").removeClass("mentor-goal-2-none");
    } else {
        alert("파일은 최대 2개까지 업로드 가능합니다.");
    }
});

$(".bi-trash2").on("click", function () {
    let targetName = $(this).closest(".mentor-goal-2-name-box").find(".mentor-goal-2-file-name1").text();
    $(this).closest(".mentor-goal-2-name-box").find(".mentor-goal-2-file-name1").text("");
    $(this).closest(".mentor-goal-2-name-box").find(".mentor-goal-2-name1").addClass("mentor-goal-2-none");
    $(this).closest(".mentor-goal-2-name-box").find(".mentor-goal-2-file-name2").text("");
    $(this).closest(".mentor-goal-2-name-box").find(".mentor-goal-2-name2").addClass("mentor-goal-2-none");

    let $input = $("#mentor-goal-2-file");
    let oldFiles = $input[0].files;
    console.log($input[0].files);

    let dt = new DataTransfer();

    for (let i = 0; i < 2; i++) {
        if ($input[0].files[i].name != targetName) {
            dt.items.add(oldFiles[i]);
        }
    }
    let newFiles = dt.files;

    $input[0].files = newFiles;

    console.log($input[0].files);

});

// ========================================
// 인증 태그 js

// 셀렉트 박스 클릭 이벤트
$('.certi-select').on('click', function (){
    let $optionBox = $(this).find('.certi-option__box');
    if($optionBox.css('display') == 'none'){
        $optionBox.show();
    }else{
        $optionBox.hide();
    }
});

// 옵션 클릭 이벤트
$('.certi-option__box').on('click', '.certi-option', function (){
    let $selectedValue = $(this).closest('.certi-select').find('.certi-selected-value');
    $selectedValue.text($(this).text());

    let $ul = $(this).closest('ul');

    if($ul.hasClass('certi-first-option-box')){
        if($(this).val() == 1){
            getCertificationJ();
        }else {
            getCertificationH();
        }
    }else if($ul.hasClass('certi-second-job-box')){
        getCertificationSub($(this).val());
    }else if($ul.hasClass('certi-third-job-box')){

        if($('.certi-tag').length > 0){
            return;
        }

        let subName = $(this).text();
        let value = $(this).val();
        console.log(value);
        $('.certi-select-tag').append(`
                                <div class="certi-tag">@${subName}
                                 <input type="hidden" class="certi-input" id="certi-input" name="certificationNumber" value="${value}"/>
                             </div>`);
    }


});

$(".certi-select-tag").on("click", ".certi-tag", function () {
    $(this).detach();
});

function makeCertiOptionList(result){
    let htmlTags = '';

    result.forEach(obj => {
        htmlTags += `<li class="certi-option" value="${obj.mainCode}">${obj.mainName ? obj.mainName : obj.subName}</li>`;
    });

    return htmlTags
}

function makeCertiSubOptionList(result){
    let htmlTags = '';

    result.forEach(obj => {
        htmlTags += `<li class="certi-option" value="${obj.subNumber}">${obj.mainName ? obj.mainName : obj.subName}</li>`;
    });

    return htmlTags
}

function getCertificationSub(mainCode){
    $.ajax({
        url: '/users/certificationSub',
        type: 'get',
        data: {mainCode: mainCode},
        dataType: 'json',
        success: function (result) {
            console.log(result)
            $('.certi-third-job-box').html(makeCertiSubOptionList(result));
        }
    });
}

function getCertificationH(){
    $.ajax({
        url: "/users/certificationH",
        type: "get",
        dataType : 'json',
        success: function (result) {
            console.log(result);
            $('.certi-second-job-box').html(makeCertiOptionList(result));
        },
    });
}

function getCertificationJ(){
    $.ajax({
        url: "/users/certificationJ",
        type: "get",
        dataType : 'json',
        success: function (result) {
            console.log(result);
           $('.certi-second-job-box').html(makeCertiOptionList(result));
        },
    });
}





// ========================================
// SMS 인증

let timeout = null;

$('#sms-check').on('click', function (){
    let phoneNumber = $('#userPhoneNumber').val();

    console.log(phoneNumber);

    $.ajax({
        url: "/userSms/v1/send",
        type: "post",
        data: JSON.stringify({phoneNumber : phoneNumber}),
        contentType: "application/json; charset=utf-8",
        success: function (result){
            console.log(result)

            let time = 180;
            let min = '';
            let sec = '';

            timeout = setInterval(function (){
                min = parseInt(time / 60);
                sec = time % 60;
                $('.self-timer').text(`${min}${sec}초`);

                time--;

                if(time < 0){
                    clearInterval(timeout);
                    $('.self-timer').text('시간초과');
                }
            }, 1000);

        }
    })
});

$('#self-check-number').on('click', function (){
    let inputNumber= $('#userVerification').val();

    $.ajax({
        url : '/userSms/v1/check',
        type : 'post',
        data : {authNumber : inputNumber},
        success : function (result){
            if(result){
                $('#user-phone-msg').text("인증이 완료되었습니다.");
                clearInterval(timeout);
                $('.self-timer').text('');
            }else{
                $('#user-phone-msg').text("인증번호가 올바르지 않습니다.");
            }
        }
    });
})


📸 view

Image




// 멘티로 가입시 여기서 회원가입 완료



JoinGip

⚠️ **GitHub.com Fallback** ⚠️