validator; } /** * 构建查询条件 */ protected function buildQueryConfig(Request $request, string $scene = 'index'): array { $p = $request->all(); $config = []; $config['model'] = $this->modelClass; switch ($scene) { case 'index': // ====== ====== 排序 ====== ====== $config['order']['id'] = 'desc'; // ====== ====== 筛选 ====== ====== // 汇款国家 if (isset($p['country_id']) && !empty($p['country_id'])) { $config['where']['country_id'] = $p['country_id']; } // 收款账户筛选 if (isset($p['account_id']) && !empty($p['account_id'])) { $config['where']['account_id'] = $p['account_id']; } // 入账资料超时 if (isset($p['scene']) && $p['scene'] == 'file_timeout') { $config['where']['claimed_at'] = ['between', [1, time()-24*60*60]]; } // 关键字 if (isset($p['keyword']) && $p['keyword']) { $k = '%' . $p['keyword'] . '%'; $config['orWhere'][] = ['remitter', 'like', $k]; } break; case 'show': $config['where']['id'] = $p['id']; break; case 'update': case 'destroy': $config['where']['id'] = $p['id']; break; case 'store': break; } return $config; } public function beforeServiceStore($data, Request $request) { $data['apply_no'] = $this->generateUniqueApplyNo(); $data['doc_user_id'] = $request->user->uid; $data['submit_files'] = json_encode($data['submit_files']); redis::set('stock_' . $data['doc_user_id'], json_encode($request->post('stock')), 'EX', 30); unset($data['stock']); if($data['submit_files'] == '[]' || $data['submit_files'] == '{}' ) $data['submit_files'] = ''; return $data; } public function afterServiceStore($res) { $data = [ 'payment_apply_id' => $res['id'], ]; $piStock = json_decode(redis::get('stock_' . $res['doc_user_id']), true); redis::del('stock' . $res['doc_user_id']); foreach ($piStock as $stock) { foreach ($stock['stock_id'] as $v) { $data['stock_id'] = $v; $data['pi_no'] = $stock['pi_on']; FinPaymentStock::create($data); } } } public function beforeServiceUpdate($data, Request $request) { $data['submit_files'] = json_encode($data['submit_files']); if($data['submit_files'] == '[]' || $data['submit_files'] == '{}' ) $data['submit_files'] = ''; return $data; } /** * 生成唯一的付款申请编码 * 格式:PA + 日期 + 6位字母数字组合 * * @return string 唯一编码 */ public function generateUniqueApplyNo() { $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $maxAttempts = 10; // 防止无限循环 $secondChar = 'PA' . date('Ymd'); for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { // 生成后6位随机字符 $suffix = ''; for ($i = 0; $i < 6; $i++) { $suffix .= $chars[rand(0, strlen($chars) - 1)]; } $applyNo = $secondChar . $suffix; // 检查是否已存在 $existing = FinPaymentApply::where('apply_no', $applyNo)->first(); if (!$existing) { return $applyNo; } } // 如果1000次尝试后仍然重复,使用时间戳确保唯一性 $timestamp = substr(time(), -6); return $secondChar . $timestamp; } /** * 根据相似度排序付款记录 * @param Request $request * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|\Illuminate\Pagination\LengthAwarePaginator */ public function complexQueryIndex(Request $request) { $limit = (int)$request->get('size', 15); $page = (int)$request->get('current', 1); $param = $request->all(); $where = []; $orWhere = []; // 汇款国家 if (isset($param['country_id']) && !empty($param['country_id'])) { $where[] = ['country_id', $param['country_id']]; } // 收款账户筛选 if (isset($param['account_id']) && !empty($param['account_id'])) { $where[] = ['account_id', $param['account_id']]; } // 入账资料超时 if (isset($param['scene']) && $param['scene'] == 'file_timeout') { $where[] = ['submit_files', '']; $where[] = ['claimed_at', '<', time()-24*60*60]; $where[] = ['claimed_at', '>', 1]; } // 关键字 if (isset($param['keyword']) && $param['keyword']) { $k = '%' . $param['keyword'] . '%'; $where[] = ['remitter', 'like', $k]; } // 构建查询 $query = $this->modelClass::where($where); // 是否已关联收款记录的筛选 $correlation = $param['correlation']??''; if ($correlation === 'receipt') { //已关联 $query->whereHas('receipt'); } elseif ($correlation === 'unbind') { //未关联 $query->whereDoesntHave('receipt'); } if ((isset($param['scene']) && $param['scene'] == 'list') || empty($param['receipt_id'])) { return $query->orderBy('id','desc')->paginate($limit, ['*'], 'page', $page); } $receipt = FinReceipt::where('id', $param['receipt_id'])->first(); $account_id = $receipt->account_id; $currency_id = $receipt->currency_id; $remitter = $receipt->remitter; $amount = $receipt->amount; // 计算十天前的时间戳 $sevenDaysAgo = time() - (10 * 24 * 60 * 60); // 构建相似度排序逻辑 $similarityOrder = []; // 如果有传入参数,计算相似度 if (!empty($account_id)) { $similarityOrder[] = "CASE WHEN account_id = {$account_id} THEN 0 ELSE 1 END"; } if (!empty($currency_id)) { $similarityOrder[] = "CASE WHEN currency_id = {$currency_id} THEN 0 ELSE 1 END"; } if (!empty($remitter)) { $similarityOrder[] = "CASE WHEN remitter = {$remitter} THEN 0 ELSE 1 END"; } if (!empty($amount)) { $amount = (float)$amount; $similarityOrder[] = "ABS(amount - {$amount}) ASC"; $similarityOrder[] = "CASE WHEN (ABS(amount - {$amount}) / {$amount} * 100) <= 5 THEN 0 ELSE 1 END"; } // 构建排序SQL $orderByClause = ""; if (!empty($similarityOrder)) { $orderByClause = "CASE WHEN created_at >= {$sevenDaysAgo} THEN (" . implode(' + ', $similarityOrder) . ") ELSE 0 END ASC, "; } $orderByClause .= "CASE WHEN created_at > {$sevenDaysAgo} THEN id ELSE 999999 END DESC, "; $orderByClause .= "id DESC"; $query->orderByRaw($orderByClause); return $query->paginate($limit, ['*'], 'page', $page); } }