BarcodeCombine.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <template>
  2. <div class="goods">
  3. <van-dialog v-model:show="goodsTrueFalseBy"
  4. :beforeClose="beforeClose"
  5. title="组合商品上架"
  6. show-cancel-button>
  7. <div style="width:100%;max-height:150px;overflow:auto">
  8. <div v-for="(item,index) in matchedSkuList" :key="index">
  9. <van-cell center :title="item.matchedJson.barcode" :label="item.matchedJson.skuName">
  10. <template #value>
  11. <div>{{ item.matchedJson.quantity }}件/套</div>
  12. <div class="goods-tips">待上架:{{ (item.expectedQuantity || 0) - (item.receivedQuantity || 0) }}件</div>
  13. </template>
  14. </van-cell>
  15. </div>
  16. </div>
  17. <div class="goods-number">可上架套数:{{ maxCount }}</div>
  18. <van-field label="上架套数" type="number" class="code-input" v-model="count" ref="countRef" placeholder="上架套数" />
  19. </van-dialog>
  20. </div>
  21. </template>
  22. <script setup>
  23. /** 组合商品上架弹框 */
  24. import { computed, ref } from 'vue'
  25. import { showToast } from 'vant'
  26. const goodsTrueFalseBy = ref(false)
  27. const countRef = ref(null)
  28. const count = ref('')
  29. const props = defineProps({
  30. matchedSku: { type: Array, default: () => [] },
  31. })
  32. const matchedSkuList = computed(() => props.matchedSku)
  33. const maxCount = computed(() => {
  34. const min = Math.min(
  35. ...props.matchedSku.map((item) => ((item.expectedQuantity || 0) - (item.receivedQuantity || 0)) / (item.matchedJson?.quantity || 1))
  36. )
  37. return Number.isFinite(min) ? Math.floor(min) : 0
  38. })
  39. const show = () => {
  40. count.value = ''
  41. goodsTrueFalseBy.value = true
  42. setTimeout(() => {
  43. countRef.value?.focus()
  44. }, 200)
  45. }
  46. const dataResult = (data) =>
  47. data.map((item) => {
  48. const { matchedJson, ...rest } = item
  49. return { ...rest, quantity: matchedJson.quantity * Number(count.value) }
  50. })
  51. const emit = defineEmits(['setCombine', 'cancel'])
  52. const beforeClose = (action) =>
  53. new Promise((resolve) => {
  54. if (action === 'confirm') {
  55. if (count.value == '') {
  56. showToast('请输入上架套数')
  57. return resolve(false)
  58. }
  59. if (Number(count.value) <= 0) {
  60. showToast('请输入有效上架套数')
  61. return resolve(false)
  62. }
  63. if (Number(count.value) > maxCount.value) {
  64. showToast({ duration: 3000, message: '上架套数不能大于可上架套数' })
  65. return resolve(false)
  66. }
  67. const dataList = dataResult(matchedSkuList.value)
  68. emit('setCombine', { dataList, count: Number(count.value) })
  69. } else {
  70. emit('cancel')
  71. }
  72. resolve(true)
  73. })
  74. defineExpose({ show })
  75. </script>
  76. <style scoped lang="sass">
  77. .goods
  78. .code-input
  79. font-size: 16px
  80. font-weight: bold
  81. border-bottom: 2px solid #0077ff
  82. :deep(.van-cell--center)
  83. padding: 5px 20px
  84. :deep(.van-cell__title)
  85. text-align: left !important
  86. :deep(.van-cell__value)
  87. width: 40% !important
  88. flex: 0 0 40% !important
  89. color: #000
  90. .goods-number
  91. text-align: left
  92. font-size: 16px
  93. padding-left: 20px
  94. margin-top: 5px
  95. .goods-tips
  96. font-size: 12px
  97. text-align: right
  98. color: #333
  99. </style>