325 lines
12 KiB
PHP
325 lines
12 KiB
PHP
<?php
|
||
|
||
namespace app\admin\controller;
|
||
|
||
use app\common\controller\Backend;
|
||
use app\common\facade\Token;
|
||
use app\common\library\DatabaseRoute;
|
||
use app\utils\WuYouPayUtils;
|
||
use ba\Random;
|
||
use think\facade\Db;
|
||
use think\Collection;
|
||
|
||
class CashOutAudit extends Backend
|
||
{
|
||
|
||
protected array $noNeedPermission = ['page', 'alipaytransfersummaryquery'];
|
||
|
||
// 提现列表
|
||
public function page()
|
||
{
|
||
$params = $this->request->get();
|
||
$cashOut = [];
|
||
if (!empty($params)) {
|
||
$cashOut = array_intersect_key($params, array_flip([
|
||
'user_id', 'user_name', 'zhifubao_name', 'zhifubao',
|
||
'bank_name', 'user_type', 'state', 'start_time', 'end_time'
|
||
]));
|
||
}
|
||
$cashOutList = DatabaseRoute::paginateAllDb('cash_out', function ($query) use($cashOut) {
|
||
if (!empty($cashOut['user_id'])) {
|
||
$query->where('user_id', $cashOut['user_id']);
|
||
}
|
||
// 用户名模糊查询(对应Java的userName匹配zhifubaoName)
|
||
if (!empty($cashOut['user_name'])) {
|
||
$query->whereLike('zhifubao_name', "%{$cashOut['user_name']}%");
|
||
}
|
||
// 支付宝姓名模糊查询
|
||
if (!empty($cashOut['zhifubao_name'])) {
|
||
$query->whereLike('zhifubao_name', "%{$cashOut['zhifubao_name']}%");
|
||
}
|
||
// 支付宝账号模糊查询
|
||
if (!empty($cashOut['zhifubao'])) {
|
||
$query->whereLike('zhifubao', "%{$cashOut['zhifubao']}%");
|
||
}
|
||
// 银行名称模糊查询
|
||
if (!empty($cashOut['bank_name'])) {
|
||
$query->whereLike('bank_name', "%{$cashOut['bank_name']}%");
|
||
}
|
||
// 用户类型条件
|
||
if (isset($cashOut['user_type']) && $cashOut['user_type'] !== '') {
|
||
$query->where('user_type', $cashOut['user_type']);
|
||
}
|
||
// 状态条件
|
||
if (isset($cashOut['state']) && $cashOut['state'] !== '') {
|
||
$query->where('state', $cashOut['state']);
|
||
}
|
||
// 时间范围条件
|
||
$startTime = isset($cashOut['start_time']) ? $cashOut['start_time'] : '';
|
||
$endTime = isset($cashOut['end_time']) ? $cashOut['end_time'] : '';
|
||
if ($startTime && $endTime) {
|
||
$query->whereBetween('create_at', $startTime, $endTime);
|
||
} elseif ($startTime) {
|
||
$query->where('create_at', '>=', $startTime);
|
||
} elseif ($endTime) {
|
||
$query->where('create_at', '<=', $endTime);
|
||
}
|
||
return $query;
|
||
}, $params['page'], $params['limit'], 'create_at');
|
||
|
||
// 补充关联数据
|
||
if (!empty($cashOutList['list'])) {
|
||
// 提取所有用户ID
|
||
$userIdList = Collection::make($cashOutList['list'])->column('user_id');
|
||
$userIdList = array_unique(array_filter($userIdList)); // 去重并过滤空值
|
||
if($userIdList) {
|
||
$countInfoList_n = [];
|
||
foreach ($userIdList as $k => $user_id) {
|
||
$db_name = Db::connect(DatabaseRoute::getConnection('tb_user', ['user_id' => $user_id]));
|
||
$userNameMap[] = $db_name->name('tb_user')->where(['user_id' => $user_id])->field('user_id, user_name')
|
||
->select()
|
||
->column('user_name', 'user_id');
|
||
|
||
$countInfoList[] = $db_name
|
||
->query("SELECT user_id as userId,
|
||
ROUND(SUM(CASE WHEN state = 1 THEN money ELSE 0 END), 2) AS total,
|
||
COUNT(CASE WHEN state = 1 THEN 1 END) AS count,
|
||
ROUND(SUM(CASE WHEN state = 3 THEN money ELSE 0 END), 2) AS verifyTotal,
|
||
COUNT(CASE WHEN state = 3 THEN 1 END) AS verifyCount
|
||
FROM cash_out
|
||
WHERE user_id=" . $user_id . "
|
||
GROUP BY user_id")[0];
|
||
}
|
||
$countInfoMap = [];
|
||
foreach ($countInfoList as $item) {
|
||
|
||
$countInfoMap[$item['userId']] = $item;
|
||
}
|
||
|
||
// 补充字段到结果集
|
||
foreach ($cashOutList['list'] as &$item) {
|
||
// 补充用户名
|
||
$item['user_name'] = $userNameMap[$item['user_id']] ?? '';
|
||
|
||
// 补充统计信息
|
||
if (isset($countInfoMap[$item['user_id']])) {
|
||
$countInfo = $countInfoMap[$item['user_id']];
|
||
$item['total'] = $countInfo['total'];
|
||
$item['count'] = $countInfo['count'];
|
||
$item['verify_count'] = $countInfo['verifyCount'];
|
||
$item['verify_total'] = $countInfo['verifyTotal'];
|
||
} else {
|
||
$item['total'] = 0;
|
||
$item['count'] = 0;
|
||
$item['verify_count'] = 0;
|
||
$item['verify_total'] = 0;
|
||
}
|
||
}
|
||
unset($item); // 解除引用
|
||
}
|
||
}
|
||
$this->n_success(['page' => $cashOutList]);
|
||
}
|
||
|
||
//
|
||
public function alipaytransfersummaryquery()
|
||
{
|
||
$get = $this->request->get();
|
||
// 校验支付宝账户名
|
||
if (empty($get['alipayAccountName'])) {
|
||
$this->error('支付宝账号不能为空');
|
||
}
|
||
$alipayAccountName = $get['alipayAccountName'];
|
||
// 初始化返回数据结构
|
||
$data = [
|
||
'alipayAccountName' => $alipayAccountName,
|
||
'sum' => 0.00,
|
||
'count' => 0,
|
||
'list' => []
|
||
];
|
||
|
||
$cashOutList = DatabaseRoute::getAllDbData('cash_out', function ($query) use($alipayAccountName) {
|
||
return $query->where('state', 1)
|
||
->where('zhifubao_name', $alipayAccountName);
|
||
})->select()->toArray();
|
||
// 无记录则直接返回
|
||
if (empty($cashOutList)) {
|
||
$this->n_success($data);
|
||
}
|
||
// 按用户ID分组(替代Java的Collectors.groupingBy)
|
||
$groupedByUserId = [];
|
||
foreach ($cashOutList as $record) {
|
||
$userId = $record['user_id'];
|
||
$groupedByUserId[$userId][] = $record;
|
||
}
|
||
|
||
|
||
// 处理每个用户的汇总数据
|
||
foreach ($groupedByUserId as $userId => $userRecords) {
|
||
// 计算该用户的提现总金额
|
||
$subSum = array_sum(array_column($userRecords, 'money'));
|
||
|
||
// 初始化用户记录
|
||
$record = [
|
||
'userId' => $userId,
|
||
'userName' => '未知',
|
||
'inviterCode' => '',
|
||
'phone' => '',
|
||
'zhiFuBaoName' => implode(' / ', array_unique(array_column($userRecords, 'zhifubao_name'))),
|
||
'zhiFuBao' => implode(' / ', array_unique(array_column($userRecords, 'zhifubao'))),
|
||
'subTotal' => $subSum,
|
||
'subCount' => count($userRecords)
|
||
];
|
||
|
||
// 查询用户信息
|
||
$userEntity = Db::name('user')
|
||
->where('user_id', $userId)
|
||
->find();
|
||
|
||
// 补充用户信息
|
||
if ($userEntity) {
|
||
$record['userId'] = $userEntity['user_id'];
|
||
$record['userName'] = $userEntity['user_name'];
|
||
$record['inviterCode'] = $userEntity['inviter_code'];
|
||
$record['phone'] = $userEntity['phone'];
|
||
}
|
||
|
||
// 添加到结果列表
|
||
$data['list'][] = $record;
|
||
|
||
// 更新总统计
|
||
$data['sum'] += $subSum;
|
||
$data['count'] += count($userRecords);
|
||
}
|
||
$this->n_success($data);
|
||
}
|
||
|
||
|
||
public function audit()
|
||
{
|
||
$cashOut = $this->request->post();
|
||
// 1. 验证审核状态
|
||
$isAgree = $cashOut['isAgree'] ?? null;
|
||
|
||
if ($isAgree === null) {
|
||
$this->error("请选择同意或者拒绝!");
|
||
}
|
||
// 拒绝时必须填写原因
|
||
if ($isAgree == 0 && trim($cashOut['refund'] ?? '') === '') {
|
||
$this->error("请输入拒绝原因!");
|
||
}
|
||
|
||
$db = Db::connect(DatabaseRoute::getConnection('cash_out', ['user_id' => $cashOut['userId']], true));
|
||
|
||
// 2. 查询提现申请实体
|
||
$entity = $db->name('cash_out')
|
||
->where('user_id', $cashOut['userId'])
|
||
->where('id', $cashOut['id'])
|
||
->find();
|
||
if (!$entity) {
|
||
$this->error("提现申请不存在!");
|
||
}
|
||
|
||
// 3. 验证申请状态(必须为待审核状态:state=3)
|
||
if ($entity['state'] != 3) {
|
||
$this->error("提现申请状态无效,请刷新后重试!");
|
||
}
|
||
|
||
// 4. 根据审核结果更新状态
|
||
if ($isAgree == 1) {
|
||
$entity['state'] = 0; // 同意
|
||
} else {
|
||
$entity['state'] = 2; // 拒绝
|
||
$entity['refund'] = $cashOut['refund']; // 拒绝原因
|
||
}
|
||
|
||
// 5. 验证用户/代理信息是否存在
|
||
$isUser = true;
|
||
if ($entity['user_type'] == 2) {
|
||
$isUser = false; // 代理用户
|
||
}
|
||
|
||
if ($isUser) {
|
||
// 普通用户
|
||
$user = $db->name('tb_user')->where('user_id', $entity['user_id'])->find();
|
||
if (!$user) {
|
||
$this->error("提现用户信息不存在!");
|
||
}
|
||
} else {
|
||
// 代理用户
|
||
$sysUser = $db->name('sys_user')->where('user_id', $entity['user_id'])->find();
|
||
if (!$sysUser) {
|
||
$this->error("提现代理信息不存在!");
|
||
}
|
||
}
|
||
|
||
// 6. 拒绝时退回金额并返回
|
||
if ($isAgree == 0) {
|
||
\app\admin\model\Cash::backCashAmount($entity, $db);
|
||
$this->success();
|
||
}
|
||
|
||
// 7. 同意时处理提现逻辑
|
||
$isHistoryData = false;
|
||
// 历史数据判断(无银行名称的普通用户)
|
||
if ($isUser && trim($entity['bank_name'] ?? '') === '') {
|
||
$isHistoryData = true;
|
||
}
|
||
|
||
// 更新状态为处理中
|
||
$entity['state'] = 4;
|
||
$db->name('cash_out')
|
||
->where('user_id', $entity['user_id'])
|
||
->where('id', $entity['id'])
|
||
->update([
|
||
'state' => 4
|
||
]);
|
||
|
||
// 生成订单号(为空时)
|
||
if (trim($entity['order_number'] ?? '') === '') {
|
||
$entity['order_number'] = Random::generateRandomPrefixedId(19);
|
||
$db->name('cash_out')
|
||
->where('id', $entity['id'])
|
||
->update(['order_number' => $entity['order_number']]);
|
||
}
|
||
|
||
// 8. 调用支付接口执行提现
|
||
$baseResp = WuYouPayUtils::extractOrder(
|
||
$isHistoryData,
|
||
$entity['order_number'],
|
||
$entity['user_id'],
|
||
$entity['money'],
|
||
$isUser,
|
||
$entity['zhifubao'] ?? '',
|
||
$entity['zhifubao_name'] ?? '',
|
||
$entity['bank_name'] ?? '',
|
||
empty($entity['province']) ? '1' : $entity['province'],
|
||
empty($entity['city']) ? '1' : $entity['city'],
|
||
empty($entity['bank_branch']) ? '1' : $entity['bank_branch']
|
||
);
|
||
|
||
// 9. 根据支付结果更新状态
|
||
$updateData = [];
|
||
if (isset($baseResp['status']) && ($baseResp['status'] == 2 || $baseResp['status'] == 10000)) {
|
||
$entity['state'] = 1; // 提现成功
|
||
} elseif (!empty($baseResp['error_msg'])) {
|
||
$entity['state'] = 2; // 提现失败
|
||
if (strpos($baseResp['error_msg'], '收款人账户号出款属性不匹配') !== false) {
|
||
$entity['refund'] = "提现失败,请检查收款账号与收款人姓名后重试。";
|
||
} else {
|
||
$entity['refund'] = $baseResp['error_msg'];
|
||
}
|
||
\app\admin\model\Cash::backCashAmount($entity, $db); // 失败时退回金额
|
||
} elseif (!empty($baseResp['msg'])) {
|
||
$entity['state'] = 2; // 提现失败
|
||
$entity['refund'] = "提现失败,请检查收款账号与收款人姓名后重试。";
|
||
\app\admin\model\Cash::backCashAmount($entity, $db); // 失败时退回金额
|
||
}
|
||
// 调用用户ID更新方法(原updateByUserId)
|
||
\app\admin\model\Cash::updateByUserId($entity, $db);
|
||
}
|
||
|
||
|
||
|
||
|
||
} |