Files
crm_uiapp/src/components/erp-scan/item-list.vue

158 lines
3.5 KiB
Vue
Raw Normal View History

<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>