云
3 天以前 2f9c84cf0e0c03a8e3bf07d3924ccdf791070b77
src/views/mobile/scanner.vue
@@ -1,12 +1,13 @@
<script setup lang="ts">
import { onBeforeUnmount, onDeactivated, onMounted, ref } from 'vue';
import { nextTick, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
import Icon from '#/mobile/icon.vue';
const props=defineProps<{disabled?:boolean}>();
const props=defineProps<{disabled?:boolean;continuous?:boolean}>();
const emit=defineEmits<{code:[value:string]}>();
const input=ref(''),error=ref(''),active=ref(false),starting=ref(false),video=ref<HTMLVideoElement>();
const input=ref(''),error=ref(''),active=ref(false),starting=ref(false),video=ref<HTMLVideoElement>(),codeInput=ref<HTMLInputElement>();
let stream:MediaStream|undefined,frame=0,generation=0,last=0;
function stop(){generation++;active.value=false;starting.value=false;cancelAnimationFrame(frame);stream?.getTracks().forEach(t=>t.stop());stream=undefined;if(video.value)video.value.srcObject=null;}
function accept(value:string){if(props.disabled)return;stop();input.value=value;emit('code',value);}
function accept(value:string){if(props.disabled)return;stop();input.value=props.continuous?'':value;emit('code',value);}
watch([()=>props.disabled,()=>props.continuous],async ([disabled,continuous])=>{if(!disabled&&continuous){await nextTick();codeInput.value?.focus();}});
async function start(){
  error.value='';stop();const ticket=generation;starting.value=true;
  try{
@@ -52,7 +53,7 @@
  <template v-else><video ref="video" class="m-camera" muted playsinline aria-label="二维码取景"/><button type="button" class="m-secondary" @click="stop">关闭摄像头</button></template>
  <p v-if="error" class="m-error" role="alert">{{error}}</p>
  <form @submit.prevent="accept(input)">
    <label class="m-field" style="margin-top:16px"><span>码值 / 溯源链接</span><input v-model="input" autocomplete="off" :disabled="disabled" placeholder="手动输入或使用扫码设备" maxlength="2048" /></label>
    <label class="m-field" style="margin-top:16px"><span>码值 / 溯源链接</span><input ref="codeInput" v-model="input" autocomplete="off" :disabled="disabled" placeholder="手动输入或使用扫码设备" maxlength="2048" /></label>
    <button class="m-secondary" :disabled="disabled||!input.trim()" type="submit">{{disabled?'正在处理…':'识别码值'}}</button>
  </form>
</div>