fix : 테넌트별 옵션설정 작업
- Tenant Fields - Tenant Option Groups - Tenant Option Values - Tenant Profiles
This commit is contained in:
194
app/Services/TenantUserProfileService.php
Normal file
194
app/Services/TenantUserProfileService.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Helpers\ApiResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
use App\Models\Tenants\SettingFieldDef;
|
||||
use App\Models\Tenants\TenantFieldSetting;
|
||||
use App\Models\Tenants\TenantUserProfile;
|
||||
|
||||
class TenantUserProfileService
|
||||
{
|
||||
/** 활성 테넌트 ID */
|
||||
protected static function tenantId(): ?int
|
||||
{
|
||||
return app('tenant_id');
|
||||
}
|
||||
|
||||
/** 효과값 필드(Enabled) 맵: field_key => [def, setting] */
|
||||
protected static function effectiveFieldMap(int $tenantId): array
|
||||
{
|
||||
$defs = SettingFieldDef::all()->keyBy('field_key');
|
||||
$settings = TenantFieldSetting::where('tenant_id', $tenantId)->get()->keyBy('field_key');
|
||||
|
||||
$map = [];
|
||||
foreach ($defs as $key => $def) {
|
||||
$s = $settings->get($key);
|
||||
$enabled = $s ? (bool)$s->enabled : (bool)$def->is_core;
|
||||
if (!$enabled) continue;
|
||||
$map[$key] = ['def' => $def, 'setting' => $s];
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* [GET] 프로필 목록 (페이징)
|
||||
* params: per_page?, q?
|
||||
*/
|
||||
public static function index(array $params = [])
|
||||
{
|
||||
$tenantId = self::tenantId();
|
||||
if (!$tenantId) {
|
||||
return ApiResponse::error('활성 테넌트가 없습니다.', 400);
|
||||
}
|
||||
|
||||
$per = (int)($params['per_page'] ?? $params['size'] ?? 20);
|
||||
$q = TenantUserProfile::where('tenant_id', $tenantId)
|
||||
->with(['user:id,name,email']);
|
||||
|
||||
if (!empty($params['q'])) {
|
||||
$kw = $params['q'];
|
||||
$q->where(function ($w) use ($kw) {
|
||||
$w->where('display_name', 'like', "%{$kw}%")
|
||||
->orWhere('json_extra->employee_no', 'like', "%{$kw}%");
|
||||
});
|
||||
}
|
||||
|
||||
$page = isset($params['page']) ? (int)$params['page'] : null;
|
||||
$data = $q->orderByDesc('id')->paginate($per, ['*'], 'page', $page);
|
||||
|
||||
return ApiResponse::response('result', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* [GET] 프로필 단건 조회
|
||||
*/
|
||||
public static function show(int $userId)
|
||||
{
|
||||
$tenantId = self::tenantId();
|
||||
if (!$tenantId) {
|
||||
return ApiResponse::error('활성 테넌트가 없습니다.', 400);
|
||||
}
|
||||
if (!$userId) {
|
||||
return ApiResponse::error('userId가 올바르지 않습니다.', 422);
|
||||
}
|
||||
|
||||
$item = TenantUserProfile::where('tenant_id', $tenantId)
|
||||
->where('user_id', $userId)
|
||||
->with(['user:id,name,email'])
|
||||
->first();
|
||||
|
||||
if (!$item) {
|
||||
return ApiResponse::error('프로필을 찾을 수 없습니다.', 404);
|
||||
}
|
||||
|
||||
return ApiResponse::response('result', $item->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* [PATCH] 관리자 수정: enabled 필드만 write-back
|
||||
* - 입력 payload는 field_key: value 포맷(예: {"position":"manager","employee_no":"A-001"})
|
||||
*/
|
||||
public static function update(int $userId, array $params = [])
|
||||
{
|
||||
$tenantId = self::tenantId();
|
||||
if (!$tenantId) {
|
||||
return ApiResponse::error('활성 테넌트가 없습니다.', 400);
|
||||
}
|
||||
if (!$userId) {
|
||||
return ApiResponse::error('userId가 올바르지 않습니다.', 422);
|
||||
}
|
||||
|
||||
// (선택) 간단 유효성: 최소 1개 키 존재
|
||||
if (empty($params) || !is_array($params)) {
|
||||
return ApiResponse::error('수정할 항목이 없습니다.', 422);
|
||||
}
|
||||
|
||||
$fields = self::effectiveFieldMap($tenantId);
|
||||
$profile = TenantUserProfile::firstOrCreate(['tenant_id' => $tenantId, 'user_id' => $userId]);
|
||||
|
||||
try {
|
||||
DB::transaction(function () use ($fields, $profile, $params) {
|
||||
foreach ($fields as $key => $meta) {
|
||||
if (!array_key_exists($key, $params)) continue; // 입력이 없으면 스킵
|
||||
|
||||
$def = $meta['def'];
|
||||
$value = $params[$key];
|
||||
|
||||
switch ($def->storage_area) {
|
||||
case 'tenant_profile':
|
||||
if ($def->storage_key) {
|
||||
$profile->{$def->storage_key} = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'tenant_profile_json':
|
||||
$jsonKey = $def->storage_key ?: $key;
|
||||
$extra = is_array($profile->json_extra) ? $profile->json_extra : (array) json_decode((string)$profile->json_extra, true);
|
||||
$extra[$jsonKey] = $value;
|
||||
$profile->json_extra = $extra;
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
// 정책상 기본 비권장: 무시
|
||||
// 필요 시 UsersService 등으로 화이트리스트 업데이트 구현
|
||||
break;
|
||||
}
|
||||
}
|
||||
$profile->save();
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
return ApiResponse::error('프로필 저장 중 오류가 발생했습니다.', 500);
|
||||
}
|
||||
|
||||
$fresh = TenantUserProfile::where('tenant_id', $tenantId)
|
||||
->where('user_id', $userId)
|
||||
->with(['user:id,name,email'])
|
||||
->first();
|
||||
|
||||
return ApiResponse::response('result', $fresh ? $fresh->toArray() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* [GET] 내 프로필 조회
|
||||
*/
|
||||
public static function me(array $params = [])
|
||||
{
|
||||
$tenantId = self::tenantId();
|
||||
if (!$tenantId) {
|
||||
return ApiResponse::error('활성 테넌트가 없습니다.', 400);
|
||||
}
|
||||
$userId = auth()->id();
|
||||
if (!$userId) {
|
||||
return ApiResponse::error('인증 정보가 없습니다.', 401);
|
||||
}
|
||||
|
||||
$item = TenantUserProfile::where('tenant_id', $tenantId)
|
||||
->where('user_id', $userId)
|
||||
->with(['user:id,name,email'])
|
||||
->first();
|
||||
|
||||
// 없으면 null 반환(스펙에 따라 404로 바꾸려면 위와 동일 처리)
|
||||
return ApiResponse::response('result', $item ? $item->toArray() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* [PATCH] 내 프로필 수정
|
||||
* - enabled 필드만 반영 (관리자 수정과 동일 로직)
|
||||
*/
|
||||
public static function updateMe(array $params = [])
|
||||
{
|
||||
$tenantId = self::tenantId();
|
||||
if (!$tenantId) {
|
||||
return ApiResponse::error('활성 테넌트가 없습니다.', 400);
|
||||
}
|
||||
$userId = auth()->id();
|
||||
if (!$userId) {
|
||||
return ApiResponse::error('인증 정보가 없습니다.', 401);
|
||||
}
|
||||
return self::update($userId, $params);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user