- 新增 invoice_title、showcase、wallet_log 模型及对应语言包 - 新增后台控制器、视图及搜索字段配置 - 修复服务类目删除保护逻辑 - 优化后台登录页面文案及样式 - 新增前端角色切换逻辑及页面拦截 - 新增 SVG 图标及样式变量 - 修复接口权限及下拉框默认值问题
234 行
8.1 KiB
PHP
234 行
8.1 KiB
PHP
<?php
|
||
|
||
namespace app\api\controller;
|
||
|
||
use app\common\library\InvoiceService;
|
||
use think\Log;
|
||
|
||
/**
|
||
* 发票中心(个人业主与企业商家通用):
|
||
* 额度汇总 / 按单勾选开票 / 发票抬头管理 / 开票记录与详情 / 撤回申请
|
||
*/
|
||
class Invoice extends Base
|
||
{
|
||
/**
|
||
* 开票首页概览(可开票额度、默认抬头、未开票订单数、记录统计)
|
||
*/
|
||
public function summary()
|
||
{
|
||
$quota = InvoiceService::getQuotaSummary($this->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('已删除');
|
||
}
|
||
}
|