zhangwencui
2026-05-15 226a9245d5b060836ab0a858e1623d365113e9ac
上传封装组件,且设备保修应用
已添加1个文件
已修改1个文件
274 ■■■■■ 文件已修改
src/components/CommonUpload.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/add.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/CommonUpload.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,164 @@
<template>
  <view class="common-upload">
    <u-upload
      :fileList="internalFileList"
      @afterRead="afterRead"
      @delete="deleteFile"
      :name="name"
      :multiple="multiple"
      :maxCount="maxCount"
      :accept="accept"
      :disabled="disabled"
    ></u-upload>
  </view>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import { getToken } from "@/utils/auth";
import config from "@/config";
const props = defineProps({
  // çˆ¶ç»„件传入的文件列表(对应后端存储的对象列表)
  modelValue: {
    type: Array,
    default: () => []
  },
  // æœ€å¤§ä¸Šä¼ æ•°é‡
  maxCount: {
    type: Number,
    default: 9
  },
  // æ˜¯å¦æ”¯æŒå¤šé€‰
  multiple: {
    type: Boolean,
    default: true
  },
  // æŽ¥å—的文件类型
  accept: {
    type: String,
    default: 'image'
  },
  // ä¸Šä¼ æŽ¥å£å¯¹åº”的参数名
  name: {
    type: String,
    default: 'file'
  },
  // æ˜¯å¦ç¦ç”¨
  disabled: {
    type: Boolean,
    default: false
  }
});
const emit = defineEmits(['update:modelValue']);
// ç”¨äºŽ u-upload æ˜¾ç¤ºçš„内部列表
const internalFileList = ref([]);
// ç›‘听外部 modelValue å˜åŒ–,同步到内部显示列表
watch(() => props.modelValue, (newVal) => {
  if (newVal) {
    internalFileList.value = newVal.map(item => ({
      ...item,
      url: item.url || item.previewURL,
      status: 'success',
      message: ''
    }));
  }
}, { immediate: true, deep: true });
const showToast = (message) => {
  uni.showToast({
    title: message,
    icon: "none",
  });
};
// ä¸Šä¼ é€»è¾‘
const uploadFilePromise = (url) => {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: config.baseUrl + "/common/upload",
      filePath: url,
      name: "files", // æ³¨æ„ï¼šè¿™é‡Œæ ¹æ®åŽŸä»£ç æ˜¯ "files"
      header: {
        Authorization: "Bearer " + getToken(),
      },
      success: (res) => {
        try {
          const data = JSON.parse(res.data);
          if (data.code === 200) {
            // å¦‚果返回的是数组,取第一个元素
            const resultData = Array.isArray(data.data) ? data.data[0] : data.data;
            // å¤„理 url èµ‹å€¼
            if (!resultData.url && resultData.previewURL) {
              resultData.url = resultData.previewURL;
            }
            // å…¼å®¹åŽŸä»£ç ä¸­çš„ name èµ‹å€¼
            if (!resultData.name && resultData.originalFilename) {
              resultData.name = resultData.originalFilename;
            }
            resolve(resultData);
          } else {
            reject(data.msg || "上传失败");
          }
        } catch (e) {
          reject("解析响应失败");
        }
      },
      fail: (err) => {
        reject(err);
      },
    });
  });
};
// ä¸Šä¼ åŽçš„处理
const afterRead = async (event) => {
  let lists = [].concat(event.file);
  let currentModelValue = [...props.modelValue];
  // å…ˆåœ¨å†…部列表中添加占位(上传中状态)
  lists.forEach(item => {
    internalFileList.value.push({
      ...item,
      status: 'uploading',
      message: '上传中'
    });
  });
  for (let i = 0; i < lists.length; i++) {
    try {
      const result = await uploadFilePromise(lists[i].url);
      // æ›´æ–° modelValue
      currentModelValue.push(result);
      emit('update:modelValue', currentModelValue);
    } catch (e) {
      // å¦‚果上传失败,从内部列表中移除刚才添加的项
      const errorIndex = internalFileList.value.findIndex(item => item.status === 'uploading');
      if (errorIndex > -1) {
        internalFileList.value.splice(errorIndex, 1);
      }
      showToast(typeof e === "string" ? e : "上传失败");
    }
  }
};
// åˆ é™¤å¤„理
const deleteFile = (event) => {
  const newList = [...props.modelValue];
  newList.splice(event.index, 1);
  emit('update:modelValue', newList);
};
</script>
<style scoped lang="scss">
.common-upload {
  width: 100%;
}
</style>
src/pages/equipmentManagement/repair/add.vue
@@ -97,13 +97,7 @@
        <u-form-item label="图片附件"
                     prop="storageBlobDTOs"
                     border-bottom>
          <u-upload :fileList="fileList"
                    @afterRead="afterRead"
                    @delete="deleteFile"
                    name="file"
                    multiple
                    :maxCount="9"
                    accept="image"></u-upload>
          <CommonUpload v-model="form.storageBlobDTOs" />
        </u-form-item>
      </u-cell-group>
      <!-- æäº¤æŒ‰é’® -->
@@ -135,6 +129,7 @@
  import { ref, computed, onMounted, onUnmounted } from "vue";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import CommonUpload from "@/components/CommonUpload.vue";
  import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
  import {
    addRepair,
@@ -143,8 +138,6 @@
  } from "@/api/equipmentManagement/repair";
  import dayjs from "dayjs";
  import { formatDateToYMD } from "@/utils/ruoyi";
  import { getToken } from "@/utils/auth";
  import config from "@/config";
  const showToast = message => {
    uni.showToast({
      title: message,
@@ -210,8 +203,6 @@
    storageBlobDTOs: [], // å›¾ç‰‡é™„ä»¶
  });
  const fileList = ref([]);
  // æŠ¥ä¿®çŠ¶æ€é€‰é¡¹
  const repairStatusOptions = ref([
    { name: "待维修", value: "0" },
@@ -265,15 +256,6 @@
          form.value.machineryCategory = data.machineryCategory;
          form.value.remark = data.remark;
          form.value.storageBlobDTOs = data.storageBlobVOs || [];
          // è®¾ç½®å›¾ç‰‡åˆ—表显示
          if (data.storageBlobVOs && data.storageBlobVOs.length > 0) {
            fileList.value = data.storageBlobVOs.map(item => ({
              url: item.url,
              name: item.name,
              status: "success",
              message: "",
            }));
          }
          repairStatusText.value =
            repairStatusOptions.value.find(item => item.value == data.status)
              ?.name || "";
@@ -377,94 +359,6 @@
    form.value.repairTime = formatDateToYMD(e.value);
    pickerDateValue.value = dayjs(e.value).format("YYYY-MM-DD");
    showDate.value = false;
  };
  // å›¾ç‰‡ä¸Šä¼ åŽçš„处理
  const afterRead = async event => {
    // å½“设置 mutiple ä¸º true æ—¶, file ä¸ºæ•°ç»„格式,否则为对象格式
    let lists = [].concat(event.file);
    let fileListLen = fileList.value.length;
    lists.map(item => {
      fileList.value.push({
        ...item,
        status: "uploading",
        message: "上传中",
      });
    });
    for (let i = 0; i < lists.length; i++) {
      try {
        const result = await uploadFilePromise(lists[i].url);
        let item = fileList.value[fileListLen];
        fileList.value.splice(
          fileListLen,
          1,
          Object.assign(item, {
            status: "success",
            message: "",
            url: result.url,
            name: result.name,
          })
        );
        // åŒæ­¥åˆ°è¡¨å•数据
        form.value.storageBlobDTOs.push(result);
        fileListLen++;
      } catch (e) {
        let item = fileList.value[fileListLen];
        fileList.value.splice(
          fileListLen,
          1,
          Object.assign(item, {
            status: "failed",
            message: "上传失败",
          })
        );
        showToast(typeof e === "string" ? e : "上传失败");
      }
    }
  };
  const uploadFilePromise = url => {
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        url: config.baseUrl + "/common/upload",
        filePath: url,
        name: "files",
        header: {
          Authorization: "Bearer " + getToken(),
        },
        success: res => {
          try {
            const data = JSON.parse(res.data);
            if (data.code === 200) {
              // å¦‚果返回的是数组,取第一个元素,避免嵌套数组
              const resultData = Array.isArray(data.data)
                ? data.data[0]
                : data.data;
              // å¦‚æžœ url ä¸ºç©ºä¸” previewURL å­˜åœ¨ï¼Œåˆ™å¤„理 previewURL èµ‹å€¼ç»™ url
              if (!resultData.url && resultData.previewURL) {
                resultData.url = resultData.previewURL;
              }
              resultData.name = resultData.originalFilename;
              resolve(resultData);
            } else {
              reject(data.msg || "上传失败");
            }
          } catch (e) {
            reject("解析响应失败");
          }
        },
        fail: err => {
          reject(err);
        },
      });
    });
  };
  const deleteFile = event => {
    fileList.value.splice(event.index, 1);
    form.value.storageBlobDTOs.splice(event.index, 1);
  };
  onShow(() => {