|
|
@@ -125,16 +125,17 @@
|
|
|
v-for="(product, index) in productList"
|
|
|
:key="product.id"
|
|
|
:class="{ selected: isSelected(product) }"
|
|
|
+ :style="getRowStyle(product)"
|
|
|
@click="onProductSelect(product)"
|
|
|
class="clickable-row"
|
|
|
>
|
|
|
- <td
|
|
|
- v-if="isFirstInOwnerGroup(product, index)"
|
|
|
+ <td
|
|
|
+ v-if="shouldShowOwner(product, index)"
|
|
|
:rowspan="getOwnerRowspan(product, index)"
|
|
|
- class="owner-cell"
|
|
|
+ class="owner-cell"
|
|
|
style="width: 40px"
|
|
|
>
|
|
|
- {{ product.owner }}
|
|
|
+ {{ shouldShowOwnerText(product, index) ? product.owner : '' }}
|
|
|
</td>
|
|
|
<td class="location-cell">{{ product.location }}</td>
|
|
|
<td class="barcode-cell">{{ product.barcode }}</td>
|
|
|
@@ -144,6 +145,7 @@
|
|
|
<td class="checkbox-cell">
|
|
|
<van-checkbox
|
|
|
:model-value="isSelected(product)"
|
|
|
+ :disabled="product.quantityAvailable <= 0"
|
|
|
@update:model-value="onProductSelect(product)"
|
|
|
/>
|
|
|
</td>
|
|
|
@@ -162,8 +164,8 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted, onUnmounted, computed, nextTick } from 'vue'
|
|
|
-import { showConfirmDialog, showNotify, showToast } from 'vant'
|
|
|
+import { ref, onMounted, onUnmounted, nextTick } from 'vue'
|
|
|
+import { showConfirmDialog, showNotify } from 'vant'
|
|
|
import nodataUrl from '@/assets/nodata.png'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
import { useStore } from '@/store/modules/user'
|
|
|
@@ -254,7 +256,14 @@ const _handlerScan = (code) => {
|
|
|
return b.location.localeCompare(a.location)
|
|
|
})
|
|
|
productList.value = res.data
|
|
|
- onProductSelect(productList.value[0])
|
|
|
+ // 查找第一个可用数量大于0的商品进行选中
|
|
|
+ const firstAvailableProduct = productList.value.find(item => item.quantityAvailable > 0)
|
|
|
+ if (firstAvailableProduct) {
|
|
|
+ onProductSelect(firstAvailableProduct)
|
|
|
+ } else {
|
|
|
+ // 如果所有商品可用数量都为0,则不选择任何商品
|
|
|
+ selectedProducts.value = {}
|
|
|
+ }
|
|
|
// 数据加载完成后重新计算表格高度
|
|
|
setTimeout(() => {
|
|
|
calculateTableHeight()
|
|
|
@@ -289,7 +298,7 @@ const _handlerScan = (code) => {
|
|
|
}else if (scanType.value == 4) {
|
|
|
scanSuccess()
|
|
|
targetLocation.value = code
|
|
|
- tips.value = '请手动进行移库操作'
|
|
|
+ onConfirm()
|
|
|
}
|
|
|
targetLocationRef.value?.blur()
|
|
|
productBarcodeRef.value?.blur()
|
|
|
@@ -333,13 +342,13 @@ const onConfirm=()=>{
|
|
|
showConfirmDialog({
|
|
|
title: '移库确认',
|
|
|
message:
|
|
|
- `${productBarcode.value}从"${sourceLocation.value}"移动至"${targetLocation.value}"-${transferQuantity.value}件`
|
|
|
+ `${productBarcode.value}从"${sourceLocation.value}"移动至"${targetLocation.value}"共:${transferQuantity.value}件`
|
|
|
})
|
|
|
.then(() => {
|
|
|
- const {fmContainer,lotNumber,ownerCode,sku,location}=selectedProducts.value
|
|
|
+ const {traceId,lotNumber,ownerCode,sku}=selectedProducts.value
|
|
|
const data={
|
|
|
fmLocation:sourceLocation.value,
|
|
|
- fmContainer,
|
|
|
+ fmContainer:traceId,
|
|
|
owner:ownerCode,
|
|
|
sku,
|
|
|
lotNum:lotNumber,
|
|
|
@@ -348,7 +357,7 @@ const onConfirm=()=>{
|
|
|
toLocation:targetLocation.value
|
|
|
}
|
|
|
showLoading()
|
|
|
- inventoryMovement(data).then(res=>{
|
|
|
+ inventoryMovement(data).then(()=>{
|
|
|
closeLoading()
|
|
|
scanSuccess()
|
|
|
showNotify({ type: 'success', duration: 3000, message: `操作成功,请继续扫描商品条码` })
|
|
|
@@ -398,6 +407,11 @@ const calculateTableHeight = () => {
|
|
|
}
|
|
|
|
|
|
const onProductSelect = (product) => {
|
|
|
+ // 如果可用数量为0,则不允许选择
|
|
|
+ if (product.quantityAvailable <= 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
selectedProducts.value = product
|
|
|
// 选择商品时自动赋值移库数量
|
|
|
transferQuantity.value = product.quantityAvailable
|
|
|
@@ -411,6 +425,67 @@ const isSelected = (product) => {
|
|
|
return selectedProducts.value?.id === product.id
|
|
|
}
|
|
|
|
|
|
+// 根据 locationUsage 返回行样式
|
|
|
+const getRowStyle = (product) => {
|
|
|
+ const locationUsageColors = {
|
|
|
+ 'PC': 'white',
|
|
|
+ 'CS': 'white',
|
|
|
+ 'EA': 'white',
|
|
|
+ 'RS': 'rgb(255, 250, 250)', // Snow
|
|
|
+ 'ST': 'lightgray'
|
|
|
+ }
|
|
|
+
|
|
|
+ const backgroundColor = locationUsageColors[product.locationUsage] || 'white'
|
|
|
+
|
|
|
+ return {
|
|
|
+ backgroundColor
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 判断是否应该显示货主单元格(始终显示单元格)
|
|
|
+const shouldShowOwner = (product, index: number) => {
|
|
|
+ // 如果当前行被选中,则显示单元格
|
|
|
+ if (isSelected(product)) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查同一货主组中是否有选中的行
|
|
|
+ const sameOwnerProducts = productList.value.filter(p => p.owner === product.owner)
|
|
|
+ const hasSelectedInGroup = sameOwnerProducts.some(p => isSelected(p))
|
|
|
+
|
|
|
+ // 如果同一货主组中有选中的行,则其他未选中行显示空单元格
|
|
|
+ if (hasSelectedInGroup) {
|
|
|
+ // 检查当前行是否为未选中的连续组的第一行
|
|
|
+ if (index === 0 || productList.value[index - 1].owner !== product.owner || isSelected(productList.value[index - 1])) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果同一货主组中没有选中的行,则在第一行显示单元格
|
|
|
+ return isFirstInOwnerGroup(product, index)
|
|
|
+}
|
|
|
+
|
|
|
+// 判断是否应该显示货主文字
|
|
|
+const shouldShowOwnerText = (product, index: number) => {
|
|
|
+ // 如果当前行被选中,则显示文字
|
|
|
+ if (isSelected(product)) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查同一货主组中是否有选中的行
|
|
|
+ const sameOwnerProducts = productList.value.filter(p => p.owner === product.owner)
|
|
|
+ const hasSelectedInGroup = sameOwnerProducts.some(p => isSelected(p))
|
|
|
+
|
|
|
+ // 如果同一货主组中有选中的行,则其他未选中行不显示文字
|
|
|
+ if (hasSelectedInGroup) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果同一货主组中没有选中的行,则在第一行显示文字
|
|
|
+ return isFirstInOwnerGroup(product, index)
|
|
|
+}
|
|
|
+
|
|
|
// 检查是否为同一货主的第一行
|
|
|
const isFirstInOwnerGroup = (product, index: number) => {
|
|
|
if (index === 0) return true
|
|
|
@@ -419,6 +494,30 @@ const isFirstInOwnerGroup = (product, index: number) => {
|
|
|
|
|
|
// 计算相同货主的行跨度
|
|
|
const getOwnerRowspan = (product, index: number) => {
|
|
|
+ // 如果当前行被选中,rowspan为1
|
|
|
+ if (isSelected(product)) {
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查同一货主组中是否有选中的行
|
|
|
+ const sameOwnerProducts = productList.value.filter(p => p.owner === product.owner)
|
|
|
+ const hasSelectedInGroup = sameOwnerProducts.some(p => isSelected(p))
|
|
|
+
|
|
|
+ // 如果同一货主组中有选中的行,则计算未选中行的rowspan
|
|
|
+ if (hasSelectedInGroup) {
|
|
|
+ let rowspan = 1
|
|
|
+ // 向下查找连续的未选中的同货主行
|
|
|
+ for (let i = index + 1; i < productList.value.length; i++) {
|
|
|
+ if (productList.value[i].owner === product.owner && !isSelected(productList.value[i])) {
|
|
|
+ rowspan++
|
|
|
+ } else {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return rowspan
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算正常的rowspan(没有选中行的情况)
|
|
|
let rowspan = 1
|
|
|
for (let i = index + 1; i < productList.value.length; i++) {
|
|
|
if (productList.value[i].owner === product.owner) {
|
|
|
@@ -429,6 +528,7 @@ const getOwnerRowspan = (product, index: number) => {
|
|
|
}
|
|
|
return rowspan
|
|
|
}
|
|
|
+
|
|
|
// 数据刷新
|
|
|
const loadData = () => {
|
|
|
}
|
|
|
@@ -440,7 +540,7 @@ onUnmounted(() => {
|
|
|
}
|
|
|
window.removeEventListener('resize', calculateTableHeight)
|
|
|
})
|
|
|
-window.onRefresh = loadData
|
|
|
+// window.onRefresh = loadData
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
@@ -679,7 +779,7 @@ window.onRefresh = loadData
|
|
|
|
|
|
.header-table th:nth-child(2),
|
|
|
.body-table td:nth-child(2) {
|
|
|
- width: 15%;
|
|
|
+ width: 25%;
|
|
|
}
|
|
|
|
|
|
.header-table th:nth-child(3),
|
|
|
@@ -715,11 +815,9 @@ window.onRefresh = loadData
|
|
|
border-collapse: collapse;
|
|
|
}
|
|
|
|
|
|
-.product-table th{
|
|
|
- padding: 8px 0;
|
|
|
-}
|
|
|
+.product-table th,
|
|
|
.product-table td {
|
|
|
- padding:0;
|
|
|
+ padding: 8px 0;
|
|
|
text-align: center;
|
|
|
border-bottom: 1px solid #ebedf0;
|
|
|
font-size: 12px;
|
|
|
@@ -749,6 +847,12 @@ window.onRefresh = loadData
|
|
|
.checkbox-cell {
|
|
|
width: 25px;
|
|
|
}
|
|
|
-
|
|
|
+::v-deep(.checkbox-cell .van-checkbox){
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+::v-deep(.checkbox-cell .van-checkbox__icon){
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 50%;
|
|
|
+}
|
|
|
|
|
|
</style>
|