Files
pk10/App/Controllers/Admin/EmployeeController.php
T

155 lines
6.9 KiB
PHP

<?php
namespace App\Controllers\Admin;
use App\Core\AdminBaseController;
use Db\Database;
class EmployeeController extends AdminBaseController {
private $db;
public function __construct(Database $db) { $this->db = $db; }
public function index() {
$this->checkLogin(); $this->checkAdmin();
$employees = $this->db->select('employees', '*', ['ORDER' => ['id' => 'DESC']]);
$this->render('Admin/employees.php', compact('employees'));
}
public function update() {
$this->checkLogin(); $this->checkAdmin();
$data = json_decode(file_get_contents('php://input'), true);
$id = (int)($data['id'] ?? 0);
$fields = [
'emp_code' => trim($data['emp_code'] ?? ''),
'username' => trim($data['username'] ?? ''),
'real_name' => trim($data['real_name'] ?? ''),
'shift' => $data['shift'] ?? 'all',
'permissions' => json_encode($data['permissions'] ?? ['deposit','withdraw']),
'status' => (int)($data['status'] ?? 1),
];
if ($id > 0) {
if (!empty($data['password'])) $fields['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$this->db->update('employees', $fields, ['id' => $id]);
} else {
if (empty($data['password'])) { $this->json(['status'=>'error','message'=>'Password required']); return; }
$fields['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$this->db->insert('employees', $fields);
}
$this->json(['status' => 'success']);
}
public function delete($id) {
$this->checkLogin(); $this->checkAdmin();
$this->db->delete('employees', ['id' => (int)$id]);
$this->json(['status' => 'success']);
}
// 员工登录(独立入口)
public function loginPage() {
include ROOT_PATH . 'App/Views/Admin/employee_login.php';
}
public function loginSubmit() {
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
$db = new Database();
$emp = $db->get('employees', '*', ['username' => trim($data['username'] ?? '')]);
if (!$emp || !password_verify($data['password'] ?? '', $emp['password'])) {
echo json_encode(['success' => false, 'message' => 'Invalid credentials']); return;
}
if (!$emp['status']) {
echo json_encode(['success' => false, 'message' => 'Account disabled']); return;
}
// 班次检查
$hour = (int)date('H');
if ($emp['shift'] === 'day' && ($hour < 8 || $hour >= 20)) {
echo json_encode(['success' => false, 'message' => 'Not your shift']); return;
}
if ($emp['shift'] === 'night' && ($hour >= 8 && $hour < 20)) {
echo json_encode(['success' => false, 'message' => 'Not your shift']); return;
}
if (session_status() === PHP_SESSION_NONE) session_start();
$_SESSION['emp_id'] = $emp['id'];
$_SESSION['emp_code'] = $emp['emp_code'];
$_SESSION['emp_permissions'] = json_decode($emp['permissions'], true) ?: [];
$_SESSION['emp_last_activity'] = time();
$db->update('employees', ['last_login' => date('Y-m-d H:i:s')], ['id' => $emp['id']]);
echo json_encode(['success' => true, 'redirect' => '/employee/dashboard']);
}
// 员工操作面板(仅上下分)
public function dashboard() {
$this->checkEmployee();
$users = $this->db->select('users', ['id','username','balance','is_virtual'], [
'is_virtual' => 0, 'ORDER' => ['username' => 'ASC']
]);
$logs = $this->db->select('employee_logs', '*', [
'emp_id' => $_SESSION['emp_id'],
'ORDER' => ['id' => 'DESC'], 'LIMIT' => 50
]);
include ROOT_PATH . 'App/Views/Admin/employee_dashboard.php';
}
public function adjustBalance() {
$this->checkEmployee();
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
$userId = (int)($data['user_id'] ?? 0);
$action = $data['action'] ?? ''; // deposit / withdraw
$amount = abs(floatval($data['amount'] ?? 0));
$remark = trim($data['remark'] ?? '');
$perms = $_SESSION['emp_permissions'] ?? [];
if (!in_array($action, ['deposit','withdraw']) || !in_array($action, $perms)) {
echo json_encode(['success' => false, 'message' => 'No permission']); return;
}
if ($amount <= 0 || $userId <= 0) {
echo json_encode(['success' => false, 'message' => 'Invalid input']); return;
}
try {
$this->db->medoo->pdo->beginTransaction();
$stmt = $this->db->medoo->pdo->prepare("SELECT balance FROM users WHERE id = :id FOR UPDATE");
$stmt->execute([':id' => $userId]);
$user = $stmt->fetch(\PDO::FETCH_ASSOC);
if (!$user) { $this->db->medoo->pdo->rollBack(); echo json_encode(['success'=>false,'message'=>'User not found']); return; }
$old = (float)$user['balance'];
$new = $action === 'deposit' ? $old + $amount : $old - $amount;
if ($new < 0) { $this->db->medoo->pdo->rollBack(); echo json_encode(['success'=>false,'message'=>'Insufficient balance']); return; }
$this->db->update('users', ['balance' => $new], ['id' => $userId]);
$this->db->insert('transactions', [
'user_id' => $userId, 'type' => 'manual_' . $action,
'amount' => $action === 'deposit' ? $amount : -$amount,
'balance_before' => $old, 'balance_after' => $new,
'description' => "Employee {$_SESSION['emp_code']}: $remark",
'operator_id' => $_SESSION['emp_id'], 'operator_type' => 'employee',
'created_at' => date('Y-m-d H:i:s'),
]);
$this->db->insert('employee_logs', [
'emp_id' => $_SESSION['emp_id'], 'action' => $action,
'target_user_id' => $userId, 'amount' => $amount,
'remark' => $remark, 'created_at' => date('Y-m-d H:i:s'),
]);
$this->db->medoo->pdo->commit();
echo json_encode(['success' => true, 'new_balance' => $new]);
} catch (\Throwable $e) {
if ($this->db->medoo->pdo->inTransaction()) $this->db->medoo->pdo->rollBack();
echo json_encode(['success' => false, 'message' => 'Error']);
}
}
private function checkEmployee() {
if (session_status() === PHP_SESSION_NONE) session_start();
if (empty($_SESSION['emp_id'])) { header('Location: /employee/login'); exit; }
if (time() - ($_SESSION['emp_last_activity'] ?? 0) > 7200) {
unset($_SESSION['emp_id']); header('Location: /employee/login'); exit;
}
$_SESSION['emp_last_activity'] = time();
}
private function json($data) { header('Content-Type: application/json'); echo json_encode($data); }
}