| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- <template>
- <div class="unique-code">
- <van-dialog v-model:show="uniqueCodeTrueFalseBy"
- :keyboardEnabled="false"
- :beforeClose="beforeClose"
- :confirm-button-text="'完成收货'"
- title="唯一码录入"
- show-cancel-button>
- <div>
- <div class="unique-code-type">
- <div class="tips">{{ tag }}</div>
- <div v-if="!isCombineMode">
- <div :class="newCheckAllType?'unique-v-active':'unique-v-no-active'" @click="onCheckAllType"> <van-icon name="exchange" /> 条码校验</div>
- <!-- <van-button type="primary" size="mini" :plain="!newCheckAllType" @click="onCheckAllType" icon="exchange" >条码校验</van-button>-->
- </div>
- </div>
- <div v-if="combineSetCount > 0" class="combine-set-info">
- 组合{{ combineSetCount }}套 | 唯一码{{ containerList.length }}/{{ searchCount }}
- </div>
- <div class="unique-input-list" v-if="newCheckAllType && !isCombineMode">
- <div class="unique-input-list-left">商品条码:</div>
- <div class="unique-input-list-right">
- <van-field class="code-input"
- v-model="uniqueBarcode"
- ref="uniqueBarcodeRef"
- clearable
- autocomplete="off"
- placeholder="请扫描商品条码"
- type="text"
- @keydown.enter="uniqueBarcodeChange"
- :style="uniqueCodeScanType == 'barcode' ? { 'border-bottom': '2px solid #1989fa' } : {}"
- @focus="uniqueCodeScanType = 'barcode'"
- />
- </div>
- </div>
- <div class="unique-input-list">
- <div class="unique-input-list-left">唯 一 码:</div>
- <div class="unique-input-list-right">
- <van-field class="code-input"
- v-model="uniqueCode"
- ref="uniqueCodeRef"
- clearable
- autocomplete="off"
- placeholder="请扫描唯一码"
- type="text"
- @keydown.enter="onKeydown"
- :style="uniqueCodeScanType == 'unique' ? { 'border-bottom': '2px solid #1989fa' } : {}"
- @focus="uniqueCodeScanType = 'unique'"
- />
- </div>
- </div>
- </div>
- <div class="container-list">
- <div v-for="(item,i) in containerList" class="container-item" :key="i">
- <div style="display: flex;justify-content: space-between;align-items: center;">
- <div style="margin-right: 3px;">{{ containerList.length - i }}</div>
- <div class="container-item-line"></div>
- </div>
- <div class="container-item-no">
- <van-notice-bar :background="'none'" color="#000" :speed="10" :text="item" />
- </div>
- <div class="container-item-clear" @click="containerList.splice(i,1)">
- <van-icon name="delete-o" color="#ee0a24" size="15" />
- </div>
- </div>
- </div>
- </van-dialog>
- </div>
- </template>
- <script setup>
- import { computed, nextTick, ref } from 'vue'
- import { showNotify } from 'vant'
- import { scanError, scanSuccess } from '@/utils/android'
- import { barcodeToUpperCase } from '@/utils/dataType.js'
- const uniqueCodeTrueFalseBy = ref(false)
- //商品条码
- const uniqueBarcode=ref('')
- const uniqueBarcodeRef=ref(null)
- //唯一码
- const uniqueCode = ref('')
- const uniqueCodeRef = ref(null)
- const tag = ref('')
- // 定义传入的 props
- const props = defineProps({
- uniqueCodeList: Array,
- scanType: Number,
- searchCount: [String, Number],
- asnInfo:Object,
- checkAllType:Boolean,
- /** 组合商品收货套数 */
- combineSetCount: { type: Number, default: 0 },
- /** 组合外箱码获取内件码 */
- resolvePanpassCodes: { type: Function, default: undefined },
- })
- const isCombineMode = computed(() => Number(props.combineSetCount) > 0)
- const getDefaultCheckAllType = () => !isCombineMode.value && !!props.checkAllType
- const scanInputType = getDefaultCheckAllType() ? 'barcode' : 'unique'
- const uniqueCodeScanType=ref(scanInputType)
- // 定义自定义的 emit
- const emit = defineEmits(['update:scanType', 'update:uniqueCodeList', 'setUniqueCode','update:checkAllType'])
- const containerList = computed(() => {
- return props.uniqueCodeList
- })
- const uniqueRuleMap = ref({})
- const show = async (code, desc, tips, uniqueRule) => {
- if (tips !== undefined) {
- tag.value = tips
- }
- uniqueRuleMap.value = uniqueRule
- newCheckAllType.value = getDefaultCheckAllType()
- uniqueCodeScanType.value = newCheckAllType.value ? 'barcode' : 'unique'
- uniqueBarcode.value = ''
- uniqueCode.value = ''
- uniqueCodeTrueFalseBy.value = true
- await nextTick()
- if (newCheckAllType.value) uniqueBarcodeRef.value?.focus()
- else uniqueCodeRef.value?.focus()
- }
- const newCheckAllType = ref(getDefaultCheckAllType())
- // 切换校验类型
- const onCheckAllType=()=>{
- if (isCombineMode.value) return
- newCheckAllType.value = !newCheckAllType.value
- uniqueCodeScanType.value = newCheckAllType.value ? 'barcode' : 'unique';
- localStorage.setItem('checkAllType',newCheckAllType.value)
- emit('update:checkAllType',newCheckAllType.value)
- }
- const refocusAfterUniqueInput = () => {
- uniqueBarcode.value = ''
- uniqueCode.value = ''
- if (newCheckAllType.value && !isCombineMode.value) uniqueBarcodeRef.value?.focus()
- else uniqueCodeRef.value?.focus()
- }
- //商品条码验证
- const uniqueBarcodeChange=()=>{
- if (isCombineMode.value) return true
- if(newCheckAllType.value){
- if (props.resolvePanpassCodes) return true
- if(!uniqueBarcode.value){
- showNotify({ type: 'danger', duration: 3000, message: `请先扫描商品条码` })
- scanError()
- return false
- }
- const barcode = Array.from(new Set([props.asnInfo.barcode, props.asnInfo.barcode2, props.asnInfo.sku].filter(Boolean)))
- if (barcode.some(item => barcodeToUpperCase(item) === barcodeToUpperCase(uniqueBarcode.value))) {
- scanSuccess()
- uniqueCodeRef.value?.focus()
- return true
- }else {
- showNotify({ type: 'danger', duration: 3000, message: `${uniqueBarcode.value}-商品条码不匹配、请重新扫描` })
- uniqueBarcode.value=''
- scanError()
- return false
- }
- }
- return true
- }
- const onKeydown = async () => {
- if(!uniqueBarcodeChange()) return
- if (uniqueCode.value) {
- if (props.resolvePanpassCodes) {
- const result = await props.resolvePanpassCodes(uniqueCode.value)
- if (result == null) {
- uniqueCode.value = ''
- return
- }
- refocusAfterUniqueInput()
- return
- }
- const uniqueRegExp = uniqueRuleMap.value['sku'] ? uniqueRuleMap.value['sku'] : uniqueRuleMap.value['all']
- const isValidCode = new RegExp(uniqueRegExp).test(uniqueCode.value)
- if (!isValidCode) {
- scanError()
- showNotify({ type: 'danger', duration: 3000, message: `唯一码《${uniqueCode.value}》不符合规则、请重新扫描` })
- uniqueCode.value = ''
- return
- }
- if (containerList.value.includes(uniqueCode.value)) {
- scanError()
- showNotify({ type: 'danger', duration: 3000, message: `唯一码《${uniqueCode.value}》已存在列表内请重新扫描` })
- uniqueCode.value = ''
- return
- }
- scanSuccess()
- containerList.value.unshift(uniqueCode.value)
- refocusAfterUniqueInput()
- }
- emit('update:uniqueCodeList', containerList.value)
- }
- const beforeClose = (action) =>
- new Promise(async (resolve) => {
- if (action === 'confirm') {
- if (containerList.value.length != props.searchCount) {
- scanError()
- showNotify({
- type: 'danger',
- duration: 3000,
- message: `当前扫描唯一码数量:${containerList.value.length}、收货数量:${props.searchCount},请扫描相同数量唯一码`,
- })
- return resolve(false)
- }
- resolve(true)
- emit('update:scanType', 2)
- emit('setUniqueCode')
- } else {
- resolve(true)
- emit('update:scanType', 2)
- }
- })
- defineExpose({ show ,uniqueBarcode,uniqueCodeScanType })
- </script>
- <style scoped lang="sass">
- .unique-code
- .unique-code-type
- display: flex
- justify-content: space-between
- align-items: center
- padding: 0 15px
- .unique-v-active
- background: #1989fa
- font-size: 10px
- color: #FFFFFF
- border-radius: 5px
- padding: 5px
- .unique-v-no-active
- background: #6e6c6c
- color: #FFFFFF
- font-size: 10px
- border-radius: 5px
- padding: 5px
- .unique-input-list
- display: flex
- padding: 0 10px
- .unique-input-list-left
- display: flex
- justify-content: center
- align-items: center
- gap: 10px
- .unique-input-list-right
- flex: 1
- .code-input
- font-size: 22px
- font-weight: bold
- border-bottom: 2px solid #efefef
- margin-top: 10px
- .completion
- text-align: right
- font-size: 12px
- padding: 5px 20px
- cursor: pointer
- text-decoration: underline
- .container-list
- max-height: 100px
- font-size: 13px
- font-weight: bold
- display: flex
- margin: 10px 15px
- justify-content: space-between
- flex-wrap: wrap
- overflow: auto
- .container-item
- width: 99%
- display: flex
- justify-items: center
- align-items: center
- padding: 2px
- cursor: pointer
- border-bottom: 1px solid #efefef
- .container-item-line
- width: 5px
- height: 5px
- background: #0077ff
- border-radius: 50%
- margin-right: 5px
- .container-item-no
- flex: 1
- text-align: left
- text-decoration: underline
- .container-item-clear
- padding: 0 15px
- .container-item:last-child
- border-bottom: none
- .tips
- font-size: 14px
- color: #ff4141
- line-height: 20px
- .combine-set-info
- font-size: 14px
- color: #1989fa
- font-weight: bold
- line-height: 22px
- padding: 4px 15px 0
- width: 100%
- box-sizing: border-box
- </style>
|