- 新增地址选择插件,支持地图位置选择并返回地址和经纬度 - 新增微信订阅消息发送功能,支持审核结果、提现通知等场景 - 新增订单支付状态查询、提现收款人姓名保存等接口 - 新增服务区域管理,支持按省市区划分并同步到信息发布 - 新增资金流水和营收报表导出功能 - 新增可用优惠券查询、订单退款拆分处理等功能 - 优化后台角标显示、首页数据统计、UI配置下发等 - 修复订单支付并发问题、地区管理逻辑等
140 行
4.7 KiB
PHP
140 行
4.7 KiB
PHP
<?php
|
||
|
||
namespace app\admin\controller\fc;
|
||
|
||
use app\common\controller\Backend;
|
||
use think\Db;
|
||
|
||
/**
|
||
* 同城-提现
|
||
*
|
||
* @icon fa fa-circle-o
|
||
*/
|
||
class Withdraw extends Backend
|
||
{
|
||
|
||
/**
|
||
* FcWithdraw模型对象
|
||
* @var \app\admin\model\FcWithdraw
|
||
*/
|
||
protected $model = null;
|
||
|
||
public function _initialize()
|
||
{
|
||
parent::_initialize();
|
||
$this->model = new \app\admin\model\FcWithdraw;
|
||
$this->view->assign("statusList", $this->model->getStatusList());
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
|
||
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
|
||
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
|
||
*/
|
||
|
||
/**
|
||
* 提现打款/驳回
|
||
*/
|
||
public function pay()
|
||
{
|
||
$ids = $this->request->post('ids');
|
||
$op = $this->request->post('op');
|
||
$reason = $this->request->post('reason', '');
|
||
if (!in_array($op, ['pay', 'reject'])) {
|
||
$this->error('操作类型错误');
|
||
}
|
||
if ($op === 'reject' && trim((string)$reason) === '') {
|
||
$this->error('驳回需填写原因');
|
||
}
|
||
$ids = is_array($ids) ? $ids : explode(',', (string)$ids);
|
||
$ids = array_filter($ids);
|
||
if (!$ids) {
|
||
$this->error('请选择要操作的提现记录');
|
||
}
|
||
$withdraws = Db::name('fc_withdraw')->where('id', 'in', $ids)->select();
|
||
if (!$withdraws) {
|
||
$this->error('提现记录不存在');
|
||
}
|
||
|
||
$done = 0;
|
||
$pending = 0;
|
||
$failed = 0;
|
||
$errors = [];
|
||
|
||
if ($op === 'reject') {
|
||
try {
|
||
Db::transaction(function () use ($withdraws, $reason, &$done) {
|
||
foreach ($withdraws as $withdraw) {
|
||
// 行锁 + 状态校验:已处理的记录不会被二次驳回
|
||
$locked = Db::name('fc_withdraw')->where('id', $withdraw['id'])->lock(true)->find();
|
||
if (!$locked || (string)$locked['status'] !== 'auditing') {
|
||
continue;
|
||
}
|
||
$done++;
|
||
|
||
Db::name('fc_withdraw')->where('id', $locked['id'])->update([
|
||
'status' => 'rejected',
|
||
'reason' => $reason,
|
||
'updatetime' => time(),
|
||
]);
|
||
Db::name('fc_message')->insert([
|
||
'user_id' => $locked['user_id'],
|
||
'type' => 'system',
|
||
'title' => '提现驳回',
|
||
'content' => '您的提现申请「' . $locked['withdraw_no'] . '」被驳回' . ($reason ? ',原因:' . $reason : ''),
|
||
'isread' => 0,
|
||
'createtime' => time(),
|
||
]);
|
||
}
|
||
});
|
||
} catch (\Throwable $e) {
|
||
$this->error('操作失败:' . $e->getMessage());
|
||
}
|
||
|
||
if ($done === 0) {
|
||
$this->error('选中的提现记录均已处理,请刷新后重试');
|
||
}
|
||
$this->success('驳回成功(' . $done . ' 条)');
|
||
}
|
||
|
||
// 通过 → 逐笔发起微信商家转账(外部调用不能放在事务里)
|
||
foreach ($withdraws as $withdraw) {
|
||
if ((string)$withdraw['status'] !== 'auditing') {
|
||
continue;
|
||
}
|
||
try {
|
||
$res = \app\common\library\WxTransfer::approve((int)$withdraw['id']);
|
||
$done++;
|
||
if ($res['withdrawState'] === 'paying') {
|
||
$pending++;
|
||
} elseif ($res['withdrawState'] === 'failed') {
|
||
$failed++;
|
||
}
|
||
} catch (\Throwable $e) {
|
||
$errors[] = $withdraw['withdraw_no'] . ':' . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
if ($done === 0) {
|
||
$this->error('转账失败:' . implode(';', $errors));
|
||
}
|
||
|
||
$msg = '已发起转账 ' . $done . ' 笔';
|
||
if ($pending > 0) {
|
||
$msg .= '(其中 ' . $pending . ' 笔等待用户在微信确认收款)';
|
||
}
|
||
if ($failed > 0) {
|
||
$msg .= ',' . $failed . ' 笔转账失败';
|
||
}
|
||
if ($errors) {
|
||
$msg .= ';失败 ' . count($errors) . ' 笔:' . implode(';', $errors);
|
||
}
|
||
$this->success($msg);
|
||
}
|
||
|
||
|
||
|
||
}
|