Files
financial/public/merchant_rules.php
T
2026-06-07 00:33:58 +09:00

264 lines
11 KiB
PHP

<?php
require_once __DIR__ . '/../app/lib/auth.php';
require_once __DIR__ . '/../app/lib/db.php';
require_once __DIR__ . '/../app/lib/helpers.php';
check_auth();
$pdo = db();
$uid = user_id();
$error = '';
$msg = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$mode = $_POST['mode'] ?? 'create';
if ($mode === 'create') {
$keyword = trim($_POST['keyword'] ?? '');
$categoryId = (int)($_POST['category_id'] ?? 0);
$priority = (int)($_POST['priority'] ?? 100);
if ($keyword === '') {
throw new RuntimeException('키워드를 입력하세요.');
}
if ($categoryId <= 0) {
throw new RuntimeException('카테고리를 선택하세요.');
}
$stmt = $pdo->prepare("
INSERT INTO merchant_pattern_rules
(user_id, pattern_text, normalized_pattern, match_type, category_id, priority, confidence, is_active, memo)
VALUES (?, ?, ?, 'contains', ?, ?, 0.90, 1, 'manual')
");
$normalized = mb_strtolower($keyword,'UTF-8');
$normalized = str_replace([' ','-','(',')','.',',','㈜'],'',$normalized);
$stmt->execute([$uid, $keyword, $normalized, $categoryId, $priority]);
$msg = '규칙이 추가되었습니다.';
}
if ($mode === 'update') {
$id = (int)($_POST['id'] ?? 0);
$keyword = trim($_POST['keyword'] ?? '');
$categoryId = (int)($_POST['category_id'] ?? 0);
$priority = (int)($_POST['priority'] ?? 100);
$isActive = isset($_POST['is_active']) ? 1 : 0;
if ($id <= 0) {
throw new RuntimeException('규칙 ID가 올바르지 않습니다.');
}
if ($keyword === '') {
throw new RuntimeException('키워드를 입력하세요.');
}
if ($categoryId <= 0) {
throw new RuntimeException('카테고리를 선택하세요.');
}
$stmt = $pdo->prepare("
UPDATE merchant_pattern_rules
SET pattern_text = ?, normalized_pattern = ?, category_id = ?, priority = ?, is_active = ?
WHERE id = ? AND user_id = ?
");
$normalized = mb_strtolower($keyword,'UTF-8');
$normalized = str_replace([' ','-','(',')','.',',','㈜'],'',$normalized);
$stmt->execute([
$keyword,
$normalized,
$categoryId,
$priority,
$isActive,
$id,
$uid
]);
$msg = '규칙이 수정되었습니다.';
}
if ($mode === 'delete') {
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
throw new RuntimeException('규칙 ID가 올바르지 않습니다.');
}
$stmt = $pdo->prepare("DELETE FROM merchant_pattern_rules WHERE id = ? AND user_id = ?");
$stmt->execute([$id, $uid]);
$msg = '규칙이 삭제되었습니다.';
}
} catch (Throwable $e) {
$error = $e->getMessage();
}
}
$stmt = $pdo->prepare("
SELECT id, category_type, name
FROM categories
WHERE user_id = ?
AND is_active = 1
ORDER BY category_type, sort_order, id
");
$stmt->execute([$uid]);
$categories = $stmt->fetchAll();
$stmt = $pdo->prepare("
SELECT
r.*,
c.name AS category_name,
c.category_type
FROM merchant_pattern_rules r
JOIN categories c ON c.id = r.category_id
WHERE r.user_id = ?
ORDER BY r.priority ASC, r.id ASC
");
$stmt->execute([$uid]);
$rules = $stmt->fetchAll();
require __DIR__ . '/../app/views/header.php';
?>
<div class="page-head">
<h2>상호명 자동분류 규칙</h2>
</div>
<?php if ($error): ?>
<div class="alert alert-danger"><?= h($error) ?></div>
<?php endif; ?>
<?php if ($msg): ?>
<div class="alert alert-success"><?= h($msg) ?></div>
<?php endif; ?>
<div class="row g-4">
<div class="col-12 col-xl-4">
<div class="card finance-card">
<div class="card-body">
<h5 class="mb-3">규칙 추가</h5>
<form method="post" class="row g-3">
<input type="hidden" name="mode" value="create">
<div class="col-12">
<label class="form-label">키워드</label>
<input type="text" name="keyword" class="form-control" placeholder="예: 스타벅스, 쿠팡, 배달의민족" required>
</div>
<div class="col-12">
<label class="form-label">카테고리</label>
<select name="category_id" class="form-select" required>
<option value="">선택하세요</option>
<?php foreach ($categories as $c): ?>
<option value="<?= $c['id'] ?>">
[<?= h($c['category_type']) ?>] <?= h($c['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12">
<label class="form-label">우선순위</label>
<input type="number" name="priority" class="form-control" value="100" min="1" required>
<div class="form-text">숫자가 작을수록 우선 적용됩니다.</div>
</div>
<div class="col-12">
<button class="btn btn-primary">추가</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-12 col-xl-8">
<div class="card finance-card">
<div class="card-body mobile-scroll">
<table class="table align-middle mb-0">
<thead>
<tr>
<th>ID</th>
<th>키워드</th>
<th>카테고리</th>
<th>우선순위</th>
<th>활성</th>
<th>관리</th>
</tr>
</thead>
<tbody>
<?php foreach ($rules as $rule): ?>
<tr>
<td><?= $rule['id'] ?></td>
<td><?= h($rule['pattern_text']) ?></td>
<td>[<?= h($rule['category_type']) ?>] <?= h($rule['category_name']) ?></td>
<td><?= $rule['priority'] ?></td>
<td><?= $rule['is_active'] ? 'Y' : 'N' ?></td>
<td class="text-nowrap">
<button
type="button"
class="btn btn-sm btn-outline-primary"
data-bs-toggle="collapse"
data-bs-target="#rule-edit-<?= $rule['id'] ?>"
>
수정
</button>
<form method="post" class="d-inline">
<input type="hidden" name="mode" value="delete">
<input type="hidden" name="id" value="<?= $rule['id'] ?>">
<button class="btn btn-sm btn-outline-danger" onclick="return confirm('삭제하시겠습니까?');">삭제</button>
</form>
</td>
</tr>
<tr class="collapse" id="rule-edit-<?= $rule['id'] ?>">
<td colspan="6">
<form method="post" class="row g-2 p-2">
<input type="hidden" name="mode" value="update">
<input type="hidden" name="id" value="<?= $rule['id'] ?>">
<div class="col-md-3">
<label class="form-label">키워드</label>
<input type="text" name="keyword" class="form-control" value="<?= h($rule['pattern_text']) ?>" required>
</div>
<div class="col-md-4">
<label class="form-label">카테고리</label>
<select name="category_id" class="form-select" required>
<?php foreach ($categories as $c): ?>
<option value="<?= $c['id'] ?>" <?= (int)$rule['category_id'] === (int)$c['id'] ? 'selected' : '' ?>>
[<?= h($c['category_type']) ?>] <?= h($c['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2">
<label class="form-label">우선순위</label>
<input type="number" name="priority" class="form-control" value="<?= $rule['priority'] ?>" min="1" required>
</div>
<div class="col-md-2 d-flex align-items-end">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="is_active" id="is_active_<?= $rule['id'] ?>" <?= $rule['is_active'] ? 'checked' : '' ?>>
<label class="form-check-label" for="is_active_<?= $rule['id'] ?>">활성</label>
</div>
</div>
<div class="col-md-1 d-flex align-items-end">
<button class="btn btn-primary btn-sm w-100">저장</button>
</div>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php if (!$rules): ?>
<tr>
<td colspan="6" class="text-center text-secondary py-5">등록된 규칙이 없습니다.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php require __DIR__ . '/../app/views/footer.php'; ?>