uid()); $titles = InvoiceService::getTitleList($this->uid()); $this->success('', [ 'quota' => $quota, 'titles' => $titles, ]); } /** * 可开票已完成订单列表(支持分页或传入 order_ids 核对已勾选订单) */ public function orders() { $page = max(1, (int)$this->request->param('page', 1)); $limit = min(100, max(1, (int)$this->request->param('limit', 20))); $rawIds = $this->request->param('order_ids/a', []); $filterIds = InvoiceService::parseIds($rawIds); $res = InvoiceService::getInvoiceableOrders($this->uid(), $page, $limit, $filterIds); $this->success('', $res); } /** * 提交开票申请(支持按勾选订单合并开票或按可用额度开票,严格校验专票要素) * @ApiMethod (POST) */ public function apply() { $params = [ 'order_ids' => $this->request->post('order_ids/a', []), 'amount' => $this->request->post('amount', 0), 'title_id' => $this->request->post('title_id', 0), 'type' => $this->request->post('type', 'normal'), 'title_type' => $this->request->post('title_type', ''), 'title' => $this->request->post('title', ''), 'tax_no' => $this->request->post('tax_no', ''), 'bank_name' => $this->request->post('bank_name', ''), 'bank_account' => $this->request->post('bank_account', ''), 'reg_address' => $this->request->post('reg_address', ''), 'reg_mobile' => $this->request->post('reg_mobile', ''), 'email' => $this->request->post('email', ''), 'receive_mobile' => $this->request->post('receive_mobile', ''), 'remark' => $this->request->post('remark', ''), 'save_title' => $this->request->post('save_title', 0), ]; try { $result = InvoiceService::submitInvoice($this->uid(), $params, true); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } catch (\Exception $e) { Log::error('[Invoice::apply] ' . $e->getMessage()); $this->error('提交开票申请失败,请稍后重试'); return; } $this->success('开票申请已提交,预计 1-3 个工作日内开具', $result); } /** * 开票记录分页列表 */ public function records() { $status = trim((string)$this->request->param('status', 'all')); $page = max(1, (int)$this->request->param('page', 1)); $limit = min(50, max(1, (int)$this->request->param('limit', 20))); $res = InvoiceService::getRecordList($this->uid(), $status, $page, $limit); $quota = InvoiceService::getQuotaSummary($this->uid()); $res['quota'] = [ 'available' => $quota['available'], 'paid_amount' => $quota['paid_amount'], 'used_amount' => $quota['used_amount'], 'issued_amount' => $quota['issued_amount'], 'wait_count' => $quota['wait_count'], 'record_count' => $quota['record_count'], ]; $this->success('', $res); } /** * 开票申请详情(含完整票面信息、电子发票附件、驳回说明、关联订单明细) */ public function detail() { $id = (int)$this->request->param('id', 0); try { $detail = InvoiceService::getInvoiceDetail($this->uid(), $id); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } $this->success('', ['detail' => $detail]); } /** * 撤回待处理(wait)开票申请 * @ApiMethod (POST) */ public function cancel() { $id = (int)$this->request->post('id', 0); try { InvoiceService::cancelInvoice($this->uid(), $id); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } catch (\Exception $e) { Log::error('[Invoice::cancel] ' . $e->getMessage()); $this->error('撤回失败,请刷新后重试'); return; } $this->success('已撤回开票申请,可开票额度已释放'); } /** * 发票抬头列表 */ public function titles() { $list = InvoiceService::getTitleList($this->uid()); $this->success('', ['list' => $list]); } /** * 发票抬头详情 */ public function titleDetail() { $id = (int)$this->request->param('id', 0); try { $detail = InvoiceService::getOwnTitle($this->uid(), $id); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } $this->success('', ['detail' => $detail]); } /** * 新增 / 编辑发票抬头 * @ApiMethod (POST) */ public function titleSave() { $input = [ 'id' => (int)$this->request->post('id', 0), 'title_type' => $this->request->post('title_type', 'personal'), 'default_invoice_type' => $this->request->post('default_invoice_type', 'normal'), 'title' => $this->request->post('title', ''), 'tax_no' => $this->request->post('tax_no', ''), 'bank_name' => $this->request->post('bank_name', ''), 'bank_account' => $this->request->post('bank_account', ''), 'reg_address' => $this->request->post('reg_address', ''), 'reg_mobile' => $this->request->post('reg_mobile', ''), 'email' => $this->request->post('email', ''), 'receive_mobile' => $this->request->post('receive_mobile', ''), 'is_default' => (int)$this->request->post('is_default', 0), ]; try { $saved = InvoiceService::saveTitle($this->uid(), $input); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } catch (\Exception $e) { Log::error('[Invoice::titleSave] ' . $e->getMessage()); $this->error('保存失败,请稍后重试'); return; } $this->success('保存成功', ['detail' => $saved, 'id' => (int)$saved['id']]); } /** * 设为默认发票抬头 * @ApiMethod (POST) */ public function titleDefault() { $id = (int)$this->request->post('id', 0); try { InvoiceService::setDefaultTitle($this->uid(), $id); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } catch (\Exception $e) { Log::error('[Invoice::titleDefault] ' . $e->getMessage()); $this->error('设置失败,请稍后重试'); return; } $this->success('已设为默认抬头'); } /** * 删除发票抬头 * @ApiMethod (POST) */ public function titleDelete() { $id = (int)$this->request->post('id', 0); try { InvoiceService::deleteTitle($this->uid(), $id); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return; } catch (\Exception $e) { Log::error('[Invoice::titleDelete] ' . $e->getMessage()); $this->error('删除失败,请稍后重试'); return; } $this->success('已删除'); } }