feat: 重构后台服务字典与商品独立定价体系及前后端交互优化
这个提交包含在:
@@ -248,33 +248,92 @@ class Merchant extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* 开票记录
|
||||
* 开票记录与可开票额度(个人用户与认证商家通用)
|
||||
*/
|
||||
public function invoices()
|
||||
{
|
||||
$merchant = $this->requireMerchant();
|
||||
$list = Db::name('invoice')->where('merchant_id', $merchant['id'])->order('id desc')->limit(30)->select();
|
||||
$merchant = $this->merchantInfo();
|
||||
$isPassMerchant = ($merchant && $merchant['verify_status'] === 'pass');
|
||||
|
||||
if ($isPassMerchant) {
|
||||
$uids = $this->merchantUserIds($merchant);
|
||||
$mid = (int)$merchant['id'];
|
||||
$list = Db::name('invoice')
|
||||
->where(function ($q) use ($mid, $uids) {
|
||||
$q->where('merchant_id', $mid)->whereOr('user_id', 'in', $uids);
|
||||
})
|
||||
->order('id desc')
|
||||
->limit(30)
|
||||
->select();
|
||||
$paid = (float)Db::name('order')->where('user_id', 'in', $uids)->where('pay_status', 1)->sum('pay_amount');
|
||||
$used = (float)Db::name('invoice')
|
||||
->where(function ($q) use ($mid, $uids) {
|
||||
$q->where('merchant_id', $mid)->whereOr('user_id', 'in', $uids);
|
||||
})
|
||||
->where('status', 'in', ['wait', 'issued'])
|
||||
->sum('amount');
|
||||
$issued = (float)Db::name('invoice')
|
||||
->where(function ($q) use ($mid, $uids) {
|
||||
$q->where('merchant_id', $mid)->whereOr('user_id', 'in', $uids);
|
||||
})
|
||||
->where('status', 'issued')
|
||||
->sum('amount');
|
||||
} else {
|
||||
$uid = $this->uid();
|
||||
$list = Db::name('invoice')->where('user_id', $uid)->order('id desc')->limit(30)->select();
|
||||
$paid = (float)Db::name('order')->where('user_id', $uid)->where('pay_status', 1)->sum('pay_amount');
|
||||
$used = (float)Db::name('invoice')->where('user_id', $uid)->where('status', 'in', ['wait', 'issued'])->sum('amount');
|
||||
$issued = (float)Db::name('invoice')->where('user_id', $uid)->where('status', 'issued')->sum('amount');
|
||||
}
|
||||
|
||||
$statusText = ['wait' => '开票中', 'issued' => '已开票', 'reject' => '已驳回'];
|
||||
foreach ($list as &$row) {
|
||||
$row['amount'] = (float)$row['amount'];
|
||||
$row['status_text'] = isset($statusText[$row['status']]) ? $statusText[$row['status']] : $row['status'];
|
||||
$row['type_text'] = $row['type'] === 'special' ? '专用发票' : '普通发票';
|
||||
$row['title_type'] = !empty($row['tax_no']) ? 'enterprise' : 'personal';
|
||||
$row['title_type_text'] = !empty($row['tax_no']) ? '企业单位' : '个人/非企业';
|
||||
$row['time_text'] = date('Y-m-d H:i', (int)$row['createtime']);
|
||||
}
|
||||
unset($row);
|
||||
$this->success('', ['list' => $list]);
|
||||
|
||||
$userRow = Db::name('user')->where('id', $this->uid())->field('nickname,mobile')->find();
|
||||
$personalDefaultTitle = ($userRow && !empty($userRow['nickname'])) ? (string)$userRow['nickname'] : '个人';
|
||||
|
||||
$this->success('', [
|
||||
'list' => $list,
|
||||
'quota' => [
|
||||
'available' => round(max(0, $paid - $used), 2),
|
||||
'paid_amount' => round($paid, 2),
|
||||
'used_amount' => round($used, 2),
|
||||
'issued_amount' => round($issued, 2),
|
||||
'is_merchant' => $isPassMerchant,
|
||||
'default_title_type' => $isPassMerchant ? 'enterprise' : 'personal',
|
||||
'default_title' => $isPassMerchant ? ($merchant['invoice_title'] ?: $merchant['name']) : $personalDefaultTitle,
|
||||
'default_tax_no' => $isPassMerchant ? (string)$merchant['invoice_tax_no'] : '',
|
||||
'enterprise_title' => $merchant ? (string)($merchant['invoice_title'] ?: $merchant['name']) : '',
|
||||
'enterprise_tax_no' => $merchant ? (string)$merchant['invoice_tax_no'] : '',
|
||||
'personal_title' => $personalDefaultTitle,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请开票
|
||||
* 申请开票(支持个人用户与认证商家)
|
||||
* @ApiMethod (POST)
|
||||
*/
|
||||
public function invoice()
|
||||
{
|
||||
$merchant = $this->requireMerchant();
|
||||
$merchant = $this->merchantInfo();
|
||||
$isPassMerchant = ($merchant && $merchant['verify_status'] === 'pass');
|
||||
|
||||
$amount = round((float)$this->request->post('amount'), 2);
|
||||
$type = $this->request->post('type', 'normal');
|
||||
$email = trim((string)$this->request->post('email'));
|
||||
$titleType = trim((string)$this->request->post('title_type', ''));
|
||||
$title = trim((string)$this->request->post('title', ''));
|
||||
$taxNo = strtoupper(trim((string)$this->request->post('tax_no', '')));
|
||||
$email = trim((string)$this->request->post('email', ''));
|
||||
$remark = trim((string)$this->request->post('remark', ''));
|
||||
|
||||
if ($amount <= 0) {
|
||||
$this->error('请填写开票金额');
|
||||
@@ -283,21 +342,64 @@ class Merchant extends Base
|
||||
$this->error('发票类型错误');
|
||||
}
|
||||
|
||||
$paid = (float)Db::name('order')->where('user_id', 'in', $this->merchantUserIds($merchant))->where('pay_status', 1)->sum('pay_amount');
|
||||
$used = (float)Db::name('invoice')->where('merchant_id', $merchant['id'])->where('status', 'in', ['wait', 'issued'])->sum('amount');
|
||||
if (!in_array($titleType, ['personal', 'enterprise'], true)) {
|
||||
$titleType = ($isPassMerchant || $taxNo !== '' || $type === 'special') ? 'enterprise' : 'personal';
|
||||
}
|
||||
|
||||
if ($titleType === 'personal') {
|
||||
if ($type === 'special') {
|
||||
$this->error('个人抬头仅支持开具普通发票');
|
||||
}
|
||||
if ($title === '') {
|
||||
$userRow = Db::name('user')->where('id', $this->uid())->field('nickname')->find();
|
||||
$title = ($userRow && !empty($userRow['nickname'])) ? (string)$userRow['nickname'] : '个人';
|
||||
}
|
||||
$taxNo = '';
|
||||
} else {
|
||||
if ($title === '' && $isPassMerchant) {
|
||||
$title = (string)($merchant['invoice_title'] ?: $merchant['name']);
|
||||
}
|
||||
if ($taxNo === '' && $isPassMerchant) {
|
||||
$taxNo = strtoupper(trim((string)$merchant['invoice_tax_no']));
|
||||
}
|
||||
if ($title === '') {
|
||||
$this->error('请填写企业发票抬头');
|
||||
}
|
||||
if ($taxNo === '') {
|
||||
$this->error('请填写纳税人识别号(税号)');
|
||||
}
|
||||
}
|
||||
|
||||
if ($isPassMerchant) {
|
||||
$uids = $this->merchantUserIds($merchant);
|
||||
$mid = (int)$merchant['id'];
|
||||
$paid = (float)Db::name('order')->where('user_id', 'in', $uids)->where('pay_status', 1)->sum('pay_amount');
|
||||
$used = (float)Db::name('invoice')
|
||||
->where(function ($q) use ($mid, $uids) {
|
||||
$q->where('merchant_id', $mid)->whereOr('user_id', 'in', $uids);
|
||||
})
|
||||
->where('status', 'in', ['wait', 'issued'])
|
||||
->sum('amount');
|
||||
} else {
|
||||
$uid = $this->uid();
|
||||
$paid = (float)Db::name('order')->where('user_id', $uid)->where('pay_status', 1)->sum('pay_amount');
|
||||
$used = (float)Db::name('invoice')->where('user_id', $uid)->where('status', 'in', ['wait', 'issued'])->sum('amount');
|
||||
}
|
||||
|
||||
$available = round(max(0, $paid - $used), 2);
|
||||
if ($amount > $available) {
|
||||
$this->error('可开票金额不足,当前可开 ¥' . $available);
|
||||
}
|
||||
|
||||
Db::name('invoice')->insert([
|
||||
'merchant_id' => (int)$merchant['id'],
|
||||
'merchant_id' => $isPassMerchant ? (int)$merchant['id'] : 0,
|
||||
'user_id' => $this->uid(),
|
||||
'amount' => $amount,
|
||||
'type' => $type,
|
||||
'title' => $merchant['invoice_title'] ?: $merchant['name'],
|
||||
'tax_no' => $merchant['invoice_tax_no'],
|
||||
'title' => $title,
|
||||
'tax_no' => $taxNo,
|
||||
'email' => $email,
|
||||
'remark' => $remark,
|
||||
'status' => 'wait',
|
||||
'createtime' => time(),
|
||||
'updatetime' => time(),
|
||||
|
||||
在新工单中引用
屏蔽一个用户