| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- <template>
- <view class="page">
- <view class="camera-area">
- <camera
- v-if="!isDevTool"
- device-position="back"
- mode="scanCode"
- :flash="cameraFlash"
- @scancode="debounceScan"
- @ready="handleReady"
- @error="handleError"
- :style="{ width: '100%', height: `${cameraHeight}px` }"
- ></camera>
- <view
- v-else
- class="mock-camera"
- :style="{ width: '100%', height: `${cameraHeight}px` }"
- ></view>
- </view>
- <view class="action-bar">
- <cover-view class="flash-toggle" @click="toggleFlash">
- <cover-image
- style="width: 28px; height: 28px; margin: 0 auto"
- src="/static/scan/scan-code-light.png"
- ></cover-image>
- <cover-view style="color: rgba(255,255,255,0.7); font-size: 13px; margin-top: 10px;">
- {{ cameraFlash === "off" ? "轻触照亮" : "轻触关闭" }}
- </cover-view>
- </cover-view>
- <!-- <view class="action-buttons">
- <view class="action-btn" @click="chooseImage">
- <image class="action-icon" mode="widthFix" src="/static/scan/scan-code-album.png"></image>
- <view class="action-label">打开相册</view>
- </view>
- </view> -->
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { ref } from "vue";
- import { isDevTool } from "@/utils/device";
- import { onLoad } from "@dcloudio/uni-app";
- import { debounce } from "@/utils/common";
- const cameraHeight = ref(0);
- const cameraFlash = ref("off");
- onLoad(() => {
- const windowInfo = uni.getWindowInfo();
- const rpxRatio = windowInfo.windowWidth / 750;
- const actionBarH = 222 * rpxRatio;
- const systemInfo = uni.getSystemInfoSync();
- let safeBottom = 0;
- if (systemInfo.safeAreaInsets) {
- safeBottom = systemInfo.safeAreaInsets.bottom || 0;
- } else if (systemInfo.safeArea) {
- safeBottom = systemInfo.screenHeight - systemInfo.safeArea.bottom;
- }
- cameraHeight.value = windowInfo.windowHeight - actionBarH - safeBottom;
- });
- const handleReady = () => {
- // 相机就绪,页面已可正常使用
- };
- const handleScancode = (e: any) => {
- if (!e.detail || !e.detail.result) return;
- const shortId = e.detail.result.split("#")[1];
- uni.vibrateShort({});
- uni.navigateTo({
- url: '/pages-wash/device/index?shortId=' + shortId
- });
- };
- const debounceScan = debounce(handleScancode, 2000);
- const handleError = (e: any) => {
- if (e.detail && e.detail.errMsg && /auth/.test(e.detail.errMsg)) {
- uni.showModal({
- content: "请打开摄像头权限开关",
- success: () => {
- uni.openSetting();
- },
- });
- return;
- }
- uni.showModal({
- content: e.detail.errMsg,
- });
- };
- const toggleFlash = () => {
- cameraFlash.value = cameraFlash.value === "off" ? "on" : "off";
- };
- const chooseImage = () => {
- uni.chooseImage({
- count: 1,
- sizeType: ["compressed"],
- sourceType: ["album"],
- success: () => {
- uni.showLoading({ title: "正在识别" });
- },
- fail: (err) => {
- if (/cancel/.test(err.errMsg)) return;
- uni.showModal({ content: err.errMsg || "出现错误,请重试" });
- },
- });
- };
- </script>
- <style lang="scss" scoped>
- .page {
- position: relative;
- height: 100vh;
- background-color: #0d0d0d;
- overflow: hidden;
- }
- .camera-area {
- position: relative;
- overflow: hidden;
- }
- .mock-camera {
- background-color: $uni-text-color-tertiary;
- }
- .action-bar {
- position: relative;
- box-sizing: content-box;
- padding-bottom: constant(safe-area-inset-bottom);
- padding-bottom: env(safe-area-inset-bottom);
- }
- .flash-toggle {
- text-align: center;
- position: absolute;
- width: 100%;
- left: 0;
- top: -96px;
- }
- .action-buttons {
- height: 222rpx;
- display: flex;
- }
- .action-btn {
- width: 50%;
- height: 222rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .action-icon {
- width: 96rpx;
- }
- .action-label {
- font-size: 24rpx;
- color: #fff;
- margin-top: 20rpx;
- }
- </style>
|