diff --git a/api.hyungi.net/db/migrations/20260119095549_add_worker_display_fields.js b/api.hyungi.net/db/migrations/20260119095549_add_worker_display_fields.js new file mode 100644 index 0000000..3a52b9e --- /dev/null +++ b/api.hyungi.net/db/migrations/20260119095549_add_worker_display_fields.js @@ -0,0 +1,34 @@ +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = async function(knex) { + await knex.schema.alterTable('workers', (table) => { + // 작업 보고서 표시 여부 (기본값: true, 작업자는 표시, 관리자는 선택 가능) + table.boolean('show_in_work_reports') + .defaultTo(true) + .notNullable() + .comment('작업 보고서에 표시 여부'); + + // 재직 상태 (employed: 재직, resigned: 퇴사) + table.enum('employment_status', ['employed', 'resigned']) + .defaultTo('employed') + .notNullable() + .comment('재직 상태'); + }); + + console.log('✅ workers 테이블에 show_in_work_reports, employment_status 컬럼 추가 완료'); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function(knex) { + await knex.schema.alterTable('workers', (table) => { + table.dropColumn('show_in_work_reports'); + table.dropColumn('employment_status'); + }); + + console.log('✅ workers 테이블에서 show_in_work_reports, employment_status 컬럼 삭제 완료'); +}; diff --git a/api.hyungi.net/models/workerModel.js b/api.hyungi.net/models/workerModel.js index ca519a0..f2ef1ab 100644 --- a/api.hyungi.net/models/workerModel.js +++ b/api.hyungi.net/models/workerModel.js @@ -19,14 +19,16 @@ const create = async (worker, callback) => { join_date = null, salary = null, annual_leave = null, - status = 'active' + status = 'active', + show_in_work_reports = true, + employment_status = 'employed' } = worker; const [result] = await db.query( `INSERT INTO workers - (worker_name, job_type, join_date, salary, annual_leave, status) - VALUES (?, ?, ?, ?, ?, ?)`, - [worker_name, job_type, formatDate(join_date), salary, annual_leave, status] + (worker_name, job_type, join_date, salary, annual_leave, status, show_in_work_reports, employment_status) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, + [worker_name, job_type, formatDate(join_date), salary, annual_leave, status, show_in_work_reports, employment_status] ); callback(null, result.insertId); @@ -81,7 +83,9 @@ const update = async (worker, callback) => { status, join_date, salary, - annual_leave + annual_leave, + show_in_work_reports, + employment_status } = worker; // 업데이트할 필드만 동적으로 구성 @@ -112,6 +116,14 @@ const update = async (worker, callback) => { updates.push('annual_leave = ?'); values.push(annual_leave); } + if (show_in_work_reports !== undefined) { + updates.push('show_in_work_reports = ?'); + values.push(show_in_work_reports); + } + if (employment_status !== undefined) { + updates.push('employment_status = ?'); + values.push(employment_status); + } if (updates.length === 0) { callback(new Error('업데이트할 필드가 없습니다')); diff --git a/web-ui/js/daily-work-report.js b/web-ui/js/daily-work-report.js index aeb8d53..a91223f 100644 --- a/web-ui/js/daily-work-report.js +++ b/web-ui/js/daily-work-report.js @@ -206,16 +206,21 @@ async function loadData() { async function loadWorkers() { try { console.log('Workers API 호출 중... (통합 API 사용)'); - // 활성 작업자 1000명까지 조회 (서버 사이드 필터링 적용) - const data = await window.apiCall(`${window.API}/workers?status=active&limit=1000`); + // 모든 작업자 1000명까지 조회 + const data = await window.apiCall(`${window.API}/workers?limit=1000`); const allWorkers = Array.isArray(data) ? data : (data.data || data.workers || []); - // 활성화된 작업자만 필터링 + // 작업 보고서에 표시할 작업자만 필터링 + // 1. show_in_work_reports가 true + // 2. employment_status가 resigned가 아님 workers = allWorkers.filter(worker => { - return worker.status === 'active' || worker.is_active === 1 || worker.is_active === true; + const showInReports = worker.show_in_work_reports !== 0 && worker.show_in_work_reports !== false; + const notResigned = worker.employment_status !== 'resigned'; + return showInReports && notResigned; }); console.log(`✅ Workers 로드 성공: ${workers.length}명 (전체: ${allWorkers.length}명)`); + console.log(`📊 필터링 조건: show_in_work_reports=true, employment_status≠resigned`); } catch (error) { console.error('작업자 로딩 오류:', error); throw error; diff --git a/web-ui/js/worker-management.js b/web-ui/js/worker-management.js index 46d187f..781c0de 100644 --- a/web-ui/js/worker-management.js +++ b/web-ui/js/worker-management.js @@ -197,18 +197,23 @@ function renderWorkers() { const jobType = jobTypeMap[worker.job_type] || jobTypeMap['worker']; const isInactive = worker.status === 'inactive' || worker.is_active === 0 || worker.is_active === false; - + const isResigned = worker.employment_status === 'resigned'; + const showInWorkReports = worker.show_in_work_reports !== 0 && worker.show_in_work_reports !== false; + console.log('🎨 카드 렌더링:', { worker_id: worker.worker_id, worker_name: worker.worker_name, status: worker.status, is_active: worker.is_active, - isInactive: isInactive + isInactive: isInactive, + isResigned: isResigned, + showInWorkReports: showInWorkReports }); - + return ` -
- ${isInactive ? '
🚫 비활성화됨
' : ''} +
+ ${isResigned ? '
🚪 퇴사
' : + isInactive ? '
🏢 사무직
' : ''}
@@ -216,7 +221,8 @@ function renderWorkers() {

${worker.worker_name} - ${isInactive ? '(비활성)' : ''} + ${isResigned ? '(퇴사)' : + isInactive ? '(사무직)' : ''}

${jobType.icon} ${jobType.text} @@ -224,14 +230,15 @@ function renderWorkers() { ${worker.email ? `📧 ${worker.email}` : ''} ${worker.department ? `🏢 ${worker.department}` : ''} ${worker.hire_date ? `📅 입사: ${formatDate(worker.hire_date)}` : ''} - ${isInactive ? '⚠️ 작업보고서에서 숨김' : ''} + ${isResigned ? '⚠️ 퇴사 처리됨' : + !showInWorkReports ? '⚠️ 작업보고서에서 숨김' : ''}
-
+
- - 체크 해제 시 작업보고서 입력에서 숨겨집니다 + + +
+ + + + 체크 해제 시 일일 작업보고서 작성 시 이 작업자가 목록에 나타나지 않습니다 + + + + + + 체크: 현장직 (출퇴근 관리 필요) / 체크 해제: 사무직 (출퇴근 관리 불필요) + + + + + + 퇴사한 작업자로 표시됩니다. 작업자 목록에서 별도로 표시됩니다 + +