From 64aaf44b6b2948631ebd0d9840d51e5e31ae5479 Mon Sep 17 00:00:00 2001
From: zhangchen <1652267879@qq.com>
Date: 星期五, 25 七月 2025 01:44:25 +0800
Subject: [PATCH] Merge branch 'ID1825-床旁副屏改版' into test

---
 src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue |  330 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 330 insertions(+), 0 deletions(-)

diff --git a/src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue b/src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue
new file mode 100644
index 0000000..10d1d6e
--- /dev/null
+++ b/src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue
@@ -0,0 +1,330 @@
+<template>
+  <div class="setting-device-dialog-container">
+    <el-dialog
+      v-model="isShow"
+      center
+      title="设置编号"
+      width="80%"
+      :show-close="false"
+      class="scheduled-task-dialog"
+    >
+      <template #header>
+        <div class="setting-dialog-header">
+          <span class="header-title">设置编号</span>
+          <img
+            :src="closeImg"
+            class="header-close"
+            @click="handleCancel"
+            alt=""
+          />
+        </div>
+      </template>
+      <div class="setting-device-dialog-content">
+        <div class="content-row1">
+          <div class="row1-label">设备编号</div>
+          <div class="row1-inp-box">
+            <input
+              v-model="devcieCode"
+              type="text"
+              class="row1-inp"
+              placeholder="请输入设备编号或扫码二维码"
+            />
+          </div>
+        </div>
+        <div class="content-row2">
+          <el-upload
+            v-loading="isUploading"
+            class="upload-demo"
+            drag
+            :show-file-list="false"
+            accept="image/*"
+            :limit="1"
+            :before-upload="onBeforeUpload"
+          >
+            <div class="el-upload__text">
+              <img :src="uploadImg" class="upload-img" alt="" />
+              <p class="upload-text">点击虚线区域选择文件并识别二维码</p>
+              <div class="upload-btn">二维码上传</div>
+            </div>
+          </el-upload>
+        </div>
+      </div>
+      <template #footer>
+        <div class="my-button cancel" @click="handleCancel">取消</div>
+        <div class="my-button confirm" @click="handleConfirm">确认</div>
+        <div class="my-button refresh" @click="handleRefresh">刷新</div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage, UploadRawFile } from "element-plus";
+import { ref } from "vue";
+import {
+  BrowserMultiFormatReader,
+  NotFoundException,
+  ChecksumException,
+  FormatException,
+} from "@zxing/library";
+import closeImg from "@/img/close.png";
+import uploadImg from "@/img/upload.png";
+import { useBedsideAuxiliaryScreenStore } from "@/store/bedsideAuxiliaryScreen";
+
+const bedsideAuxiliaryScreenStore = useBedsideAuxiliaryScreenStore();
+
+const isShow = ref(false);
+const isUploading = ref(false);
+const devcieCode = ref("");
+
+const openDialog = () => {
+  devcieCode.value = bedsideAuxiliaryScreenStore.deviceCode + "";
+  isShow.value = true;
+};
+
+const onBeforeUpload = async (uploadFile: UploadRawFile) => {
+  const file = uploadFile;
+  if (!file) return;
+
+  isUploading.value = true;
+  try {
+    const result = await decodeQRCodeFromFile(file);
+    devcieCode.value = result;
+    ElMessage.success("识别成功");
+  } catch (err) {
+    if (err instanceof NotFoundException) {
+      ElMessage.error("未找到二维码");
+    } else if (err instanceof ChecksumException) {
+      ElMessage.error("校验错误");
+    } else if (err instanceof FormatException) {
+      ElMessage.error("格式错误");
+    } else {
+      ElMessage.error("识别错误请重新识别");
+      console.error(err);
+    }
+  } finally {
+    isUploading.value = false;
+  }
+  return false;
+};
+
+const decodeQRCodeFromFile = async (file: File): Promise<string> => {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+
+    reader.onload = async (e: any) => {
+      const imageBase64 = e.target.result;
+      const codeReader = new BrowserMultiFormatReader();
+
+      try {
+        const result = await codeReader.decodeFromImage(undefined, imageBase64);
+        resolve(result.getText());
+      } catch (err) {
+        reject(err);
+      }
+    };
+
+    reader.onerror = () => reject(new Error("读取文件失败"));
+    reader.readAsDataURL(file);
+  });
+};
+
+const handleCancel = () => {
+  isShow.value = false;
+};
+
+const handleConfirm = () => {
+  bedsideAuxiliaryScreenStore.setDeviceCode(devcieCode.value + "");
+  handleRefresh();
+  handleCancel();
+};
+
+const handleRefresh = () => {
+    bedsideAuxiliaryScreenStore.refresh(
+    `${import.meta.env.VITE_SSE_BASE_URL}${devcieCode.value}`
+  );
+};
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style lang="less" scoped>
+.setting-device-dialog-container {
+  ::v-deep(.el-dialog) {
+    padding: 0;
+    border-radius: 6px;
+    overflow: hidden;
+  }
+  ::v-deep(.el-dialog__footer) {
+    padding: 4px;
+  }
+  ::v-deep(.el-upload-dragger) {
+    height: 65px;
+    padding: 0 !important;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  ::v-deep(.el-upload-dragger .el-icon--upload) {
+    display: none;
+  }
+  ::v-deep(.el-dialog__header) {
+    padding-bottom: 6px;
+  }
+  .setting-dialog-header {
+    position: relative;
+    height: 16px;
+    background: #769aff;
+    .header-title {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translateX(-50%) translateY(-50%);
+      font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
+      font-weight: 500;
+      font-size: 8px;
+      color: #ffffff;
+      line-height: 11px;
+      text-align: center;
+    }
+    .header-close {
+      position: absolute;
+      top: 50%;
+      transform: translateY(-50%);
+      right: 6px;
+      width: 15px;
+      height: 15px;
+      transition: transform 0.2s;
+
+      &:active {
+        opacity: 0.6;
+        transform: translateY(-50%) scale(0.95);
+      }
+    }
+  }
+  .setting-device-dialog-content {
+    padding: 0 12px 6px;
+    margin-bottom: 4px;
+    border-bottom: 1px solid #d8d8d8;
+    .content-row1 {
+      display: flex;
+      align-items: center;
+      margin-bottom: 6px;
+
+      .row1-label {
+        margin-right: 6px;
+        padding: 0 4px;
+        background: #769aff;
+        border-radius: 2px;
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 600;
+        font-size: 8px;
+        line-height: 16px;
+        color: #ffffff;
+        font-style: normal;
+      }
+      .row1-inp-box {
+        flex: 1;
+        height: 16px;
+        border-radius: 2px;
+        border: 1px solid #979797;
+        overflow: hidden;
+
+        .row1-inp {
+          width: 100%;
+          height: 100%;
+          border: none;
+          outline: none;
+          padding: 0 4px; 
+          line-height: 16px;
+          font-size: 9px;
+          font-family: PingFangSC, PingFang SC;
+          vertical-align: middle; 
+          box-sizing: border-box; // 避免padding撑高
+
+          &::placeholder {
+            font-family: inherit;
+            font-size: inherit;
+            line-height: inherit;
+            color: #aaaaaa;
+            opacity: 1;
+          }
+        }
+      }
+    }
+
+    .el-upload__text {
+      display: flex;
+      align-items: center;
+      flex-direction: column;
+      justify-content: center;
+      .upload-img {
+        height: 8px;
+      }
+      .upload-text {
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 500;
+        font-size: 5px;
+        color: #5a6470;
+        letter-spacing: 0px;
+        text-align: center;
+        font-style: normal;
+      }
+      .upload-btn {
+        padding: 0 2px;
+        background-color: #409eff;
+        border-radius: 1px;
+        font-family: PingFangSC, PingFang SC;
+        font-size: 4px;
+        color: #fff;
+        letter-spacing: 0px;
+        line-height: 8px;
+        text-align: center;
+        font-style: normal;
+      }
+    }
+  }
+
+  .my-button {
+    display: inline-block;
+    border-radius: 2px;
+    padding: 0px 10px;
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 500;
+    font-size: 7px;
+    color: #ffffff;
+    line-height: 16px;
+    letter-spacing: 1px;
+    text-align: center;
+    font-style: normal;
+    transition: transform 0.1s ease, opacity 0.1s ease;
+    cursor: pointer;
+    &:active {
+      transform: scale(0.95);
+      opacity: 0.8;
+    }
+
+    &:not(:first-child) {
+      margin-left: 6px;
+    }
+    &.cancel {
+      background: #bbc6dd;
+    }
+    &.confirm {
+      background: #769aff;
+    }
+    &.refresh {
+      background: #e6a23c;
+    }
+  }
+}
+</style>
+<style>
+.scheduled-task-dialog {
+  margin: 0 auto;
+  top: 50% !important;
+  transform: translateY(-50%) !important;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0