5 changed files with 609 additions and 157 deletions
@ -0,0 +1,548 @@ |
|||||
|
<!-- 跳转企业二维码load页面 --> |
||||
|
<template> |
||||
|
<div class="home app_content"> |
||||
|
<!-- 中间 --> |
||||
|
<div class="warp_body"> |
||||
|
<div class="white-body"> |
||||
|
<div class="boutique_box"> |
||||
|
<div class="box-qr-title">执法监督码</div> |
||||
|
<div class="boutique_body"> |
||||
|
<div class="box-qr-code"> |
||||
|
<img class="box-qr-code-img" :src="data.qrCodeImg" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup name="Home"> |
||||
|
import Vconsole from "vconsole"; |
||||
|
import {showFailToast,showToast} from 'vant'; |
||||
|
import {checkIsState,getEnterpriseInfoBySj} from '@/api/enforce'; |
||||
|
import {szyptGetToken} from "@/api/Home"; |
||||
|
import { baseUrl } from "../../config/env"; |
||||
|
import wx from "weixin-js-sdk"; |
||||
|
|
||||
|
const {useCommon} = $globalStore; |
||||
|
const router = useRouter(); |
||||
|
//路由参数 |
||||
|
const route = useRoute(); |
||||
|
const intervalId = ref(null); |
||||
|
const data = reactive({ |
||||
|
showNoScanPicker: ref(false), |
||||
|
qrCodeImg: baseUrl + "/profile/upload/2024/11/29/03043b8531b8e1aad5a0f72d2fc605f0.jpg", |
||||
|
}); |
||||
|
const indexSens = ref(3); |
||||
|
const butText = ref("点击跳转企业画像....,"+indexSens.value+"秒后自动跳转"); |
||||
|
|
||||
|
|
||||
|
const openScan = () => { |
||||
|
let fullUrl = window.location.href; |
||||
|
let code = fullUrl.substring(fullUrl.indexOf('code=') + 5, fullUrl.indexOf('&state=')); |
||||
|
let paramUrl = window.location.href.split("#")[0]; |
||||
|
let param = {code: code, url: paramUrl}; |
||||
|
console.log(paramUrl); |
||||
|
szyptGetToken(param, success => { |
||||
|
let resMsg = success.data; |
||||
|
console.log(resMsg); |
||||
|
wx.config({ |
||||
|
// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 |
||||
|
debug: false, |
||||
|
// 必填,公众号的唯一标识 |
||||
|
appId: resMsg.corpid, |
||||
|
// 必填,生成签名的时间戳 |
||||
|
timestamp: resMsg.timestamp, |
||||
|
// 必填,生成签名的随机串 |
||||
|
nonceStr: resMsg.nonceStr, |
||||
|
// 必填,签名,见附录1 |
||||
|
signature: resMsg.signature, |
||||
|
// 必填,需要使用的JS接口列表,所有JS接口列表见附录2 |
||||
|
jsApiList: ["scanQRCode"], |
||||
|
}); |
||||
|
wx.ready(() => { |
||||
|
//微信扫一扫请求操作 |
||||
|
ClickScan() |
||||
|
}); |
||||
|
wx.error((res) => { |
||||
|
console.log("获取失败"); |
||||
|
}); |
||||
|
}, error => { |
||||
|
}); |
||||
|
}; |
||||
|
const ClickScan = () => { |
||||
|
wx.scanQRCode({ |
||||
|
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, |
||||
|
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有 |
||||
|
success: (res) => { |
||||
|
// 页面跳转 |
||||
|
console.log("=========== 扫码返回 ===========") |
||||
|
console.log(res) |
||||
|
//TODO 判断是否是市监 |
||||
|
if(isHttpLink(res.resultStr)){ |
||||
|
//判断地址是否存在cid统一信用代码 |
||||
|
getEnterpriseInfoBySj({"url":res.resultStr},success =>{ |
||||
|
if (success.success) { |
||||
|
var element = success.data; |
||||
|
//TODO 添加延时弹出监督码 |
||||
|
showToast({ |
||||
|
duration: 3000, |
||||
|
message:"企业监督码", |
||||
|
icon: baseUrl + element.qrCodeGenerateHistory.qrCodeUrl, |
||||
|
iconSize:"100px", |
||||
|
onClose: openEnterpriseView(element.enterpriseNumber) |
||||
|
}) |
||||
|
|
||||
|
} else { |
||||
|
showFailToast(success.message); |
||||
|
router.push({ |
||||
|
path: "/enforce/scanQrCode", |
||||
|
}) |
||||
|
} |
||||
|
},error =>{}) |
||||
|
}else{ |
||||
|
const scanObj = JSON.parse(res.resultStr); |
||||
|
// 判断二维码是否过期, 如果已过期则跳转提示页 |
||||
|
checkIsState(scanObj.salt, scanObj.codeId, success => { |
||||
|
console.log(success) |
||||
|
if (success.data) { |
||||
|
router.push({ |
||||
|
path: "/enterpriseScanPreview", |
||||
|
query: { |
||||
|
enterpriseNumber: scanObj.salt, |
||||
|
isNoScan: false |
||||
|
} |
||||
|
}) |
||||
|
} else { |
||||
|
showFailToast(success.message); |
||||
|
router.push({ |
||||
|
path: "/enforce/scanQrCode", |
||||
|
}) |
||||
|
} |
||||
|
}, error => { |
||||
|
showFailToast("该二维码不正确"); |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
error: function(res) { |
||||
|
console.log("错误回调",res) |
||||
|
if (res.errMsg.indexOf('function_not_exist') > 0) { |
||||
|
showFailToast('版本过低请升级') |
||||
|
} |
||||
|
}, |
||||
|
cancel: (res) => { |
||||
|
console.log('err', res); |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const toScanPageView = async () => { |
||||
|
openScan(); |
||||
|
}; |
||||
|
onMounted(() => { |
||||
|
// new Vconsole(); |
||||
|
startTimer(route?.query?.enterpriseNumber); |
||||
|
console.log("企业统一信用代码:",route?.query?.enterpriseNumber) |
||||
|
console.log("企业二维码地址:",route?.query?.qrCodeUrl) |
||||
|
}) |
||||
|
//定时器 |
||||
|
const startTimer = (enterpriseNumber) => { |
||||
|
// 假设我们每隔1秒钟执行一些操作 |
||||
|
intervalId.value = setInterval(() => { |
||||
|
console.log('定时器执行中...'); |
||||
|
// 执行一些定时器相关的操作 |
||||
|
indexSens.value--; |
||||
|
if(indexSens.value >= 0){ |
||||
|
console.log("加减",indexSens.value) |
||||
|
butText.value = "点击跳转企业画像....,"+indexSens.value+"秒后自动跳转"; |
||||
|
}else{ |
||||
|
console.log("清除定时器") |
||||
|
console.log("清除定时器",enterpriseNumber) |
||||
|
clearInterval(intervalId.value); |
||||
|
router.push({ |
||||
|
path: "/enterpriseScanPreview", |
||||
|
query: { |
||||
|
enterpriseNumber: enterpriseNumber, |
||||
|
isNoScan: false |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, 1000); |
||||
|
}; |
||||
|
|
||||
|
// 返回 |
||||
|
const goBack = () => { |
||||
|
router.go(-1); |
||||
|
}; |
||||
|
|
||||
|
const isHttpLink = (url) =>{ |
||||
|
return url.indexOf("http://") === 0 || url.indexOf("https://") === 0; |
||||
|
} |
||||
|
const openEnterpriseView = (enterpriseNumber) =>{ |
||||
|
console.log("外层获取企业统一信用代码",enterpriseNumber); |
||||
|
setTimeout(() =>{ |
||||
|
console.log("定时内获取企业统一信用代码",enterpriseNumber); |
||||
|
router.push({ |
||||
|
path: "/enterpriseScanPreview", |
||||
|
query: { |
||||
|
enterpriseNumber: enterpriseNumber, |
||||
|
isNoScan: false |
||||
|
} |
||||
|
}) |
||||
|
}, 3000); |
||||
|
} |
||||
|
onUnmounted(() => { |
||||
|
// 清除定时器 |
||||
|
if (intervalId.value) { |
||||
|
clearInterval(intervalId.value); |
||||
|
} |
||||
|
}); |
||||
|
</script> |
||||
|
<script> |
||||
|
//不扫码企业筛选弹窗 |
||||
|
import Popup from '@/views/enforce/noScanFilter.vue'; |
||||
|
import { baseUrl } from "../../config/env"; |
||||
|
|
||||
|
export default { |
||||
|
components: { |
||||
|
Popup |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
popupVisible: false, |
||||
|
popupContent: '' |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
showPopup() { |
||||
|
this.popupVisible = true; |
||||
|
}, |
||||
|
closePopup() { |
||||
|
this.popupVisible = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.home { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height: 100%; |
||||
|
overflow: hidden; |
||||
|
background-color: #ebf3fb; |
||||
|
|
||||
|
.warp_body { |
||||
|
position: relative; |
||||
|
background-image: linear-gradient(to bottom, #ebf3fb, transparent); |
||||
|
|
||||
|
.carousel_box { |
||||
|
position: relative; |
||||
|
top: 2%; |
||||
|
height: 4rem; |
||||
|
width: 100%; |
||||
|
background: url("/src/assets/images/scan-mean.jpg") no-repeat center center; |
||||
|
background-size: 60%; |
||||
|
opacity: 0.75; |
||||
|
|
||||
|
.box-scan-one, .box-scan-two { |
||||
|
position: absolute; |
||||
|
top: 30%; |
||||
|
left: 15%; |
||||
|
height: 2.67rem; |
||||
|
width: 30%; |
||||
|
font-size: 0.4rem; |
||||
|
color: #999; |
||||
|
|
||||
|
.box-scan-text { |
||||
|
margin-top: 70%; |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
text-align: center |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.box-scan-two { |
||||
|
left: auto; |
||||
|
right: 12.5%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.boutique_box { |
||||
|
position: relative; |
||||
|
top: 5%; |
||||
|
z-index: 100; |
||||
|
width: 100%; |
||||
|
|
||||
|
.boutique_body { |
||||
|
padding: 0 0 0.27rem 0; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
; |
||||
|
|
||||
|
.box-qr-code { |
||||
|
width: 80%; |
||||
|
text-align: right; |
||||
|
height: 7rem; |
||||
|
//background-color: var(--van-primary-color); |
||||
|
// background: url("../../assets/images/qrCode.jpg") no-repeat center center; |
||||
|
background-size: 100%; |
||||
|
// border-radius: 0.27rem; |
||||
|
// background-size: cover; |
||||
|
// border-radius: 50%; |
||||
|
// background-image: url("@/assets/images/scan.png"); |
||||
|
.box-qr-code-text { |
||||
|
margin-right: 25%; |
||||
|
margin-top: 70%; |
||||
|
display: block; |
||||
|
font-size: 0.45rem; |
||||
|
} |
||||
|
.box-qr-code-img{ |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
// img { |
||||
|
// position: absolute; |
||||
|
// top: 0%; |
||||
|
// left: 34%; |
||||
|
// } |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.white-body { |
||||
|
position: relative; |
||||
|
margin: 0 3%; |
||||
|
width: 94%; |
||||
|
height: 99%; |
||||
|
background-color: #fff; |
||||
|
border-radius: 0.27rem; |
||||
|
} |
||||
|
.box-qr-title{ |
||||
|
margin: 3% 0 0; |
||||
|
width: 90%; |
||||
|
font-size: 0.42rem; |
||||
|
text-align: center; |
||||
|
transform: translate(5%, 5%); |
||||
|
line-height: 3; |
||||
|
} |
||||
|
|
||||
|
.nocode { |
||||
|
margin: 3% 0 0; |
||||
|
width: 90%; |
||||
|
font-size: 0.42rem; |
||||
|
text-align: center; |
||||
|
line-height: 3; |
||||
|
background-color: #619cd9; |
||||
|
transform: translate(5%, 5%); |
||||
|
border-radius: 6px; |
||||
|
} |
||||
|
|
||||
|
.scan-note { |
||||
|
width: 100%; |
||||
|
font-size: 0.45rem; |
||||
|
text-align: center; |
||||
|
line-height: 2; |
||||
|
margin-top: 2%; |
||||
|
} |
||||
|
|
||||
|
.popup { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background: rgba(0, 0, 0, 0.35); |
||||
|
} |
||||
|
|
||||
|
.popup-content { |
||||
|
position: fixed; |
||||
|
z-index: 999; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
padding: 0 3%; |
||||
|
width: 94%; |
||||
|
height: 35vh; |
||||
|
background: #fff; |
||||
|
overflow-y: auto; |
||||
|
font-size: 0.37rem; |
||||
|
} |
||||
|
|
||||
|
.subtitle { |
||||
|
margin: 5% 2% 2%; |
||||
|
width: 96%; |
||||
|
/*font-size: 0.4rem; |
||||
|
font-weight: 600;*/ |
||||
|
border-bottom: 1px solid #f4f4f4; |
||||
|
line-height: 2; |
||||
|
} |
||||
|
|
||||
|
.item-btn { |
||||
|
float: left; |
||||
|
margin: 0.3rem 0.2rem; |
||||
|
padding: 0.2rem 0.3rem; |
||||
|
background-color: #f2f3f4; |
||||
|
color: #999; |
||||
|
border-radius: 1rem; |
||||
|
font-size: 0.35rem; |
||||
|
} |
||||
|
|
||||
|
.item-btn.active { |
||||
|
background-color: #e9f2fb; |
||||
|
color: #1367fe; |
||||
|
} |
||||
|
|
||||
|
.btnbox { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
position: absolute; |
||||
|
bottom: 1rem; |
||||
|
left: 5%; |
||||
|
width: 90%; |
||||
|
height: 1rem; |
||||
|
} |
||||
|
|
||||
|
.btn-reset { |
||||
|
display: inline-block; |
||||
|
margin: 0 2%; |
||||
|
padding: 0; |
||||
|
width: 60%; |
||||
|
color: #fff; |
||||
|
font-size: 0.35rem; |
||||
|
border-radius: 1rem; |
||||
|
background: #1367fe; |
||||
|
border: 1px solid #1367fe; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.btn-search { |
||||
|
display: inline-block; |
||||
|
margin: 3% 7%; |
||||
|
padding: 0; |
||||
|
width: 70%; |
||||
|
color: #fff; |
||||
|
font-size: 0.35rem; |
||||
|
border-radius: 1rem; |
||||
|
background: #1367fe; |
||||
|
border: 1px solid #1367fe; |
||||
|
text-align: center; |
||||
|
height: 90%; |
||||
|
} |
||||
|
|
||||
|
.btn-reset { |
||||
|
width: 35%; |
||||
|
background-color: #fff; |
||||
|
border-color: rgba(19, 103, 254, .7); |
||||
|
color: #1367fe; |
||||
|
} |
||||
|
|
||||
|
.close-button { |
||||
|
position: absolute; |
||||
|
top: 0.15rem; |
||||
|
right: 0.1rem; |
||||
|
width: 0.8rem; |
||||
|
height: 0.8rem; |
||||
|
background-color: rgba(255, 255, 255, .5); |
||||
|
border: 0.05rem solid rgba(255, 255, 255, .7); |
||||
|
border-radius: 50%; |
||||
|
transform: rotate(45deg); |
||||
|
} |
||||
|
|
||||
|
.close-button:before, |
||||
|
.close-button:after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
background: #333; |
||||
|
border-radius: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
height: 0.4rem; |
||||
|
width: 0.02rem; |
||||
|
} |
||||
|
|
||||
|
.close-button:after { |
||||
|
height: 0.02rem; |
||||
|
width: 0.4rem; |
||||
|
} |
||||
|
|
||||
|
.nav-div { |
||||
|
display: flex; |
||||
|
margin: 15% 2% 0; |
||||
|
width: 96%; |
||||
|
color: #287eef; |
||||
|
font-size: 0.4rem; |
||||
|
line-height: 2; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.nav-div > div { |
||||
|
margin: 2% 3%; |
||||
|
width: 45%; |
||||
|
} |
||||
|
|
||||
|
.nav-div div span{ |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
.nav-div div i { |
||||
|
margin: 0.35rem; |
||||
|
width: 1.5rem; |
||||
|
height: 1.5rem; |
||||
|
font-size: 0.8rem; |
||||
|
background: #e6eff7; |
||||
|
border-radius: 50%; |
||||
|
text-align: center; |
||||
|
line-height: 1.85; |
||||
|
} |
||||
|
|
||||
|
.nav-div .act-note { |
||||
|
margin: 10% 0 0; |
||||
|
width: 100%; |
||||
|
font-size: 0.3rem; |
||||
|
color: #d3d0d0; |
||||
|
line-height: 1.5; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
.addinfo { |
||||
|
position: absolute; |
||||
|
bottom: 2rem; |
||||
|
right: 2%; |
||||
|
z-index: 999; |
||||
|
width: 1.5rem; |
||||
|
height: 1.5rem; |
||||
|
background-color: #e0e9f9; |
||||
|
border-radius: 50%; |
||||
|
box-shadow: 0 0 0.27rem #90b6f9; |
||||
|
color: #0240f7; |
||||
|
font-size: 0.4rem; |
||||
|
text-align: center; |
||||
|
vertical-align: middle; |
||||
|
padding-top: 0.45rem; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.record { |
||||
|
position: absolute; |
||||
|
bottom: 2rem; |
||||
|
color: #bbbaba; |
||||
|
font-size: 0.35rem; |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.record a { |
||||
|
color: #287eef; |
||||
|
} |
||||
|
|
||||
|
</style> |
||||
|
|
||||
@ -1,135 +0,0 @@ |
|||||
<style scoped> |
|
||||
.scan-area { |
|
||||
width: 100%; |
|
||||
height: 18.15rem; |
|
||||
} |
|
||||
</style> |
|
||||
|
|
||||
<template> |
|
||||
<div class="scan-area"> |
|
||||
<qrcode-stream @click="handleClick" :paused="scanPause" :track="paintOutLineAndCenterText" @error="handleError" @camera-on="onCameraOn"> |
|
||||
<div v-if="!cameraReady"> |
|
||||
loading... |
|
||||
</div> |
|
||||
</qrcode-stream> |
|
||||
<!-- <audio ref="audioRef" src="/src/assets/Di.mp3"></audio> --> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<script setup lang="ts"> |
|
||||
// import Vconsole from "vconsole"; |
|
||||
import { QrcodeStream } from "vue-qrcode-reader"; |
|
||||
import {ref} from 'vue' |
|
||||
const audioRef = ref(null); |
|
||||
const errorInfo = ref(''); |
|
||||
const cameraReady = ref(false); |
|
||||
const scanPause = ref(false); |
|
||||
const reactAngles = ref<any>([]); |
|
||||
const onCameraOn = function () { |
|
||||
cameraReady.value = true; |
|
||||
// new Vconsole(); |
|
||||
} |
|
||||
const handleError = function (err) { |
|
||||
errorInfo.value = `[${err.name}]: ` |
|
||||
if (err.name === 'NotAllowedError') { |
|
||||
errorInfo.value += '您需要授予相机访问权限' |
|
||||
} else if (err.name === 'NotFoundError') { |
|
||||
errorInfo.value = '此设备上没有检测到摄像头'; |
|
||||
} else if (err.name === 'NotReadableError') { |
|
||||
errorInfo.value = '相机被占用' |
|
||||
} else if (err.name === 'NotSupportedError') { |
|
||||
errorInfo.value = 'secure context required (HTTPS, localhost)' |
|
||||
} else if (err.name === 'OverconstrainedError') { |
|
||||
errorInfo.value += '' |
|
||||
} else if (err.name === 'StreamApiNotSupportedError') { |
|
||||
errorInfo.value += 'Stream API is not supported in this browser' |
|
||||
} else if (err.name === 'InsecureContextError') { |
|
||||
errorInfo.value += 'Camera access is only permitted in secure context. Use HTTPS or localhost rather than HTTP.' |
|
||||
} else { |
|
||||
errorInfo.value += err.message |
|
||||
} |
|
||||
console.log(errorInfo.value); |
|
||||
errorInfo.value = ''; |
|
||||
} |
|
||||
|
|
||||
const paintOutLineAndCenterText = (detectedCodes, ctx) => { |
|
||||
// 暂停页面 |
|
||||
scanPause.value = true; |
|
||||
// 播放语音 |
|
||||
// audioRef.value.play(); |
|
||||
// 画边框和文本 |
|
||||
reactAngles.value.splice(); |
|
||||
for (const detectedCode of detectedCodes) { |
|
||||
// 画边框 |
|
||||
ctx.lineWidth = 1; |
|
||||
const [firstPoint, ...otherPoints] = detectedCode.cornerPoints |
|
||||
ctx.strokeStyle = 'red' |
|
||||
ctx.beginPath() |
|
||||
ctx.moveTo(firstPoint.x, firstPoint.y) |
|
||||
for (const { x, y } of otherPoints) { |
|
||||
ctx.lineTo(x, y) |
|
||||
} |
|
||||
ctx.lineTo(firstPoint.x, firstPoint.y) |
|
||||
ctx.closePath(); |
|
||||
ctx.stroke(); |
|
||||
// 画文字 |
|
||||
const { boundingBox, rawValue } = detectedCode |
|
||||
const centerX = boundingBox.x + boundingBox.width / 2 |
|
||||
const centerY = boundingBox.y + boundingBox.height / 2 |
|
||||
const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width) |
|
||||
console.log(boundingBox.width, ctx.canvas.width) |
|
||||
ctx.lineWidth = 2; |
|
||||
ctx.font = `${fontSize}px sans-serif` |
|
||||
ctx.textAlign = 'center' |
|
||||
ctx.strokeStyle = '#35e5a7' |
|
||||
ctx.strokeText('>', centerX, centerY) |
|
||||
// 配置矩形内容 |
|
||||
if (detectedCode.cornerPoints.length==4) { |
|
||||
reactAngles.value.push({ |
|
||||
leftTop: {x: firstPoint.x, y:firstPoint.y}, |
|
||||
rightTop: {x: otherPoints[0].x, y:otherPoints[0].y}, |
|
||||
rightBottom: {x: otherPoints[1].x, y:otherPoints[1].y}, |
|
||||
leftBottom: {x: otherPoints[2].x, y:otherPoints[2].y}, |
|
||||
text: detectedCode.rawValue |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
// 获取事件的发生位置 |
|
||||
const getEventPosition = (ev) => { |
|
||||
var x, y; |
|
||||
if (ev.layerX || ev.layerX == 0) { |
|
||||
x = ev.layerX; |
|
||||
y = ev.layerY; |
|
||||
} else if (ev.offsetX || ev.offsetX == 0) { // Opera |
|
||||
x = ev.offsetX; |
|
||||
y = ev.offsetY; |
|
||||
} |
|
||||
return {x: x, y: y}; |
|
||||
}; |
|
||||
|
|
||||
const handleClick = function (event) { |
|
||||
// 1. 获取点击点的位置 |
|
||||
var eventPosition = getEventPosition(event); |
|
||||
// 2. 判断在不在已有的矩形内部,在的话获取二维码解析的结果,并进行业务处理 |
|
||||
var resolveText = handleClickRectAngle(eventPosition); |
|
||||
if (resolveText != undefined) { |
|
||||
alert(resolveText); |
|
||||
} |
|
||||
// 3. 业务处理完,如果决定跳转就跳转,不决定跳转的话就关闭暂停 |
|
||||
scanPause.value = false; |
|
||||
} |
|
||||
|
|
||||
// 判断一个点在不在某个矩形内部的算法,后面可以采取凸包算法,优化判断的实现,不过这里已经能实现了,没必要深究 |
|
||||
const handleClickRectAngle = function (eventPosition) { |
|
||||
for (let i = 0; i < reactAngles.value.length; i++) { |
|
||||
let reactAngle = reactAngles.value[i]; |
|
||||
if ( ((eventPosition.x >= Math.min(reactAngle.leftTop.x, reactAngle.leftBottom.x)) && (eventPosition.x <= Math.max(reactAngle.rightTop.x, reactAngle.rightBottom.x))) |
|
||||
&& ((eventPosition.y >= Math.min(reactAngle.leftTop.y, reactAngle.rightTop.y)) && (eventPosition.y <= Math.max(reactAngle.leftBottom.y, reactAngle.rightBottom.y))) |
|
||||
) { |
|
||||
return reactAngle.text; |
|
||||
} |
|
||||
} |
|
||||
return undefined; |
|
||||
} |
|
||||
</script> |
|
||||
Loading…
Reference in new issue