logic = (new FinReceiptLogic()); } /** * 获取验证器 */ public function getValidator() { return new $this->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['payment_apply']) && $p['payment_apply'] == 'not') { //未认领 $config['where']['payment_apply_id'] = 0; } elseif (isset($p['payment_apply']) && $p['payment_apply'] == 'already') { //已认领 $config['where']['payment_apply_id'] = ['>', 0]; } elseif (isset($p['payment_apply']) && $p['payment_apply'] == 'timeout') { //超时未认领 $config['where']['payment_apply_id'] = 0; $config['where']['created_at'] = ['<' ,time() - 24*60*60]; } // 收款申请筛选 if (isset($p['payment_apply_id']) && !empty($p['payment_apply_id'])) { $config['where']['payment_apply_id'] = $p['payment_apply_id']; } // 收款账户筛选 if (isset($p['account_id']) && !empty($p['account_id'])) { $config['where']['account_id'] = $p['account_id']; } // 关键字 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 'payment': case 'destroy': $config['where']['id'] = $p['id']; break; case 'store': break; } return $config; } public function beforeServiceStore($data, Request $request) { if(isset($data['payment_apply_id']) && empty($data['payment_apply_id'])){ unset($data['payment_apply_id']); } $data['receipt_no'] = $this->generateUniqueReceipt(); $data['arrived_at'] = strtotime( $data['arrived_at']); $data['created_by'] = $request->user->uid; $data['updated_by'] = $request->user->uid; $data['fx_receipt_file'] = json_encode($data['fx_receipt_file']); if($data['fx_receipt_file'] == '[]' || $data['fx_receipt_file'] == '{}' || $data['fx_receipt_file'] == '""') $data['fx_receipt_file'] = ''; return $data; } public function afterServiceStore($res) { $receipt = FinReceipt::where('id',$res->id)->first()->toArray(); $receipt = array_merge($receipt,['receipt_id' => $res->id]); unset($receipt['id']); FinReceiptHis::create($receipt); } public function beforeServiceUpdate($data, Request $request) { $data['updated_by'] = $request->user->uid; if(isset($data['arrived_at'])) $data['arrived_at'] = strtotime($data['arrived_at']); if(isset($data['received_at'])) $data['received_at'] = strtotime($data['received_at']); $data['fx_receipt_file'] = json_encode($data['fx_receipt_file']); if($data['fx_receipt_file'] == '[]' || $data['fx_receipt_file'] == '{}' || $data['fx_receipt_file'] == '""') $data['fx_receipt_file'] = ''; return $data; } public function afterServiceUpdate($res) { $receipt = FinReceipt::where('id',$res['id'])->first()->toArray(); $receipt = array_merge($receipt,['receipt_id' => $res['id']]); unset($receipt['id']); FinReceiptHis::create($receipt); } /** * 生成唯一的付款申请编码 * 格式:PA + 日期 + 6位字母数字组合 * * @return string 唯一编码 */ public function generateUniqueReceipt() { $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $maxAttempts = 10; // 防止无限循环 $secondChar = 'RE' . date('Ymd'); for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { // 生成后6位随机字符 $suffix = ''; for ($i = 0; $i < 6; $i++) { $suffix .= $chars[rand(0, strlen($chars) - 1)]; } $ReceiptNo = $secondChar . $suffix; // 检查是否已存在 $existing = FinReceipt::where('receipt_no', $ReceiptNo)->first(); if (!$existing) { return $ReceiptNo; } } // 如果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 = []; // 汇款国家 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['payment_apply_id']) && !empty($param['payment_apply_id'])) { $where[]['payment_apply_id'] = $param['payment_apply_id']; } // 关键字 if (isset($param['keyword']) && $param['keyword']) { $k = '%' . $param['keyword'] . '%'; $where[] = ['remitter', 'like', $k]; } // 构建查询 $query = $this->modelClass::where($where); // 没有付款记录的收款记录 if (isset($param['payment_apply']) && $param['payment_apply'] == 'not') { $query->where('payment_apply_id', 0); } elseif (isset($param['payment_apply']) && $param['payment_apply'] == 'already') { $query->where('payment_apply_id', '>', 0); } elseif (isset($param['payment_apply']) && $param['payment_apply'] == 'timeout') { //超时未认领 $query->where('payment_apply_id', 0); $query->where('created_at', '<' ,time() - 24*60*60); } if (isset($param['scene']) && $param['scene'] == 'list') { return $query->paginate($limit, ['*'], 'page', $page); } // 计算七天前的时间戳 $sevenDaysAgo = time() - (10 * 24 * 60 * 60); // 构建相似度排序逻辑 $similarityOrder = []; // 如果有传入参数,计算相似度 if (isset($param['account_id']) && !empty($param['account_id'])) { $similarityOrder[] = "CASE WHEN account_id = {$param['account_id']} THEN 0 ELSE 1 END"; } if (isset($param['country_id']) && !empty($param['country_id'])) { $similarityOrder[] = "CASE WHEN country_id = {$param['country_id']} THEN 0 ELSE 1 END"; } if (isset($param['keyword']) && $param['keyword']) { $keyword = addslashes($param['keyword']); $similarityOrder[] = "CASE WHEN remitter LIKE '%{$keyword}%' THEN 0 ELSE 1 END"; } if (isset($param['amount']) && !empty($param['amount'])) { $amount = (float)$param['amount']; $similarityOrder[] = "ABS(amount - {$amount})"; } // 构建排序SQL $orderByClause = ""; if (!empty($similarityOrder)) { $orderByClause = "CASE WHEN created_at >= {$sevenDaysAgo} THEN (" . implode(' + ', $similarityOrder) . ") ELSE 999999 END ASC, "; } $orderByClause .= "CASE WHEN created_at < {$sevenDaysAgo} THEN id ELSE 0 END DESC"; $query->orderByRaw($orderByClause); return $query->paginate($limit, ['*'], 'page', $page); } public function credit($id) { $finReceipt = FinReceipt::find($id); if(!empty($finReceipt->received_at)){ throw new BusinessException('该记录已将确认入账'); } $res = $this->logic->credit($id); $this->afterServiceUpdate(['id'=>$id]); return $res; } /** * 更新:绑定收款记录,计算折让金额 * @param Request $request * @param array $data * @param string $scene * @return mixed */ public function serviceUpdatePayment(Request $request, array $data = [], string $scene = 'payment') { $payment_apply_id = $request->input('payment_apply_id'); $id = $request->input('id'); $data = $this->preProcess(ucfirst($scene), $data, $request); $config = $this->buildQueryConfig($request, $scene); FinPaymentApply::where('id', $payment_apply_id)->update(['receipt_id' => $id, 'claimed_at' => time(), 'claimed_by' => $request->user->uid]); FinPaymentStock::where('payment_apply_id', $payment_apply_id)->update(['receipt_id' => $id]); //折让金额 $payment = FinPaymentApply::where('id', $payment_apply_id)->first(); $receipt = FinReceipt::find($id); $data['discount_amount'] = $payment->amount - $receipt->amount ?? 0; $updated = $this->logicUpdateBy($config, $data); return $this->postProcess(ucfirst($scene), $data); } }