feat: 商品添加克重字段,订单添加通道费,运费按重量计算
- 商品模型: 添加weight字段(克重) - 订单模型: 添加channel_fee字段(支付通道费) - 后台商品管理: 添加克重输入框 - 后台订单详情: 显示通道费 - 订单创建: 根据商品重量计算运费,添加通道费计算 - 购物车: 根据商品重量计算运费,显示通道费 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,10 @@
|
||||
<span>税费</span>
|
||||
<span>¥{{ (currentOrder.tax || 0).toFixed(2) }}</span>
|
||||
</div>
|
||||
<div class="fee-item" v-if="currentOrder.channel_fee > 0">
|
||||
<span>通道费</span>
|
||||
<span>¥{{ (currentOrder.channel_fee || 0).toFixed(2) }}</span>
|
||||
</div>
|
||||
<div class="fee-item total">
|
||||
<span>合计</span>
|
||||
<span class="total-amount">¥{{ (currentOrder.total_amount || 0).toFixed(2) }}</span>
|
||||
|
||||
@@ -80,17 +80,22 @@
|
||||
<div class="form-section">
|
||||
<div class="section-title">价格库存</div>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="价格" required>
|
||||
<el-input-number v-model="form.price" :precision="2" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="库存">
|
||||
<el-input-number v-model="form.stock" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="克重(克)">
|
||||
<el-input-number v-model="form.weight" :precision="1" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="上架">
|
||||
<el-switch v-model="form.is_active" />
|
||||
</el-form-item>
|
||||
@@ -188,6 +193,7 @@ const form = reactive({
|
||||
name: '',
|
||||
description: '',
|
||||
price: 0,
|
||||
weight: 0,
|
||||
stock: 0,
|
||||
min_purchase: 1,
|
||||
max_purchase: undefined as number | undefined,
|
||||
@@ -264,11 +270,11 @@ async function fetchBrands() {
|
||||
|
||||
function openAdd() {
|
||||
editing.value = null
|
||||
Object.assign(form, {
|
||||
name: '', description: '', price: 0, stock: 0,
|
||||
min_purchase: 1, max_purchase: undefined,
|
||||
require_credit: false, credit_cost: 0, credit_reward: 0,
|
||||
is_active: true, category_ids: [], brand_id: undefined
|
||||
Object.assign(form, {
|
||||
name: '', description: '', price: 0, weight: 0, stock: 0,
|
||||
min_purchase: 1, max_purchase: undefined,
|
||||
require_credit: false, credit_cost: 0, credit_reward: 0,
|
||||
is_active: true, category_ids: [], brand_id: undefined
|
||||
})
|
||||
fileList.value = []
|
||||
uploadedUrls.value = []
|
||||
@@ -281,6 +287,7 @@ function editProd(row: any) {
|
||||
name: row.name,
|
||||
description: row.description || '',
|
||||
price: row.price,
|
||||
weight: row.weight || 0,
|
||||
stock: row.stock || 0,
|
||||
min_purchase: row.min_purchase || 1,
|
||||
max_purchase: row.max_purchase,
|
||||
|
||||
@@ -209,7 +209,12 @@
|
||||
<span>税费 ({{ settings.tax_rate || 0 }}%)</span>
|
||||
<span>¥{{ taxFee.toFixed(2) }}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="summary-row" v-if="channelFee > 0">
|
||||
<span>通道费 ({{ settings.payment_channel_fee_rate || 0 }}%)</span>
|
||||
<span>¥{{ channelFee.toFixed(2) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="summary-divider"></div>
|
||||
|
||||
<div class="summary-row summary-total">
|
||||
@@ -334,11 +339,18 @@ const selectedQuantity = computed(() => {
|
||||
.reduce((sum, item) => sum + item.quantity, 0)
|
||||
})
|
||||
|
||||
// 计算选中商品的总重量
|
||||
const selectedWeight = computed(() => {
|
||||
return items.value
|
||||
.filter(item => selectedIds.value.includes(item.id))
|
||||
.reduce((sum, item) => sum + (item.product?.weight || 0) * item.quantity, 0)
|
||||
})
|
||||
|
||||
const shippingFee = computed(() => {
|
||||
const firstWeight = parseFloat(settings.value.shipping_fee_first_weight || '0')
|
||||
const perGram = parseFloat(settings.value.shipping_fee_per_gram || '0')
|
||||
if (selectedTotal.value >= 99 || firstWeight === 0) return 0
|
||||
return firstWeight + perGram * Math.max(0, selectedQuantity.value - 500)
|
||||
return firstWeight + perGram * Math.max(0, selectedWeight.value - 500)
|
||||
})
|
||||
|
||||
const serviceFee = computed(() => {
|
||||
@@ -351,8 +363,13 @@ const taxFee = computed(() => {
|
||||
return selectedTotal.value * rate / 100
|
||||
})
|
||||
|
||||
const channelFee = computed(() => {
|
||||
const rate = parseFloat(settings.value.payment_channel_fee_rate || '0')
|
||||
return selectedTotal.value * rate / 100
|
||||
})
|
||||
|
||||
const grandTotal = computed(() => {
|
||||
return selectedTotal.value + shippingFee.value + serviceFee.value + taxFee.value
|
||||
return selectedTotal.value + shippingFee.value + serviceFee.value + taxFee.value + channelFee.value
|
||||
})
|
||||
|
||||
const canCheckout = computed(() => {
|
||||
|
||||
Reference in New Issue
Block a user