148 lines
8.2 KiB
PHP
Executable File
148 lines
8.2 KiB
PHP
Executable File
<?php
|
||
require_once __DIR__ . '/includes/auth.php';
|
||
require_once __DIR__ . '/includes/functions.php';
|
||
requireLogin();
|
||
|
||
$msg = '';
|
||
$oldCodes = $_POST['codes'] ?? [];
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
if (!verifyCsrf($_POST['csrf_token'] ?? '')) { die('CSRF token无效'); }
|
||
$content = trim($_POST['content'] ?? '');
|
||
$codes = array_filter($_POST['codes'] ?? [], fn($v) => trim($v) !== '');
|
||
$codes = array_map('trim', $codes);
|
||
$codesStr = implode("\n", $codes);
|
||
$attachment = '';
|
||
|
||
if ($content === '') {
|
||
$msg = '<div class="alert alert-danger">工单内容不能为空</div>';
|
||
} elseif (empty($codes)) {
|
||
$msg = '<div class="alert alert-danger">请至少关联一个兑换码</div>';
|
||
} elseif (count($codes) > 10) {
|
||
$msg = '<div class="alert alert-danger">最多关联10个兑换码</div>';
|
||
} elseif (count(array_unique($codes)) !== count($codes)) {
|
||
$msg = '<div class="alert alert-danger">关联的兑换码不能重复</div>';
|
||
} else {
|
||
$userId = getCurrentUserId();
|
||
$pid = getCurrentProductId();
|
||
$placeholders = implode(',', array_fill(0, count($codes), '?'));
|
||
$stmt = $pdo->prepare("SELECT code, status FROM claim_records WHERE user_id = ? AND product_id = ? AND code IN ($placeholders)");
|
||
$stmt->execute(array_merge([$userId, $pid], $codes));
|
||
$foundCodes = $stmt->fetchAll();
|
||
$expiredCodes = array_map(fn($r) => $r['code'], array_filter($foundCodes, fn($r) => (int)$r['status'] === 3));
|
||
$invalidCodes = array_diff($codes, array_column($foundCodes, 'code'));
|
||
if (!empty($expiredCodes)) {
|
||
$msg = '<div class="alert alert-danger">以下兑换码已过期,无法提交工单:' . h(implode(', ', $expiredCodes)) . '</div>';
|
||
} elseif (!empty($invalidCodes)) {
|
||
$msg = '<div class="alert alert-danger">以下兑换码不在您的领取记录中:' . h(implode(', ', $invalidCodes)) . '</div>';
|
||
} else {
|
||
// 检查是否已在未处理工单中
|
||
$stmt = $pdo->prepare("SELECT code FROM work_orders WHERE creator_id = ? AND product_id = ? AND status = '未处理'");
|
||
$stmt->execute([$userId, $pid]);
|
||
$pendingOrderCodes = [];
|
||
while ($row = $stmt->fetch()) {
|
||
$pendingOrderCodes = array_merge($pendingOrderCodes, array_filter(explode("\n", $row['code'] ?? '')));
|
||
}
|
||
$pendingOrderCodes = array_map('trim', $pendingOrderCodes);
|
||
$inPending = array_intersect($codes, $pendingOrderCodes);
|
||
if (!empty($inPending)) {
|
||
$msg = '<div class="alert alert-danger">以下兑换码已在未处理的工单中,请处理后再提交:' . h(implode(', ', $inPending)) . '</div>';
|
||
} else {
|
||
if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] === UPLOAD_ERR_OK) {
|
||
$ext = strtolower(pathinfo($_FILES['attachment']['name'], PATHINFO_EXTENSION));
|
||
$allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'zip', 'rar', 'txt'];
|
||
if (!in_array($ext, $allowed)) {
|
||
$msg = '<div class="alert alert-danger">不支持的文件格式</div>';
|
||
} elseif ($_FILES['attachment']['size'] > 10 * 1024 * 1024) {
|
||
$msg = '<div class="alert alert-danger">文件大小不能超过10MB</div>';
|
||
} else {
|
||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||
$mime = finfo_file($finfo, $_FILES['attachment']['tmp_name']);
|
||
finfo_close($finfo);
|
||
if (!in_array($mime, ['image/jpeg','image/png','image/gif','application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/vnd.ms-excel','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/zip','application/x-rar-compressed','text/plain'])) {
|
||
$msg = '<div class="alert alert-danger">不支持的文件格式</div>';
|
||
} else {
|
||
$filename = bin2hex(random_bytes(16)) . '.' . $ext;
|
||
$dest = __DIR__ . '/uploads/' . $filename;
|
||
if (move_uploaded_file($_FILES['attachment']['tmp_name'], $dest)) {
|
||
$attachment = 'uploads/' . $filename;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!$msg) {
|
||
try {
|
||
$stmt = $pdo->prepare('INSERT INTO work_orders (product_id, content, code, attachment, creator_id, created_at, status) VALUES (?, ?, ?, ?, ?, NOW(), ?)');
|
||
$stmt->execute([$pid, $content, $codesStr ?: null, $attachment ?: null, getCurrentUserId(), '未处理']);
|
||
$_SESSION['flash_msg'] = '工单提交成功';
|
||
$_SESSION['flash_type'] = 'success';
|
||
header('Location: work_order_records.php');
|
||
exit;
|
||
} catch (Exception $e) {
|
||
$msg = '<div class="alert alert-danger">提交失败,请重试</div>';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$pageTitle = '发起工单';
|
||
require __DIR__ . '/includes/header.php';
|
||
?>
|
||
<div class="card">
|
||
<h2>发起工单</h2>
|
||
<?= $msg ?>
|
||
<form method="post" enctype="multipart/form-data">
|
||
<input type="hidden" name="csrf_token" value="<?= csrfToken() ?>">
|
||
<div class="form-group">
|
||
<label>工单内容 <span style="color:red">*</span></label>
|
||
<textarea name="content" class="form-control" required><?= h($_POST['content'] ?? '') ?></textarea>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>关联兑换码 <span style="color:red">*</span></label>
|
||
<div id="codesContainer">
|
||
<?php if (empty($oldCodes)): ?>
|
||
<div class="code-row" style="display:flex;gap:6px;margin-bottom:6px;">
|
||
<input type="text" name="codes[]" class="form-control" placeholder="输入兑换码" style="flex:1;">
|
||
<button type="button" class="btn btn-danger btn-sm" onclick="removeCode(this)" style="display:none;">删除</button>
|
||
</div>
|
||
<?php else: ?>
|
||
<?php foreach ($oldCodes as $v): ?>
|
||
<div class="code-row" style="display:flex;gap:6px;margin-bottom:6px;">
|
||
<input type="text" name="codes[]" class="form-control" value="<?= h($v) ?>" placeholder="输入兑换码" style="flex:1;">
|
||
<button type="button" class="btn btn-danger btn-sm" onclick="removeCode(this)">删除</button>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<button type="button" class="btn btn-info btn-sm" onclick="addCode()">+ 添加兑换码</button>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>附件</label>
|
||
<input type="file" name="attachment" class="form-control-file">
|
||
<div style="font-size:12px;color:#999;margin-top:4px;">支持 jpg/png/gif/pdf/doc/xls/zip/rar/txt,最大10MB</div>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary">提交工单</button>
|
||
<button type="button" class="btn btn-default" onclick="history.back()" style="margin-left:8px;">取消</button>
|
||
</form>
|
||
</div>
|
||
<script>
|
||
function addCode() {
|
||
var c = document.getElementById('codesContainer');
|
||
if (c.children.length >= 10) { alert('最多添加10个兑换码'); return; }
|
||
var row = document.createElement('div');
|
||
row.className = 'code-row';
|
||
row.style.cssText = 'display:flex;gap:6px;margin-bottom:6px;';
|
||
row.innerHTML = '<input type="text" name="codes[]" class="form-control" placeholder="输入兑换码" style="flex:1;">' +
|
||
'<button type="button" class="btn btn-danger btn-sm" onclick="removeCode(this)">删除</button>';
|
||
c.appendChild(row);
|
||
}
|
||
function removeCode(btn) {
|
||
var row = btn.parentNode;
|
||
row.parentNode.removeChild(row);
|
||
}
|
||
</script>
|
||
<?php require __DIR__ . '/includes/footer.php'; ?>
|