Просмотр исходного кода

feat: 扫码后先开门再选择补货/盘点 + 图标下方加文字

- 扫码解析deviceId后调用openDeviceDoor开门
- 开门成功弹出补货/盘点选项 失败提示重试
- 图标下方显示「扫码开门」文字
- scan-area包裹按钮+文字 统一居中定位

Co-Authored-By: Claude <noreply@anthropic.com>
skyline 2 дней назад
Родитель
Сommit
d60636b0a1
1 измененных файлов с 23 добавлено и 7 удалено
  1. 23 7
      haha-admin-mp/src/pages/replenish/home.vue

+ 23 - 7
haha-admin-mp/src/pages/replenish/home.vue

@@ -51,10 +51,13 @@
     </scroll-view>
 
     <!-- 扫码浮钮 -->
-    <view class="scan-fab" @click="handleScan">
-      <view class="scan-icon">
-        <view class="scan-beam"></view>
+    <view class="scan-area" @click="handleScan">
+      <view class="scan-fab">
+        <view class="scan-icon">
+          <view class="scan-beam"></view>
+        </view>
       </view>
+      <text class="scan-label">扫码开门</text>
     </view>
   </view>
 </template>
@@ -62,7 +65,7 @@
 <script setup lang="ts">
 import { ref, onMounted } from 'vue';
 import { onShow } from '@dcloudio/uni-app';
-import { getDeviceList } from '@/api/replenish';
+import { getDeviceList, openDeviceDoor } from '@/api/replenish';
 import { clearAuth } from '@/utils/auth';
 
 const statusBarHeight = ref(0);
@@ -90,7 +93,7 @@ const handleScan = () => {
   uni.scanCode({
     onlyFromCamera: true,
     scanType: ['qrCode', 'barCode'],
-    success: (res: any) => {
+    success: async (res: any) => {
       // 与 haha-mp 一致的 deviceId 提取逻辑
       let deviceId = '';
       try {
@@ -112,6 +115,17 @@ const handleScan = () => {
         return;
       }
 
+      // 先开门
+      uni.showLoading({ title: '开门中...', mask: true });
+      try {
+        await openDeviceDoor(deviceId);
+      } catch {
+        uni.hideLoading();
+        uni.showToast({ title: '开门失败,请重试', icon: 'none' });
+        return;
+      }
+      uni.hideLoading();
+
       uni.showActionSheet({
         itemList: ['设备补货', '库存盘点'],
         success: (sheetRes) => {
@@ -199,9 +213,11 @@ onShow(async () => { await loadData(); });
   &:active { opacity: 0.7; }
 }
 
-.scan-fab { position: fixed; left: 50%; bottom: calc(120rpx + env(safe-area-inset-bottom)); transform: translateX(-50%); width: 128rpx; height: 128rpx; border-radius: 50%; background: $primary-color; box-shadow: 0 12rpx 36rpx rgba(255,193,7,0.4); display: flex; align-items: center; justify-content: center; z-index: 1000;
-  &:active { transform: translateX(-50%) scale(0.92); background: $primary-color-dark; }
+.scan-area { position: fixed; left: 50%; bottom: calc(80rpx + env(safe-area-inset-bottom)); transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 12rpx; z-index: 1000; }
+.scan-fab { width: 128rpx; height: 128rpx; border-radius: 50%; background: $primary-color; box-shadow: 0 12rpx 36rpx rgba(255,193,7,0.4); display: flex; align-items: center; justify-content: center;
+  &:active { transform: scale(0.92); background: $primary-color-dark; }
 }
+.scan-label { font-size: 24rpx; font-weight: 500; color: $primary-color-dark; }
 .scan-icon { width: 50rpx; height: 50rpx; position: relative;
   &::before { content: ''; position: absolute; top: 0; left: 0; width: 14rpx; height: 14rpx; border-top: 4rpx solid $text-color-primary; border-left: 4rpx solid $text-color-primary; border-radius: 4rpx 0 0 0; }
   &::after { content: ''; position: absolute; bottom: 0; right: 0; width: 14rpx; height: 14rpx; border-bottom: 4rpx solid $text-color-primary; border-right: 4rpx solid $text-color-primary; border-radius: 0 0 4rpx 0; }