Toggle navigation
Toggle navigation
This project
Loading...
Sign in
zhouhui.jiang
/
test_cursor
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
zhouhui.jiang
2025-09-29 10:32:24 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
f99868497bf68f1459d114ec9e18edefaa836c6d
f9986849
1 parent
fadab012
update 订单、出库、发票
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
509 additions
and
50 deletions
backend/src/main/java/com/apple/erp/controller/DeliveryMainController.java
backend/src/main/java/com/apple/erp/controller/InvoiceMainController.java
backend/src/main/java/com/apple/erp/dto/DeliveryAddReq.java
backend/src/main/java/com/apple/erp/dto/DeliveryItemAddReq.java
backend/src/main/java/com/apple/erp/dto/DeliveryItemRes.java
backend/src/main/java/com/apple/erp/dto/DeliveryItemUpdateReq.java
backend/src/main/java/com/apple/erp/dto/DeliveryRes.java
backend/src/main/java/com/apple/erp/dto/DeliveryUpdateReq.java
backend/src/main/java/com/apple/erp/dto/InvoiceItemAddReq.java
backend/src/main/java/com/apple/erp/dto/InvoiceItemRes.java
backend/src/main/java/com/apple/erp/dto/InvoiceItemUpdateReq.java
backend/src/main/java/com/apple/erp/dto/InvoiceQueryReq.java
backend/src/main/java/com/apple/erp/entity/DeliveryItem.java
backend/src/main/java/com/apple/erp/entity/InvoiceItem.java
backend/src/main/java/com/apple/erp/entity/InvoiceMain.java
backend/src/main/java/com/apple/erp/mapper/DeliveryItemMapper.java
backend/src/main/java/com/apple/erp/mapper/DeliveryMainMapper.java
backend/src/main/java/com/apple/erp/mapper/InvoiceItemMapper.java
backend/src/main/java/com/apple/erp/mapper/InvoiceMainMapper.java
backend/src/main/java/com/apple/erp/service/DeliveryMainService.java
backend/src/main/java/com/apple/erp/service/InvoiceMainService.java
backend/src/main/java/com/apple/erp/service/impl/DeliveryMainServiceImpl.java
backend/src/main/java/com/apple/erp/service/impl/InvoiceMainServiceImpl.java
frontend/src/views/delivery/index.vue
frontend/src/views/invoice/index.vue
backend/src/main/java/com/apple/erp/controller/DeliveryMainController.java
View file @
f998684
...
...
@@ -141,3 +141,4 @@ public class DeliveryMainController {
}
}
...
...
backend/src/main/java/com/apple/erp/controller/InvoiceMainController.java
View file @
f998684
...
...
@@ -87,7 +87,7 @@ public class InvoiceMainController {
@Operation
(
summary
=
"删除发票"
,
description
=
"根据发票ID逻辑删除发票"
)
@DeleteMapping
(
"/{invoiceId}"
)
@PreAuthorize
(
"hasAuthority('invoice:
delet
e')"
)
@PreAuthorize
(
"hasAuthority('invoice:
remov
e')"
)
public
ApiRes
<
Void
>
deleteInvoice
(
@Parameter
(
description
=
"发票ID"
,
required
=
true
)
@PathVariable
Long
invoiceId
)
{
try
{
...
...
@@ -141,3 +141,4 @@ public class InvoiceMainController {
}
}
...
...
backend/src/main/java/com/apple/erp/dto/DeliveryAddReq.java
View file @
f998684
...
...
@@ -61,3 +61,4 @@ public class DeliveryAddReq {
private
List
<
DeliveryItemAddReq
>
deliveryItems
;
}
...
...
backend/src/main/java/com/apple/erp/dto/DeliveryItemAddReq.java
View file @
f998684
...
...
@@ -37,3 +37,4 @@ public class DeliveryItemAddReq {
private
BigDecimal
deliveryAmount
;
}
...
...
backend/src/main/java/com/apple/erp/dto/DeliveryItemRes.java
View file @
f998684
...
...
@@ -59,3 +59,4 @@ public class DeliveryItemRes {
private
LocalDateTime
updateTime
;
}
...
...
backend/src/main/java/com/apple/erp/dto/DeliveryItemUpdateReq.java
View file @
f998684
...
...
@@ -40,3 +40,4 @@ public class DeliveryItemUpdateReq {
private
BigDecimal
deliveryAmount
;
}
...
...
backend/src/main/java/com/apple/erp/dto/DeliveryRes.java
View file @
f998684
...
...
@@ -67,3 +67,4 @@ public class DeliveryRes {
private
List
<
DeliveryItemRes
>
deliveryItems
;
}
...
...
backend/src/main/java/com/apple/erp/dto/DeliveryUpdateReq.java
View file @
f998684
...
...
@@ -65,3 +65,4 @@ public class DeliveryUpdateReq {
private
List
<
DeliveryItemUpdateReq
>
deliveryItems
;
}
...
...
backend/src/main/java/com/apple/erp/dto/InvoiceItemAddReq.java
View file @
f998684
...
...
@@ -42,3 +42,4 @@ public class InvoiceItemAddReq {
private
BigDecimal
taxAmount
;
}
...
...
backend/src/main/java/com/apple/erp/dto/InvoiceItemRes.java
View file @
f998684
...
...
@@ -62,3 +62,4 @@ public class InvoiceItemRes {
private
LocalDateTime
updateTime
;
}
...
...
backend/src/main/java/com/apple/erp/dto/InvoiceItemUpdateReq.java
View file @
f998684
...
...
@@ -45,3 +45,4 @@ public class InvoiceItemUpdateReq {
private
BigDecimal
taxAmount
;
}
...
...
backend/src/main/java/com/apple/erp/dto/InvoiceQueryReq.java
View file @
f998684
...
...
@@ -55,3 +55,4 @@ public class InvoiceQueryReq {
private
Integer
pageSize
=
10
;
}
...
...
backend/src/main/java/com/apple/erp/entity/DeliveryItem.java
View file @
f998684
...
...
@@ -66,3 +66,4 @@ public class DeliveryItem {
private
String
delFlag
;
}
...
...
backend/src/main/java/com/apple/erp/entity/InvoiceItem.java
View file @
f998684
...
...
@@ -72,3 +72,4 @@ public class InvoiceItem {
private
String
delFlag
;
}
...
...
backend/src/main/java/com/apple/erp/entity/InvoiceMain.java
View file @
f998684
...
...
@@ -81,3 +81,4 @@ public class InvoiceMain {
private
String
delFlag
;
}
...
...
backend/src/main/java/com/apple/erp/mapper/DeliveryItemMapper.java
View file @
f998684
...
...
@@ -14,3 +14,4 @@ import org.apache.ibatis.annotations.Mapper;
public
interface
DeliveryItemMapper
extends
BaseMapper
<
DeliveryItem
>
{
}
...
...
backend/src/main/java/com/apple/erp/mapper/DeliveryMainMapper.java
View file @
f998684
...
...
@@ -14,3 +14,4 @@ import org.apache.ibatis.annotations.Mapper;
public
interface
DeliveryMainMapper
extends
BaseMapper
<
DeliveryMain
>
{
}
...
...
backend/src/main/java/com/apple/erp/mapper/InvoiceItemMapper.java
View file @
f998684
...
...
@@ -14,3 +14,4 @@ import org.apache.ibatis.annotations.Mapper;
public
interface
InvoiceItemMapper
extends
BaseMapper
<
InvoiceItem
>
{
}
...
...
backend/src/main/java/com/apple/erp/mapper/InvoiceMainMapper.java
View file @
f998684
...
...
@@ -14,3 +14,4 @@ import org.apache.ibatis.annotations.Mapper;
public
interface
InvoiceMainMapper
extends
BaseMapper
<
InvoiceMain
>
{
}
...
...
backend/src/main/java/com/apple/erp/service/DeliveryMainService.java
View file @
f998684
...
...
@@ -69,3 +69,4 @@ public interface DeliveryMainService extends IService<DeliveryMain> {
boolean
updateDeliveryStatus
(
Long
deliveryId
,
Integer
deliveryStatus
);
}
...
...
backend/src/main/java/com/apple/erp/service/InvoiceMainService.java
View file @
f998684
...
...
@@ -69,3 +69,4 @@ public interface InvoiceMainService extends IService<InvoiceMain> {
boolean
updateInvoiceStatus
(
Long
invoiceId
,
Integer
invoiceStatus
);
}
...
...
backend/src/main/java/com/apple/erp/service/impl/DeliveryMainServiceImpl.java
View file @
f998684
...
...
@@ -229,3 +229,4 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del
}
}
...
...
backend/src/main/java/com/apple/erp/service/impl/InvoiceMainServiceImpl.java
View file @
f998684
...
...
@@ -112,6 +112,7 @@ public class InvoiceMainServiceImpl extends ServiceImpl<InvoiceMainMapper, Invoi
InvoiceMain
invoiceMain
=
new
InvoiceMain
();
BeanUtils
.
copyProperties
(
addReq
,
invoiceMain
);
invoiceMain
.
setUpdateTime
(
LocalDateTime
.
now
());
invoiceMain
.
setCreateTime
(
LocalDateTime
.
now
());
invoiceMain
.
setUpdateTime
(
LocalDateTime
.
now
());
invoiceMain
.
setDelFlag
(
"0"
);
...
...
frontend/src/views/delivery/index.vue
View file @
f998684
...
...
@@ -63,7 +63,7 @@
<!-- 操作按钮区域 -->
<div class="action-section">
<div class="action-buttons">
<button @click="handleAdd" class="action-btn primary">
➕ 新增出库
</button>
<button @click="handleAdd" class="action-btn primary">
✨ 新增
</button>
<button @click="handleExport" class="action-btn secondary">📋 导出</button>
</div>
</div>
...
...
@@ -175,10 +175,18 @@
<div class="dialog-body">
<div v-if="orderDetail" class="detail-content">
<div class="detail-section">
<h4>
订单
基本信息</h4>
<h4>
出库
基本信息</h4>
<div class="detail-grid">
<div class="detail-item">
<label>订单编号:</label>
<label>出库单ID:</label>
<span>{{ orderDetail.deliveryId }}</span>
</div>
<div class="detail-item">
<label>出库单编号:</label>
<span>{{ orderDetail.deliveryNo }}</span>
</div>
<div class="detail-item">
<label>关联订单编号:</label>
<span>{{ orderDetail.orderNo }}</span>
</div>
<div class="detail-item">
...
...
@@ -190,12 +198,8 @@
<span>{{ orderDetail.dealerName }}</span>
</div>
<div class="detail-item">
<label>订单日期:</label>
<span>{{ formatDate(orderDetail.orderDate) }}</span>
</div>
<div class="detail-item">
<label>订单总金额:</label>
<span>{{ formatCurrency(orderDetail.totalAmount) }}</span>
<label>出库日期:</label>
<span>{{ formatDate(orderDetail.deliveryDate) }}</span>
</div>
<div class="detail-item">
<label>出库状态:</label>
...
...
@@ -204,33 +208,47 @@
</span>
</div>
<div class="detail-item">
<label>出库时间:</label>
<label>仓库编码:</label>
<span>{{ orderDetail.warehouseCode }}</span>
</div>
<div class="detail-item">
<label>数据来源:</label>
<span>{{ orderDetail.dataSource || '-' }}</span>
</div>
<div class="detail-item">
<label>上传时间:</label>
<span>{{ formatTime(orderDetail.uploadTime || '') }}</span>
</div>
<div class="detail-item">
<label>创建时间:</label>
<span>{{ formatTime(orderDetail.createTime || '') }}</span>
</div>
<div class="detail-item">
<label>更新时间:</label>
<span>{{ formatTime(orderDetail.updateTime || '') }}</span>
</div>
</div>
</div>
<div class="detail-section" v-if="orderDetail.
orderItems && orderDetail.order
Items.length > 0">
<div class="detail-section" v-if="orderDetail.
deliveryItems && orderDetail.delivery
Items.length > 0">
<h4>出库明细</h4>
<table class="detail-table">
<thead>
<tr>
<th>产品编码</th>
<th>产品名称</th>
<th>产品型号</th>
<th>数量</th>
<th>单价</th>
<th>总价</th>
<th>出库数量</th>
<th>出库单价</th>
<th>出库金额</th>
</tr>
</thead>
<tbody>
<tr v-for="item in orderDetail.
orderItems" :key="item.i
temId">
<tr v-for="item in orderDetail.
deliveryItems" :key="item.deliveryI
temId">
<td>{{ item.productCode }}</td>
<td>{{ item.productName }}</td>
<td>{{ item.productModel }}</td>
<td>{{ item.quantity }}</td>
<td>{{ formatCurrency(item.unitPrice) }}</td>
<td>{{ formatCurrency(item.totalPrice) }}</td>
<td>{{ item.deliveryQty }}</td>
<td>{{ formatCurrency(item.deliveryPrice) }}</td>
<td>{{ formatCurrency(item.deliveryAmount) }}</td>
</tr>
</tbody>
</table>
...
...
frontend/src/views/invoice/index.vue
View file @
f998684
...
...
@@ -71,7 +71,7 @@
<!-- 操作按钮区域 -->
<div class="action-section">
<div class="action-buttons">
<button @click="handleAdd" class="action-btn primary">✨ 新增
发票
</button>
<button @click="handleAdd" class="action-btn primary">✨ 新增</button>
<button @click="handleExport" class="action-btn secondary">📋 导出</button>
</div>
</div>
...
...
@@ -101,7 +101,7 @@
<th>开票日期</th>
<th>发票金额</th>
<th>开票状态</th>
<th>
开票
时间</th>
<th>
上传
时间</th>
<th>关联订单编号</th>
<th>操作</th>
</tr>
...
...
@@ -124,6 +124,7 @@
<td class="action-col">
<button @click="handleView(order)" class="view-btn">👁️ 查看</button>
<button @click="handleEdit(order)" class="edit-btn">✏️ 编辑</button>
<button @click="handleDelete(order)" class="delete-btn">🗑️ 删除</button>
</td>
</tr>
</tbody>
...
...
@@ -177,7 +178,7 @@
<!-- 新增/编辑发票对话框 -->
<div v-if="showDialog" class="dialog-overlay" @click="closeDialog">
<div class="dialog-content" @click.stop>
<div class="dialog-content
large-dialog
" @click.stop>
<div class="dialog-header">
<h3>{{ isEdit ? '编辑发票' : '新增发票' }}</h3>
<button @click="closeDialog" class="close-btn">×</button>
...
...
@@ -206,11 +207,41 @@
</div>
<div class="form-row">
<div class="form-item">
<label>出库单编号:</label>
<input
v-model="formData.deliveryNo"
class="form-input"
placeholder="请输入出库单编号"
/>
</div>
<div class="form-item">
<label class="required">经销商编码:</label>
<input
v-model="formData.dealerCode"
class="form-input"
placeholder="请输入经销商编码"
required
/>
</div>
</div>
<div class="form-row">
<div class="form-item">
<label class="required">经销商名称:</label>
<input
v-model="formData.dealerName"
class="form-input"
placeholder="请输入经销商名称"
required
/>
</div>
</div>
<div class="form-row">
<div class="form-item">
<label class="required">开票日期:</label>
<input
v-model="formData.invoiceDate"
class="form-input"
type="date
time-local
"
type="date"
required
/>
</div>
...
...
@@ -221,7 +252,8 @@
class="form-input"
type="number"
step="0.01"
placeholder="请输入开票金额"
placeholder="开票金额(自动计算)"
readonly
required
/>
</div>
...
...
@@ -235,6 +267,7 @@
type="number"
step="0.01"
placeholder="请输入税率"
@input="calculateTaxAmount"
/>
</div>
<div class="form-item">
...
...
@@ -244,10 +277,84 @@
class="form-input"
type="number"
step="0.01"
placeholder="请输入税额"
placeholder="税额(自动计算)"
readonly
/>
</div>
</div>
<!-- 发票明细信息 -->
<div class="form-section">
<div class="section-header">
<h4>发票明细</h4>
<button type="button" @click="addInvoiceItem" class="add-item-btn">+ 添加明细</button>
</div>
<div class="invoice-items-container">
<div v-for="(item, index) in formData.invoiceItems" :key="index" class="invoice-item">
<div class="item-row-single">
<div class="form-item" style="flex: 0 0 120px;">
<label>产品编码:</label>
<input
v-model="item.productCode"
class="form-input"
placeholder="产品编码"
/>
</div>
<div class="form-item" style="flex: 1 1 200px; min-width: 150px;">
<label>产品名称:</label>
<input
v-model="item.productName"
class="form-input"
placeholder="产品名称"
/>
</div>
<div class="form-item" style="flex: 0 0 80px;">
<label>数量:</label>
<input
v-model.number="item.productQty"
class="form-input"
type="number"
@input="calculateInvoiceItemTotal(item)"
/>
</div>
<div class="form-item" style="flex: 0 0 100px;">
<label>单价:</label>
<input
v-model.number="item.unitPrice"
class="form-input"
type="number"
step="0.01"
@input="calculateInvoiceItemTotal(item)"
/>
</div>
<div class="form-item" style="flex: 0 0 100px;">
<label>金额:</label>
<input
v-model.number="item.itemAmount"
class="form-input"
type="number"
step="0.01"
readonly
/>
</div>
<div class="form-item" style="flex: 0 0 100px;">
<label>税额:</label>
<input
v-model.number="item.taxAmount"
class="form-input"
type="number"
step="0.01"
readonly
/>
</div>
<div class="form-item" style="flex: 0 0 60px;">
<button type="button" @click="removeInvoiceItem(index)" class="remove-item-btn">删除</button>
</div>
</div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-item full-width">
<label>备注:</label>
...
...
@@ -321,11 +428,11 @@
</div>
<div class="detail-item">
<label>税率:</label>
<span>{{ invoiceDetail.taxRate ?
(invoiceDetail.taxRate * 100).toFixed(2)
+ '%' : '-' }}</span>
<span>{{ invoiceDetail.taxRate ?
invoiceDetail.taxRate
+ '%' : '-' }}</span>
</div>
<div class="detail-item">
<label>税额:</label>
<span class="amount-text">{{ formatCurrency((invoiceDetail.totalAmount || 0) * (invoiceDetail.taxRate || 0)) }}</span>
<span class="amount-text">{{ formatCurrency((invoiceDetail.totalAmount || 0) * (invoiceDetail.taxRate || 0)
/ 100
) }}</span>
</div>
<div class="detail-item">
<label>数据来源:</label>
...
...
@@ -363,22 +470,22 @@
</tr>
</thead>
<tbody>
<tr v-for="item in invoiceDetail.invoiceItems" :key="item.itemId">
<tr v-for="item in invoiceDetail.invoiceItems" :key="item.i
nvoiceI
temId">
<td>{{ item.productCode }}</td>
<td>{{ item.productName }}</td>
<td>{{ item.
product
Qty }}</td>
<td>{{ formatCurrency(item.unitPrice) }}</td>
<td class="amount-text">{{ formatCurrency(item.
itemAmount
) }}</td>
<td>{{ i
tem.taxRate ? (item.taxRate *
100).toFixed(2) + '%' : '-' }}</td>
<td>{{ item.
invoice
Qty }}</td>
<td>{{ formatCurrency(item.unitPrice
NoTax
) }}</td>
<td class="amount-text">{{ formatCurrency(item.
amountNoTax
) }}</td>
<td>{{ i
nvoiceDetail.taxRate ? (invoiceDetail.taxRate /
100).toFixed(2) + '%' : '-' }}</td>
<td class="amount-text">{{ formatCurrency(item.taxAmount || 0) }}</td>
</tr>
</tbody>
<tfoot>
<tr class="total-row">
<td colspan="4" class="total-label">合计:</td>
<td class="amount-text total-amount">{{ formatCurrency(invoiceDetail.
totalAmount
) }}</td>
<td class="amount-text total-amount">{{ formatCurrency(invoiceDetail.
invoiceItems.reduce((sum, item) => sum + (item.amountNoTax || 0), 0)
) }}</td>
<td>-</td>
<td class="amount-text total-amount">{{ formatCurrency(
(invoiceDetail.totalAmount || 0) * (invoiceDetail.taxRate ||
0)) }}</td>
<td class="amount-text total-amount">{{ formatCurrency(
invoiceDetail.invoiceItems.reduce((sum, item) => sum + (item.taxAmount || 0),
0)) }}</td>
</tr>
</tfoot>
</table>
...
...
@@ -445,13 +552,18 @@ const totalPages = computed(() => Math.ceil(pagination.total / pagination.pageSi
// 表单数据
const formData = reactive({
invoiceId: 0,
orderNo: '',
invoiceNo: '',
deliveryNo: '',
dealerCode: '',
dealerName: '',
invoiceDate: '',
invoiceAmount: 0,
taxRate: 0,
taxAmount: 0,
remark: ''
remark: '',
invoiceItems: [] as any[]
})
// 状态相关方法
...
...
@@ -550,29 +662,148 @@ const handleReset = () => {
const handleAdd = () => {
isEdit.value = false
Object.assign(formData, {
invoiceId: 0,
orderNo: '',
invoiceNo: '',
deliveryNo: '',
dealerCode: '',
dealerName: '',
invoiceDate: '',
invoiceAmount: 0,
taxRate: 0,
taxAmount: 0,
remark: ''
remark: '',
invoiceItems: []
})
showDialog.value = true
}
const handleEdit = (order: InvoiceInfo) => {
isEdit.value = true
Object.assign(formData, {
orderNo: order.orderNo,
invoiceNo: order.invoiceNo,
invoiceDate: order.invoiceDate,
invoiceAmount: order.totalAmount,
taxRate: 0,
taxAmount: 0,
remark: ''
// 发票明细相关方法
const addInvoiceItem = () => {
const newItem = {
productCode: '',
productName: '',
productQty: 1,
unitPrice: 0,
itemAmount: 0,
taxAmount: 0
}
formData.invoiceItems.push(newItem)
// 计算新明细项目的金额
calculateInvoiceItemTotal(newItem)
}
const removeInvoiceItem = (index: number) => {
formData.invoiceItems.splice(index, 1)
// 删除明细项目后,重新计算开票金额和税额
calculateTaxAmount()
}
const calculateInvoiceItemTotal = (item: any) => {
if (item.productQty && item.unitPrice) {
item.itemAmount = parseFloat((item.productQty * item.unitPrice).toFixed(2))
}
// 明细项目变化时,重新计算开票金额和税额
calculateTaxAmount()
}
const calculateTaxAmount = () => {
// 计算开票金额(基于明细项目的金额总和)
const totalAmount = formData.invoiceItems.reduce((sum, item) => {
return sum + (item.itemAmount || 0)
}, 0)
console.log('计算开票金额:', {
invoiceItems: formData.invoiceItems,
totalAmount: totalAmount,
taxRate: formData.taxRate
})
// 更新开票金额(保留两位小数)
formData.invoiceAmount = parseFloat(totalAmount.toFixed(2))
// 计算税额(基于主表税率)
if (totalAmount && formData.taxRate) {
formData.taxAmount = parseFloat((totalAmount * formData.taxRate / 100).toFixed(2))
// 更新明细项目的税额(基于主表税率)
formData.invoiceItems.forEach(item => {
if (item.itemAmount && formData.taxRate) {
item.taxAmount = parseFloat((item.itemAmount * formData.taxRate / 100).toFixed(2))
} else {
item.taxAmount = 0
}
})
} else {
formData.taxAmount = 0
// 清空明细项目的税额
formData.invoiceItems.forEach(item => {
item.taxAmount = 0
})
}
console.log('计算结果:', {
invoiceAmount: formData.invoiceAmount,
taxAmount: formData.taxAmount
})
showDialog.value = true
}
const handleEdit = async (order: InvoiceInfo) => {
try {
// 调用详情API获取最新的发票信息
const response = await invoiceApi.getInvoiceDetail(order.invoiceId) as any
console.log('发票编辑详情API响应:', response)
if (response && response.invoiceId) {
isEdit.value = true
Object.assign(formData, {
invoiceId: response.invoiceId,
orderNo: response.orderNo,
invoiceNo: response.invoiceNo,
deliveryNo: response.deliveryNo || '',
dealerCode: response.dealerCode,
dealerName: response.dealerName,
invoiceDate: response.invoiceDate,
invoiceAmount: response.totalAmount,
taxRate: response.taxRate || 0,
taxAmount: (response.totalAmount || 0) * (response.taxRate || 0) / 100,
remark: '',
invoiceItems: (response.invoiceItems || []).map((item: any) => ({
invoiceItemId: item.invoiceItemId,
invoiceId: item.invoiceId,
invoiceNo: item.invoiceNo,
orderNo: item.orderNo,
productCode: item.productCode,
productName: item.productName,
productQty: item.invoiceQty, // 映射字段名
unitPrice: item.unitPriceNoTax, // 映射字段名
itemAmount: item.amountNoTax, // 映射字段名
taxAmount: item.taxAmount
}))
})
// 确保税额计算正确
calculateTaxAmount()
showDialog.value = true
} else {
showMessage('获取发票详情失败', 'error')
}
} catch (error) {
console.error('获取发票详情失败:', error)
showMessage('获取发票详情失败, 请重试', 'error')
}
}
const handleDelete = async (order: InvoiceInfo) => {
if (confirm(`确定要删除发票"${order.invoiceNo}"吗?`)) {
try {
await invoiceApi.deleteInvoice(order.invoiceId)
showMessage('删除发票成功', 'success')
fetchOrders() // 刷新列表
} catch (error) {
console.error('删除发票失败:', error)
showMessage('删除发票失败, 请重试', 'error')
}
}
}
const handleView = async (order: InvoiceInfo) => {
...
...
@@ -606,8 +837,85 @@ const handlePrintInvoice = (invoice: InvoiceInfo) => {
const handleSubmit = async () => {
try {
showMessage('发票保存功能开发中...', 'warning')
// 验证必填字段
if (!formData.orderNo || !formData.invoiceNo || !formData.dealerCode || !formData.dealerName || !formData.invoiceDate || !formData.invoiceAmount) {
showMessage('请填写所有必填字段', 'error')
return
}
// 验证明细
if (!formData.invoiceItems || formData.invoiceItems.length === 0) {
showMessage('请至少添加一个发票明细', 'error')
return
}
// 验证明细字段
for (let i = 0; i < formData.invoiceItems.length; i++) {
const item = formData.invoiceItems[i]
if (!item.productCode || !item.productName || !item.productQty || !item.unitPrice) {
showMessage(`请填写第${i + 1}个明细的所有必填字段`, 'error')
return
}
}
if (isEdit.value) {
// 编辑发票
const updateData = {
invoiceId: formData.invoiceId,
invoiceNo: formData.invoiceNo,
orderNo: formData.orderNo,
deliveryNo: formData.deliveryNo,
dealerCode: formData.dealerCode,
dealerName: formData.dealerName,
totalAmount: formData.invoiceAmount,
invoiceDate: formData.invoiceDate,
invoiceStatus: 1,
taxRate: formData.taxRate,
dataSource: 'ERP系统',
invoiceItems: formData.invoiceItems.map((item: any) => ({
itemId: item.invoiceItemId,
productCode: item.productCode,
productName: item.productName,
invoiceQty: item.productQty, // 映射字段名
unitPriceNoTax: item.unitPrice, // 映射字段名
amountNoTax: item.itemAmount, // 映射字段名
taxRate: item.taxRate,
taxAmount: item.taxAmount
}))
}
await invoiceApi.updateInvoice(updateData)
showMessage('发票更新成功', 'success')
} else {
// 新增发票
const addData = {
invoiceNo: formData.invoiceNo,
orderNo: formData.orderNo,
deliveryNo: formData.deliveryNo,
dealerCode: formData.dealerCode,
dealerName: formData.dealerName,
totalAmount: formData.invoiceAmount,
invoiceDate: formData.invoiceDate,
invoiceStatus: 1,
taxRate: formData.taxRate,
dataSource: 'ERP系统',
invoiceItems: formData.invoiceItems.map((item: any) => ({
productCode: item.productCode,
productName: item.productName,
invoiceQty: item.productQty, // 映射字段名
unitPriceNoTax: item.unitPrice, // 映射字段名
amountNoTax: item.itemAmount, // 映射字段名
taxRate: item.taxRate,
taxAmount: item.taxAmount
}))
}
await invoiceApi.addInvoice(addData)
showMessage('发票新增成功', 'success')
}
closeDialog()
fetchOrders() // 刷新列表
} catch (error) {
console.error('保存发票失败:', error)
showMessage('保存发票失败, 请重试', 'error')
...
...
@@ -883,6 +1191,19 @@ onMounted(() => {
color: #333;
}
.delete-btn {
background: #dc3545;
color: white;
}
/* 只读字段样式 */
.form-input[readonly] {
background-color: #f8f9fa;
color: #6c757d;
cursor: not-allowed;
border-color: #dee2e6;
}
.status-btn {
background: #28a745;
color: white;
...
...
@@ -1310,4 +1631,101 @@ onMounted(() => {
.detail-actions .close-btn:hover {
background: #5a6268;
}
/* 发票明细样式 */
.form-section {
margin: 20px 0;
border: 1px solid #e0e0e0;
border-radius: 6px;
padding: 15px;
background: #f9f9f9;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #ddd;
}
.section-header h4 {
margin: 0;
color: #333;
font-size: 16px;
font-weight: 600;
}
.add-item-btn {
background: #28a745;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
transition: background 0.2s;
}
.add-item-btn:hover {
background: #218838;
}
.invoice-items-container {
max-height: 300px;
overflow-y: auto;
}
.invoice-item {
background: white;
border: 1px solid #ddd;
border-radius: 4px;
padding: 10px;
margin-bottom: 10px;
}
.item-row-single {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: nowrap;
}
.item-row-single .form-item {
flex: 0 0 auto;
margin-bottom: 0;
min-width: 0;
}
.item-row-single .form-item label {
font-size: 11px;
color: #666;
margin-bottom: 2px;
display: block;
}
.item-row-single .form-input {
width: 100%;
padding: 4px 6px;
font-size: 11px;
border: 1px solid #ddd;
border-radius: 3px;
}
.remove-item-btn {
background: #dc3545;
color: white;
border: none;
padding: 4px 8px;
border-radius: 3px;
cursor: pointer;
font-size: 11px;
height: 28px;
transition: background 0.2s;
}
.remove-item-btn:hover {
background: #c82333;
}
</style>
...
...
Please
register
or
login
to post a comment