fix: 李红攀:V2.0.063,其它入库、其它出库扫码功能

This commit is contained in:
2026-05-26 17:52:56 +08:00
parent e750894e01
commit f43a490d6d
8 changed files with 2050 additions and 641 deletions

View File

@@ -0,0 +1,149 @@
<template>
<view class="recent-scan-list">
<view v-if="records.length === 0" class="recent-scan-list__empty">
暂无扫码记录开始扫码入库
</view>
<view
v-for="(record, index) in records"
:key="record.id || index"
class="scan-card"
:class="{ 'scan-card--latest': latestIndex === index }"
>
<view class="scan-card__header">
<text class="scan-card__name">{{ record.productName || '-' }}</text>
<text class="scan-card__delete" @tap="emit('delete', index)">删除</text>
</view>
<view class="scan-card__meta">
<text>条码{{ record.productBarCode || '-' }}</text>
<text>规格{{ record.productSpec || '-' }}</text>
</view>
<view class="scan-card__meta">
<text>仓库{{ record.warehouseName || '-' }}</text>
<text>单位{{ record.productUnit || '-' }}</text>
</view>
<view class="scan-card__meta">
<text>库位{{ record.locationCode || '-' }}</text>
<text>批次{{ record.batchNo || '-' }}</text>
</view>
<view class="scan-card__footer">
<view class="scan-card__count-control">
<text class="scan-card__count-btn" @tap="emit('decrease', index)">-</text>
<text class="scan-card__count">{{ record.scanCount }}</text>
<text class="scan-card__count-btn" @tap="emit('increase', index)">+</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import type { ScanRecord } from '../index.vue'
defineProps<{
records: ScanRecord[]
latestIndex?: number
}>()
const emit = defineEmits<{
(event: 'delete', index: number): void
(event: 'increase', index: number): void
(event: 'decrease', index: number): void
(event: 'clear'): void
}>()
</script>
<style lang="scss" scoped>
.recent-scan-list {
&__empty {
padding: 48rpx;
border-radius: 16rpx;
background: #fff;
color: #86909c;
text-align: center;
font-size: 26rpx;
}
}
.scan-card {
margin-bottom: 16rpx;
padding: 24rpx;
border: 2rpx solid transparent;
border-radius: 16rpx;
background: #fff;
&--latest {
border-color: #1677ff;
box-shadow: 0 8rpx 20rpx rgba(22, 119, 255, 0.12);
}
&__header,
&__meta,
&__footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16rpx;
}
&__header {
margin-bottom: 10rpx;
}
&__name {
color: #1f2329;
font-size: 28rpx;
font-weight: 600;
}
&__delete {
flex-shrink: 0;
color: #f53f3f;
font-size: 24rpx;
}
&__meta {
margin-top: 6rpx;
color: #4e5969;
font-size: 22rpx;
flex-wrap: wrap;
}
&__footer {
margin-top: 10rpx;
padding-top: 10rpx;
border-top: 2rpx solid #f2f3f5;
justify-content: flex-end;
}
&__count-control {
display: flex;
align-items: center;
gap: 16rpx;
}
&__count-btn {
width: 56rpx;
height: 56rpx;
line-height: 56rpx;
text-align: center;
border-radius: 12rpx;
background: #f2f3f5;
color: #1d2129;
font-size: 32rpx;
}
&__count {
min-width: 72rpx;
height: 56rpx;
line-height: 56rpx;
text-align: center;
border-radius: 12rpx;
background: #fff7e8;
color: #1677ff;
font-size: 28rpx;
font-weight: 700;
}
}
</style>

View File

@@ -0,0 +1,68 @@
<template>
<view class="scan-context-bar">
<view class="scan-context-bar__main">
<view class="scan-context-bar__warehouse">
<text class="scan-context-bar__label">仓库</text>
<text class="scan-context-bar__value">{{ warehouseName || '未选择仓库' }}</text>
</view>
<view class="scan-context-bar__stats">
<text>明细 {{ recordCount }} </text>
<text>累计 {{ scannedCount }} </text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
defineProps<{
warehouseName?: string
scannedCount: number
recordCount: number
}>()
</script>
<style lang="scss" scoped>
.scan-context-bar {
padding: 20rpx 24rpx;
border-radius: 16rpx;
background: #fff;
margin-bottom: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
&__main {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16rpx;
}
&__warehouse {
display: flex;
align-items: center;
gap: 12rpx;
min-width: 0;
flex: 1;
}
&__label {
flex-shrink: 0;
color: #86909c;
font-size: 24rpx;
}
&__value {
color: #1f2329;
font-size: 28rpx;
font-weight: 600;
}
&__stats {
display: flex;
gap: 20rpx;
flex-shrink: 0;
color: #1677ff;
font-size: 24rpx;
font-weight: 600;
}
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<view v-if="message" class="feedback-bar" :class="`feedback-bar--${tone}`">
{{ message }}
</view>
</template>
<script setup lang="ts">
withDefaults(
defineProps<{
tone?: 'success' | 'error' | 'idle'
message?: string
}>(),
{
tone: 'idle',
message: '',
},
)
</script>
<style lang="scss" scoped>
.feedback-bar {
min-height: 76rpx;
padding: 18rpx 24rpx;
border-radius: 14rpx;
font-size: 24rpx;
line-height: 40rpx;
&--idle {
background: #f2f3f5;
color: #4e5969;
}
&--success {
background: #f6ffed;
color: #389e0d;
}
&--error {
background: #fff2f0;
color: #cf1322;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
<template>
<view class="recent-scan-list">
<view v-if="records.length === 0" class="recent-scan-list__empty">
暂无扫码记录开始扫码出库
</view>
<view
v-for="(record, index) in records"
:key="record.id || index"
class="scan-card"
:class="{ 'scan-card--latest': latestIndex === index }"
>
<view class="scan-card__header">
<text class="scan-card__name">{{ record.productName || '-' }}</text>
<text class="scan-card__delete" @tap="emit('delete', index)">删除</text>
</view>
<view class="scan-card__meta">
<text>条码{{ record.productBarCode || '-' }}</text>
<text>规格{{ record.productSpec || '-' }}</text>
</view>
<view class="scan-card__meta">
<text>仓库{{ record.warehouseName || '-' }}</text>
<text>单位{{ record.productUnit || '-' }}</text>
</view>
<view class="scan-card__meta">
<text>库位{{ record.locationCode || '-' }}</text>
<text>库存{{ record.stockCount ?? '-' }}</text>
</view>
<view class="scan-card__footer">
<view class="scan-card__stock-hint" v-if="record.stockCount !== undefined">
剩余 {{ Math.max((record.stockCount || 0) - record.scanCount, 0) }}
</view>
<view class="scan-card__count-control">
<text class="scan-card__count-btn" @tap="emit('decrease', index)">-</text>
<text class="scan-card__count">{{ record.scanCount }}</text>
<text class="scan-card__count-btn" @tap="emit('increase', index)">+</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import type { ScanRecord } from '../index.vue'
defineProps<{
records: ScanRecord[]
latestIndex?: number
}>()
const emit = defineEmits<{
(event: 'delete', index: number): void
(event: 'increase', index: number): void
(event: 'decrease', index: number): void
(event: 'clear'): void
}>()
</script>
<style lang="scss" scoped>
.recent-scan-list {
&__empty {
padding: 48rpx;
border-radius: 16rpx;
background: #fff;
color: #86909c;
text-align: center;
font-size: 26rpx;
}
}
.scan-card {
margin-bottom: 16rpx;
padding: 24rpx;
border: 2rpx solid transparent;
border-radius: 16rpx;
background: #fff;
&--latest {
border-color: #fa8c16;
box-shadow: 0 8rpx 20rpx rgba(250, 140, 22, 0.12);
}
&__header,
&__meta,
&__footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16rpx;
}
&__header {
margin-bottom: 10rpx;
}
&__name {
color: #1f2329;
font-size: 28rpx;
font-weight: 600;
}
&__delete {
flex-shrink: 0;
color: #f53f3f;
font-size: 24rpx;
}
&__meta {
margin-top: 6rpx;
color: #4e5969;
font-size: 22rpx;
flex-wrap: wrap;
}
&__footer {
margin-top: 10rpx;
padding-top: 10rpx;
border-top: 2rpx solid #f2f3f5;
}
&__stock-hint {
color: #86909c;
font-size: 22rpx;
}
&__count-control {
display: flex;
align-items: center;
gap: 16rpx;
}
&__count-btn {
width: 56rpx;
height: 56rpx;
line-height: 56rpx;
text-align: center;
border-radius: 12rpx;
background: #f2f3f5;
color: #1d2129;
font-size: 32rpx;
}
&__count {
min-width: 72rpx;
height: 56rpx;
line-height: 56rpx;
text-align: center;
border-radius: 12rpx;
background: #fff7e8;
color: #fa8c16;
font-size: 28rpx;
font-weight: 700;
}
}
</style>

View File

@@ -0,0 +1,68 @@
<template>
<view class="scan-context-bar">
<view class="scan-context-bar__main">
<view class="scan-context-bar__warehouse">
<text class="scan-context-bar__label">仓库</text>
<text class="scan-context-bar__value">{{ warehouseName || '未选择仓库' }}</text>
</view>
<view class="scan-context-bar__stats">
<text>明细 {{ recordCount }} </text>
<text>累计 {{ scannedCount }} </text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
defineProps<{
warehouseName?: string
scannedCount: number
recordCount: number
}>()
</script>
<style lang="scss" scoped>
.scan-context-bar {
padding: 20rpx 24rpx;
border-radius: 16rpx;
background: #fff;
margin-bottom: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
&__main {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16rpx;
}
&__warehouse {
display: flex;
align-items: center;
gap: 12rpx;
min-width: 0;
flex: 1;
}
&__label {
flex-shrink: 0;
color: #86909c;
font-size: 24rpx;
}
&__value {
color: #1f2329;
font-size: 28rpx;
font-weight: 600;
}
&__stats {
display: flex;
gap: 20rpx;
flex-shrink: 0;
color: #fa8c16;
font-size: 24rpx;
font-weight: 600;
}
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<view v-if="message" class="feedback-bar" :class="`feedback-bar--${tone}`">
{{ message }}
</view>
</template>
<script setup lang="ts">
withDefaults(
defineProps<{
tone?: 'success' | 'error' | 'idle'
message?: string
}>(),
{
tone: 'idle',
message: '',
},
)
</script>
<style lang="scss" scoped>
.feedback-bar {
min-height: 76rpx;
padding: 18rpx 24rpx;
border-radius: 14rpx;
font-size: 24rpx;
line-height: 40rpx;
&--idle {
background: #f2f3f5;
color: #4e5969;
}
&--success {
background: #f6ffed;
color: #389e0d;
}
&--error {
background: #fff2f0;
color: #cf1322;
}
}
</style>

File diff suppressed because it is too large Load Diff