Files
jk8_admin/app/admin/controller/user/MoneyLog.php
2026-06-08 17:18:45 +08:00

268 lines
8.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\admin\controller\user;
use app\admin\model\MoneyLogHistory;
use Throwable;
use app\admin\model\User;
use app\admin\model\UserMoneyLog;
use app\common\controller\Backend;
use think\facade\Db;
class MoneyLog extends Backend
{
/**
* @var object
* @phpstan-var UserMoneyLog
*/
protected object $model;
protected array $withJoinTable = ['user', 'admin', 'bank'];
protected array $withTable = ['scoreLog'];
// 排除字段
protected string|array $preExcludeFields = ['create_time'];
protected string|array $quickSearchField = ['user.username', 'user.nickname'];
public function initialize(): void
{
parent::initialize();
$this->model = new UserMoneyLog();
}
/**
* 验证逻辑
*/
protected function validateModelData(array $data, string $scene = ''): void
{
if (!$this->modelValidate) return;
$validateClass = str_replace("\\model\\", "\\validate\\", get_class($this->model));
if (class_exists($validateClass)) {
$validate = new $validateClass();
if ($scene) $validate->scene($scene);
$validate->check($data);
}
}
/**
* 查看
* @throws Throwable
*/
public function index(): void
{
if ($this->request->param('select')) {
$this->select();
}
list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model
->withJoin($this->withJoinTable, $this->withJoinType)
->with($this->withTable)
->alias($alias)
->where($where)
->order($order)
->paginate($limit);
$this->success('', [
'list' => $res->items(),
'total' => $res->total(),
'remark' => get_route_remark(),
]);
}
/**
* 添加
* @param int $userId
* @throws Throwable
*/
public function add(int $userId = 0): void
{
$this->error(__('No rows were added'));
if ($this->request->isPost()) {
$data = $this->request->post();
if (!$data) {
$this->error(__('Parameter %s can not be empty', ['']));
}
$result = false;
$data = $this->excludeFields($data);
if ($data['type'] == 2) {
$data['money'] = -$data['money'];
}
$this->model->startTrans();
try {
$data['created_by'] = $this->auth->getInfo()['id'];
$result = $this->model->save($data);
$this->model->commit();
} catch (Throwable $e) {
$this->model->rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success(__('Added successfully'));
} else {
$this->error(__('No rows were added'));
}
}
$user = User::where('id', $userId)->find();
if (!$user) {
$this->error(__("The user can't find it"));
}
$this->success('', [
'user' => $user
]);
}
/**
* 编辑
* @throws Throwable
*/
public function edit(): void
{
$pk = $this->model->getPk();
$id = $this->request->param($pk);
$row = $this->model->find($id);
if (!$row) {
$this->error(__('Record not found'));
}
if ($this->request->isPost()) {
$data = $this->request->post();
if (!$data) {
$this->error(__('Parameter %s can not be empty', ['']));
}
$result = false;
$this->model->startTrans();
try {
$result = $row->save($data);
$this->model->commit();
} catch (Throwable $e) {
$this->model->rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success(__('Update successful'));
} else {
$this->error(__('No rows updated'));
}
return;
}
$this->success('', [
'row' => $row
]);
}
public function logHistory($id): void
{
$bindFields = [
'admin' => ['id','username'],
];
$history = MoneyLogHistory::withJoin($bindFields, 'left')
->where('money_log_id', $id)
->select();
if (!empty($history)) {
foreach ($history as &$item) {
$item['admin_name'] = $item['admin']['username'] ?? '';
unset($item['admin']);
}
unset($item);
}
$this->success('', $history);
}
public function annualReport()
{
$year = $this->request->param('year/d', date('Y'));
$timeExpression = "create_time";
$list = Db::table('ba_user_money_log')
->whereRaw("FROM_UNIXTIME({$timeExpression}, '%Y') = ?", [$year])
->fieldRaw("
FROM_UNIXTIME({$timeExpression}, '%c') as month,
-- 1. DEPOSIT (分转元保留2位小数)
ROUND(SUM(CASE WHEN type IN (1, 3) THEN money / 100 ELSE 0 END), 2) as deposit_amount,
-- 2. WITHDRAW (从变更记录看提现通常存正数,这里直接累加,分转元)
ROUND(SUM(CASE WHEN type IN (2, 4) THEN money / 100 ELSE 0 END), 2) as withdraw_amount,
-- 3. TRANSACTION (DEPOSIT)
COUNT(CASE WHEN type IN (1, 3) THEN id END) as deposit_count,
-- 4. TRANSACTION (WITHDRAW)
COUNT(CASE WHEN type IN (2, 4) THEN id END) as withdraw_count,
-- 5. ACTIVE PLAYER (每月去重活跃用户)
COUNT(DISTINCT user_id) as active_player,
-- 6. FIRST DEPOSIT (首充去重人数)
COUNT(DISTINCT CASE WHEN type = 1 AND label = 1 THEN user_id END) as first_deposit_count,
-- 7. UNCLAIM RECEIPT (未领单数)
COUNT(CASE WHEN type = 1 AND label = 2 THEN id END) as unclaim_count,
-- 8. UNCLAIM AMOUNT (未领金额)
ROUND(SUM(CASE WHEN type = 1 AND label = 2 THEN money / 100 ELSE 0 END), 2) as unclaim_amount
")
->group("month")
->select()
->toArray();
$monthsData = [];
foreach ($list as $row) {
$monthsData[intval($row['month'])] = $row;
}
$rowsSkeleton = [
'deposit' => ['name' => 'DEPOSIT', 'is_price' => true],
'withdraw' => ['name' => 'WITHDRAW', 'is_price' => true],
'trans_deposit' => ['name' => 'TRANSACTION (DEPOSIT)', 'is_price' => false],
'trans_withdraw' => ['name' => 'TRANSACTION (WITHDRAW)', 'is_price' => false],
'active_player' => ['name' => 'ACTIVE PLAYER', 'is_price' => false],
'first_deposit' => ['name' => 'FIRST DEPOSIT', 'is_price' => false],
'unclaim_receipt' => ['name' => 'UNCLAIM RECEIPT', 'is_price' => false],
'unclaim_amount' => ['name' => 'UNCLAIM AMOUNT', 'is_price' => true],
];
$finalReport = [];
foreach ($rowsSkeleton as $key => $meta) {
$rowData = [
'title' => $meta['name']
];
$yearTotal = 0;
for ($m = 1; $m <= 12; $m++) {
$monthValue = 0;
if (isset($monthsData[$m])) {
$monthValue = match ($key) {
'deposit' => (float)$monthsData[$m]['deposit_amount'],
'withdraw' => (float)$monthsData[$m]['withdraw_amount'],
'trans_deposit' => (int)$monthsData[$m]['deposit_count'],
'trans_withdraw' => (int)$monthsData[$m]['withdraw_count'],
'active_player' => (int)$monthsData[$m]['active_player'],
'first_deposit' => (int)$monthsData[$m]['first_deposit_count'],
'unclaim_receipt' => (int)$monthsData[$m]['unclaim_count'],
'unclaim_amount' => (float)$monthsData[$m]['unclaim_amount'],
};
}
$rowData['month_' . $m] = $meta['is_price'] ? number_format($monthValue, 2, '.', '') : $monthValue;
$yearTotal += $monthValue;
}
$rowData['year_total'] = $meta['is_price'] ? number_format($yearTotal, 2, '.', '') : $yearTotal;
$finalReport[] = $rowData;
}
$this->success('', [
'year' => $year,
'report_table' => $finalReport
]);
}
}