213 lines
5.2 KiB
PHP
213 lines
5.2 KiB
PHP
<?php
|
||
/**
|
||
* VR票务插件 - C端票夹API控制器
|
||
*
|
||
* 路由机制(PluginsService::PluginsApiCall):
|
||
* URL: ?s=api/plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=list
|
||
* → pluginsname=vr_ticket, pluginscontrol=ticket, pluginsaction=list
|
||
* → class = \app\plugins\vr_ticket\api\Ticket (ucfirst('ticket') = 'Ticket')
|
||
* → method = ucfirst('list') = 'list'
|
||
* → app/plugins/vr_ticket/api/Ticket.php::list() ✓
|
||
*
|
||
* @package vr_ticket\api
|
||
*/
|
||
|
||
namespace app\plugins\vr_ticket\api;
|
||
|
||
use app\plugins\vr_ticket\service\WalletService;
|
||
|
||
/**
|
||
* C端票夹 API
|
||
*/
|
||
class Ticket
|
||
{
|
||
/**
|
||
* 获取当前登录用户ID
|
||
*
|
||
* ShopXO 使用 X-Token 或 Authorization 头
|
||
* @return int|null
|
||
*/
|
||
private static function getUserId()
|
||
{
|
||
// 方式1:从 header 获取(推荐)
|
||
$token = request()->header('X-Token') ?: request()->header('Authorization', '');
|
||
if (!empty($token)) {
|
||
$token = str_replace('Bearer ', '', $token);
|
||
$user = self::parseToken($token);
|
||
if (!empty($user['id'])) {
|
||
return intval($user['id']);
|
||
}
|
||
}
|
||
|
||
// 方式2:从 session 获取
|
||
$userId = session('user_id');
|
||
if (!empty($userId)) {
|
||
return intval($userId);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 解析 Token(JWT格式)
|
||
*
|
||
* @param string $token
|
||
* @return array
|
||
*/
|
||
private static function parseToken(string $token): array
|
||
{
|
||
$parts = explode('.', $token);
|
||
if (count($parts) !== 3) {
|
||
return [];
|
||
}
|
||
|
||
$payload = base64_decode(strtr($parts[1], '-_', '+/'));
|
||
if ($payload === false) {
|
||
return [];
|
||
}
|
||
|
||
$data = json_decode($payload, true);
|
||
return is_array($data) ? $data : [];
|
||
}
|
||
|
||
/**
|
||
* 返回未登录错误
|
||
*
|
||
* @return Json
|
||
*/
|
||
private static function unauthorized(string $msg = '请先登录'): Json
|
||
{
|
||
return json([
|
||
'code' => 401,
|
||
'msg' => $msg,
|
||
'data' => [],
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 返回成功响应
|
||
*
|
||
* @param mixed $data
|
||
* @param string $msg
|
||
* @return Json
|
||
*/
|
||
private static function success($data = [], string $msg = 'success'): Json
|
||
{
|
||
return json([
|
||
'code' => 0,
|
||
'msg' => $msg,
|
||
'data' => $data,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 返回错误响应
|
||
*
|
||
* @param string $msg
|
||
* @param int $code
|
||
* @return Json
|
||
*/
|
||
private static function error(string $msg = '请求失败', int $code = -1): Json
|
||
{
|
||
return json([
|
||
'code' => $code,
|
||
'msg' => $msg,
|
||
'data' => [],
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 获取用户票列表
|
||
*
|
||
* GET ?s=api/plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=list
|
||
*
|
||
* @return Json
|
||
*/
|
||
public function list(): Json
|
||
{
|
||
$userId = self::getUserId();
|
||
if (empty($userId)) {
|
||
return self::unauthorized();
|
||
}
|
||
|
||
try {
|
||
$tickets = WalletService::getUserTickets($userId);
|
||
|
||
return self::success([
|
||
'tickets' => $tickets,
|
||
'count' => count($tickets),
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return self::error('获取票列表失败: ' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取票详情(含 QR payload)
|
||
*
|
||
* GET ?s=api/plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=detail&id=X
|
||
*
|
||
* @return Json
|
||
*/
|
||
public function detail(): Json
|
||
{
|
||
$userId = self::getUserId();
|
||
if (empty($userId)) {
|
||
return self::unauthorized();
|
||
}
|
||
|
||
$ticketId = input('id', 0, 'intval');
|
||
if ($ticketId <= 0) {
|
||
return self::error('参数错误:票ID无效');
|
||
}
|
||
|
||
try {
|
||
$ticket = WalletService::getTicketDetail($ticketId, $userId);
|
||
|
||
if (empty($ticket)) {
|
||
return self::error('票不存在或无权访问', -404);
|
||
}
|
||
|
||
return self::success([
|
||
'ticket' => $ticket,
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return self::error('获取票详情失败: ' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 强制刷新 QR payload
|
||
*
|
||
* GET ?s=api/plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=refreshQr&id=X
|
||
*
|
||
* @return Json
|
||
*/
|
||
public function refreshQr(): Json
|
||
{
|
||
$userId = self::getUserId();
|
||
if (empty($userId)) {
|
||
return self::unauthorized();
|
||
}
|
||
|
||
$ticketId = input('id', 0, 'intval');
|
||
if ($ticketId <= 0) {
|
||
return self::error('参数错误:票ID无效');
|
||
}
|
||
|
||
try {
|
||
$ticket = WalletService::refreshQrPayload($ticketId, $userId);
|
||
|
||
if (empty($ticket)) {
|
||
return self::error('票不存在或无权访问', -404);
|
||
}
|
||
|
||
return self::success([
|
||
'ticket' => $ticket,
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return self::error('刷新QR失败: ' . $e->getMessage());
|
||
}
|
||
}
|
||
}
|