feat: 글자크기를 계정별·메뉴별로 저장(재로그인 유지)

기존 전역 localStorage 방식(모든 메뉴 일괄 적용)을 화면 경로(메뉴키) 기준
계정별 DB 저장으로 변경. A−/A+ 조정 시 해당 화면만 조정·저장되고, 다음
방문·재로그인 시 각 화면의 저장값이 서버 주입으로 복원된다.

- member_menu_font_scale 테이블 + 저장 엔드포인트(bag/pref/font-scale)
- member_font_scale_for() 헬퍼로 렌더 시 현재 화면 저장값 주입
- admin/portal/embed 레이아웃 + 워크스페이스(탭 iframe)에 적용
  · 워크스페이스는 포커스된 탭(메뉴)만 조정, 디바운스 저장으로 CSRF 경합 방지

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
taekyoungc
2026-07-13 11:12:43 +09:00
parent 62f7bda290
commit 03c2bbc05c
8 changed files with 210 additions and 47 deletions

View File

@@ -224,6 +224,56 @@ class Bag extends BaseController
]);
}
/**
* 계정별·메뉴별 글자크기(zoom %) 저장. AJAX 전용.
* menu_key(화면 경로) + scale(70~150)을 로그인 계정 기준으로 upsert.
*/
public function saveFontScale(): ResponseInterface
{
$mbIdx = (int) (session()->get('mb_idx') ?? 0);
if ($mbIdx <= 0) {
return $this->response->setJSON(['ok' => false, 'csrf' => csrf_hash()]);
}
$menuKey = trim((string) ($this->request->getPost('menu_key') ?? ''));
$scale = (int) ($this->request->getPost('scale') ?? 0);
if ($menuKey === '' || $scale < 70 || $scale > 150) {
return $this->response->setJSON(['ok' => false, 'csrf' => csrf_hash()]);
}
$menuKey = mb_substr($menuKey, 0, 191);
$db = \Config\Database::connect();
if (! $db->tableExists('member_menu_font_scale')) {
$db->query(<<<'SQL'
CREATE TABLE IF NOT EXISTS `member_menu_font_scale` (
`mmf_idx` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`mmf_mb_idx` INT UNSIGNED NOT NULL,
`mmf_menu_key` VARCHAR(191) NOT NULL,
`mmf_scale` SMALLINT UNSIGNED NOT NULL DEFAULT 100,
`mmf_updated` DATETIME NOT NULL,
PRIMARY KEY (`mmf_idx`),
UNIQUE KEY `uk_mb_menu` (`mmf_mb_idx`,`mmf_menu_key`),
KEY `idx_mb` (`mmf_mb_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
SQL);
}
$now = date('Y-m-d H:i:s');
$exists = $db->table('member_menu_font_scale')
->where('mmf_mb_idx', $mbIdx)->where('mmf_menu_key', $menuKey)->countAllResults();
if ($exists > 0) {
$db->table('member_menu_font_scale')
->where('mmf_mb_idx', $mbIdx)->where('mmf_menu_key', $menuKey)
->update(['mmf_scale' => $scale, 'mmf_updated' => $now]);
} else {
$db->table('member_menu_font_scale')->insert([
'mmf_mb_idx' => $mbIdx, 'mmf_menu_key' => $menuKey,
'mmf_scale' => $scale, 'mmf_updated' => $now,
]);
}
return $this->response->setJSON(['ok' => true, 'csrf' => csrf_hash()]);
}
// ──────────────────────────────────────────────
// 기본정보관리 (단가·포장 단위 진입 허브)
// ──────────────────────────────────────────────