1、合作商余额查询

2、分油账户司机可用额度
This commit is contained in:
2026-10-08 23:12:33 +08:00
parent ae94c1dc00
commit 45452c1799
32 changed files with 2024 additions and 6 deletions
+139
View File
@@ -90,6 +90,8 @@ class OilCard extends Controller
$driverName = trim((string)($data['name'] ?? ''));
// 企油通:司机身份证号。两个支付通道都要求实名,必传
$idCard = strtoupper(trim((string)($data['idCard'] ?? '')));
// 车牌号:下单平台必传,仅本地留存与后台展示,不上送企油通
$plateNo = strtoupper(trim((string)($data['plateNo'] ?? '')));
// 请求参数orgNo与请求头appKey不存在对应关系
if($partners['orgNo'] != $orgNo){
return $this->oilRenderError('12','0014');
@@ -113,6 +115,14 @@ class OilCard extends Controller
if(!preg_match('/^\d{17}[\dX]$/', $idCard)){
return $this->oilRenderError('12','0013', '', 'idCard 身份证号格式不正确(18位)');
}
// 车牌号:必传,兼容普通车牌(7位)与新能源车牌(8位)
if($plateNo === ''){
return $this->oilRenderError('12','0001', '', '缺少必填请求参数 plateNo(车牌号)');
}
// 省份简称 + 城市字母(不含 I/O,避免与 1/0 混淆) + 5~7 位序号(含新能源 8 位车牌)
if(!preg_match('/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,6}$/u', $plateNo)){
return $this->oilRenderError('12','0013', '', 'plateNo 车牌号格式不正确');
}
// 金额:由下单平台直接传入(单位:元,最多两位小数)
if($amount === '' || !preg_match('/^\d{1,8}(\.\d{1,2})?$/', (string)$amount) || (float)$amount <= 0){
return $this->oilRenderError('12','0013', '', 'amount 金额格式不正确(单位:元,最多两位小数且大于0)');
@@ -141,6 +151,7 @@ class OilCard extends Controller
'mobile' => $mobile,
'driver_name' => $driverName,
'id_card' => $idCard,
'plate_no' => $plateNo,
// 企业与通道随单固化:之后改绑定或切默认企业,在途单仍按下单时的企业发放
'qyt_enterprise_id' => $enterprise['enterprise_id'],
'passageway' => $enterprise['passageway'],
@@ -266,6 +277,134 @@ class OilCard extends Controller
}
}
/**
* 合作商余额查询
* 查的是我方账户余额(下单时按分油金额实时扣减,发放失败/退款原路回补)
* @return Json
*/
public function balance()
{
$headers = Request::header();
$data = json_decode(Request::instance()->getContent(), true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
if($method != 'syb.oil.account.balance'){
return $this->oilRenderError('12', '0005');
}
try {
Db::name('request_log')->insert([
'request_id' => $requestId,
'app_key' => $appKey,
'create_time' => time()
]);
} catch (\think\Exception $e) {
if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
return $this->oilRenderError('12', '0012');
}
return $this->oilRenderError('99', '9999');
}
$partners = PartnersModel::detail(['appKey' => $appKey]);
if(!$partners){
return $this->oilRenderError('02','0004');
}
$crypto = new RsaUtil($partners);
$result = $crypto->processResponse(['header'=>$headers,'encryptData'=>$data]);
if ($result['code'] !== '00') {
return $this->oilRenderError($result['code'], $result['errCode'], '', $result['errMessage'] ?? '');
}
if($partners['orgNo'] != ($result['data']['orgNo'] ?? '')){
return $this->oilRenderError('12','0014');
}
$balance = PartnersBalance::balance((int)$partners['partners_id']);
return $this->oilRenderSuccess([
'orgNo' => $partners['orgNo'],
'balance' => number_format($balance, 2, '.', ''),
'queryTime' => date('Y-m-d H:i:s'),
]);
}
/**
* 分油账户司机可用额度
* 查的是司机在上游(企油通)的油费钱包:按本合作商绑定的企业维度统计
* @return Json
*/
public function driverQuota()
{
$headers = Request::header();
$data = json_decode(Request::instance()->getContent(), true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
if($method != 'syb.oil.driver.quota'){
return $this->oilRenderError('12', '0005');
}
try {
Db::name('request_log')->insert([
'request_id' => $requestId,
'app_key' => $appKey,
'create_time' => time()
]);
} catch (\think\Exception $e) {
if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
return $this->oilRenderError('12', '0012');
}
return $this->oilRenderError('99', '9999');
}
$partners = PartnersModel::detail(['appKey' => $appKey]);
if(!$partners){
return $this->oilRenderError('02','0004');
}
$crypto = new RsaUtil($partners);
$result = $crypto->processResponse(['header'=>$headers,'encryptData'=>$data]);
if ($result['code'] !== '00') {
return $this->oilRenderError($result['code'], $result['errCode'], '', $result['errMessage'] ?? '');
}
$body = $result['data'];
if($partners['orgNo'] != ($body['orgNo'] ?? '')){
return $this->oilRenderError('12','0014');
}
$mobile = trim((string)($body['mobile'] ?? ''));
$idCard = strtoupper(trim((string)($body['idCard'] ?? '')));
if(!preg_match('/^1[3-9]\d{9}$/', $mobile)){
return $this->oilRenderError('12','0013', '', '手机号格式不正确');
}
// 上游按「手机号 + 身份证号」定位司机,两个都必传
if($idCard === ''){
return $this->oilRenderError('12','0001', '', '缺少必填请求参数 idCard(司机身份证号)');
}
if(!preg_match('/^\d{17}[\dX]$/', $idCard)){
return $this->oilRenderError('12','0013', '', 'idCard 身份证号格式不正确(18位)');
}
$enterprise = EnterpriseModel::resolve((int)$partners['qyt_enterprise_id']);
if(!$enterprise){
return $this->oilRenderError('01','2052', '', '系统未配置可用企业,请联系平台');
}
$res = QytOil::forEnterprise($enterprise)->driverBalanceQuery($mobile, $idCard, 1, 20);
if($res['code'] !== '00'){
return $this->oilRenderError('01','2052', '', $res['message'] ?: '司机额度查询失败');
}
// 上游金额单位是「分」,统一转成「元」返回
$upstream = (array)$res['data'];
$list = [];
foreach ((array)($upstream['list'] ?? []) as $row) {
$list[] = [
'enterpriseName' => (string)($row['enterprise_name'] ?? ''),
'totalAmount' => QytOil::fenToYuan((int)($row['total_amount'] ?? 0)),
'availableAmount' => QytOil::fenToYuan((int)($row['available_amount'] ?? 0)),
];
}
return $this->oilRenderSuccess([
'mobile' => $mobile,
'totalGrantAmount' => QytOil::fenToYuan((int)($upstream['totalGrantAmount'] ?? 0)),
'availableAmount' => QytOil::fenToYuan((int)($upstream['availableBalance'] ?? 0)),
'list' => $list,
]);
}
public static function createOrderNo(): string
{
// 获取当前时间戳到毫秒(13位)