158 lines
3.5 KiB
Vue
158 lines
3.5 KiB
Vue
<template>
|
||
<view class="item-list">
|
||
<view v-if="items.length === 0" class="item-list__empty">
|
||
暂无扫码明细
|
||
</view>
|
||
<view v-for="(item, index) in items" :key="`${item.warehouseId}-${item.productId}-${index}`" class="item-card">
|
||
<view class="item-card__header">
|
||
<text class="item-card__name">{{ item.productName }}</text>
|
||
<text class="item-card__remove" @tap="emit('remove', index)">删除</text>
|
||
</view>
|
||
<view class="item-card__meta">
|
||
<text>仓库:{{ item.warehouseName || '-' }}</text>
|
||
<text>条码:{{ item.productBarCode || '-' }}</text>
|
||
</view>
|
||
<view class="item-card__meta">
|
||
<text>规格:{{ item.productSpec || '-' }}</text>
|
||
<text>单位:{{ item.productUnitName || '-' }}</text>
|
||
</view>
|
||
<view class="item-card__meta">
|
||
<text>单价:{{ formatNumber(item.productPrice) }}</text>
|
||
<text v-if="showStock">库存:{{ formatNumber(item.stockCount) }}</text>
|
||
</view>
|
||
<view class="item-card__footer">
|
||
<view class="counter">
|
||
<text class="counter__button" @tap="emit('decrease', index)">-</text>
|
||
<text class="counter__value">{{ formatNumber(item.count) }}</text>
|
||
<text class="counter__button" @tap="emit('increase', index)">+</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
export interface ItemCardValue {
|
||
warehouseId: number
|
||
warehouseName?: string
|
||
productId: number
|
||
productName: string
|
||
productBarCode?: string
|
||
productSpec?: string
|
||
productUnitName?: string
|
||
productPrice?: number
|
||
stockCount?: number
|
||
count: number
|
||
}
|
||
|
||
withDefaults(
|
||
defineProps<{
|
||
items: ItemCardValue[]
|
||
showStock?: boolean
|
||
}>(),
|
||
{
|
||
showStock: false,
|
||
},
|
||
)
|
||
|
||
const emit = defineEmits<{
|
||
(event: 'increase', index: number): void
|
||
(event: 'decrease', index: number): void
|
||
(event: 'remove', index: number): void
|
||
}>()
|
||
|
||
/**
|
||
* 功能说明:格式化数值展示,避免 `undefined` 直接透出到页面。
|
||
* 适用场景:数量、库存、单价展示。
|
||
* @param value 原始数值
|
||
* @return 格式化后的字符串
|
||
* 注意事项:扫码页优先保证可读性,这里只保留最多 4 位小数,不做复杂金额格式化。
|
||
*/
|
||
function formatNumber(value?: number) {
|
||
if (value === undefined || value === null) {
|
||
return '-'
|
||
}
|
||
|
||
return Number(value).toFixed(Number.isInteger(Number(value)) ? 0 : 4)
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.item-list__empty {
|
||
padding: 28rpx;
|
||
border-radius: 16rpx;
|
||
background: #fff;
|
||
color: #86909c;
|
||
text-align: center;
|
||
}
|
||
|
||
.item-card {
|
||
margin-bottom: 20rpx;
|
||
padding: 24rpx;
|
||
border-radius: 16rpx;
|
||
background: #fff;
|
||
|
||
&__header,
|
||
&__meta,
|
||
&__footer {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
&__header {
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
&__name {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
}
|
||
|
||
&__remove {
|
||
color: #f53f3f;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
&__meta {
|
||
margin-top: 8rpx;
|
||
color: #4e5969;
|
||
font-size: 24rpx;
|
||
gap: 16rpx;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
&__footer {
|
||
margin-top: 20rpx;
|
||
}
|
||
}
|
||
|
||
.counter {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 24rpx;
|
||
|
||
&__button,
|
||
&__value {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 64rpx;
|
||
height: 64rpx;
|
||
border-radius: 12rpx;
|
||
background: #f2f3f5;
|
||
}
|
||
|
||
&__button {
|
||
font-size: 36rpx;
|
||
color: #1d2129;
|
||
}
|
||
|
||
&__value {
|
||
min-width: 88rpx;
|
||
background: #fff7e8;
|
||
color: #ad6800;
|
||
}
|
||
}
|
||
</style>
|