172 lines
5.5 KiB
PHP
172 lines
5.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Controllers\Api\Admin;
|
||
|
|
|
||
|
|
use App\Http\Controllers\Controller;
|
||
|
|
use Illuminate\Http\JsonResponse;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Illuminate\Support\Facades\DB;
|
||
|
|
|
||
|
|
class SourceTableSearchController extends Controller
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 소스 테이블별 검색 설정
|
||
|
|
* model: Eloquent 모델 클래스 (없으면 DB 쿼리빌더 사용)
|
||
|
|
* search_columns: 검색 대상 컬럼
|
||
|
|
* select: 반환할 컬럼
|
||
|
|
* title_field: 표시 제목 필드
|
||
|
|
* subtitle_field: 표시 부제목 필드
|
||
|
|
* has_tenant: tenant_id 필터 여부
|
||
|
|
* has_active: is_active 필터 여부
|
||
|
|
*/
|
||
|
|
private function getTableConfig(): array
|
||
|
|
{
|
||
|
|
return [
|
||
|
|
'items' => [
|
||
|
|
'model' => \App\Models\Items\Item::class,
|
||
|
|
'search_columns' => ['name', 'code'],
|
||
|
|
'select' => ['id', 'code', 'name', 'item_type', 'unit'],
|
||
|
|
'title_field' => 'name',
|
||
|
|
'subtitle_field' => 'code',
|
||
|
|
'has_tenant' => true,
|
||
|
|
'has_active' => true,
|
||
|
|
'order_by' => 'name',
|
||
|
|
],
|
||
|
|
'processes' => [
|
||
|
|
'model' => \App\Models\Process::class,
|
||
|
|
'search_columns' => ['process_name', 'process_code'],
|
||
|
|
'select' => ['id', 'process_code', 'process_name'],
|
||
|
|
'title_field' => 'process_name',
|
||
|
|
'subtitle_field' => 'process_code',
|
||
|
|
'has_tenant' => true,
|
||
|
|
'has_active' => true,
|
||
|
|
'order_by' => 'process_name',
|
||
|
|
],
|
||
|
|
'lots' => [
|
||
|
|
'table' => 'lots',
|
||
|
|
'search_columns' => ['lot_number', 'specification'],
|
||
|
|
'select' => ['id', 'lot_number', 'item_id', 'specification'],
|
||
|
|
'title_field' => 'lot_number',
|
||
|
|
'subtitle_field' => 'specification',
|
||
|
|
'has_tenant' => true,
|
||
|
|
'has_active' => false,
|
||
|
|
'order_by' => 'lot_number',
|
||
|
|
],
|
||
|
|
'users' => [
|
||
|
|
'model' => \App\Models\User::class,
|
||
|
|
'search_columns' => ['name', 'email'],
|
||
|
|
'select' => ['id', 'name', 'email'],
|
||
|
|
'title_field' => 'name',
|
||
|
|
'subtitle_field' => 'email',
|
||
|
|
'has_tenant' => false,
|
||
|
|
'has_active' => false,
|
||
|
|
'order_by' => 'name',
|
||
|
|
],
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 소스 테이블 통합 검색
|
||
|
|
* GET /api/admin/source-tables/{table}/search?q=xxx&item_type=RM,SM&ids=1,2,3
|
||
|
|
*/
|
||
|
|
public function search(Request $request, string $table): JsonResponse
|
||
|
|
{
|
||
|
|
$config = $this->getTableConfig()[$table] ?? null;
|
||
|
|
|
||
|
|
if (! $config) {
|
||
|
|
return response()->json([
|
||
|
|
'success' => false,
|
||
|
|
'message' => "지원하지 않는 테이블: {$table}",
|
||
|
|
], 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
$query = $request->input('q', '');
|
||
|
|
|
||
|
|
// Eloquent 모델 또는 DB 쿼리빌더
|
||
|
|
if (isset($config['model'])) {
|
||
|
|
$builder = $config['model']::query();
|
||
|
|
} else {
|
||
|
|
$builder = DB::table($config['table'])->whereNull('deleted_at');
|
||
|
|
}
|
||
|
|
|
||
|
|
// 테넌트 필터
|
||
|
|
if ($config['has_tenant'] && $tenantId) {
|
||
|
|
$builder->where('tenant_id', $tenantId);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 활성 필터
|
||
|
|
if ($config['has_active']) {
|
||
|
|
$builder->where('is_active', true);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 검색어 필터
|
||
|
|
if ($query) {
|
||
|
|
$builder->where(function ($q) use ($query, $config) {
|
||
|
|
foreach ($config['search_columns'] as $col) {
|
||
|
|
$q->orWhere($col, 'like', "%{$query}%");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 추가 파라미터 필터 (item_type 등)
|
||
|
|
if ($request->has('item_type')) {
|
||
|
|
$builder->whereIn('item_type', explode(',', $request->input('item_type')));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ID 목록으로 조회
|
||
|
|
if ($request->has('ids')) {
|
||
|
|
$builder->whereIn('id', explode(',', $request->input('ids')));
|
||
|
|
}
|
||
|
|
|
||
|
|
$results = $builder
|
||
|
|
->orderBy($config['order_by'])
|
||
|
|
->limit(30)
|
||
|
|
->get($config['select']);
|
||
|
|
|
||
|
|
return response()->json([
|
||
|
|
'success' => true,
|
||
|
|
'data' => $results,
|
||
|
|
'meta' => [
|
||
|
|
'title_field' => $config['title_field'],
|
||
|
|
'subtitle_field' => $config['subtitle_field'],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 사용 가능한 소스 테이블 목록
|
||
|
|
* GET /api/admin/source-tables
|
||
|
|
*/
|
||
|
|
public function tables(): JsonResponse
|
||
|
|
{
|
||
|
|
$config = $this->getTableConfig();
|
||
|
|
|
||
|
|
$tables = collect($config)->map(function ($cfg, $key) {
|
||
|
|
return [
|
||
|
|
'key' => $key,
|
||
|
|
'title_field' => $cfg['title_field'],
|
||
|
|
'subtitle_field' => $cfg['subtitle_field'],
|
||
|
|
];
|
||
|
|
})->values();
|
||
|
|
|
||
|
|
// system_field_definitions에서 라벨 가져오기
|
||
|
|
$labels = DB::table('system_field_definitions')
|
||
|
|
->select('source_table', 'source_table_label')
|
||
|
|
->groupBy('source_table', 'source_table_label')
|
||
|
|
->pluck('source_table_label', 'source_table')
|
||
|
|
->toArray();
|
||
|
|
|
||
|
|
$tables = $tables->map(function ($t) use ($labels) {
|
||
|
|
$t['label'] = $labels[$t['key']] ?? ucfirst($t['key']);
|
||
|
|
|
||
|
|
return $t;
|
||
|
|
});
|
||
|
|
|
||
|
|
return response()->json([
|
||
|
|
'success' => true,
|
||
|
|
'data' => $tables,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|