فهرست منبع

아이디찾기/비밀번호찾기 완료

DESKTOP-T61HUSC\user 4 ماه پیش
والد
کامیت
08122d711b
5فایلهای تغییر یافته به همراه1206 افزوده شده و 929 حذف شده
  1. 1 1
      assets/scss/style.scss
  2. 2 0
      backend/app/Config/Routes.php
  3. 299 2
      backend/app/Controllers/Auth.php
  4. 136 904
      backend/app/Controllers/Mypage.php
  5. 768 22
      pages/index.vue

+ 1 - 1
assets/scss/style.scss

@@ -3521,6 +3521,7 @@ p.success-txt {
   min-height: 700px;
   background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
   overflow: hidden;
+  overflow-y: auto;
   
   &::after {
     content: '';
@@ -3545,7 +3546,6 @@ p.success-txt {
     50% { transform: scale(1.1) rotate(180deg); opacity: 0.8; }
   }
   
-  overflow-y: auto;
   .login-box {
     height: auto;
     box-shadow: 0 25px 50px rgba(0,0,0,0.15);

+ 2 - 0
backend/app/Config/Routes.php

@@ -18,6 +18,8 @@ $routes->get('auth/naverLogin', 'Auth::naverLogin');
 $routes->get('auth/naver', 'Auth::naver');
 $routes->get('auth/naverWithdrawal', 'Auth::naverWithdrawal');
 $routes->post('auth/checkId', 'Auth::checkId'); // 사용 중 체크 아이디
+$routes->post('auth/findId', 'Auth::findId');
+$routes->post('auth/findPw', 'Auth::findPw');
 
 $routes->get('/', 'Home::index'); //홈화면 리다이렉트용
 $routes->post('roulette/login', 'Roulette::login'); //로그인 페이지 토큰 상관없이 호출가능

+ 299 - 2
backend/app/Controllers/Auth.php

@@ -13,9 +13,9 @@ use App\Libraries\JwtLib\Key;
 
 class Auth extends ResourceController
 {
-    private const FRONTEND_BASE_URL = "http://localhost:3000";
+    //private const FRONTEND_BASE_URL = "http://localhost:3000";
 
-    //private const FRONTEND_BASE_URL = 'https://shopdeli.mycafe24.com';
+    private const FRONTEND_BASE_URL = 'https://shopdeli.mycafe24.com';
     protected $userModel;
 
     public function __construct()
@@ -1005,4 +1005,301 @@ class Auth extends ResourceController
             ])->setStatusCode(500);
         }
     }
+
+    /***********************************
+     * 아이디 찾기
+     **********************************/
+    public function findId()
+    {
+        $postData = $this->request->getJSON(true);
+
+        // POST 데이터에서 값 추출
+        $name = $postData['name'] ?? null;
+        $email = $postData['email'] ?? null;
+        $memberType = $postData['memberType'] ?? null;
+
+        // 필수값 검증
+        if (empty($name) || empty($email) || empty($memberType)) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => '필수 정보가 누락되었습니다.'
+            ])->setStatusCode(400);
+        }
+
+        $db = \Config\Database::connect();
+        $foundUserIds = [];
+
+        try {
+            // memberType에 따라 다른 테이블에서 아이디 찾기
+            if ($memberType === 'vendor') {
+                // 벤더 회원의 경우 VENDOR_LIST 테이블 검색 (REG_DATE 컬럼 사용)
+                $builder = $db->table('VENDOR_LIST');
+                $users = $builder
+                    ->select('ID, COMPANY_NAME, NAME, REG_DATE')
+                    ->where('NAME', $name)
+                    ->where('EMAIL', $email)
+                    ->get()
+                    ->getResultArray();
+
+                foreach ($users as $user) {
+                    $foundUserIds[] = [
+                        'id' => $user['ID'],
+                        'memberType' => 'vendor',
+                        'joinDate' => $user['REG_DATE'], // REG_DATE 컬럼 사용
+                        'companyName' => $user['COMPANY_NAME']
+                    ];
+                }
+
+            } elseif ($memberType === 'brand') {
+                // 브랜드 회원의 경우 BRAND_LIST 테이블 검색 (REG_DATE 컬럼 사용)
+                $builder = $db->table('BRAND_LIST');
+                $users = $builder
+                    ->select('ID, COMPANY_NAME, NAME, REG_DATE')
+                    ->where('NAME', $name)
+                    ->where('EMAIL', $email)
+                    ->get()
+                    ->getResultArray();
+
+                foreach ($users as $user) {
+                    $foundUserIds[] = [
+                        'id' => $user['ID'],
+                        'memberType' => 'brand',
+                        'joinDate' => $user['REG_DATE'], // REG_DATE 컬럼 사용
+                        'companyName' => $user['COMPANY_NAME']
+                    ];
+                }
+
+            } elseif ($memberType === 'influence' || $memberType === 'influencer') {
+                // 인플루언서(일반회원)의 경우 USER_LIST 테이블 검색
+                $builder = $db->table('USER_LIST');
+                $users = $builder
+                    ->select('ID, NAME, NICK_NAME, REGDATE')
+                    ->where('NAME', $name)
+                    ->where('EMAIL', $email)
+                    ->get()
+                    ->getResultArray();
+
+                foreach ($users as $user) {
+                    $foundUserIds[] = [
+                        'id' => $user['ID'],
+                        'memberType' => 'influence',
+                        'joinDate' => $user['REGDATE'],
+                        'nickname' => $user['NICK_NAME']
+                    ];
+                }
+
+            } else {
+                return $this->response->setJSON([
+                    'status' => 'fail',
+                    'message' => '유효하지 않은 회원 유형입니다.'
+                ])->setStatusCode(400);
+            }
+
+            // 결과가 없는 경우
+            if (empty($foundUserIds)) {
+                return $this->response->setJSON([
+                    'status' => 'not_found',
+                    'message' => '입력하신 정보와 일치하는 아이디가 없습니다.',
+                    'userIds' => []
+                ])->setStatusCode(404);
+            }
+
+            // 아이디를 찾은 경우
+            return $this->response->setJSON([
+                'status' => 'success',
+                'message' => '아이디를 찾았습니다.',
+                'userIds' => $foundUserIds
+            ])->setStatusCode(200);
+
+        } catch (\Throwable $e) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => 'DB 오류: ' . $e->getMessage()
+            ])->setStatusCode(500);
+        }
+    }
+
+    /***********************************
+     * 비밀번호 찾기
+     **********************************/
+    public function findPw()
+    {
+        $postData = $this->request->getJSON(true);
+
+        // POST 데이터에서 값 추출
+        $step = $postData['step'] ?? 'verify'; // verify: 사용자 확인, change: 비밀번호 변경
+
+        if ($step === 'verify') {
+            // 첫 번째 단계: 사용자 정보 확인
+            return $this->verifyUserForPasswordReset($postData);
+        } elseif ($step === 'change') {
+            // 두 번째 단계: 비밀번호 변경
+            return $this->changeUserPassword($postData);
+        } else {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => '잘못된 요청입니다.'
+            ])->setStatusCode(400);
+        }
+    }
+
+    private function verifyUserForPasswordReset($postData)
+    {
+        $name = $postData['name'] ?? null;
+        $userId = $postData['userId'] ?? null;
+        $email = $postData['email'] ?? null;
+        $memberType = $postData['memberType'] ?? null;
+
+        // 필수값 검증
+        if (empty($name) || empty($userId) || empty($email) || empty($memberType)) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => '필수 정보가 누락되었습니다.'
+            ])->setStatusCode(400);
+        }
+
+        $db = \Config\Database::connect();
+
+        try {
+            // memberType에 따라 다른 테이블에서 사용자 확인
+            if ($memberType === 'vendor') {
+                // 벤더 회원의 경우 VENDOR_LIST 테이블 검색
+                $builder = $db->table('VENDOR_LIST');
+                $user = $builder
+                    ->select('ID, NAME, EMAIL')
+                    ->where('ID', $userId)
+                    ->where('NAME', $name)
+                    ->where('EMAIL', $email)
+                    ->get()
+                    ->getRowArray();
+
+            } elseif ($memberType === 'brand') {
+                // 브랜드 회원의 경우 BRAND_LIST 테이블 검색
+                $builder = $db->table('BRAND_LIST');
+                $user = $builder
+                    ->select('ID, NAME, EMAIL')
+                    ->where('ID', $userId)
+                    ->where('NAME', $name)
+                    ->where('EMAIL', $email)
+                    ->get()
+                    ->getRowArray();
+
+            } elseif ($memberType === 'influence' || $memberType === 'influencer') {
+                // 인플루언서(일반회원)의 경우 USER_LIST 테이블 검색
+                $builder = $db->table('USER_LIST');
+                $user = $builder
+                    ->select('ID, NAME, EMAIL')
+                    ->where('ID', $userId)
+                    ->where('NAME', $name)
+                    ->where('EMAIL', $email)
+                    ->get()
+                    ->getRowArray();
+
+            } else {
+                return $this->response->setJSON([
+                    'status' => 'fail',
+                    'message' => '유효하지 않은 회원 유형입니다.'
+                ])->setStatusCode(400);
+            }
+
+            // 사용자를 찾을 수 없는 경우
+            if (empty($user)) {
+                return $this->response->setJSON([
+                    'status' => 'not_found',
+                    'message' => '입력하신 정보와 일치하는 사용자가 없습니다.'
+                ])->setStatusCode(404);
+            }
+
+            // 사용자를 찾은 경우
+            return $this->response->setJSON([
+                'status' => 'success',
+                'message' => '사용자 정보가 확인되었습니다.',
+                'user' => [
+                    'userId' => $user['ID'],
+                    'memberType' => $memberType
+                ]
+            ])->setStatusCode(200);
+
+        } catch (\Throwable $e) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => 'DB 오류: ' . $e->getMessage()
+            ])->setStatusCode(500);
+        }
+    }
+
+    private function changeUserPassword($postData)
+    {
+        $userId = $postData['userId'] ?? null;
+        $memberType = $postData['memberType'] ?? null;
+        $newPassword = $postData['newPassword'] ?? null;
+
+        // 필수값 검증
+        if (empty($userId) || empty($memberType) || empty($newPassword)) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => '필수 정보가 누락되었습니다.'
+            ])->setStatusCode(400);
+        }
+
+        // 비밀번호 길이 검증
+        if (strlen($newPassword) < 6) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => '비밀번호는 최소 6자 이상이어야 합니다.'
+            ])->setStatusCode(400);
+        }
+
+        $db = \Config\Database::connect();
+
+        try {
+            // 비밀번호 해시화
+            $hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);
+
+            // memberType에 따라 다른 테이블에서 비밀번호 업데이트
+            if ($memberType === 'vendor') {
+                $builder = $db->table('VENDOR_LIST');
+                $result = $builder
+                    ->where('ID', $userId)
+                    ->update(['PASSWORD' => $hashedPassword]);
+
+            } elseif ($memberType === 'brand') {
+                $builder = $db->table('BRAND_LIST');
+                $result = $builder
+                    ->where('ID', $userId)
+                    ->update(['PASSWORD' => $hashedPassword]);
+
+            } elseif ($memberType === 'influence' || $memberType === 'influencer') {
+                $builder = $db->table('USER_LIST');
+                $result = $builder
+                    ->where('ID', $userId)
+                    ->update(['PASSWORD' => $hashedPassword]);
+
+            } else {
+                return $this->response->setJSON([
+                    'status' => 'fail',
+                    'message' => '유효하지 않은 회원 유형입니다.'
+                ])->setStatusCode(400);
+            }
+
+            if (!$result) {
+                return $this->response->setJSON([
+                    'status' => 'fail',
+                    'message' => '비밀번호 변경에 실패했습니다.'
+                ])->setStatusCode(500);
+            }
+
+            // 비밀번호 변경 성공
+            return $this->response->setJSON([
+                'status' => 'success',
+                'message' => '비밀번호가 성공적으로 변경되었습니다.'
+            ])->setStatusCode(200);
+
+        } catch (\Throwable $e) {
+            return $this->response->setJSON([
+                'status' => 'fail',
+                'message' => 'DB 오류: ' . $e->getMessage()
+            ])->setStatusCode(500);
+        }
+    }
 }

+ 136 - 904
backend/app/Controllers/Mypage.php

@@ -3,959 +3,191 @@
 namespace App\Controllers;
 
 use CodeIgniter\RESTful\ResourceController;
+use App\Libraries\JwtLib\JWT;
+use App\Libraries\JwtLib\Key;
+use App\Models\LoginModel;
 
-class Deli extends ResourceController
+class Mypage extends ResourceController
 {
-    // New: 공동구매 주문 내역 리스트
-    public function orderList()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
-
-        // ITEM_ORDER_LIST와 ITEM_LIST를 JOIN해서 주문 목록 조회
-        $builder = $db->table('ITEM_ORDER_LIST IOL')
-            ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2, IL.TYPE as ITEM_TYPE, IL.THUMB_FILE')
-            ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
-            ->where('IL.DEL_YN', 'N'); // 삭제되지 않은 아이템만
-
-        // 아이템 타입 필터링
-        if (!empty($itemType)) {
-            $builder->where('IL.TYPE', $itemType);
-        }
-
-        // 사용자 타입에 따른 필터링
-        if ($memberType === 'VENDOR' && !empty($companyNumber)) {
-            // 벤더사: 자사 아이템의 주문만
-            $builder->where('IL.COMPANY_NUMBER', $companyNumber);
-        } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
-            // 인플루언서: 자신이 담당하는 주문만
-            $builder->where('IOL.INF_SEQ', $infSeq);
-        } elseif ($memberType === 'BRAND' && !empty($infSeq)) {
-            // 브랜드사: 자사가 담당하는 아이템의 주문만
-            $builder->where('IL.CONTACT_BRD', $infSeq);
-        }
-
-        // 주문일 기준으로 최신순 정렬
-        $builder->orderBy('IOL.ORDER_DATE', 'DESC');
-
-        $lists = $builder->get()->getResultArray();
-
-        return $this->respond($lists, 200);
-    }
-
-
-    // New: 공동구매 주문 내역 등록/업데이트
-    public function orderRegister()
+    // 사용자 상세 정보 조회
+    public function myDetail()
     {
         // 한국 시간으로 설정
         date_default_timezone_set('Asia/Seoul');
 
         $db = \Config\Database::connect();
         $request = $this->request->getJSON(true);
-
-        $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
-        $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
-        $orderList = $request['orderList'] ?? [];
-
-        if (!$itemSeq) {
-            return $this->fail('필수 파라미터가 누락되었습니다.', 400);
-        }
-
-        // orderList가 비어있으면 해당 item_seq의 모든 데이터 삭제만 수행
-        if (empty($orderList)) {
-            $db->transBegin();
-            try {
-                // 기존 데이터 모두 삭제
-                $deletedCount = $db->table('ITEM_ORDER_LIST')
-                    ->where('ITEM_SEQ', $itemSeq)
-                    ->delete();
-
-                $db->transCommit();
-                return $this->respond([
-                    'message' => '주문 내역이 성공적으로 처리되었습니다.',
-                    'updated_count' => 0,
-                    'new_count' => 0,
-                    'deleted_count' => $deletedCount,
-                    'errors' => []
-                ], 200);
-            } catch (\Exception $e) {
-                $db->transRollback();
-                return $this->fail('주문 내역 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
-            }
-        }
-
-        // 빈 데이터나 변경사항 없는 경우 먼저 체크
-        $hasValidData = false;
-        foreach ($orderList as $order) {
-            if (!empty($order['ORDER_NUMB']) && !empty($order['BUYER_NAME'])) {
-                $hasValidData = true;
-                break;
-            }
-        }
-
-        // 유효한 데이터가 없으면 기존 데이터와 비교해서 변경사항 확인
-        if (!$hasValidData) {
-            $existingCount = $db->table('ITEM_ORDER_LIST')
-                ->where('ITEM_SEQ', $itemSeq)
-                ->countAllResults();
-
-            // 기존 데이터도 없고 새로운 유효 데이터도 없으면 변경사항 없음
-            if ($existingCount == 0) {
-                return $this->respond([
-                    'message' => '저장할 데이터가 없습니다.',
-                    'updated_count' => 0,
-                    'new_count' => 0,
-                    'deleted_count' => 0,
-                    'errors' => []
-                ], 200);
-            }
-        }
-
-        // 유효성 검사 (유효한 데이터가 있을 때만)
-        foreach ($orderList as $index => $order) {
-            // 빈 행은 건너뛰기
-            if (empty($order['ORDER_NUMB']) && empty($order['BUYER_NAME'])) {
-                continue;
-            }
-
-            $requiredFields = ['ORDER_NUMB', 'BUYER_NAME'];
-            foreach ($requiredFields as $field) {
-                if (!isset($order[$field]) || $order[$field] === '') {
-                    return $this->fail("orderList[$index] 항목의 '{$field}' 값이 누락되었습니다.", 400);
-                }
-            }
-        }
-
-        $db->transBegin();
-        $updatedCount = 0;
-        $newCount = 0;
-        $deletedCount = 0;
-        $errors = [];
+        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
+        $memberSeq = isset($request['MEMBER_SEQ']) ? $request['MEMBER_SEQ'] : null;
 
         try {
-            // 1. 먼저 해당 item_seq의 기존 데이터를 모두 조회
-            $existingOrders = $db->table('ITEM_ORDER_LIST')
-                ->where('ITEM_SEQ', $itemSeq)
-                ->get()->getResultArray();
-
-            // 2. 현재 전송된 데이터 목록에서 ORDER_NUMB + BUYER_NAME 조합 추출
-            $currentOrderKeys = [];
-            foreach ($orderList as $order) {
-                if (!empty($order['ORDER_NUMB']) && !empty($order['BUYER_NAME'])) {
-                    $currentOrderKeys[] = $order['ORDER_NUMB'] . '_' . $order['BUYER_NAME'];
-                }
-            }
-
-            // 3. 기존 데이터 중 현재 목록에 없는 항목들 삭제
-            foreach ($existingOrders as $existingOrder) {
-                $existingKey = $existingOrder['ORDER_NUMB'] . '_' . $existingOrder['BUYER_NAME'];
-                if (!in_array($existingKey, $currentOrderKeys)) {
-                    $deleteResult = $db->table('ITEM_ORDER_LIST')
-                        ->where('SEQ', $existingOrder['SEQ'])
-                        ->delete();
-
-                    if ($deleteResult) {
-                        $deletedCount++;
-                    }
-                }
-            }
-
-            // 4. 업데이트 또는 신규 추가 처리
-            foreach ($orderList as $order) {
-                $metadata = $order['_metadata'] ?? [];
-                $isUpdated = $metadata['isUpdated'] ?? false;
-                $isNew = $metadata['isNew'] ?? false;
-
-                // 메타데이터가 없는 경우 DB에서 기존 데이터 확인
-                if (!$isUpdated && !$isNew) {
-                    $existingRecord = $db->table('ITEM_ORDER_LIST')
-                        ->where('ITEM_SEQ', $itemSeq)
-                        ->where('ORDER_NUMB', $order['ORDER_NUMB'])
-                        ->where('BUYER_NAME', $order['BUYER_NAME'])
-                        ->get()->getRowArray();
-
-                    if ($existingRecord) {
-                        $isUpdated = true;
-                    } else {
-                        // 주문번호+구매자명이 정확히 일치하지 않으면 신규 추가
-                        $isNew = true;
-                    }
-                }
-
-                if ($isUpdated) {
-                    // 기존 데이터 조회하여 변경사항 확인
-                    $existingRecord = $db->table('ITEM_ORDER_LIST')
-                        ->where('ITEM_SEQ', $itemSeq)
-                        ->where('ORDER_NUMB', $order['ORDER_NUMB'])
-                        ->where('BUYER_NAME', $order['BUYER_NAME'])
-                        ->get()->getRowArray();
-
-                    if ($existingRecord) {
-                        $updateData = [];
-                        $hasChanges = false;
-
-                        // 각 필드별로 변경사항 확인
-                        if (($existingRecord['PHONE'] ?? '') !== ($order['PHONE'] ?? '')) {
-                            $updateData['PHONE'] = $order['PHONE'] ?? '';
-                            $hasChanges = true;
-                        }
-                        if (($existingRecord['QTY'] ?? 0) != ($order['QTY'] ?? 0)) {
-                            $updateData['QTY'] = $order['QTY'] ?? 0;
-                            $hasChanges = true;
-                        }
-                        if (($existingRecord['ADDRESS'] ?? '') != ($order['ADDRESS'] ?? 0)) {
-                            $updateData['ADDRESS'] = $order['ADDRESS'] ?? 0;
-                            $hasChanges = true;
-                        }
-                        if (($existingRecord['DELI_COMP'] ?? '') !== ($order['DELI_COMP'] ?? '')) {
-                            $updateData['DELI_COMP'] = $order['DELI_COMP'] ?? '';
-                            $hasChanges = true;
-                        }
-                        if (($existingRecord['DELI_NUMB'] ?? '') !== ($order['DELI_NUMB'] ?? '')) {
-                            $updateData['DELI_NUMB'] = $order['DELI_NUMB'] ?? '';
-                            $hasChanges = true;
-                        }
-
-                        // 실제 변경사항이 있을 때만 UPDATE_DATE 갱신
-                        if ($hasChanges) {
-                            $updateData['UPDATE_DATE'] = date('Y-m-d H:i:s');
-
-                            $result = $db->table('ITEM_ORDER_LIST')
-                                ->where('ITEM_SEQ', $itemSeq)
-                                ->where('ORDER_NUMB', $order['ORDER_NUMB'])
-                                ->where('BUYER_NAME', $order['BUYER_NAME'])
-                                ->update($updateData);
-
-                            if ($result) {
-                                $updatedCount++;
-                            } else {
-                                $errors[] = "업데이트 실패: {$order['ORDER_NUMB']} - {$order['BUYER_NAME']}";
-                            }
-                        }
-                        // 변경사항이 없으면 업데이트하지 않음
-                    } else {
-                        // 기존 데이터를 찾을 수 없으면 신규로 처리
-                        $isNew = true;
-                    }
-
-                }
-
-                if ($isNew) {
-                    // 신규 데이터 추가
-                    $insertData = [
-                        'ITEM_SEQ' => $itemSeq,
-                        'ORDER_NUMB' => $order['ORDER_NUMB'],
-                        'BUYER_NAME' => $order['BUYER_NAME'],
-                        'PHONE' => $order['PHONE'] ?? '',
-                        'QTY' => $order['QTY'] ?? 0,
-                        'ADDRESS' => $order['ADDRESS'] ?? '',
-                        'INF_SEQ' => $infSeq,
-                        'DELI_COMP' => $order['DELI_COMP'] ?? '',
-                        'DELI_NUMB' => $order['DELI_NUMB'] ?? '',
-                        'REG_DATE' => $metadata['originalCreatedAt'] ?? date('Y-m-d H:i:s'),
-                        'UPDATE_DATE' => $metadata['lastModifiedAt'] ?? date('Y-m-d H:i:s'),
-                    ];
-
-                    $result = $db->table('ITEM_ORDER_LIST')->insert($insertData);
-
-                    if ($result) {
-                        $newCount++;
-                    } else {
-                        $errors[] = "삽입 실패: {$order['ORDER_NUMB']} - {$order['BUYER_NAME']}";
-                    }
+            // 멤버 타입에 따라 다른 테이블에서 조회
+            switch ($memberType) {
+                case 'INFLUENCER':
+                case 'I':
+                    $userInfo = $db->table('USER_LIST')
+                        ->where('SEQ', $memberSeq)
+                        ->get()
+                        ->getRowArray();
+                    break;
+
+                case 'VENDOR':
+                case 'V':
+                    $userInfo = $db->table('VENDOR_LIST')
+                        ->where('SEQ', $memberSeq)
+                        ->get()
+                        ->getRowArray();
+                    break;
+
+                case 'BRAND':
+                case 'B':
+                    $userInfo = $db->table('BRAND_LIST')
+                        ->where('SEQ', $memberSeq)
+                        ->get()
+                        ->getRowArray();
+                    break;
+
+                default:
+                    return $this->respond([
+                        'status' => 'fail',
+                        'message' => '알 수 없는 회원 타입입니다.'
+                    ], 400);
+            }
+
+            if (!$userInfo) {
+                return $this->respond([
+                    'status' => 'fail',
+                    'message' => '사용자 정보를 찾을 수 없습니다.'
+                ], 404);
+            }
+
+            // MEMBER_TYPE 정규화 (I -> INFLUENCER 등)
+            if (isset($userInfo['MEMBER_TYPE'])) {
+                switch ($userInfo['MEMBER_TYPE']) {
+                    case 'I':
+                        $userInfo['MEMBER_TYPE'] = 'INFLUENCER';
+                        break;
+                    case 'V':
+                        $userInfo['MEMBER_TYPE'] = 'VENDOR';
+                        break;
+                    case 'B':
+                        $userInfo['MEMBER_TYPE'] = 'BRAND';
+                        break;
                 }
             }
 
-            // 에러가 있으면 실패로 처리
-            if (count($errors) > 0) {
-                $db->transRollback();
-                return $this->fail(implode(' | ', $errors), 400);
-            }
-
-            if ($updatedCount > 0 || $newCount > 0 || $deletedCount > 0) {
-                $db->transCommit();
-                return $this->respond([
-                    'message' => '주문 내역이 성공적으로 처리되었습니다.',
-                    'updated_count' => $updatedCount,
-                    'new_count' => $newCount,
-                    'deleted_count' => $deletedCount,
-                    'errors' => $errors
-                ], 200);
-            } else {
-                $db->transRollback();
-                return $this->fail('처리할 수 있는 데이터가 없습니다.', 400);
-            }
+            return $this->respond($userInfo, 200);
 
         } catch (\Exception $e) {
-            $db->transRollback();
-            return $this->fail('주문 내역 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
+            return $this->respond([
+                'status' => 'fail',
+                'message' => 'DB 오류: ' . $e->getMessage()
+            ], 500);
         }
     }
 
+    // 사용자 정보 수정
+    public function myUpdate(){
+        // 한국 시간으로 설정
+        date_default_timezone_set('Asia/Seoul');
 
-    //아이템 리스트
-    public function itemlist()
-    {
-        $db = \Config\Database::connect();
-
-        // POST JSON 파라미터 받기
-        $request = $this->request->getJSON(true);
-
-        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
-        $showYn = isset($request['SHOW_YN']) ? $request['SHOW_YN'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
-
-        // 서브쿼리: 사용자 타입에 따른 주문 집계
-        $subQuery = $db->table('ITEM_ORDER_LIST')
-            ->select('ITEM_SEQ, SUM(QTY) AS sum_qty, SUM(TOTAL) AS sum_total, MAX(REG_DATE) AS latest_reg_date');
-
-        // 인플루언서: 본인이 받은 주문만
-        if ($memberType === 'INFLUENCER') {
-            if (is_null($infSeq)) {
-                // INF_SEQ가 없으면 빈 결과 반환
-                return $this->respond([], 200);
-            }
-            $subQuery->where('INF_SEQ', $infSeq);
-        }
-
-        // 배송정보가 등록되지 않은 주문만 (배송관리 페이지용)
-        // 배송업체와 송장번호가 모두 비어있는 경우만 포함 (AND 조건)
-        $subQuery->where('(DELI_COMP IS NULL OR DELI_COMP = "")')
-            ->where('(DELI_NUMB IS NULL OR DELI_NUMB = "")');
-
-        $subQuery->groupBy('ITEM_SEQ');
-
-        // 메인 쿼리: ITEM_LIST와 위 서브쿼리 조인 (실제 주문이 있는 제품만)
-        $builder = $db->table('ITEM_LIST I')
-            ->select('I.*, O.sum_qty, O.sum_total, O.latest_reg_date')
-            ->join("(" . $subQuery->getCompiledSelect() . ") O", 'I.SEQ = O.ITEM_SEQ', 'inner')
-            ->where('I.DEL_YN', 'N');
-
-        // 벤더: 자사 제품만 필터링
-        if ($memberType === 'VENDOR') {
-            if (empty($companyNumber)) {
-                // COMPANY_NUMBER가 없으면 빈 결과 반환
-                return $this->respond([], 200);
-            }
-            $builder->where('I.COMPANY_NUMBER', $companyNumber);
-        }
-
-        if (!is_null($showYn) && $showYn !== '') {
-            $builder->where('I.SHOW_YN', $showYn);
-        }
-
-        $builder->where('I.TYPE', $itemType);
-
-        $builder->orderBy('I.UDPDATE', 'DESC');
-
-        $lists = $builder->get()->getResultArray();
-
-
-        return $this->respond($lists, 200);
-    }
-
-    //아이템 검색
-    public function deliSearch()
-    {
         $db = \Config\Database::connect();
-
-        // 요청 바디에서 filter와 keyword 추출
         $request = $this->request->getJSON(true);
-        $filter = isset($request['filter']) ? $request['filter'] : null;
-        $keyword = isset($request['keyword']) ? $request['keyword'] : null;
-        $startDate = $request['startDate'] ?? null;
-        $endDate = $request['endDate'] ?? null;
-        $showYN = $request['showYN'] ?? null;
-        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
         $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
         $memberSeq = isset($request['MEMBER_SEQ']) ? $request['MEMBER_SEQ'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-
-        $filterMap = [
-            'name' => 'I.NAME',
-        ];
-
-        // 서브쿼리: 사용자 타입에 따른 주문 집계
-        $subQuery = $db->table('ITEM_ORDER_LIST')
-            ->select('ITEM_SEQ, SUM(QTY) AS sum_qty, SUM(TOTAL) AS sum_total, MAX(REG_DATE) AS latest_reg_date');
 
-        // 인플루언서: 본인이 받은 주문만
-        if ($memberType === 'INFLUENCER') {
-            if (is_null($infSeq)) {
-                // INF_SEQ가 없으면 빈 결과 반환
-                return $this->respond([], 200);
-            }
-            $subQuery->where('INF_SEQ', $infSeq);
-        }
-
-        // 배송정보가 등록되지 않은 주문만 (배송관리 페이지용)
-        $subQuery->where('(DELI_COMP IS NULL OR DELI_COMP = "")')
-            ->where('(DELI_NUMB IS NULL OR DELI_NUMB = "")');
-
-        $subQuery->groupBy('ITEM_SEQ');
+        try {
+            // 멤버 타입에 따라 다른 테이블에서 업데이트
+            switch ($memberType) {
+                case 'INFLUENCER':
+                case 'I':
+                    $table = 'USER_LIST';
+                    break;
 
-        // 메인 쿼리: ITEM_LIST와 위 서브쿼리 조인 (실제 주문이 있는 제품만)
-        $builder = $db->table('ITEM_LIST I')
-            ->select('I.*, O.sum_qty, O.sum_total, O.latest_reg_date')
-            ->join("(" . $subQuery->getCompiledSelect() . ") O", 'I.SEQ = O.ITEM_SEQ', 'inner')
-            ->where('I.DEL_YN', 'N');
+                case 'VENDOR':
+                case 'V':
+                    $table = 'VENDOR_LIST';
+                    break;
 
-        // 사용자 타입별 필터링
-        if ($memberType === 'VENDOR' && !empty($companyNumber)) {
-            // 벤더사의 경우: 자사 제품만 검색
-            $builder->where('I.COMPANY_NUMBER', $companyNumber);
-        } elseif ($memberType === 'INFLUENCER' && !empty($memberSeq)) {
-            // 인플루언서의 경우: 파트너십이 체결된 벤더사의 제품만 검색
-            $builder->select('I.*, O.sum_qty, O.sum_total, O.latest_reg_date, VIP.STATUS as PARTNERSHIP_STATUS');
-            $builder->join('VENDOR_LIST VL', 'I.COMPANY_NUMBER = VL.COMPANY_NUMBER', 'inner');
-            $builder->join('VENDOR_INFLUENCER_PARTNERSHIP VIP', 'VL.SEQ = VIP.VENDOR_SEQ', 'inner');
-            $builder->where('VIP.INFLUENCER_SEQ', $memberSeq);
-            $builder->where('VIP.STATUS', 'APPROVED');
-            $builder->where('VIP.IS_ACTIVE', 'Y');
-        }
+                case 'BRAND':
+                case 'B':
+                    $table = 'BRAND_LIST';
+                    break;
 
-        // 키워드 검색
-        if (!empty($keyword)) {
-            if (empty($filter)) {
-                // 필터를 선택 안했으면 전체 검색
-                $first = true;
-                foreach ($filterMap as $column) {
-                    if ($first) {
-                        $builder->like($column, $keyword);
-                        $first = false;
-                    } else {
-                        $builder->orLike($column, $keyword);
-                    }
-                }
-            } elseif (isset($filterMap[$filter])) {
-                // 특정 필터 검색
-                $builder->like($filterMap[$filter], $keyword);
+                default:
+                    return $this->respond([
+                        'status' => 'fail',
+                        'message' => '알 수 없는 회원 타입입니다.'
+                    ], 400);
             }
-        }
-
-        // 노출중, 비노출 여부 확인
-        if (!empty($showYN)) {
-            $builder->where('I.SHOW_YN', $showYN);
-        }
-        if (!empty($itemType)) {
-            $builder->where('I.TYPE', $itemType);
-        }
-
-        // INF_SEQ 조건 추가 (값이 있을 때만)
-        if (!empty($infSeq)) {
-            $builder->where('I.CONTACT_INF', $infSeq);
-        }
-
-        // 날짜 범위 검색 (latest_reg_date 기준)
-        if (!empty($startDate)) {
-            $builder->where('O.latest_reg_date >=', $startDate . ' 00:00:00');
-        }
-        if (!empty($endDate)) {
-            $builder->where('O.latest_reg_date <=', $endDate . ' 23:59:59');
-        }
-
-        $builder->orderBy('I.UDPDATE', 'DESC');
-
-        // 조회
-        $lists = $builder->get()->getResultArray();
-
-        return $this->respond($lists, 200);
-    }
-
-    //배송중 검색
-    public function shippingSearch()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
 
-        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
-        $filter = isset($request['filter']) ? $request['filter'] : null;
-        $keyword = isset($request['keyword']) ? $request['keyword'] : null;
-        $startDate = isset($request['startDate']) ? $request['startDate'] : null;
-        $endDate = isset($request['endDate']) ? $request['endDate'] : null;
-
-        $builder = $db->table('ITEM_ORDER_LIST IOL')
-            ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2')
-            ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
-            ->where('IOL.DELI_COMP !=', '')
-            ->where('IOL.DELI_NUMB !=', '')
-            ->where('IOL.DELI_COMP IS NOT NULL')
-            ->where('IOL.DELI_NUMB IS NOT NULL');
+            // 업데이트할 데이터
+            $data = [];
 
-        // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
-        $columns = $db->getFieldNames('ITEM_ORDER_LIST');
-        if (in_array('DELIVERY_STATUS', $columns)) {
-            $builder->where('IOL.DELIVERY_STATUS', 'SHIPPING');
-        } else {
-            // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 배송중으로 간주
-            // 단, 배송완료된 것은 제외 (DELIVERED_DATE가 없는 것만)
-            if (in_array('DELIVERED_DATE', $columns)) {
-                $builder->where('IOL.DELIVERED_DATE IS NULL');
+            // 공통 필드
+            if (isset($request['EMAIL'])) {
+                $data['EMAIL'] = $request['EMAIL'];
             }
-        }
-
-        // 아이템 타입 필터링
-        if (!empty($itemType)) {
-            $builder->where('IL.TYPE', $itemType);
-        }
-
-        // 검색 조건 추가
-        if (!empty($keyword)) {
-            if ($filter === 'name') {
-                $builder->like('IL.NAME', $keyword);
-            } elseif ($filter === 'buyer') {
-                $builder->like('IOL.BUYER_NAME', $keyword);
-            } else {
-                // 전체 검색
-                $builder->groupStart()
-                    ->like('IL.NAME', $keyword)
-                    ->orLike('IOL.BUYER_NAME', $keyword)
-                    ->groupEnd();
+            if (isset($request['PASSWORD']) && !empty($request['PASSWORD'])) {
+                $data['PASSWORD'] = password_hash($request['PASSWORD'], PASSWORD_DEFAULT);
             }
-        }
-
-        // 날짜 범위 검색
-        if (!empty($startDate)) {
-            $builder->where('DATE(IOL.SHIPPING_DATE) >=', $startDate);
-        }
-        if (!empty($endDate)) {
-            $builder->where('DATE(IOL.SHIPPING_DATE) <=', $endDate);
-        }
-
-        // 사용자 타입에 따른 필터링
-        if ($memberType === 'VENDOR' && !empty($companyNumber)) {
-            $builder->where('IL.COMPANY_NUMBER', $companyNumber);
-        } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
-            $builder->where('IOL.INF_SEQ', $infSeq);
-        }
-
-        $builder->orderBy('IOL.REG_DATE', 'DESC');
-        $lists = $builder->get()->getResultArray();
 
-        return $this->respond($lists, 200);
-    }
-
-
-    //구매자 리스트
-    public function delilist()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-        $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
-        $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
-
-        // 쿼리 빌더
-        $builder = $db->table('ITEM_ORDER_LIST I');
-        $builder->select('I.*, U.NICK_NAME');
-        $builder->join('USER_LIST U', 'I.INF_SEQ = U.SEQ', 'left');
-
-        $builder->where('I.ITEM_SEQ', $itemSeq);
-        if ($infSeq) {
-            $builder->where('I.INF_SEQ', $infSeq);
-        }
-
-        // 배송정보가 등록되지 않은 주문만 표시 (송장번호 등록용)
-        // 배송업체와 송장번호가 모두 비어있는 경우만 포함
-        $builder->where('(I.DELI_COMP IS NULL OR I.DELI_COMP = "")')
-            ->where('(I.DELI_NUMB IS NULL OR I.DELI_NUMB = "")');
-
-        // 주문일 기준으로 정렬
-        $builder->orderBy('I.ORDER_DATE', 'DESC');
-        $lists = $builder->get()->getResultArray();
-
-
-        return $this->respond($lists, 200);
-    }
-
-    //구매자 등록
-    public function deliRegister()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
-        $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
-        $deliveryList = $request['deliveryList'] ?? [];
-
-        // 🔍 먼저 전체 유효성 검사
-        foreach ($deliveryList as $index => $delivery) {
-            $requiredFields = ['buyerName', 'address', 'phone', 'qty', 'total', 'orderDate'];
-            foreach ($requiredFields as $field) {
-                if (!isset($delivery[$field]) || $delivery[$field] === '') {
-                    return $this->fail("deliveryList[$index] 항목의 '{$field}' 값이 누락되었습니다.", 400);
+            // 인플루언서 전용 필드
+            if (($memberType === 'INFLUENCER' || $memberType === 'I')) {
+                if (isset($request['PHONE'])) {
+                    $data['PHONE'] = $request['PHONE'];
                 }
-            }
-        }
-
-        // ✅ 유효성 통과 후 삭제 + 삽입
-        $db->table('ITEM_ORDER_LIST')
-            ->where('ITEM_SEQ', $itemSeq)
-            ->where('INF_SEQ', $infSeq)
-            ->delete();
-
-        foreach ($deliveryList as $delivery) {
-            $data = [
-                'ITEM_SEQ' => $itemSeq,
-                'INF_SEQ' => $infSeq,
-                'BUYER_NAME' => $delivery['buyerName'],
-                'ADDRESS' => $delivery['address'],
-                'PHONE' => $delivery['phone'],
-                'EMAIL' => $delivery['email'],
-                'QTY' => $delivery['qty'],
-                'TOTAL' => $delivery['total'],
-                'DELI_COMP' => $delivery['deliComp'] ?? '',
-                'DELI_NUMB' => $delivery['deliNumb'] ?? '',
-                'ORDER_DATE' => date('Y-m-d H:i:s', strtotime($delivery['orderDate'])),
-                'REG_DATE' => date('Y-m-d'),
-            ];
-
-            $db->table('ITEM_ORDER_LIST')->insert($data);
-        }
-
-        return $this->respond(['message' => '배송 데이터가 성공적으로 저장되었습니다.'], 200);
-    }
-
-    //벤더사용 배송정보 업데이트
-    public function updateDeliveryInfo()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
-        $deliveryUpdates = $request['deliveryUpdates'] ?? [];
-
-        if (!$itemSeq || empty($deliveryUpdates)) {
-            return $this->fail('필수 파라미터가 누락되었습니다.', 400);
-        }
-
-        $db->transBegin();
-        $updatedCount = 0;
-        $errors = [];
-
-        try {
-            foreach ($deliveryUpdates as $update) {
-                $buyerName = $update['buyerName'] ?? '';
-                $phone = $update['phone'] ?? '';
-                $deliComp = $update['deliComp'] ?? '';
-                $deliNumb = $update['deliNumb'] ?? '';
-
-                if (!$buyerName || !$phone) {
-                    $errors[] = "구매자명과 연락처는 필수입니다.";
-                    continue;
+                if (isset($request['NICK_NAME'])) {
+                    $data['NICK_NAME'] = $request['NICK_NAME'];
                 }
-
-                // 업데이트할 데이터 준비
-                $updateData = [
-                    'DELI_COMP' => $deliComp,
-                    'DELI_NUMB' => $deliNumb
-                ];
-
-                // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 추가
-                $columns = $db->getFieldNames('ITEM_ORDER_LIST');
-                if (in_array('DELIVERY_STATUS', $columns)) {
-                    $updateData['DELIVERY_STATUS'] = 'SHIPPING';
+                if (isset($request['SNS_TYPE'])) {
+                    $data['SNS_TYPE'] = $request['SNS_TYPE'];
                 }
-                if (in_array('SHIPPING_DATE', $columns)) {
-                    $updateData['SHIPPING_DATE'] = date('Y-m-d H:i:s');
+                if (isset($request['SNS_LINK_ID'])) {
+                    $data['SNS_LINK_ID'] = $request['SNS_LINK_ID'];
                 }
+            }
 
-                // 구매자명과 연락처로 해당 주문 찾기
-                $result = $db->table('ITEM_ORDER_LIST')
-                    ->where('ITEM_SEQ', $itemSeq)
-                    ->where('BUYER_NAME', $buyerName)
-                    ->where('PHONE', $phone)
-                    ->update($updateData);
-
-                if ($result) {
-                    $updatedCount++;
-                } else {
-                    $errors[] = "매칭되는 주문을 찾을 수 없습니다: {$buyerName}({$phone})";
+            // 벤더/브랜드 전용 필드
+            if (($memberType !== 'INFLUENCER' && $memberType !== 'I')) {
+                if (isset($request['COMPANY_NAME'])) {
+                    $data['COMPANY_NAME'] = $request['COMPANY_NAME'];
+                }
+                if (isset($request['HP'])) {
+                    $data['HP'] = $request['HP'];
                 }
             }
 
-            if ($updatedCount > 0) {
-                $db->transCommit();
+            if (empty($data)) {
                 return $this->respond([
-                    'message' => "배송정보가 성공적으로 업데이트되었습니다.",
-                    'updated_count' => $updatedCount,
-                    'errors' => $errors
+                    'status' => 'fail',
+                    'message' => '업데이트할 데이터가 없습니다.'
+                ], 400);
+            }
+
+            // 업데이트 실행
+            $result = $db->table($table)
+                ->where('SEQ', $memberSeq)
+                ->update($data);
+
+            if ($result) {
+                return $this->respond([
+                    'status' => 'success',
+                    'message' => '사용자 정보가 성공적으로 업데이트되었습니다.',
+                    'data' => $data
                 ], 200);
             } else {
-                $db->transRollback();
-                return $this->fail('업데이트할 수 있는 데이터가 없습니다.', 400);
+                return $this->respond([
+                    'status' => 'fail',
+                    'message' => '업데이트에 실패했습니다.'
+                ], 500);
             }
 
         } catch (\Exception $e) {
-            $db->transRollback();
-            return $this->fail('배송정보 업데이트 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
-        }
-    }
-
-    //아이템 상세
-    public function itemDetail($seq)
-    {
-        // DB 객체 얻기
-        $db = \Config\Database::connect();
-
-        $builder = $db->table('ITEM_LIST');
-        $item = $builder->where('seq', $seq)->get()->getRowArray();
-
-        if($item){
-            return $this->respond($item, 200);
-        } else {
             return $this->respond([
                 'status' => 'fail',
-                'message' => '유효하지 않은 seq입니다.'
-            ], 404);
-        }
-    }
-
-    //아이템 삭제
-    public function itemDelete($seq)
-    {
-        $db = \Config\Database::connect();
-        $db->transBegin();
-
-        //아이템 삭제
-        $deleted = $db->table('ITEM_LIST')
-            ->where('SEQ', $seq)
-            ->update(['DEL_YN' => 'Y']);
-
-        if ($db->transStatus() === false || !$deleted) {
-            $db->transRollback();
-            return $this->respond(['status' => 'fail', 'message' => '이벤트 삭제 중 오류가 발생했습니다.']);
-        }
-        $db->transCommit();
-        return $this->respond(['status' => 'success', 'message' => '이벤트가 삭제되었습니다.'], 200);
-    }
-
-    // 배송중 리스트 조회
-    public function getShippingList()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
-
-        $builder = $db->table('ITEM_ORDER_LIST IOL')
-            ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2')
-            ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
-            ->where('IOL.DELI_COMP !=', '')
-            ->where('IOL.DELI_NUMB !=', '')
-            ->where('IOL.DELI_COMP IS NOT NULL')
-            ->where('IOL.DELI_NUMB IS NOT NULL');
-
-        // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
-        $columns = $db->getFieldNames('ITEM_ORDER_LIST');
-        if (in_array('DELIVERY_STATUS', $columns)) {
-            $builder->where('IOL.DELIVERY_STATUS', 'SHIPPING');
-        } else {
-            // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 배송중으로 간주
-            // 단, 배송완료된 것은 제외 (DELIVERED_DATE가 없는 것만)
-            if (in_array('DELIVERED_DATE', $columns)) {
-                $builder->where('IOL.DELIVERED_DATE IS NULL');
-            }
-        }
-
-        // 아이템 타입 필터링
-        if (!empty($itemType)) {
-            $builder->where('IL.TYPE', $itemType);
-        }
-
-        // 사용자 타입에 따른 필터링
-        if ($memberType === 'VENDOR' && !empty($companyNumber)) {
-            $builder->where('IL.COMPANY_NUMBER', $companyNumber);
-        } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
-            $builder->where('IOL.INF_SEQ', $infSeq);
+                'message' => 'DB 오류: ' . $e->getMessage()
+            ], 500);
         }
-
-        $builder->orderBy('IOL.REG_DATE', 'DESC');
-        $lists = $builder->get()->getResultArray();
-
-
-        return $this->respond($lists, 200);
-    }
-
-    // 배송완료 리스트 조회
-    public function getDeliveredList()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
-
-        $builder = $db->table('ITEM_ORDER_LIST IOL')
-            ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2')
-            ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner');
-
-        // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
-        $columns = $db->getFieldNames('ITEM_ORDER_LIST');
-        if (in_array('DELIVERY_STATUS', $columns)) {
-            $builder->where('IOL.DELIVERY_STATUS', 'DELIVERED');
-        } else {
-            // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 배송완료로 간주
-            $builder->where('IOL.DELI_COMP !=', '')
-                ->where('IOL.DELI_NUMB !=', '')
-                ->where('IOL.DELI_COMP IS NOT NULL')
-                ->where('IOL.DELI_NUMB IS NOT NULL');
-        }
-
-        // 아이템 타입 필터링
-        if (!empty($itemType)) {
-            $builder->where('IL.TYPE', $itemType);
-        }
-
-        // 정산완료되지 않은 주문만 표시 (배송완료 페이지용)
-        if (in_array('SETTLEMENT_STATUS', $columns)) {
-            $builder->where('(IOL.SETTLEMENT_STATUS IS NULL OR IOL.SETTLEMENT_STATUS != "COMPLETED")');
-        }
-
-        // 사용자 타입에 따른 필터링
-        if ($memberType === 'VENDOR' && !empty($companyNumber)) {
-            $builder->where('IL.COMPANY_NUMBER', $companyNumber);
-        } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
-            $builder->where('IOL.INF_SEQ', $infSeq);
-        }
-
-        // 정렬을 안전하게 처리
-        if (in_array('DELIVERED_DATE', $columns)) {
-            $builder->orderBy('IOL.DELIVERED_DATE', 'DESC');
-        } else {
-            $builder->orderBy('IOL.REG_DATE', 'DESC');
-        }
-
-        $lists = $builder->get()->getResultArray();
-
-
-        return $this->respond($lists, 200);
-    }
-
-    // 배송완료 처리
-    public function markAsDelivered()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $orderIds = isset($request['order_ids']) ? $request['order_ids'] : [];
-
-        if (empty($orderIds)) {
-            return $this->fail('처리할 주문이 선택되지 않았습니다.', 400);
-        }
-
-        $db->transBegin();
-
-        try {
-            foreach ($orderIds as $orderId) {
-                $db->table('ITEM_ORDER_LIST')
-                    ->where('SEQ', $orderId)
-                    ->update([
-                        'DELIVERY_STATUS' => 'DELIVERED',
-                        'DELIVERED_DATE' => date('Y-m-d H:i:s')
-                    ]);
-            }
-
-            $db->transCommit();
-            return $this->respond(['message' => '배송완료 처리되었습니다.'], 200);
-
-        } catch (\Exception $e) {
-            $db->transRollback();
-            return $this->fail('배송완료 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
-        }
-    }
-
-    // 정산완료 처리
-    public function markAsSettled()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $orderIds = isset($request['order_ids']) ? $request['order_ids'] : [];
-
-        if (empty($orderIds)) {
-            return $this->fail('처리할 주문이 선택되지 않았습니다.', 400);
-        }
-
-        $db->transBegin();
-
-        try {
-            foreach ($orderIds as $orderId) {
-                $db->table('ITEM_ORDER_LIST')
-                    ->where('SEQ', $orderId)
-                    ->update([
-                        'SETTLEMENT_STATUS' => 'COMPLETED',
-                        'SETTLED_DATE' => date('Y-m-d H:i:s')
-                    ]);
-            }
-
-            $db->transCommit();
-            return $this->respond(['message' => '정산완료 처리되었습니다.'], 200);
-
-        } catch (\Exception $e) {
-            $db->transRollback();
-            return $this->fail('정산완료 처리 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
-        }
-    }
-
-    // 정산관리 리스트 조회
-    public function getSettlementList()
-    {
-        $db = \Config\Database::connect();
-        $request = $this->request->getJSON(true);
-
-        $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
-        $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
-        $settlementStatus = isset($request['SETTLEMENT_STATUS']) ? $request['SETTLEMENT_STATUS'] : null;
-
-        $builder = $db->table('ITEM_ORDER_LIST IOL')
-            ->select('IOL.*, IL.NAME as ITEM_NAME, IL.PRICE1, IL.PRICE2, IL.TYPE as ITEM_TYPE, UL.NICK_NAME as INF_NICK_NAME')
-            ->join('ITEM_LIST IL', 'IOL.ITEM_SEQ = IL.SEQ', 'inner')
-            ->join('USER_LIST UL', 'IOL.INF_SEQ = UL.SEQ', 'left');
-
-        // DELIVERY_STATUS 컬럼이 존재하는지 확인하고 조건 추가
-        $columns = $db->getFieldNames('ITEM_ORDER_LIST');
-        if (in_array('DELIVERY_STATUS', $columns)) {
-            $builder->where('IOL.DELIVERY_STATUS', 'DELIVERED');
-        } else {
-            // DELIVERY_STATUS 컬럼이 없으면 배송업체와 송장번호가 있는 것을 대상으로 함
-            $builder->where('IOL.DELI_COMP !=', '')
-                ->where('IOL.DELI_NUMB !=', '')
-                ->where('IOL.DELI_COMP IS NOT NULL')
-                ->where('IOL.DELI_NUMB IS NOT NULL');
-        }
-
-        // 정산 상태 필터링 (SETTLEMENT_STATUS 컬럼이 존재하는 경우만)
-        if ($settlementStatus && in_array('SETTLEMENT_STATUS', $columns)) {
-            $builder->where('IOL.SETTLEMENT_STATUS', $settlementStatus);
-        }
-
-        // 사용자 타입에 따른 필터링
-        if ($memberType === 'VENDOR' && !empty($companyNumber)) {
-            $builder->where('IL.COMPANY_NUMBER', $companyNumber);
-        } elseif ($memberType === 'INFLUENCER' && !empty($infSeq)) {
-            $builder->where('IOL.INF_SEQ', $infSeq);
-        }
-
-        $builder->orderBy('IOL.DELIVERED_DATE', 'DESC');
-        $lists = $builder->get()->getResultArray();
-
-        return $this->respond($lists, 200);
     }
 }

+ 768 - 22
pages/index.vue

@@ -150,8 +150,8 @@
             >
           </div>
           <div class="join--btn--wrap">
-            <v-btn class="custom-btn text--btn" @click="showComingSoon">아이디 찾기</v-btn>
-            <v-btn class="custom-btn text--btn" @click="showComingSoon">비밀번호 찾기</v-btn>
+            <v-btn class="custom-btn text--btn" @click="openFindIdModal">아이디 찾기</v-btn>
+            <v-btn class="custom-btn text--btn" @click="openFindPwModal">비밀번호 찾기</v-btn>
             <v-btn class="custom-btn text--btn" @click="location('join')">회원가입</v-btn>
           </div>
           <div class="short--login--wrap" v-if="loginForm.loginType == 'influence'">
@@ -170,6 +170,255 @@
         </div>
       </div>
     </div>
+
+    <!-- 아이디 찾기 모달 -->
+    <v-dialog v-model="showFindIdModal" max-width="600px" persistent>
+      <v-card class="inquiry-modal">
+        <v-card-title class="modal-header">
+          <h3>아이디 찾기</h3>
+          <v-btn icon @click="closeFindIdModal" class="close-btn">
+            <v-icon>mdi-close</v-icon>
+          </v-btn>
+        </v-card-title>
+
+        <v-card-text class="modal-body">
+          <form @submit.prevent="findUserId">
+            <div class="form-group">
+              <label>이름 <span class="required">*</span></label>
+              <v-text-field
+                v-model="findIdForm.name"
+                variant="outlined"
+                hide-details
+                placeholder="이름을 입력해주세요"
+                class="custom-input"
+                :error="!findIdValidation.name"
+              ></v-text-field>
+            </div>
+
+            <div class="form-group mb--0">
+              <label>이메일 <span class="required">*</span></label>
+              <div class="email-input-group">
+                <v-text-field
+                  v-model="findIdForm.emailLocal"
+                  variant="outlined"
+                  hide-details
+                  placeholder="이메일"
+                  class="custom-input email-local"
+                  :error="!findIdValidation.email"
+                ></v-text-field>
+                <span class="email-at">@</span>
+                <v-combobox
+                  v-model="findIdForm.emailDomain"
+                  :items="['gmail.com', 'naver.com', 'daum.net', 'hotmail.com', 'yahoo.com']"
+                  hide-details
+                  variant="outlined"
+                  placeholder="도메인 선택"
+                  class="custom-select email-domain"
+                  :error="!findIdValidation.email"
+                ></v-combobox>
+              </div>
+            </div>
+
+            <div class="form-group" style="display: none;">
+              <label>회원 유형 <span class="required">*</span></label>
+              <v-select
+                v-model="findIdForm.memberType"
+                :items="findIdMemberTypes"
+                readonly="true"
+                variant="outlined"
+                placeholder="회원 유형을 선택해주세요"
+                class="custom-select"
+              ></v-select>
+            </div>
+          </form>
+        </v-card-text>
+
+        <v-card-actions class="modal-footer">
+          <v-btn @click="closeFindIdModal" class="cancel-btn">취소</v-btn>
+          <v-btn @click="findUserId" class="submit-btn" :loading="findIdLoading">아이디 찾기</v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+
+    <!-- 아이디 찾기 결과 모달 -->
+    <v-dialog v-model="showFindIdResultModal" max-width="600px" persistent>
+      <v-card class="inquiry-modal">
+        <v-card-title class="modal-header">
+          <h3>아이디 찾기 결과</h3>
+          <v-btn icon @click="closeFindIdResultModal" class="close-btn">
+            <v-icon>mdi-close</v-icon>
+          </v-btn>
+        </v-card-title>
+
+        <v-card-text class="modal-body">
+          <div v-if="foundUserIds.length > 0" class="result-success">
+            <div class="success-icon">✅</div>
+            <h4>아이디를 찾았습니다!</h4>
+            <div class="found-ids">
+              <div v-for="(user, index) in foundUserIds" :key="index" class="user-info">
+                <p class="user-id">{{ maskUserId(user.id) }}</p>
+                <p class="join-date">가입일: {{ formatDate(user.joinDate) }}</p>
+              </div>
+            </div>
+          </div>
+          <div v-else class="result-error">
+            <div class="error-icon">❌</div>
+            <h4>아이디를 찾을 수 없습니다</h4>
+            <p>입력하신 정보와 일치하는 아이디가 없습니다.<br>정보를 다시 확인해 주세요.</p>
+          </div>
+        </v-card-text>
+
+        <v-card-actions class="modal-footer">
+          <v-btn @click="closeFindIdResultModal" class="cancel-btn">닫기</v-btn>
+          <v-btn v-if="foundUserIds.length > 0" @click="goToLoginFromModal" class="submit-btn">로그인하기</v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+
+    <!-- 비밀번호 찾기 모달 -->
+    <v-dialog v-model="showFindPwModal" max-width="600px" persistent>
+      <v-card class="inquiry-modal">
+        <v-card-title class="modal-header">
+          <h3>비밀번호 찾기</h3>
+          <v-btn icon @click="closeFindPwModal" class="close-btn">
+            <v-icon>mdi-close</v-icon>
+          </v-btn>
+        </v-card-title>
+
+        <v-card-text class="modal-body">
+          <form @submit.prevent="findUserPw">
+            <div class="form-group">
+              <label>이름 <span class="required">*</span></label>
+              <v-text-field
+                v-model="findPwForm.name"
+                variant="outlined"
+                hide-details
+                placeholder="이름을 입력해주세요"
+                class="custom-input"
+                :error="!findPwValidation.name"
+              ></v-text-field>
+            </div>
+
+            <div class="form-group">
+              <label>아이디 <span class="required">*</span></label>
+              <v-text-field
+                v-model="findPwForm.userId"
+                variant="outlined"
+                hide-details
+                placeholder="아이디를 입력해주세요"
+                class="custom-input"
+                :error="!findPwValidation.userId"
+              ></v-text-field>
+            </div>
+
+            <div class="form-group mb--0">
+              <label>이메일 <span class="required">*</span></label>
+              <div class="email-input-group">
+                <v-text-field
+                  v-model="findPwForm.emailLocal"
+                  variant="outlined"
+                  hide-details
+                  placeholder="이메일"
+                  class="custom-input email-local"
+                  :error="!findPwValidation.email"
+                ></v-text-field>
+                <span class="email-at">@</span>
+                <v-combobox
+                  v-model="findPwForm.emailDomain"
+                  :items="['gmail.com', 'naver.com', 'daum.net', 'hotmail.com', 'yahoo.com']"
+                  hide-details
+                  variant="outlined"
+                  placeholder="도메인 선택"
+                  class="custom-select email-domain"
+                  :error="!findPwValidation.email"
+                ></v-combobox>
+              </div>
+            </div>
+
+            <div class="form-group" style="display: none;">
+              <label>회원 유형 <span class="required">*</span></label>
+              <v-select
+                v-model="findPwForm.memberType"
+                :items="findIdMemberTypes"
+                readonly="true"
+                variant="outlined"
+                placeholder="회원 유형을 선택해주세요"
+                class="custom-select"
+              ></v-select>
+            </div>
+          </form>
+        </v-card-text>
+
+        <v-card-actions class="modal-footer">
+          <v-btn @click="closeFindPwModal" class="cancel-btn">취소</v-btn>
+          <v-btn @click="findUserPw" class="submit-btn" :loading="findPwLoading">확인</v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+
+    <!-- 비밀번호 변경 모달 -->
+    <v-dialog v-model="showChangePwModal" max-width="600px" persistent>
+      <v-card class="inquiry-modal">
+        <v-card-title class="modal-header">
+          <h3>새 비밀번호 설정</h3>
+          <v-btn icon @click="closeChangePwModal" class="close-btn">
+            <v-icon>mdi-close</v-icon>
+          </v-btn>
+        </v-card-title>
+
+        <v-card-text class="modal-body">
+          <div class="success-message mb--20">
+            <div class="success-icon">✅</div>
+            <p>회원 정보가 확인되었습니다.<br>새로운 비밀번호를 설정해주세요.</p>
+          </div>
+
+          <form @submit.prevent="changePassword">
+            <div class="form-group">
+              <label>새 비밀번호 <span class="required">*</span></label>
+              <v-text-field
+                v-model="changePwForm.newPassword"
+                :type="showNewPassword ? 'text' : 'password'"
+                variant="outlined"
+                hide-details
+                placeholder="새 비밀번호를 입력해주세요"
+                class="custom-input"
+                :error="!changePwValidation.newPassword"
+              >
+                <template v-slot:append-inner>
+                  <v-btn icon size="small" @click="showNewPassword = !showNewPassword">
+                    <v-icon>{{ showNewPassword ? 'mdi-eye-off' : 'mdi-eye' }}</v-icon>
+                  </v-btn>
+                </template>
+              </v-text-field>
+            </div>
+
+            <div class="form-group mb--0">
+              <label>새 비밀번호 확인 <span class="required">*</span></label>
+              <v-text-field
+                v-model="changePwForm.confirmPassword"
+                :type="showConfirmPassword ? 'text' : 'password'"
+                variant="outlined"
+                hide-details
+                placeholder="새 비밀번호를 다시 입력해주세요"
+                class="custom-input"
+                :error="!changePwValidation.confirmPassword"
+              >
+                <template v-slot:append-inner>
+                  <v-btn icon size="small" @click="showConfirmPassword = !showConfirmPassword">
+                    <v-icon>{{ showConfirmPassword ? 'mdi-eye-off' : 'mdi-eye' }}</v-icon>
+                  </v-btn>
+                </template>
+              </v-text-field>
+            </div>
+          </form>
+        </v-card-text>
+
+        <v-card-actions class="modal-footer">
+          <v-btn @click="closeChangePwModal" class="cancel-btn">취소</v-btn>
+          <v-btn @click="changePassword" class="submit-btn" :loading="changePwLoading">비밀번호 변경</v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
   </div>
 </template>
 
@@ -270,27 +519,64 @@
     validOtpTxt: "",
     errorCheck: false,
   });
-  // 아이디 찾기
-  const findId = ref({
-    popYn: false,
-    //tenantName: '',
-    email: "",
-    otpNum: "",
-    validCheck: {
-      input: {
-        //tenantName: true,
-        email: true,
-      },
-      otp: {
-        otpNum: true,
-      },
-      inputErrorCheck: true,
-      inputValidTxt: "",
-      otpValidTxt: "",
-      findIdValidCheck: false,
-    },
-    btnTxt: "",
+  // 아이디 찾기 모달
+  const showFindIdModal = ref(false);
+  const showFindIdResultModal = ref(false);
+  const findIdLoading = ref(false);
+  const foundUserIds = ref([]);
+  
+  const findIdForm = ref({
+    name: '',
+    emailLocal: '',
+    emailDomain: '',
+    memberType: ''
+  });
+  
+  const findIdValidation = ref({
+    name: true,
+    email: true
   });
+  
+  const findIdMemberTypes = [
+    { title: '회원 유형 선택', value: '', disabled: true },
+    { title: '인플루언서', value: 'influence' },
+    { title: '벤더사', value: 'vendor' },
+    { title: '브랜드사', value: 'brand' }
+  ];
+
+  // 비밀번호 찾기 모달
+  const showFindPwModal = ref(false);
+  const showChangePwModal = ref(false);
+  const findPwLoading = ref(false);
+  const changePwLoading = ref(false);
+  const foundUser = ref(null);
+  
+  const findPwForm = ref({
+    name: '',
+    userId: '',
+    emailLocal: '',
+    emailDomain: '',
+    memberType: ''
+  });
+  
+  const findPwValidation = ref({
+    name: true,
+    userId: true,
+    email: true
+  });
+
+  const changePwForm = ref({
+    newPassword: '',
+    confirmPassword: ''
+  });
+
+  const changePwValidation = ref({
+    newPassword: true,
+    confirmPassword: true
+  });
+
+  const showNewPassword = ref(false);
+  const showConfirmPassword = ref(false);
   // 비밀번호 초기화
   const resetPw = ref({
     popYn: false,
@@ -587,6 +873,344 @@
     });
   };
 
+  // 아이디 찾기 모달 관련 함수들
+  const openFindIdModal = () => {
+    // URL 파라미터에서 type을 가져와서 회원 유형 설정
+    const typeParam = route.query.type;
+    if (typeParam && ['influence', 'vendor', 'brand'].includes(typeParam)) {
+      findIdForm.value.memberType = typeParam;
+    } else {
+      findIdForm.value.memberType = loginForm.value.loginType || '';
+    }
+    showFindIdModal.value = true;
+  };
+
+  const closeFindIdModal = () => {
+    showFindIdModal.value = false;
+    resetFindIdForm();
+  };
+
+  const closeFindIdResultModal = () => {
+    showFindIdResultModal.value = false;
+    foundUserIds.value = [];
+  };
+
+  const resetFindIdForm = () => {
+    // URL 파라미터에서 type을 가져와서 기본값으로 설정
+    const typeParam = route.query.type;
+    let defaultMemberType = '';
+    if (typeParam && ['influence', 'vendor', 'brand'].includes(typeParam)) {
+      defaultMemberType = typeParam;
+    } else {
+      defaultMemberType = loginForm.value.loginType || '';
+    }
+    
+    findIdForm.value = {
+      name: '',
+      emailLocal: '',
+      emailDomain: '',
+      memberType: defaultMemberType
+    };
+    findIdValidation.value = {
+      name: true,
+      email: true
+    };
+  };
+
+  const validateFindIdForm = () => {
+    let isValid = true;
+    
+    // 이름 검증
+    if (!findIdForm.value.name.trim()) {
+      findIdValidation.value.name = false;
+      $toast.error("이름을 입력해주세요.");
+      isValid = false;
+    } else {
+      findIdValidation.value.name = true;
+    }
+    
+    // 이메일 검증
+    if (!findIdForm.value.emailLocal.trim() || !findIdForm.value.emailDomain) {
+      findIdValidation.value.email = false;
+      $toast.error("이메일을 입력해주세요.");
+      isValid = false;
+    } else {
+      findIdValidation.value.email = true;
+    }
+    
+    // 회원 타입 검증
+    if (!findIdForm.value.memberType) {
+      $toast.error("회원 유형을 선택해주세요.");
+      isValid = false;
+    }
+    
+    return isValid;
+  };
+
+  const findUserId = async () => {
+    if (!validateFindIdForm()) {
+      return;
+    }
+    
+    findIdLoading.value = true;
+    
+    try {
+      const fullEmail = `${findIdForm.value.emailLocal}@${findIdForm.value.emailDomain}`;
+      const response = await useAxios().post('/auth/findId', {
+        name: findIdForm.value.name.trim(),
+        email: fullEmail,
+        memberType: findIdForm.value.memberType
+      });
+      
+      if (response.data && response.data.userIds) {
+        foundUserIds.value = response.data.userIds;
+      } else {
+        foundUserIds.value = [];
+      }
+      
+      closeFindIdModal();
+      showFindIdResultModal.value = true;
+      
+    } catch (error) {
+      console.error('Find ID error:', error);
+      if (error.response?.status === 404) {
+        foundUserIds.value = [];
+        closeFindIdModal();
+        showFindIdResultModal.value = true;
+      } else {
+        $toast.error('아이디 찾기 중 오류가 발생했습니다.');
+      }
+    } finally {
+      findIdLoading.value = false;
+    }
+  };
+
+  const maskUserId = (userId) => {
+    if (!userId || userId.length < 3) {
+      return userId;
+    }
+    
+    if (userId.length <= 6) {
+      return userId.substring(0, 3) + '*'.repeat(userId.length - 3);
+    } else {
+      return userId.substring(0, 3) + '*'.repeat(4) + userId.substring(userId.length - 2);
+    }
+  };
+
+  const getMemberTypeText = (type) => {
+    const typeMap = {
+      'influence': '인플루언서',
+      'vendor': '벤더사', 
+      'brand': '브랜드사'
+    };
+    return typeMap[type] || type;
+  };
+
+  const formatDate = (dateString) => {
+    if (!dateString) return '';
+    const date = new Date(dateString);
+    return date.getFullYear() + '.' + 
+           String(date.getMonth() + 1).padStart(2, '0') + '.' + 
+           String(date.getDate()).padStart(2, '0');
+  };
+
+  const goToLoginFromModal = () => {
+    closeFindIdResultModal();
+    // 필요시 특정 아이디를 로그인 폼에 미리 채울 수 있음
+  };
+
+  // 비밀번호 찾기 모달 관련 함수들
+  const openFindPwModal = () => {
+    // URL 파라미터에서 type을 가져와서 회원 유형 설정
+    const typeParam = route.query.type;
+    if (typeParam && ['influence', 'vendor', 'brand'].includes(typeParam)) {
+      findPwForm.value.memberType = typeParam;
+    } else {
+      findPwForm.value.memberType = loginForm.value.loginType || '';
+    }
+    showFindPwModal.value = true;
+  };
+
+  const closeFindPwModal = () => {
+    showFindPwModal.value = false;
+    resetFindPwForm();
+  };
+
+  const closeChangePwModal = () => {
+    showChangePwModal.value = false;
+    resetChangePwForm();
+    foundUser.value = null;
+  };
+
+  const resetFindPwForm = () => {
+    // URL 파라미터에서 type을 가져와서 기본값으로 설정
+    const typeParam = route.query.type;
+    let defaultMemberType = '';
+    if (typeParam && ['influence', 'vendor', 'brand'].includes(typeParam)) {
+      defaultMemberType = typeParam;
+    } else {
+      defaultMemberType = loginForm.value.loginType || '';
+    }
+    
+    findPwForm.value = {
+      name: '',
+      userId: '',
+      emailLocal: '',
+      emailDomain: '',
+      memberType: defaultMemberType
+    };
+    findPwValidation.value = {
+      name: true,
+      userId: true,
+      email: true
+    };
+  };
+
+  const resetChangePwForm = () => {
+    changePwForm.value = {
+      newPassword: '',
+      confirmPassword: ''
+    };
+    changePwValidation.value = {
+      newPassword: true,
+      confirmPassword: true
+    };
+    showNewPassword.value = false;
+    showConfirmPassword.value = false;
+  };
+
+  const validateFindPwForm = () => {
+    let isValid = true;
+    
+    // 이름 검증
+    if (!findPwForm.value.name.trim()) {
+      findPwValidation.value.name = false;
+      $toast.error("이름을 입력해주세요.");
+      isValid = false;
+    } else {
+      findPwValidation.value.name = true;
+    }
+
+    // 아이디 검증
+    if (!findPwForm.value.userId.trim()) {
+      findPwValidation.value.userId = false;
+      $toast.error("아이디를 입력해주세요.");
+      isValid = false;
+    } else {
+      findPwValidation.value.userId = true;
+    }
+    
+    // 이메일 검증
+    if (!findPwForm.value.emailLocal.trim() || !findPwForm.value.emailDomain) {
+      findPwValidation.value.email = false;
+      $toast.error("이메일을 입력해주세요.");
+      isValid = false;
+    } else {
+      findPwValidation.value.email = true;
+    }
+    
+    return isValid;
+  };
+
+  const validateChangePwForm = () => {
+    let isValid = true;
+    
+    // 새 비밀번호 검증
+    if (!changePwForm.value.newPassword.trim()) {
+      changePwValidation.value.newPassword = false;
+      $toast.error("새 비밀번호를 입력해주세요.");
+      isValid = false;
+    } else if (changePwForm.value.newPassword.length < 6) {
+      changePwValidation.value.newPassword = false;
+      $toast.error("비밀번호는 최소 6자 이상 입력해주세요.");
+      isValid = false;
+    } else {
+      changePwValidation.value.newPassword = true;
+    }
+
+    // 비밀번호 확인 검증
+    if (!changePwForm.value.confirmPassword.trim()) {
+      changePwValidation.value.confirmPassword = false;
+      $toast.error("비밀번호 확인을 입력해주세요.");
+      isValid = false;
+    } else if (changePwForm.value.newPassword !== changePwForm.value.confirmPassword) {
+      changePwValidation.value.confirmPassword = false;
+      $toast.error("비밀번호가 일치하지 않습니다.");
+      isValid = false;
+    } else {
+      changePwValidation.value.confirmPassword = true;
+    }
+    
+    return isValid;
+  };
+
+  const findUserPw = async () => {
+    if (!validateFindPwForm()) {
+      return;
+    }
+    
+    findPwLoading.value = true;
+    
+    try {
+      const fullEmail = `${findPwForm.value.emailLocal}@${findPwForm.value.emailDomain}`;
+      const response = await useAxios().post('/auth/findPw', {
+        name: findPwForm.value.name.trim(),
+        userId: findPwForm.value.userId.trim(),
+        email: fullEmail,
+        memberType: findPwForm.value.memberType,
+        step: 'verify' // 첫 번째 단계: 사용자 확인
+      });
+      
+      if (response.data && response.data.user) {
+        foundUser.value = response.data.user;
+        closeFindPwModal();
+        showChangePwModal.value = true;
+      } else {
+        $toast.error('입력하신 정보와 일치하는 사용자가 없습니다.');
+      }
+      
+    } catch (error) {
+      console.error('Find password error:', error);
+      if (error.response?.status === 404) {
+        $toast.error('입력하신 정보와 일치하는 사용자가 없습니다.');
+      } else {
+        $toast.error('비밀번호 찾기 중 오류가 발생했습니다.');
+      }
+    } finally {
+      findPwLoading.value = false;
+    }
+  };
+
+  const changePassword = async () => {
+    if (!validateChangePwForm() || !foundUser.value) {
+      return;
+    }
+    
+    changePwLoading.value = true;
+    
+    try {
+      const response = await useAxios().post('/auth/findPw', {
+        userId: foundUser.value.userId,
+        memberType: foundUser.value.memberType,
+        newPassword: changePwForm.value.newPassword,
+        step: 'change' // 두 번째 단계: 비밀번호 변경
+      });
+      
+      if (response.data && response.data.status === 'success') {
+        $toast.success('비밀번호가 성공적으로 변경되었습니다.');
+        closeChangePwModal();
+      } else {
+        $toast.error('비밀번호 변경에 실패했습니다.');
+      }
+      
+    } catch (error) {
+      console.error('Change password error:', error);
+      $toast.error('비밀번호 변경 중 오류가 발생했습니다.');
+    } finally {
+      changePwLoading.value = false;
+    }
+  };
+
   const fnLoginSet = (__MSG) => {
     let param = {
       id: pageId,
@@ -938,4 +1562,126 @@
   position: relative;
   z-index: 1;
 }
+
+/* 아이디 찾기 모달 스타일 - 고객센터 모달과 동일하게 */
+.email-input-group {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.email-local {
+  flex: 2;
+}
+
+.email-at {
+  color: #333;
+  font-weight: 500;
+  margin: 0 4px;
+  font-size: 16px;
+}
+
+.email-domain {
+  flex: 2;
+}
+
+/* 결과 모달 스타일 */
+.result-success .success-icon,
+.result-error .error-icon {
+  font-size: 48px;
+  margin-bottom: 16px;
+}
+
+.result-success h4,
+.result-error h4 {
+  margin: 0 0 16px 0;
+  color: #333;
+  font-size: 1.3rem;
+  font-weight: 600;
+}
+
+.result-error p {
+  color: #666;
+  line-height: 1.5;
+  margin: 0;
+}
+
+.found-ids {
+  margin-top: 20px;
+  text-align: left;
+}
+
+.user-info {
+  background: #f8f9fa;
+  border-radius: 8px;
+  padding: 16px;
+  margin-bottom: 12px;
+  border: 1px solid #e9ecef;
+}
+
+.user-info:last-child {
+  margin-bottom: 0;
+}
+
+.user-type {
+  color: #666;
+  font-size: 12px;
+  margin: 0 0 6px 0;
+  font-weight: 500;
+  text-transform: uppercase;
+}
+
+.user-id {
+  font-size: 18px;
+  font-weight: bold;
+  color: #333;
+  margin: 0 0 6px 0;
+  letter-spacing: 1px;
+  font-family: 'Courier New', monospace;
+}
+
+.join-date {
+  color: #999;
+  font-size: 13px;
+  margin: 0;
+}
+
+/* 반응형 */
+@media (max-width: 768px) {
+  .email-input-group {
+    flex-direction: column;
+    align-items: stretch;
+    gap: 12px;
+  }
+  
+  .email-at {
+    text-align: center;
+    margin: 0;
+  }
+  
+  .email-local,
+  .email-domain {
+    flex: 1;
+  }
+}
+
+/* 비밀번호 변경 모달 스타일 */
+.success-message {
+  text-align: center;
+  background: #f0f9f4;
+  padding: 20px;
+  border-radius: 8px;
+  border: 1px solid #d1fae5;
+}
+
+.success-message .success-icon {
+  font-size: 32px;
+  margin-bottom: 8px;
+}
+
+.success-message p {
+  color: #065f46;
+  line-height: 1.5;
+  margin: 0;
+}
 </style>