revert: 恢复扫码页为双按钮版本(拍照+相册)

This commit is contained in:
2026-08-12 16:53:31 +08:00
parent 8303c8b93f
commit 9f3deb5b6c

View File

@ -1,30 +1,50 @@
<template>
<view class="page">
<!-- 扫码大按钮 -->
<view class="scan-btn" @tap="handleScanCode">
<!-- 🚀 全屏扫码大按钮 -->
<view class="scan-area">
<view class="scan-btn camera-btn" @tap="handleScanCamera">
<text class="scan-icon">📷</text>
<text class="scan-text">点击扫码</text>
<text class="scan-hint">扫描二维码 / 条码查询产品</text>
<text class="scan-text">拍照扫码</text>
<text class="scan-hint">全屏扫描二维码 / 条码</text>
</view>
<view class="scan-btn album-btn" @tap="handleScanAlbum">
<text class="scan-icon">🖼</text>
<text class="scan-text">从相册选择</text>
<text class="scan-hint">识别图片中的二维码</text>
</view>
</view>
<!-- 手动输入 -->
<view class="manual-section">
<text class="section-label">或手动输入</text>
<view class="manual-input">
<input v-model="serialNumber" class="input" type="text" maxlength="16"
placeholder="手动输入16位身份证" @confirm="handleSearch" />
placeholder="输入16位身份证" @confirm="handleSearch" />
<button class="search-btn" @tap="handleSearch" :disabled="loading">
{{ loading ? '查询中' : '查询' }}
</button>
</view>
</view>
<!-- 最近扫描 -->
<view v-if="lastScanned" class="last-scan">最近扫描: <text class="sn-text">{{ lastScanned }}</text></view>
<view v-if="loading" class="loading">查询中...</view>
<view v-if="error" class="error-box">{{ error }}</view>
<view v-if="lastScanned" class="last-scan">
<text class="last-label">最近扫描</text>
<text class="sn-text" @tap="handleSearch">{{ lastScanned }}</text>
</view>
<view v-if="loading" class="loading">
<text class="loading-icon"></text>
<text>查询中...</text>
</view>
<view v-if="error" class="error-box">
<text class="error-icon"></text>
<text>{{ error }}</text>
</view>
<!-- 空状态 -->
<view v-if="!loading && !error" class="empty">
<view v-if="!loading && !error && !lastScanned" class="empty">
<text class="empty-icon">📱</text>
<text class="empty-text">扫码或手动输入身份证查询产品进度</text>
<text class="empty-text">扫码或手动输入身份证</text>
<text class="empty-sub">查询产品流转进度</text>
</view>
</view>
</template>
@ -58,9 +78,12 @@ export default {
}
},
handleSearch() { this.doQuery(this.serialNumber.trim()); },
handleScanCode() {
// 📷 全屏相机扫码
handleScanCamera() {
uni.scanCode({
onlyFromCamera: true, scanType: ["qrCode", "barCode"],
onlyFromCamera: true,
scanType: ["qrCode", "barCode"],
success: (res) => {
const sn = (res.result || "").replace(/[^a-zA-Z0-9]/g, "").slice(0, 16);
this.doQuery(sn);
@ -72,27 +95,99 @@ export default {
},
});
},
// 🖼️ 从相册识别二维码
handleScanAlbum() {
uni.chooseImage({
count: 1,
sizeType: ["original", "compressed"],
sourceType: ["album"],
success: (chooseRes) => {
const path = chooseRes.tempFilePaths[0];
if (!path) return;
// 使用 uni.getImageInfo 获取图片后,再调用 scanCode 的 base64 模式
// 或者直接用 #ifdef 编译条件
// #ifdef APP-PLUS
this.decodeQRFromImage(path);
// #endif
// #ifndef APP-PLUS
uni.scanCode({
onlyFromCamera: false,
scanType: ["qrCode"],
success: (scanRes) => {
const sn = (scanRes.result || "").replace(/[^a-zA-Z0-9]/g, "").slice(0, 16);
this.doQuery(sn);
},
fail: () => {
uni.showToast({ title: "未识别到二维码", icon: "none" });
},
});
// #endif
},
fail: (err) => {
if (!err.errMsg || !err.errMsg.includes("cancel")) {
uni.showToast({ title: "选择失败", icon: "none" });
}
},
});
},
// APP-PLUS: 从图片解码二维码
decodeQRFromImage(path) {
// #ifdef APP-PLUS
plus.barcode.scan(path, (type, result) => {
const sn = (result || "").replace(/[^a-zA-Z0-9]/g, "").slice(0, 16);
this.doQuery(sn);
}, (err) => {
uni.showToast({ title: "未识别到二维码", icon: "none" });
}, {
filters: ["QRCODE"],
scanBoth: true,
});
// #endif
},
},
};
</script>
<style scoped>
.page { min-height: 100vh; padding: 40px 16px 16px; }
.scan-btn { display: flex; flex-direction: column; align-items: center; justify-content: center;
height: 180px; background: linear-gradient(135deg, #2563EB, #3B82F6);
border-radius: 16px; color: #fff; box-shadow: 0 4px 16px rgba(37,99,235,0.3); }
.scan-icon { font-size: 52px; margin-bottom: 8px; }
.scan-text { font-size: 20px; font-weight: 700; }
.scan-hint { font-size: 13px; opacity: 0.8; margin-top: 4px; }
.manual-input { display: flex; gap: 8px; margin-top: 16px; }
.input { flex: 1; height: 44px; padding: 0 12px; border: 1px solid #e5e7eb; border-radius: 10px; font-size: 14px; background: #fff; }
.search-btn { height: 44px; padding: 0 20px; background: #2563EB; color: #fff; border: none; border-radius: 10px; font-size: 14px; font-weight: 600; line-height: 44px; }
.search-btn[disabled] { opacity: 0.6; }
.last-scan { font-size: 12px; color: #9ca3af; margin-top: 16px; }
.sn-text { font-family: monospace; color: #4b5563; }
.loading { text-align: center; padding: 24px 0; color: #6b7280; }
.error-box { padding: 12px; border-radius: 10px; background: #fef2f2; color: #dc2626; font-size: 13px; border: 1px solid #fecaca; margin-top: 12px; }
.empty { display: flex; flex-direction: column; align-items: center; padding-top: 40px; color: #9ca3af; }
.empty-icon { font-size: 48px; margin-bottom: 8px; }
.empty-text { font-size: 14px; }
.page { min-height: 100vh; padding: 24px 16px 16px; background: #f3f4f6; }
/* 扫码区域 */
.scan-area { display: flex; gap: 12px; }
.scan-btn { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
height: 160px; border-radius: 20px; color: #fff; box-shadow: 0 4px 20px rgba(0,0,0,0.12);
transition: transform 0.15s; }
.scan-btn:active { transform: scale(0.96); }
.camera-btn { background: linear-gradient(135deg, #2563EB, #4F46E5); }
.album-btn { background: linear-gradient(135deg, #7C3AED, #A855F7); }
.scan-icon { font-size: 44px; margin-bottom: 6px; }
.scan-text { font-size: 17px; font-weight: 700; }
.scan-hint { font-size: 11px; opacity: 0.75; margin-top: 4px; }
/* 手动输入 */
.manual-section { margin-top: 24px; }
.section-label { font-size: 12px; color: #9ca3af; margin-bottom: 8px; display: block; }
.manual-input { display: flex; gap: 8px; }
.input { flex: 1; height: 48px; padding: 0 14px; border: 1px solid #e5e7eb; border-radius: 12px;
font-size: 15px; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.04); }
.search-btn { height: 48px; padding: 0 22px; background: #2563EB; color: #fff; border: none;
border-radius: 12px; font-size: 15px; font-weight: 600; line-height: 48px; }
.search-btn[disabled] { opacity: 0.5; }
/* 状态 */
.last-scan { display: flex; align-items: center; gap: 8px; margin-top: 20px; padding: 12px 16px;
background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
.last-label { font-size: 12px; color: #9ca3af; }
.sn-text { font-family: monospace; font-size: 14px; color: #2563EB; font-weight: 600; flex: 1; }
.loading { display: flex; align-items: center; justify-content: center; gap: 8px;
padding: 24px 0; color: #6b7280; font-size: 14px; }
.loading-icon { font-size: 20px; }
.error-box { display: flex; align-items: center; gap: 8px; margin-top: 16px; padding: 14px;
border-radius: 12px; background: #fef2f2; color: #dc2626; font-size: 13px; border: 1px solid #fecaca; }
.error-icon { font-size: 16px; }
.empty { display: flex; flex-direction: column; align-items: center; padding-top: 60px; color: #9ca3af; }
.empty-icon { font-size: 56px; margin-bottom: 12px; }
.empty-text { font-size: 15px; font-weight: 500; }
.empty-sub { font-size: 12px; margin-top: 4px; }
</style>