Files
webman-buildadmin-mall/app/admin/controller/mall/PlayxOrder.php

251 lines
7.5 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\mall;
use Throwable;
use app\common\controller\Backend;
use app\common\model\MallPlayxOrder;
use app\common\model\MallPlayxUserAsset;
use support\think\Db;
use support\Response;
use Webman\Http\Request;
/**
* PlayX 统一订单(后台列表)
*/
class PlayxOrder extends Backend
{
/**
* @var object|null
* @phpstan-var \app\common\model\MallPlayxOrder|null
*/
protected ?object $model = null;
protected array|string $preExcludeFields = ['id', 'create_time', 'update_time'];
protected array $withJoinTable = ['mallItem'];
protected string|array $quickSearchField = ['user_id', 'external_transaction_id', 'playx_transaction_id'];
protected string|array $indexField = [
'id',
'user_id',
'type',
'status',
'mall_item_id',
'points_cost',
'amount',
'multiplier',
'external_transaction_id',
'playx_transaction_id',
'grant_status',
'fail_reason',
'reject_reason',
'shipping_company',
'shipping_no',
'receiver_name',
'receiver_phone',
'receiver_address',
'create_time',
'update_time',
];
public function initialize(): void
{
parent::initialize();
$this->model = new \app\common\model\MallPlayxOrder();
}
/**
* 查看
* @throws Throwable
*/
public function index(Request $request): Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
if ($request->get('select') || $request->post('select')) {
return $this->select($request);
}
list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model
->with(['mallItem' => function ($query) {
$query->field('id,title');
}])
->visible(['mallItem' => ['title']])
->alias($alias)
->where($where)
->order($order)
->paginate($limit);
return $this->success('', [
'list' => $res->items(),
'total' => $res->total(),
'remark' => get_route_remark(),
]);
}
/**
* PHYSICAL 发货:更新 shipping_company/shipping_no并将状态置为 SHIPPED
*/
public function ship(Request $request): Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
if ($request->method() !== 'POST') {
return $this->error(__('Parameter error'));
}
$data = $request->post();
$id = intval($data['id'] ?? 0);
$shippingCompany = strval($data['shipping_company'] ?? '');
$shippingNo = strval($data['shipping_no'] ?? '');
if ($id <= 0 || $shippingCompany === '' || $shippingNo === '') {
return $this->error(__('Missing required fields'));
}
$order = MallPlayxOrder::where('id', $id)->find();
if (!$order) {
return $this->error(__('Record not found'));
}
if ($order->type !== MallPlayxOrder::TYPE_PHYSICAL) {
return $this->error(__('Order type not PHYSICAL'));
}
if ($order->status !== MallPlayxOrder::STATUS_PENDING) {
return $this->error(__('Order status must be PENDING'));
}
Db::startTrans();
try {
$order->shipping_company = $shippingCompany;
$order->shipping_no = $shippingNo;
$order->status = MallPlayxOrder::STATUS_SHIPPED;
$order->save();
Db::commit();
} catch (Throwable $e) {
Db::rollback();
return $this->error($e->getMessage());
}
return $this->success(__('Shipped successfully'));
}
/**
* PHYSICAL 驳回:更新状态为 REJECTED并退回积分到 available_points
*/
public function reject(Request $request): Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
if ($request->method() !== 'POST') {
return $this->error(__('Parameter error'));
}
$data = $request->post();
$id = intval($data['id'] ?? 0);
$rejectReason = strval($data['reject_reason'] ?? '');
if ($id <= 0 || $rejectReason === '') {
return $this->error(__('Missing required fields'));
}
$order = MallPlayxOrder::where('id', $id)->find();
if (!$order) {
return $this->error(__('Record not found'));
}
if ($order->type !== MallPlayxOrder::TYPE_PHYSICAL) {
return $this->error(__('Order type not PHYSICAL'));
}
if ($order->status !== MallPlayxOrder::STATUS_PENDING) {
return $this->error(__('Order status must be PENDING'));
}
Db::startTrans();
try {
$asset = MallPlayxUserAsset::where('user_id', strval($order->user_id ?? ''))->find();
if (!$asset) {
$asset = MallPlayxUserAsset::create([
'user_id' => strval($order->user_id ?? ''),
'username' => strval($order->user_id ?? ''),
'locked_points' => 0,
'available_points' => 0,
'today_limit' => 0,
'today_claimed' => 0,
'today_limit_date' => null,
'create_time' => time(),
'update_time' => time(),
]);
}
$refund = intval($order->points_cost ?? 0);
if ($refund > 0) {
$asset->available_points += $refund;
$asset->save();
}
$order->status = MallPlayxOrder::STATUS_REJECTED;
$order->reject_reason = $rejectReason;
$order->grant_status = MallPlayxOrder::GRANT_FAILED_FINAL;
$order->save();
Db::commit();
} catch (Throwable $e) {
Db::rollback();
return $this->error($e->getMessage());
}
return $this->success(__('Rejected successfully'));
}
/**
* 手动重试(仅红利/提现,且必须 FAILED_RETRYABLE
*/
public function retry(Request $request): Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
if ($request->method() !== 'POST') {
return $this->error(__('Parameter error'));
}
$id = intval($request->post('id', 0));
if ($id <= 0) {
return $this->error(__('Missing required fields'));
}
$order = MallPlayxOrder::where('id', $id)->find();
if (!$order) {
return $this->error(__('Record not found'));
}
if (!in_array($order->type, [MallPlayxOrder::TYPE_BONUS, MallPlayxOrder::TYPE_WITHDRAW], true)) {
return $this->error(__('Only BONUS/WITHDRAW can retry'));
}
if ($order->grant_status !== MallPlayxOrder::GRANT_FAILED_RETRYABLE) {
return $this->error(__('Only FAILED_RETRYABLE can retry'));
}
if (intval($order->retry_count) >= 3) {
return $this->error(__('Retry count exceeded'));
}
$order->grant_status = MallPlayxOrder::GRANT_NOT_SENT;
$order->save();
return $this->success(__('Retry queued'));
}
}