79 lines
6.8 KiB
PHP
79 lines
6.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace app\miniapi\service\VisaApplication;
|
|
|
|
use api\Httpcurl;
|
|
use think\facade\Log;
|
|
|
|
final class VisaApplicationService
|
|
{
|
|
private const ACTIONS = ['directForm', 'directSubmit', 'directStatus', 'options', 'start', 'application', 'saveDraft', 'submit', 'dataSource', 'agree', 'orderDetail', 'orderPayment'];
|
|
private const DATA_SOURCE_PARAMS = ['model', 'source_code', 'page', 'size', 'state_id', 'hotel_state', 'provinceCode', 'country', 'entry_mode', 'province', 'accommodation_province', 'accommodation_municipality', 'city', 'id', 'air_transport_type', 'state', 'japan_province', 'travel_country', 'hotel_city', 'districtCode', 'nationality_iso2', 'next_destination'];
|
|
|
|
public function directForm(int $userId, array $data, string $source): array { return $this->request('directForm',$userId,array_merge($data,['order_source'=>$source])); }
|
|
public function directSubmit(int $userId, array $data, string $source): array { return $this->request('directSubmit',$userId,array_merge($data,['order_source'=>$source])); }
|
|
public function directStatus(int $userId, array $data, string $source): array { return $this->request('directStatus',$userId,array_merge($data,['order_source'=>$source])); }
|
|
public function options(int $userId, string $orderSource): array { return $this->request('options', $userId, ['order_source' => $orderSource]); }
|
|
public function start(int $userId, array $data, string $orderSource): array { return $this->request('start', $userId, array_merge($data, ['order_source' => $orderSource])); }
|
|
public function application(int $userId, string $publicId, string $submissionToken = ''): array { return $this->request('application', $userId, ['public_id' => $publicId] + ($submissionToken !== '' ? ['submission_token' => $submissionToken] : [])); }
|
|
public function saveDraft(int $userId, array $data): array { return $this->request('saveDraft', $userId, $data); }
|
|
public function submit(int $userId, array $data): array { return self::decorateSubmitForCheck($this->request('submit', $userId, $data)); }
|
|
public function orderDetail(int $userId, array $data): array { return $this->request('orderDetail', $userId, $data); }
|
|
public function orderPayment(int $userId, array $data): array { return $this->request('orderPayment', $userId, $data); }
|
|
public function agree(string $docCode): array
|
|
{
|
|
if (!preg_match('/^[A-Za-z0-9._-]{1,64}$/', $docCode)) return ['code' => 0, 'msg' => '协议参数错误', 'data' => []];
|
|
return $this->request('agree', 0, ['doc_code' => $docCode]);
|
|
}
|
|
public static function decorateSubmitForCheck(array $result): array { if ((int)($result['code'] ?? 0) === 1 && !empty($result['data']['requires_payment']) && !empty($result['data']['order_sn'])) $result['data']['pay_url'] = 'https://www.qlevisa.com/index/pay/h5pay.html?order_sn=' . rawurlencode((string)$result['data']['order_sn']); return $result; }
|
|
public static function nativePaymentForCheck(array $data): array
|
|
{
|
|
$cents = (int)($data['total_price'] ?? 0);
|
|
if (empty($data['requires_payment']) || $cents <= 0 || !is_array($data['target_orders'] ?? null) || count($data['target_orders']) !== 1) return [];
|
|
$target = null;
|
|
foreach ($data['target_orders'] as $item) {
|
|
if (is_array($item) && (int)($item['applicant_index'] ?? -1) === 0) { $target = $item; break; }
|
|
}
|
|
if ($target === null) $target = $data['target_orders'][0] ?? null;
|
|
$table = trim((string)($target['target_table'] ?? ''));
|
|
$orderSn = trim((string)($target['target_order_sn'] ?? ''));
|
|
if (!preg_match('/^[A-Za-z0-9_]+$/', $table) || !preg_match('/^[A-Za-z0-9_-]{1,100}$/', $orderSn)) return [];
|
|
return ['target_table' => $table, 'order_sn' => $orderSn, 'money' => intdiv($cents, 100) . '.' . str_pad((string)($cents % 100), 2, '0', STR_PAD_LEFT)];
|
|
}
|
|
public function payload(int $userId, array $params = []): array { $source = (string)($params['order_source'] ?? ''); unset($params['order_source']); return ['user_token' => authcode((string)json_encode(['purpose' => 'visa_api', 'user_id' => $userId, 'order_source' => $source], JSON_UNESCAPED_UNICODE), 'ENCODE', MINIAPI_TOKEN_KEY, 120)] + $params; }
|
|
public function endpoint(string $userUrl, string $action): string
|
|
{
|
|
if (!in_array($action, self::ACTIONS, true)) return '';
|
|
$endpoint = preg_replace('#/users/[^/?]+(?:\?.*)?$#i', '/visa_service/' . $action, rtrim(trim($userUrl), '/'));
|
|
return is_string($endpoint) && $endpoint !== rtrim(trim($userUrl), '/') ? $endpoint : '';
|
|
}
|
|
public function dataSource(string $type, array $filters): array
|
|
{
|
|
try { $query = self::dataSourceQueryForCheck($type, $filters); } catch (\RuntimeException $e) { return ['code' => 0, 'msg' => '数据源参数错误', 'data' => []]; }
|
|
$url = $this->endpoint((string)config('app.user_url'), 'dataSource'); $response = $url ? Httpcurl::request($url, 'post', http_build_query($query)) : false;
|
|
if (!is_array($response) || !isset($response[0]) || !empty($response[3])) { Log::warning('miniapi visa data source request failed'); return ['code' => 0, 'msg' => '数据源暂不可用', 'data' => []]; }
|
|
$result = json_decode($response[0], true); return is_array($result) ? $result : ['code' => 0, 'msg' => '数据源暂不可用', 'data' => []];
|
|
}
|
|
public static function dataSourceQueryForCheck(string $type, array $filters): array
|
|
{
|
|
if (!preg_match('/^[A-Za-z0-9_.-]+$/', $type)) throw new \RuntimeException('invalid');
|
|
$query = ['type' => $type];
|
|
foreach (self::DATA_SOURCE_PARAMS as $key) {
|
|
$value = $filters[$key] ?? null;
|
|
if (!is_scalar($value) || $value === '') continue;
|
|
$value = (string)$value;
|
|
if (strlen($value) > 128 || ($key === 'model' && !preg_match('/^[A-Za-z0-9_.-]+$/', $value)) || ($key === 'source_code' && !preg_match('/^[A-Za-z0-9._-]{1,20}$/', $value)) || (in_array($key, ['page', 'size'], true) && !preg_match('/^[1-9][0-9]*$/', $value))) continue;
|
|
$query[$key] = $value;
|
|
}
|
|
return $query;
|
|
}
|
|
private function request(string $action, int $userId, array $params): array
|
|
{
|
|
$url = $this->endpoint((string)config('app.user_url'), $action); if ($url === '') return ['code' => 0, 'msg' => '签证服务接口地址异常', 'data' => []];
|
|
$response = Httpcurl::request($url, 'post', http_build_query($this->payload($userId, $params)));
|
|
if (!is_array($response) || !isset($response[0]) || !empty($response[3])) { Log::warning('miniapi visa application request failed'); return ['code' => 0, 'msg' => '服务异常,请稍后重试', 'data' => []]; }
|
|
$result = json_decode($response[0], true); return is_array($result) ? $result : ['code' => 0, 'msg' => '服务异常,请稍后重试', 'data' => []];
|
|
}
|
|
}
|