264 lines
11 KiB
PHP
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'; ?>
|