레거시(sam/sales/barobill/registration)를 Laravel 스타일로 마이그레이션 - Migration: barobill_members 테이블 생성 - Model: BarobillMember (상태 라벨, 사업자번호 포맷팅 등) - API Controller: CRUD + 통계 조회 (HTMX HTML 반환 지원) - API Routes: /api/admin/barobill/members/* - Views: - index.blade.php (통계 카드, 필터, 테이블, 모달) - partials/table.blade.php (HTMX 테이블) - partials/stats.blade.php (통계 카드) - partials/modal-form.blade.php (등록/수정 폼, 자동완성) 기능: - 회원사 목록 조회 (검색, 상태 필터) - 회원사 등록 (사업자번호 중복 체크) - 회원사 수정 (모달) - 회원사 삭제 (확인 후) - 테스트 데이터 자동완성 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
231 lines
7.4 KiB
PHP
231 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Admin\Barobill;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Barobill\BarobillMember;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class BarobillMemberController extends Controller
|
|
{
|
|
/**
|
|
* 회원사 목록 조회
|
|
*/
|
|
public function index(Request $request): JsonResponse|Response
|
|
{
|
|
$tenantId = session('selected_tenant_id');
|
|
|
|
$query = BarobillMember::query()
|
|
->when($tenantId, fn($q) => $q->where('tenant_id', $tenantId))
|
|
->when($request->search, function ($q, $search) {
|
|
$q->where(function ($q) use ($search) {
|
|
$q->where('corp_name', 'like', "%{$search}%")
|
|
->orWhere('biz_no', 'like', "%{$search}%")
|
|
->orWhere('barobill_id', 'like', "%{$search}%")
|
|
->orWhere('manager_name', 'like', "%{$search}%");
|
|
});
|
|
})
|
|
->when($request->status, fn($q, $status) => $q->where('status', $status))
|
|
->with('tenant:id,company_name')
|
|
->orderBy('created_at', 'desc');
|
|
|
|
$members = $query->paginate($request->integer('per_page', 15));
|
|
|
|
// HTMX 요청 시 HTML 반환
|
|
if ($request->header('HX-Request')) {
|
|
return response(
|
|
view('barobill.members.partials.table', compact('members'))->render(),
|
|
200,
|
|
['Content-Type' => 'text/html']
|
|
);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $members->items(),
|
|
'meta' => [
|
|
'current_page' => $members->currentPage(),
|
|
'last_page' => $members->lastPage(),
|
|
'per_page' => $members->perPage(),
|
|
'total' => $members->total(),
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 회원사 등록
|
|
*/
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$tenantId = session('selected_tenant_id');
|
|
|
|
if (!$tenantId) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => '테넌트를 선택해주세요.',
|
|
], 400);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'biz_no' => [
|
|
'required',
|
|
'string',
|
|
'max:20',
|
|
Rule::unique('barobill_members')->where(function ($query) use ($tenantId) {
|
|
return $query->where('tenant_id', $tenantId);
|
|
}),
|
|
],
|
|
'corp_name' => 'required|string|max:100',
|
|
'ceo_name' => 'required|string|max:50',
|
|
'addr' => 'nullable|string|max:255',
|
|
'biz_type' => 'nullable|string|max:50',
|
|
'biz_class' => 'nullable|string|max:50',
|
|
'barobill_id' => 'required|string|max:50',
|
|
'barobill_pwd' => 'required|string|max:255',
|
|
'manager_name' => 'nullable|string|max:50',
|
|
'manager_email' => 'nullable|email|max:100',
|
|
'manager_hp' => 'nullable|string|max:20',
|
|
'status' => 'nullable|in:active,inactive,pending',
|
|
], [
|
|
'biz_no.required' => '사업자번호를 입력해주세요.',
|
|
'biz_no.unique' => '이미 등록된 사업자번호입니다.',
|
|
'corp_name.required' => '상호명을 입력해주세요.',
|
|
'ceo_name.required' => '대표자명을 입력해주세요.',
|
|
'barobill_id.required' => '바로빌 아이디를 입력해주세요.',
|
|
'barobill_pwd.required' => '비밀번호를 입력해주세요.',
|
|
]);
|
|
|
|
$validated['tenant_id'] = $tenantId;
|
|
$validated['barobill_pwd'] = Hash::make($validated['barobill_pwd']);
|
|
$validated['status'] = $validated['status'] ?? 'active';
|
|
|
|
$member = BarobillMember::create($validated);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => '회원사가 등록되었습니다.',
|
|
'data' => $member,
|
|
], 201);
|
|
}
|
|
|
|
/**
|
|
* 회원사 상세 조회
|
|
*/
|
|
public function show(Request $request, int $id): JsonResponse
|
|
{
|
|
$member = BarobillMember::with('tenant:id,company_name')->find($id);
|
|
|
|
if (!$member) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => '회원사를 찾을 수 없습니다.',
|
|
], 404);
|
|
}
|
|
|
|
// HTMX 요청 시 HTML 반환
|
|
if ($request->header('HX-Request')) {
|
|
return response()->json([
|
|
'html' => view('barobill.members.partials.detail', compact('member'))->render(),
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $member,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 회원사 수정
|
|
*/
|
|
public function update(Request $request, int $id): JsonResponse
|
|
{
|
|
$member = BarobillMember::find($id);
|
|
|
|
if (!$member) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => '회원사를 찾을 수 없습니다.',
|
|
], 404);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'corp_name' => 'required|string|max:100',
|
|
'ceo_name' => 'required|string|max:50',
|
|
'addr' => 'nullable|string|max:255',
|
|
'biz_type' => 'nullable|string|max:50',
|
|
'biz_class' => 'nullable|string|max:50',
|
|
'manager_name' => 'nullable|string|max:50',
|
|
'manager_email' => 'nullable|email|max:100',
|
|
'manager_hp' => 'nullable|string|max:20',
|
|
'status' => 'nullable|in:active,inactive,pending',
|
|
]);
|
|
|
|
$member->update($validated);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => '회원사 정보가 수정되었습니다.',
|
|
'data' => $member->fresh(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 회원사 삭제
|
|
*/
|
|
public function destroy(int $id): JsonResponse
|
|
{
|
|
$member = BarobillMember::find($id);
|
|
|
|
if (!$member) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => '회원사를 찾을 수 없습니다.',
|
|
], 404);
|
|
}
|
|
|
|
$member->delete();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => '회원사가 삭제되었습니다.',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 통계 조회
|
|
*/
|
|
public function stats(Request $request): JsonResponse|Response
|
|
{
|
|
$tenantId = session('selected_tenant_id');
|
|
|
|
$query = BarobillMember::query()
|
|
->when($tenantId, fn($q) => $q->where('tenant_id', $tenantId));
|
|
|
|
$stats = [
|
|
'total' => (clone $query)->count(),
|
|
'active' => (clone $query)->where('status', 'active')->count(),
|
|
'inactive' => (clone $query)->where('status', 'inactive')->count(),
|
|
'pending' => (clone $query)->where('status', 'pending')->count(),
|
|
];
|
|
|
|
// HTMX 요청 시 HTML 반환
|
|
if ($request->header('HX-Request')) {
|
|
return response(
|
|
view('barobill.members.partials.stats', compact('stats'))->render(),
|
|
200,
|
|
['Content-Type' => 'text/html']
|
|
);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $stats,
|
|
]);
|
|
}
|
|
}
|