196 lines
8.6 KiB
PHP
196 lines
8.6 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | 后台 · 企油通司机管理
|
|
// +----------------------------------------------------------------------
|
|
// | list() 司机档案 + 从订单实时汇总的累计发放 / 已退款 / 订单数
|
|
// | detail() 档案、涉及企业、最近订单(发放失败原因里能看到二要素核验结果)
|
|
// | upstream() 实时查企油通:balance 7.12 钱包余额 / wallet 7.13 钱包流水 / voucher 7.17 支付凭证
|
|
// |
|
|
// | 身份证号全程只在后端使用,返回前端一律打码。
|
|
// +----------------------------------------------------------------------
|
|
declare (strict_types=1);
|
|
|
|
namespace app\store\controller\qyt;
|
|
|
|
use app\common\model\qyt\Enterprise as EnterpriseModel;
|
|
use app\common\service\QytOil;
|
|
use app\common\service\QytRefund;
|
|
use app\store\controller\Controller;
|
|
use think\facade\Db;
|
|
use think\response\Json;
|
|
|
|
class Driver extends Controller
|
|
{
|
|
public function list(): Json
|
|
{
|
|
$param = $this->request->param();
|
|
$keyword = trim((string) ($param['keyword'] ?? ''));
|
|
|
|
$query = Db::name('qyt_driver')->where('store_id', $this->storeId);
|
|
if ($keyword !== '') {
|
|
if (preg_match('/^\d{17}[\dXx]$/', $keyword)) {
|
|
$query->where('id_card', strtoupper($keyword));
|
|
} elseif (preg_match('/^1\d{10}$/', $keyword)) {
|
|
$query->where('mobile', $keyword);
|
|
} else {
|
|
$query->whereLike('name', '%' . $keyword . '%');
|
|
}
|
|
}
|
|
if (isset($param['conflict']) && $param['conflict'] !== '' && (int) $param['conflict'] >= 0) {
|
|
$query->where('conflict', (int) $param['conflict']);
|
|
}
|
|
|
|
$list = $query->order('last_order_time', 'desc')->paginate(15)->toArray();
|
|
$stats = $this->stats(array_column($list['data'], 'id_card'));
|
|
foreach ($list['data'] as &$row) {
|
|
$row = $this->formatDriver($row, $stats[$row['id_card']] ?? []);
|
|
}
|
|
return $this->renderSuccess(compact('list'));
|
|
}
|
|
|
|
public function detail(int $driverId): Json
|
|
{
|
|
$driver = $this->findDriver($driverId);
|
|
if (!$driver) {
|
|
return $this->renderError('司机不存在');
|
|
}
|
|
$stats = $this->stats([$driver['id_card']]);
|
|
|
|
// 涉及过的企业(上游查询要按企业查)
|
|
$entIds = Db::name('partners_order')->where('store_id', $this->storeId)
|
|
->where('id_card', $driver['id_card'])->where('qyt_enterprise_id', '>', 0)
|
|
->group('qyt_enterprise_id')->column('qyt_enterprise_id');
|
|
$enterprises = $entIds
|
|
? EnterpriseModel::whereIn('enterprise_id', $entIds)
|
|
->field('enterprise_id,company_name,passageway,status')->select()->toArray()
|
|
: [];
|
|
|
|
$orders = Db::name('partners_order')->where('store_id', $this->storeId)->where('id_card', $driver['id_card'])
|
|
->field('order_id,oilCardNo,partners_order_no,total_price,driver_name,mobile,oil_status_zsy,oil_text,use_status,refund_status,refund_text,qyt_enterprise_id,create_time')
|
|
->order('order_id', 'desc')->limit(20)->select()->toArray();
|
|
foreach ($orders as &$o) {
|
|
$o['mobile'] = QytOil::maskMobile((string) $o['mobile']);
|
|
$o['refund_status_text'] = QytRefund::STATUS_TEXT[(int) $o['refund_status']] ?? '';
|
|
$o['create_time_text'] = date('Y-m-d H:i:s', (int) $o['create_time']);
|
|
}
|
|
|
|
return $this->renderSuccess([
|
|
'detail' => $this->formatDriver($driver, $stats[$driver['id_card']] ?? []),
|
|
'enterprises' => $enterprises,
|
|
'orders' => $orders,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 实时查企油通
|
|
* type: balance 7.12 / wallet 7.13 / voucher 7.17
|
|
*/
|
|
public function upstream(int $driverId, int $enterpriseId, string $type = 'balance', int $page = 1): Json
|
|
{
|
|
$driver = $this->findDriver($driverId);
|
|
if (!$driver) {
|
|
return $this->renderError('司机不存在');
|
|
}
|
|
$enterprise = EnterpriseModel::detail($enterpriseId);
|
|
if (!$enterprise) {
|
|
return $this->renderError('企业不存在');
|
|
}
|
|
$qyt = QytOil::forEnterprise($enterprise);
|
|
$mobile = (string) $driver['mobile'];
|
|
$idCard = (string) $driver['id_card'];
|
|
$page = max(1, $page);
|
|
|
|
switch ($type) {
|
|
case 'balance':
|
|
$res = $qyt->driverBalanceQuery($mobile, $idCard, $page, 20);
|
|
break;
|
|
case 'wallet':
|
|
$res = $qyt->driverWalletQuery($mobile, $idCard, $page, 20);
|
|
break;
|
|
case 'voucher':
|
|
$res = $qyt->getVoucherList($mobile, $idCard, $page, 20);
|
|
break;
|
|
default:
|
|
return $this->renderError('查询类型不合法');
|
|
}
|
|
if ($res['code'] !== '00') {
|
|
return $this->renderError('企油通返回:' . ($res['message'] ?: '查询失败'));
|
|
}
|
|
|
|
$data = (array) $res['data'];
|
|
// 7.12 / 7.13 金额是「分」,统一转成元再给前端;7.17 本来就是元
|
|
if ($type === 'balance' || $type === 'wallet') {
|
|
foreach (['totalGrantAmount', 'availableBalance'] as $k) {
|
|
isset($data[$k]) && $data[$k . 'Yuan'] = QytOil::fenToYuan($data[$k]);
|
|
}
|
|
foreach (['list', 'transactionDetails'] as $listKey) {
|
|
foreach ((array) ($data[$listKey] ?? []) as $i => $item) {
|
|
foreach (['total_amount', 'available_amount', 'amount'] as $k) {
|
|
if (isset($item[$k]) && is_numeric($item[$k])) {
|
|
$data[$listKey][$i][$k . '_yuan'] = QytOil::fenToYuan((int) $item[$k]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $this->renderSuccess(['type' => $type, 'data' => QytOil::maskDeep($data)]);
|
|
}
|
|
|
|
// ================================================================
|
|
|
|
private function findDriver(int $driverId): ?array
|
|
{
|
|
$row = Db::name('qyt_driver')->where('store_id', $this->storeId)->where('driver_id', $driverId)->find();
|
|
return $row ?: null;
|
|
}
|
|
|
|
/**
|
|
* 从订单实时汇总,按身份证号分组
|
|
*/
|
|
private function stats(array $idCards): array
|
|
{
|
|
if (!$idCards) {
|
|
return [];
|
|
}
|
|
$rows = Db::name('partners_order')
|
|
->where('store_id', $this->storeId)
|
|
->whereIn('id_card', $idCards)
|
|
->fieldRaw('id_card,'
|
|
. ' COUNT(*) AS order_num,'
|
|
. ' SUM(IF(oil_status_zsy = 2, total_price, 0)) AS grant_amount,'
|
|
. ' SUM(IF(refund_status = 2, refund_amount, 0)) AS refund_amount,'
|
|
. ' SUM(IF(use_status = 1, 1, 0)) AS used_num,'
|
|
. ' SUM(used_amount) AS used_amount,'
|
|
. ' SUM(IF(oil_status_zsy = 3, 1, 0)) AS fail_num,'
|
|
. ' SUM(IF(oil_status_zsy = 1, 1, 0)) AS pending_num')
|
|
->group('id_card')
|
|
->select()->toArray();
|
|
return array_column($rows, null, 'id_card');
|
|
}
|
|
|
|
private function formatDriver(array $row, array $stat): array
|
|
{
|
|
$grant = round((float) ($stat['grant_amount'] ?? 0), 2);
|
|
$refund = round((float) ($stat['refund_amount'] ?? 0), 2);
|
|
$out = [
|
|
'driver_id' => (int) $row['driver_id'],
|
|
'name' => $row['name'],
|
|
'mobile' => $row['mobile'],
|
|
'id_card_mask' => QytOil::maskIdCard((string) $row['id_card']),
|
|
'conflict' => (int) $row['conflict'],
|
|
'conflict_text' => $row['conflict_text'],
|
|
'last_order_time_text' => $row['last_order_time'] ? date('Y-m-d H:i:s', (int) $row['last_order_time']) : '',
|
|
'order_num' => (int) ($stat['order_num'] ?? 0),
|
|
'used_num' => (int) ($stat['used_num'] ?? 0),
|
|
'fail_num' => (int) ($stat['fail_num'] ?? 0),
|
|
'pending_num' => (int) ($stat['pending_num'] ?? 0),
|
|
'grant_amount' => number_format($grant, 2, '.', ''),
|
|
'refund_amount' => number_format($refund, 2, '.', ''),
|
|
'used_amount' => number_format((float) ($stat['used_amount'] ?? 0), 2, '.', ''),
|
|
// 本地口径的净发放额,仅供参考;真实可用额度以企油通 7.12 为准
|
|
'net_amount' => number_format($grant - $refund, 2, '.', ''),
|
|
];
|
|
return $out;
|
|
}
|
|
}
|