完成了基本调整调整
This commit is contained in:
@@ -44,6 +44,13 @@ class QytOil extends BaseService
|
||||
/** @var EnterpriseModel|array|null 当前企业 */
|
||||
protected $enterprise = null;
|
||||
|
||||
/**
|
||||
* @var bool 最近一次请求是否属于「网络层异常」(超时、连不上、响应不是 JSON)。
|
||||
* 这类失败不能说明上游没处理——对 7.16 这种没有幂等键的写接口,必须和
|
||||
* 「上游明确返回失败」区分开,前者转人工确认,后者才可以放心重试。
|
||||
*/
|
||||
protected $transportError = false;
|
||||
|
||||
protected function initialize()
|
||||
{
|
||||
$this->conf = QytConfig::get();
|
||||
@@ -204,6 +211,132 @@ class QytOil extends BaseService
|
||||
return null;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 7.17 获取支付凭证(须真实 RSA 验签)
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* 查询某司机在当前企业下的支付凭证,退款(7.16)要用其中的 quota_id
|
||||
* @return array data.list[]: quota_id / total_amount / available_amount / used_amount / status ...(金额单位:元)
|
||||
*/
|
||||
public function getVoucherList(string $mobile, string $idCard, int $page = 1, int $pageSize = 50): array
|
||||
{
|
||||
if (($err = $this->requireEnterprise()) !== null) {
|
||||
return $err;
|
||||
}
|
||||
return $this->post('/enterprise/api/quota/getVoucherList', [
|
||||
'passageway' => (string) $this->channelCode(),
|
||||
'business_license' => $this->businessLicense(),
|
||||
'mobile' => $mobile,
|
||||
'id_card' => $idCard,
|
||||
'page' => $page,
|
||||
'page_size' => $pageSize,
|
||||
]);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 7.16 司机额度调整(须真实 RSA 验签;⚠️ 无幂等键,重复调用会重复调额)
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* @param int|string $quotaId 7.17 返回的凭证主键
|
||||
* @param string $changeType 02 增加额度 / 03 减少额度
|
||||
* @param float $amount 调整金额(元)
|
||||
* @param string $reason 操作原因(≤200 字);退款时写入退款单号,确认结果时靠它在 7.13 流水里定位
|
||||
* @param string $waybillNo 运单号(可选)
|
||||
*/
|
||||
public function adjustVoucher($quotaId, string $changeType, float $amount, string $reason = '', string $waybillNo = ''): array
|
||||
{
|
||||
if (($err = $this->requireEnterprise()) !== null) {
|
||||
return $err;
|
||||
}
|
||||
$params = [
|
||||
'passageway' => (string) $this->channelCode(),
|
||||
'business_license' => $this->businessLicense(),
|
||||
'quota_id' => (int) $quotaId,
|
||||
'change_type' => $changeType,
|
||||
'amount' => round($amount, 2),
|
||||
'operation_reason' => mb_substr($reason, 0, 200),
|
||||
];
|
||||
$waybillNo !== '' && $params['waybill_no'] = $waybillNo;
|
||||
return $this->post('/enterprise/api/quota/adjustVoucher', $params);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 7.11 企业账户余额(仅平安银行通道支持,金额:分)
|
||||
// ================================================================
|
||||
|
||||
public function distributable(): array
|
||||
{
|
||||
if (($err = $this->requireEnterprise()) !== null) {
|
||||
return $err;
|
||||
}
|
||||
if ($this->channelCode() !== 2) {
|
||||
return $this->fail('企业账户余额查询仅支持平安银行通道,支付宝企业码没有独立资金账户');
|
||||
}
|
||||
return $this->post('/enterprise/api/zhyk/distributable', [
|
||||
'business_license' => $this->businessLicense(),
|
||||
'passageway' => (string) $this->channelCode(),
|
||||
]);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 7.12 司机钱包金额 / 7.13 司机钱包明细(金额:分)
|
||||
// ================================================================
|
||||
|
||||
public function driverBalanceQuery(string $mobile, string $idCard, int $page = 1, int $pageSize = 20): array
|
||||
{
|
||||
if (($err = $this->requireEnterprise()) !== null) {
|
||||
return $err;
|
||||
}
|
||||
return $this->post('/enterprise/api/zhyk/driverBalanceQuery', [
|
||||
'business_license' => $this->businessLicense(),
|
||||
'passageway' => (string) $this->channelCode(),
|
||||
'mobile' => $mobile,
|
||||
'id_card' => $idCard,
|
||||
'page' => $page,
|
||||
'page_size' => $pageSize,
|
||||
]);
|
||||
}
|
||||
|
||||
public function driverWalletQuery(string $mobile, string $idCard, int $page = 1, int $pageSize = 20): array
|
||||
{
|
||||
if (($err = $this->requireEnterprise()) !== null) {
|
||||
return $err;
|
||||
}
|
||||
return $this->post('/enterprise/api/zhyk/driverWalletQuery', [
|
||||
'business_license' => $this->businessLicense(),
|
||||
'passageway' => (string) $this->channelCode(),
|
||||
'mobile' => $mobile,
|
||||
'id_card' => $idCard,
|
||||
'page' => $page,
|
||||
'page_size' => $pageSize,
|
||||
]);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 7.14 企业发票下载(粒度:企业 + 通道 + 月份,可选按司机手机号收窄)
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* @param string $month YYYY-MM
|
||||
* @param string $mobile 司机手机号;传了只返回该司机相关发票与加油明细
|
||||
* @return array data: business_license / invoice[] 发票地址集 / order_list[] 加油明细(分)
|
||||
*/
|
||||
public function invoice(string $month, string $mobile = ''): array
|
||||
{
|
||||
if (($err = $this->requireEnterprise()) !== null) {
|
||||
return $err;
|
||||
}
|
||||
$params = [
|
||||
'business_license' => $this->businessLicense(),
|
||||
'passageway' => (string) $this->channelCode(),
|
||||
'month' => $month,
|
||||
];
|
||||
$mobile !== '' && $params['mobile'] = $mobile;
|
||||
return $this->post('/enterprise/api/zhyk/invoice', $params);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 7.2 企业申请创建
|
||||
// ================================================================
|
||||
@@ -295,12 +428,15 @@ class QytOil extends BaseService
|
||||
['企业' => $this->enterpriseName(), 'url' => $url, 'params' => self::maskDeep($bizParams)],
|
||||
JSON_UNESCAPED_UNICODE));
|
||||
|
||||
$this->transportError = false;
|
||||
$resp = $this->curlPost($url, json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
$this->saveLog("[响应] {$path} " . self::maskText($resp));
|
||||
|
||||
$json = json_decode($resp, true);
|
||||
if (!is_array($json)) {
|
||||
return ['code' => 'ERR', 'data' => [], 'message' => '响应解析失败', 'dup_batch' => false, 'raw' => ['body' => $resp]];
|
||||
// 拿不到可解析的响应,无法判断上游是否已处理
|
||||
return ['code' => 'ERR', 'data' => [], 'message' => '响应解析失败', 'dup_batch' => false,
|
||||
'transport_error' => true, 'raw' => ['body' => mb_substr((string) $resp, 0, 500)]];
|
||||
}
|
||||
|
||||
// 通用响应结构:{ status: ok|error, data, message, serialNo, sign }
|
||||
@@ -323,6 +459,8 @@ class QytOil extends BaseService
|
||||
'data' => $json['data'] ?? [],
|
||||
'message' => $message,
|
||||
'dup_batch' => $dupBatch,
|
||||
// cURL 失败时 curlPost 会伪造一个 {"status":"error"} 的 JSON,靠标记区分
|
||||
'transport_error' => $this->transportError,
|
||||
'raw' => $json,
|
||||
];
|
||||
}
|
||||
@@ -344,9 +482,15 @@ class QytOil extends BaseService
|
||||
if ($resp === false) {
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
$this->transportError = true;
|
||||
return json_encode(['status' => 'error', 'message' => 'cURL: ' . $err], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
// 网关层 5xx:请求可能已到达上游业务层,也按结果未知处理
|
||||
if ($httpCode >= 500) {
|
||||
$this->transportError = true;
|
||||
}
|
||||
return (string) $resp;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user