|
|
@@ -15,12 +15,8 @@
|
|
|
<text class="order-banner-text">补货单 {{ orderNo }}</text>
|
|
|
</view>
|
|
|
|
|
|
- <view class="device-card">
|
|
|
- <view class="device-icon"></view>
|
|
|
- <view class="device-info">
|
|
|
- <text class="device-name">{{ deviceInfo.deviceId }} - {{ deviceInfo.name || '' }}</text>
|
|
|
- <text class="device-addr" v-if="deviceInfo.address">{{ deviceInfo.address }}</text>
|
|
|
- </view>
|
|
|
+ <view class="device-bar">
|
|
|
+ <text class="device-bar-text">{{ deviceInfo.deviceId }}<text v-if="deviceInfo.name"> · {{ deviceInfo.name }}</text></text>
|
|
|
</view>
|
|
|
|
|
|
<view class="inventory-section">
|
|
|
@@ -38,35 +34,28 @@
|
|
|
</view>
|
|
|
|
|
|
<view class="inventory-card" v-for="(item, index) in inventoryList" :key="index" v-show="!showOrderOnly || isInOrder(item)">
|
|
|
- <view class="item-top">
|
|
|
+ <view class="item-row">
|
|
|
<image v-if="item.product_image" :src="item.product_image" class="item-img" mode="aspectFill" />
|
|
|
<view v-else class="item-img-placeholder"><text>无图</text></view>
|
|
|
<view class="item-info">
|
|
|
- <text class="item-name">{{ item.product_name || item.productName || '未知商品' }}</text>
|
|
|
- <text class="item-code" v-if="item.product_code || item.productCode">{{ item.product_code || item.productCode }}</text>
|
|
|
- </view>
|
|
|
- <view class="stock-badge" :class="getStockStatus(item)">{{ getStockStatusText(item) }}</view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <view class="item-stock">
|
|
|
- <view class="stock-col">
|
|
|
- <text class="stock-label">标准库存</text>
|
|
|
- <text class="stock-num">{{ item.standard_stock || item.standardStock || '-' }}</text>
|
|
|
- </view>
|
|
|
- <view class="stock-col">
|
|
|
- <text class="stock-label">剩余库存</text>
|
|
|
- <text class="stock-num" :class="{ warn: isLowStock(item), danger: isOutOfStock(item) }">{{ item.stock || 0 }}</text>
|
|
|
+ <view class="item-name-row">
|
|
|
+ <text class="item-name">{{ item.product_name || item.productName || '未知商品' }}</text>
|
|
|
+ <view class="stock-badge" :class="getStockStatus(item)">{{ getStockStatusText(item) }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="item-meta">
|
|
|
+ <text class="item-code" v-if="item.product_code || item.productCode">{{ item.product_code || item.productCode }}</text>
|
|
|
+ <text class="item-std">标准 {{ item.standard_stock || item.standardStock || '-' }}</text>
|
|
|
+ <text class="item-cur" :class="{ warn: isLowStock(item), danger: isOutOfStock(item) }">剩余 {{ item.stock || 0 }}</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
<view class="replenish-row">
|
|
|
- <text class="replenish-label">补货数量</text>
|
|
|
<view class="qty-control">
|
|
|
<view class="qty-btn" @click="decrease(item, index)"><text>-</text></view>
|
|
|
<input class="qty-input" type="number" v-model="replenishItems[index].quantity" @blur="validateQuantity(index)" />
|
|
|
<view class="qty-btn" @click="increase(item, index)"><text>+</text></view>
|
|
|
</view>
|
|
|
- <view class="fill-btn" @click="suggestQuantity(item, index)"><text>一键补满</text></view>
|
|
|
+ <view class="fill-btn" @click="suggestQuantity(item, index)"><text>补满</text></view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -143,7 +132,7 @@ const getStockStatusText = (item: any) => (item.stock || 0) === 0 ? '缺货' : (
|
|
|
const decrease = (_: any, i: number) => { if (replenishItems.value[i].quantity > 0) replenishItems.value[i].quantity--; };
|
|
|
const increase = (_: any, i: number) => { if (replenishItems.value[i].quantity < 9999) replenishItems.value[i].quantity++; };
|
|
|
const suggestQuantity = (item: any, i: number) => {
|
|
|
- const std = item.warning_threshold || item.warningThreshold || 0;
|
|
|
+ const std = item.standard_stock || item.standardStock || 0;
|
|
|
const cur = item.stock || 0;
|
|
|
replenishItems.value[i].quantity = cur >= std ? 0 : std - cur;
|
|
|
};
|
|
|
@@ -343,36 +332,21 @@ onUnmounted(() => {
|
|
|
<style lang="scss" scoped>
|
|
|
.page { height: 100vh; background: $bg-color-page; display: flex; flex-direction: column; }
|
|
|
|
|
|
-.load-tip { display: flex; justify-content: center; padding: 200rpx 0; }
|
|
|
-.dot-row { display: flex; gap: $spacing-1; }
|
|
|
-.pulse-dot { width: 10rpx; height: 10rpx; background: $text-color-placeholder; border-radius: 50%; animation: pulse 1.2s ease-in-out infinite;
|
|
|
- &:nth-child(2) { animation-delay: 0.2s; } &:nth-child(3) { animation-delay: 0.4s; }
|
|
|
-}
|
|
|
-@keyframes pulse { 0%,80%,100% { transform: scale(0.5); opacity: 0.4; } 40% { transform: scale(1); opacity: 1; } }
|
|
|
-
|
|
|
-.order-selector { display: flex; align-items: center; gap: 12rpx; margin: $spacing-2 $spacing-3; padding: $spacing-2 $spacing-3; background: $primary-color-bg; border-radius: $radius-sm; }
|
|
|
+.order-selector { display: flex; align-items: center; gap: 12rpx; margin: 12rpx 24rpx; padding: 12rpx 20rpx; background: $primary-color-bg; border-radius: $radius-sm; }
|
|
|
.selector-label { font-size: $font-size-sm; color: $text-color-muted; flex-shrink: 0; }
|
|
|
-.selector-value { display: flex; align-items: center; gap: 6rpx; padding: 6rpx 16rpx; background: $bg-color-card; border-radius: $radius-sm; border: 1rpx solid $border-color;
|
|
|
+.selector-value { display: flex; align-items: center; gap: 6rpx; padding: 4rpx 14rpx; background: $bg-color-card; border-radius: $radius-sm; border: 1rpx solid $border-color;
|
|
|
text { font-size: $font-size-sm; color: $text-color-primary; font-weight: 500; }
|
|
|
}
|
|
|
.selector-arrow { font-size: 18rpx; color: $text-color-muted; }
|
|
|
.selector-status { font-size: 22rpx; color: $primary-color-dark; margin-left: auto; }
|
|
|
-.order-banner { margin: $spacing-2 $spacing-3; padding: $spacing-2 $spacing-3; background: $primary-color-bg; border-radius: $radius-sm; }
|
|
|
+.order-banner { margin: 12rpx 24rpx; padding: 14rpx 20rpx; background: $primary-color-bg; border-radius: $radius-sm; }
|
|
|
.order-banner-text { font-size: $font-size-sm; color: $primary-color-dark; }
|
|
|
|
|
|
-// ====== Device ======
|
|
|
-.device-card { display: flex; align-items: center; margin: 16rpx 24rpx; padding: $spacing-3; background: $bg-color-card; border-radius: $radius-md; box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05); }
|
|
|
-.device-icon { width: 48rpx; height: 48rpx; background: $success-color-bg; border-radius: $radius-base; margin-right: 16rpx; flex-shrink: 0; position: relative;
|
|
|
- &::before { content: ''; position: absolute; top: 8rpx; left: 50%; transform: translateX(-50%); width: 20rpx; height: 16rpx; border: 2.5rpx solid $success-color; border-radius: 4rpx; }
|
|
|
- &::after { content: ''; position: absolute; bottom: 4rpx; left: 50%; transform: translateX(-50%); width: 12rpx; height: 5rpx; background: $success-color; border-radius: 0 0 3rpx 3rpx; }
|
|
|
-}
|
|
|
-.device-info { flex: 1; min-width: 0; }
|
|
|
-.device-name { display: block; font-size: $font-size-md; font-weight: 600; color: $text-color-primary; }
|
|
|
-.device-addr { font-size: $font-size-sm; color: $text-color-muted; }
|
|
|
+.device-bar { margin: 12rpx 24rpx; padding: 16rpx 20rpx; background: $bg-color-card; border-radius: $radius-md; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); }
|
|
|
+.device-bar-text { font-size: $font-size-sm; font-weight: 600; color: $text-color-primary; }
|
|
|
|
|
|
-// ====== Inventory ======
|
|
|
.inventory-section { padding: 0 24rpx; flex: 1; height: 0; overflow-y: auto; }
|
|
|
-.section-head { display: flex; align-items: center; justify-content: space-between; padding: $spacing-3 0 $spacing-2; }
|
|
|
+.section-head { display: flex; align-items: center; justify-content: space-between; padding: 16rpx 0 12rpx; }
|
|
|
.section-title { font-size: $font-size-md; font-weight: 700; color: $text-color-primary; }
|
|
|
.order-toggle { display: flex; align-items: center; gap: 8rpx; }
|
|
|
.toggle-label { font-size: 20rpx; color: $text-color-muted; }
|
|
|
@@ -388,60 +362,57 @@ onUnmounted(() => {
|
|
|
}
|
|
|
.empty-text { font-size: $font-size-base; color: $text-color-muted; }
|
|
|
|
|
|
-.inventory-card { margin-bottom: 16rpx; padding: $spacing-3; background: $bg-color-card; border-radius: $radius-md; box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05); }
|
|
|
+.inventory-card { margin-bottom: 10rpx; padding: 16rpx; background: $bg-color-card; border-radius: $radius-md; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04); }
|
|
|
|
|
|
-.item-top { display: flex; align-items: center; margin-bottom: 12rpx; }
|
|
|
-.item-img { width: 72rpx; height: 72rpx; border-radius: $radius-sm; background: $bg-color-page; flex-shrink: 0; margin-right: 12rpx; }
|
|
|
-.item-img-placeholder { width: 72rpx; height: 72rpx; border-radius: $radius-sm; background: $bg-color-page; flex-shrink: 0; margin-right: 12rpx; display: flex; align-items: center; justify-content: center;
|
|
|
- text { font-size: 20rpx; color: $text-color-muted; }
|
|
|
+.item-row { display: flex; align-items: center; margin-bottom: 10rpx; }
|
|
|
+.item-img { width: 56rpx; height: 56rpx; border-radius: $radius-sm; background: $bg-color-page; flex-shrink: 0; margin-right: 12rpx; }
|
|
|
+.item-img-placeholder { width: 56rpx; height: 56rpx; border-radius: $radius-sm; background: $bg-color-page; flex-shrink: 0; margin-right: 12rpx; display: flex; align-items: center; justify-content: center;
|
|
|
+ text { font-size: 18rpx; color: $text-color-muted; }
|
|
|
}
|
|
|
.item-info { flex: 1; min-width: 0; overflow: hidden; }
|
|
|
-.item-name { display: block; font-size: $font-size-base; font-weight: 600; color: $text-color-primary; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
-.item-code { font-size: $font-size-xs; color: $text-color-muted; }
|
|
|
+.item-name-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4rpx; }
|
|
|
+.item-name { font-size: $font-size-base; font-weight: 600; color: $text-color-primary; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
|
|
|
+.item-meta { display: flex; gap: 16rpx; }
|
|
|
+.item-code { font-size: 20rpx; color: $text-color-muted; }
|
|
|
+.item-std { font-size: 20rpx; color: $text-color-muted; }
|
|
|
+.item-cur { font-size: 20rpx; font-weight: 500; color: $text-color-primary;
|
|
|
+ &.warn { color: $warning-color; }
|
|
|
+ &.danger { color: $error-color; }
|
|
|
+}
|
|
|
|
|
|
-.stock-badge { padding: 4rpx 12rpx; border-radius: $radius-sm; font-size: 22rpx; font-weight: 500; flex-shrink: 0; margin-left: 8rpx;
|
|
|
+.stock-badge { padding: 2rpx 10rpx; border-radius: $radius-sm; font-size: 20rpx; font-weight: 500; flex-shrink: 0; margin-left: 8rpx;
|
|
|
&.normal { background: $success-color-bg; color: $success-color; }
|
|
|
&.warning { background: $warning-color-bg; color: $warning-color; }
|
|
|
&.danger { background: $error-color-bg; color: $error-color; }
|
|
|
}
|
|
|
|
|
|
-.item-stock { display: flex; gap: 16rpx; margin-bottom: 12rpx; padding: 12rpx 0; background: $bg-color-page; border-radius: $radius-sm; }
|
|
|
-.stock-col { flex: 1; display: flex; flex-direction: column; align-items: center; }
|
|
|
-.stock-label { font-size: 22rpx; color: $text-color-muted; margin-bottom: 4rpx; }
|
|
|
-.stock-num { font-size: $font-size-lg; font-weight: 700; color: $text-color-primary;
|
|
|
- &.warn { color: $warning-color; }
|
|
|
- &.danger { color: $error-color; }
|
|
|
-}
|
|
|
-
|
|
|
-.replenish-row { display: flex; align-items: center; background: $bg-color-page; border-radius: $radius-base; padding: 12rpx 16rpx; }
|
|
|
-.replenish-label { font-size: $font-size-sm; color: $text-color-muted; margin-right: 12rpx; }
|
|
|
+.replenish-row { display: flex; align-items: center; background: $bg-color-page; border-radius: $radius-base; padding: 8rpx 12rpx; }
|
|
|
.qty-control { display: flex; align-items: center; border: 1rpx solid $border-color; border-radius: $radius-sm; overflow: hidden; }
|
|
|
-.qty-btn { width: 52rpx; height: 52rpx; display: flex; align-items: center; justify-content: center; background: $bg-color-card;
|
|
|
- text { font-size: 28rpx; color: $text-color-secondary; line-height: 1; }
|
|
|
+.qty-btn { width: 44rpx; height: 44rpx; display: flex; align-items: center; justify-content: center; background: $bg-color-card;
|
|
|
+ text { font-size: 26rpx; color: $text-color-secondary; line-height: 1; }
|
|
|
&:active { background: $bg-color-secondary; }
|
|
|
}
|
|
|
-.qty-input { width: 72rpx; height: 52rpx; text-align: center; font-size: $font-size-base; font-weight: 600; color: $text-color-primary; border-left: 1rpx solid $border-color; border-right: 1rpx solid $border-color; }
|
|
|
-.fill-btn { margin-left: auto; padding: 10rpx 24rpx; background: $success-color-bg; border-radius: $radius-sm;
|
|
|
+.qty-input { width: 64rpx; height: 44rpx; text-align: center; font-size: $font-size-base; font-weight: 600; color: $text-color-primary; border-left: 1rpx solid $border-color; border-right: 1rpx solid $border-color; }
|
|
|
+.fill-btn { margin-left: auto; padding: 8rpx 20rpx; background: $success-color-bg; border-radius: $radius-sm;
|
|
|
text { font-size: 22rpx; color: $success-color; font-weight: 500; }
|
|
|
&:active { opacity: 0.7; }
|
|
|
}
|
|
|
|
|
|
-// ====== Bottom ======
|
|
|
-.bottom-bar { display: flex; align-items: center; gap: 16rpx; padding: 20rpx 24rpx; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); background: $bg-color-card; border-top: 1rpx solid $border-color-light; }
|
|
|
+.bottom-bar { display: flex; align-items: center; gap: 12rpx; padding: 16rpx 24rpx; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); background: $bg-color-card; border-top: 1rpx solid $border-color-light; }
|
|
|
.total-label { font-size: $font-size-sm; color: $text-color-muted; flex-shrink: 0; }
|
|
|
.total-num { font-size: $font-size-xl; font-weight: 700; color: $primary-color-dark; margin: 0 4rpx; }
|
|
|
-.bottom-btn { flex: 1; height: 80rpx; display: flex; align-items: center; justify-content: center; border-radius: $radius-base;
|
|
|
- text { font-size: $font-size-md; font-weight: 600; line-height: 1; }
|
|
|
+.bottom-btn { flex: 1; height: 72rpx; display: flex; align-items: center; justify-content: center; border-radius: $radius-base;
|
|
|
+ text { font-size: $font-size-base; font-weight: 600; line-height: 1; }
|
|
|
&:active { opacity: 0.8; }
|
|
|
&.secondary { background: $bg-color-page; text { color: $text-color-secondary; } }
|
|
|
&.primary { background: $primary-color; text { color: $text-color-primary; } }
|
|
|
&.disabled { opacity: 0.5; pointer-events: none; }
|
|
|
}
|
|
|
-.submit-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 12rpx; height: 80rpx; background: $primary-color; border-radius: $radius-base;
|
|
|
+.submit-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 12rpx; height: 72rpx; background: $primary-color; border-radius: $radius-base;
|
|
|
text { font-size: $font-size-md; font-weight: 600; color: $text-color-primary; }
|
|
|
&:active { opacity: 0.8; }
|
|
|
&.disabled { opacity: 0.5; pointer-events: none; }
|
|
|
}
|
|
|
-.btn-spinner { width: 28rpx; height: 28rpx; border: 3rpx solid rgba(30, 41, 59, 0.2); border-top-color: $text-color-primary; border-radius: 50%; animation: spin 0.7s linear infinite; }
|
|
|
+.btn-spinner { width: 28rpx; height: 28rpx; border: 3rpx solid rgba(30,41,59,0.2); border-top-color: $text-color-primary; border-radius: 50%; animation: spin 0.7s linear infinite; }
|
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
|
</style>
|