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; } }