Files
oil/server-tp6/app/api/controller/OilCard.php
T
vipnub 45452c1799 1、合作商余额查询
2、分油账户司机可用额度
2026-10-08 23:12:33 +08:00

725 lines
33 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
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\controller\Controller;
use app\api\model\partners\Order as OrderModel;
use app\common\model\Partners as PartnersModel;
use app\common\crypto\RsaUtil;
use app\common\service\PartnersBalance;
use app\common\model\qyt\Enterprise as EnterpriseModel;
use app\common\service\QytDriver;
use app\common\service\QytOil;
use app\common\service\QytRefund;
use app\store\model\order\QrCode as QrCodeModel;
use cores\exception\BaseException;
use think\facade\Request;
use think\response\Json;
use think\facade\Db;
use think\db\exception\PDOException;
use app\common\service\QueueService;
use think\facade\Validate;
/**
* 用户分油
* Class OilCard
* @package app\api\controller\v1_0_0\oil
*/
class OilCard extends Controller
{
/**
* 用户分油
* @return Json
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function share()
{
// 获取所有 HTTP 请求头
$headers = Request::header();
// 获取 JSON 格式的请求体
$jsonData = Request::instance()->getContent();
$data = json_decode($jsonData, true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
// 请求头METHOD参数不正确
if($method != 'syb.oil.oilCard.share'){
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') {
// 业务处理
$data = $result['data'];
$orgNo = $data['orgNo'] ?? '';
$amount = $data['amount'] ?? '';
$mobile = $data['mobile'] ?? '';
$saleOrderNo = $data['saleOrderNo'] ?? '';
$oilCardType = $data['oilCardType'] ?? '';
// 企油通:司机姓名(下单平台必传,用于运单油费下发)
$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');
}
if(!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
return $this->oilRenderError('12','0013', '', '手机号格式不正确');
}
if($driverName === ''){
return $this->oilRenderError('12','0001', '', '缺少必填请求参数 name(司机姓名)');
}
// 解析本单使用的企油通企业:合作商绑定的企业 -> 默认企业
$enterprise = EnterpriseModel::resolve((int)$partners['qyt_enterprise_id']);
if(!$enterprise){
$this->saveLog('share 未匹配到可用的企油通企业,partners_id=' . $partners['partners_id']);
return $this->oilRenderError('99','9999', '', '系统未配置可用企业,请联系平台');
}
// 身份证号:两个支付通道都要求实名,必传且必须合法
if($idCard === ''){
return $this->oilRenderError('12','0001', '', '缺少必填请求参数 idCard(司机身份证号)');
}
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)');
}
$amount = round((float)$amount, 2);
// 销售平台订单号幂等:已存在则返回原订单结果(发放失败态除外)
$exist = OrderModel::detail(['partners_id' => $partners['partners_id'], 'partners_order_no' => $saleOrderNo]);
if($exist){
if((int)$exist['oil_status_zsy'] === 3){
return $this->oilRenderError('12','2023','','该销售订单号已提交且发放失败,请使用新订单号');
}
return $this->oilRenderSuccess([
'oilCardNo' => $exist['oilCardNo'],
'amount' => $exist['total_price'],
]);
}
// 额度管控:先原子扣减合作商余额(余额不足直接拒单,防并发超扣)
$balanceLogId = PartnersBalance::deduct((int)$partners['partners_id'], (float)$amount, $saleOrderNo, 0, (int)$this->storeId);
if ($balanceLogId === false) {
return $this->oilRenderError('01','2028', '', '合作商余额不足,请先充值');
}
$OrderModel = new OrderModel();
$oilCardNo = 'OIL' . self::createOrderNo();
try {
$created = $OrderModel->saveOrder([
'mobile' => $mobile,
'driver_name' => $driverName,
'id_card' => $idCard,
'plate_no' => $plateNo,
// 企业与通道随单固化:之后改绑定或切默认企业,在途单仍按下单时的企业发放
'qyt_enterprise_id' => $enterprise['enterprise_id'],
'passageway' => $enterprise['passageway'],
'oilCardType' => $oilCardType,
'oilCardNo' => $oilCardNo,
'partners_order_no' => $saleOrderNo,
'partners_id' => $partners['partners_id'],
'goods_price' => $amount,
'total_num' => 1,
'total_price' => $amount,
'total_pay_price' => $amount,
'store_id' => $this->storeId,
]);
} catch (\Throwable $e) {
// 建单失败 -> 回补刚扣减的余额
PartnersBalance::refund((int)$partners['partners_id'], (float)$amount, $saleOrderNo, 0, (int)$this->storeId);
// 并发下 (partners_id, partners_order_no) 唯一键冲突 -> 幂等返回已存在订单
if (strpos($e->getMessage(), 'Duplicate') !== false) {
$again = OrderModel::detail(['partners_id' => $partners['partners_id'], 'partners_order_no' => $saleOrderNo]);
if ($again) {
return $this->oilRenderSuccess(['oilCardNo' => $again['oilCardNo'], 'amount' => $again['total_price']]);
}
}
$this->saveLog('share saveOrder 异常:' . $e->getMessage());
return $this->oilRenderError('99', '9999');
}
if($created){
// 回填流水的订单ID(建单前尚不知 order_id)
PartnersBalance::bindOrder($balanceLogId, (int)$OrderModel->order_id);
// 司机档案(按身份证号归档并标记信息冲突;内部吞异常,不影响建单)
QytDriver::touch([
'order_id' => $OrderModel->order_id,
'id_card' => $idCard,
'driver_name' => $driverName,
'mobile' => $mobile,
'store_id' => $this->storeId,
]);
// 存入队列处理
$queueService = new QueueService();
$queueService->push('partners_queue', json_encode(['order_id'=>$OrderModel->order_id],320));
return $this->oilRenderSuccess([
'oilCardNo' => $oilCardNo,
'amount' => $amount,
]);
}
// 未建单成功 -> 回补余额
PartnersBalance::refund((int)$partners['partners_id'], (float)$amount, $saleOrderNo, 0, (int)$this->storeId);
return $this->oilRenderError('99', '9999');
} else {
// 错误处理
return $this->oilRenderError($result['code'], $result['errCode'], '', $result['errMessage'] ?? '');
}
}
/**
* 订单退款(整单全额)
* 企油通侧:7.17 查司机支付凭证 -> 7.16 按订单金额调低额度;成功后回补合作商余额,并推送油卡变动通知(optType=refund)
* @return Json
*/
public function refund()
{
$headers = Request::header();
$data = json_decode(Request::instance()->getContent(), true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
if($method != 'syb.oil.oilCard.refund'){
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');
}
$oilCardNo = trim((string)($body['oilCardNo'] ?? ''));
if($oilCardNo === ''){
return $this->oilRenderError('12','0001', '', '缺少必填请求参数 oilCardNo');
}
$reason = mb_substr(trim((string)($body['reason'] ?? '')), 0, 100);
// 只能退自己的订单
$order = OrderModel::detail(['oilCardNo' => $oilCardNo, 'partners_id' => $partners['partners_id']]);
if(!$order){
return $this->oilRenderError('01','2036');
}
$res = QytRefund::apply((int)$order['order_id'], 'api', (string)$appKey, $reason);
// 已退款(含重复调用的幂等返回)或结果确认中:都按受理成功返回,由 refundStatus 区分
// 确认中说明 7.16 已发出、上游可能已调额,不能告诉下游「失败」让它重试
if ($res['ok'] || $res['status'] === QytRefund::CONFIRM) {
return $this->oilRenderSuccess($res['data'], '00', $res['message']);
}
switch ($res['reason']) {
case QytRefund::REASON_NOT_FOUND:
return $this->oilRenderError('01', '2036', '', $res['message']);
case QytRefund::REASON_PROCESSING:
return $this->oilRenderError('01', '2032', '', $res['message']);
case QytRefund::REASON_STATE:
return $this->oilRenderError('01', '2048', '', $res['message']);
default:
return $this->oilRenderError('01', '2049', '', $res['message']);
}
}
/**
* 合作商余额查询
* 查的是我方账户余额(下单时按分油金额实时扣减,发放失败/退款原路回补)
* @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位)
$time = (int)(microtime(true) * 1000); // 返回形如 1716544103986
// 拼接一个 4 位随机数
$rand = mt_rand(1000, 9999);
return (string)($time . $rand); // 拼接成纯数字字符串
}
/**
* 付款二维码申请
* @return Json
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function getPayQrCode()
{
// 获取所有 HTTP 请求头
$headers = Request::header();
// 获取 JSON 格式的请求体
$jsonData = Request::instance()->getContent();
$data = json_decode($jsonData, true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
// 请求头METHOD参数不正确
if($method != 'syb.pay.qrCode.request'){
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') {
// 业务处理
$data = $result['data'];
$orgNo = $data['orgNo'] ?? '';
$oilCardNo = $data['oilCardNo'] ?? '';
$oilCardType = $data['oilCardType'] ?? '';
$mobile = $data['mobile'] ?? '';
// 请求参数orgNo与请求头appKey不存在对应关系
if($partners['orgNo'] != $orgNo){
return $this->oilRenderError('12','0014');
}
if(!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
return $this->oilRenderError('12','0013', '', '手机号格式不正确');
}
$order = OrderModel::detail(['oilCardNo' => $oilCardNo]);
if(!$order) {
return $this->oilRenderError('12','0013', '', '未找到对应订单');
}
// 企油通:生成司机免登加油 H5 地址(7.15)。出参 qrCode 结构不变,值由二维码链接改为 H5 URL。
// creditcode 取本单固化的企业,把登录固定到该企业;企业须已通过企油通审核
$orderEnterprise = EnterpriseModel::detail((int)$order['qyt_enterprise_id']);
if(!$orderEnterprise){
return $this->oilRenderError('12','0013', '', '本单绑定的企业不存在,无法生成加油链接');
}
$h5Url = QytOil::forEnterprise($orderEnterprise)->h5Url($order['mobile']);
if(!$h5Url){
return $this->oilRenderError('12','0013', '', '生成加油链接失败');
}
// 插入申请记录(留痕)
$QrCodeModel = new QrCodeModel();
$QrCodeModel->add([
'oilCardNo'=>$order['oilCardNo'],
'qrCode'=>$h5Url,
'amount'=>$order['goods_price'],
'order_id'=>$order['order_id'],
'user_id'=>0,
'store_id'=>$order['store_id'],
]);
return $this->oilRenderSuccess(['qrCode'=>$h5Url]);
} else {
// 错误处理
return $this->oilRenderError($result['code'], $result['errCode'], '', $result['errMessage'] ?? '');
}
}
/**
* 用户分油记录查询
* @return Json
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function shareList()
{
// 获取所有 HTTP 请求头
$headers = Request::header();
// 获取 JSON 格式的请求体
$jsonData = Request::instance()->getContent();
$data = json_decode($jsonData, true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
// 请求头METHOD参数不正确
if($method != 'syb.oil.oilCard.shareList'){
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') {
// 业务处理
$data = $result['data'];
$data['orgNo'] = $data['orgNo'] ?? '';
$data['mobile'] = $data['mobile'] ?? '';
$data['shareNo'] = $data['shareNo'] ?? '';
$data['saleOrderNo'] = $data['saleOrderNo'] ?? '';
$data['beginDate'] = $data['beginDate'] ?? '';
$data['endDate'] = $data['endDate'] ?? '';
$data['pageLimit'] = $data['pageLimit'] ?? 10;
$data['pageNum'] = $data['pageNum'] ?? 1;
$data['partners_id'] = $partners['partners_id'];
// 请求参数orgNo与请求头appKey不存在对应关系
if($partners['orgNo'] != $data['orgNo']){
return $this->oilRenderError('12','0014');
}
if(!preg_match('/^1[3-9]\d{9}$/', $data['mobile'])) {
return $this->oilRenderError('12','0013', '', '手机号格式不正确');
}
$rule = [
'beginDate' => 'require|dateFormat:Ymd',
'endDate' => 'require|dateFormat:Ymd',
'pageLimit' => 'number|between:1,30',
'pageNum' => 'number|min:1'
];
$message = [
'beginDate.require' => 'beginDate 不能为空',
'beginDate.dateFormat' => 'beginDate 格式错误,正确格式为 yyyyMMdd',
'endDate.require' => 'endDate 不能为空',
'endDate.dateFormat' => 'endDate 格式错误,正确格式为 yyyyMMdd',
'pageLimit.number' => 'pageLimit 必须是数字',
'pageLimit.between' => 'pageLimit 必须在 1-30 之间',
'pageNum.number' => 'pageNum 必须是数字',
'pageNum.min' => 'pageNum 必须大于等于 1',
];
$validate = Validate::rule($rule)->message($message);
if (!$validate->check($data)) {
return $this->oilRenderError('12','0013', '', $validate->getError());
}
// 检查日期间隔
$begin = date_create_from_format('Ymd', $data['beginDate']);
$end = date_create_from_format('Ymd', $data['endDate']);
if ($begin > $end) {
return $this->oilRenderError('12','0013', '', 'endDate 必须大于或等于 beginDate');
}
if ($begin->diff($end)->days > 365) {
return $this->oilRenderError('12','0013', '', '日期间隔不能超过 365 天');
}
$model = new OrderModel;
$list = $model->getList($data);
// 组装返回格式
$result = [
'totalNum' => $list->total(),
'totalPage' => $list->lastPage(),
'pageNum' => $list->currentPage(),
'pageLimit' => $list->listRows(),
'orderList' => array_map(function ($item) {
return [
'shareNo' => $item['shareNo'],
'mobile' => $item['mobile'],
'oilCardNo' => $item['oilCardNo'],
'num' => $item['total_num'],
'amount' => $item['total_price'],
'createTime' => $item['create_time'],
];
}, $list->items())
];
return $this->oilRenderSuccess($result);
} else {
// 错误处理
return $this->oilRenderError($result['code'], $result['errCode'], '', $result['errMessage'] ?? '');
}
}
/**
* 订单状态查询
* @return Json
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function orderStatus()
{
// 获取所有 HTTP 请求头
$headers = Request::header();
// 获取 JSON 格式的请求体
$jsonData = Request::instance()->getContent();
$data = json_decode($jsonData, true);
$appKey = $headers['appkey'] ?? '';
$requestId = $headers['requestid'] ?? '';
$method = $headers['method'] ?? '';
// 请求头METHOD参数不正确
if($method != 'syb.oil.oilCard.orderStatus'){
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') {
// 业务处理
$data = $result['data'];
$data['orgNo'] = $data['orgNo'] ?? '';
$data['oilCardNo'] = $data['oilCardNo'] ?? '';
// $data['saleOrderNo'] = $data['saleOrderNo'] ?? '';
// 请求参数orgNo与请求头appKey不存在对应关系
if($partners['orgNo'] != $data['orgNo']){
return $this->oilRenderError('12','0014');
}
$rule = [
'oilCardNo' => 'require',
];
$message = [
'oilCardNo.require' => 'oilCardNo 不能为空',
];
$validate = Validate::rule($rule)->message($message);
if (!$validate->check($data)) {
return $this->oilRenderError('12','0013', '', $validate->getError());
}
// 只能查自己的订单(原先不校验归属,一个合作商可以查到别家的单)
$detail = OrderModel::detail(['oilCardNo' => $data['oilCardNo'], 'partners_id' => $partners['partners_id']]);
if(!$detail){
return $this->oilRenderError('01','2036');
}
// 组装返回格式
$result = [
'mobile' => $detail['mobile'],
'oilCardNo' => $detail['oilCardNo'],
'shareNo' => $detail['shareNo'],
'saleOrderNo' => $detail['partners_order_no'],
'total_price' => $detail['total_price'],
'oil_status_zsy' => $detail['oil_status_zsy'],
'oil_status' => $detail['oil_status'],
'oil_time' => $detail['oil_time'],
'use_status' => $detail['use_status'],
'use_time' => $detail['use_time'],
// 一单可多次加油:已加油金额 / 加油次数 / 剩余可加油(即可退)金额
'used_amount' => number_format((float)$detail['used_amount'], 2, '.', ''),
'used_num' => (int)$detail['used_num'],
'remain_amount' => number_format(max(0, (float)$detail['total_price'] - (float)$detail['used_amount']
- ((int)$detail['refund_status'] === 2 ? (float)$detail['refund_amount'] : 0)), 2, '.', ''),
// 退款:0未退款 1退款中 2已退款 3退款失败 4退款结果确认中
'refund_status' => (int)$detail['refund_status'],
'refund_amount' => number_format((float)$detail['refund_amount'], 2, '.', ''),
'refund_time' => $detail['refund_time'] ? date('Y-m-d H:i:s', (int)$detail['refund_time']) : '',
];
return $this->oilRenderSuccess($result);
} else {
// 错误处理
return $this->oilRenderError($result['code'], $result['errCode'], '', $result['errMessage'] ?? '');
}
}
}