zhangwencui
16 小时以前 a3b12f19ce05ca3c665ebeeea5d91dbf1516a3f0
保养上传附件
已添加1个文件
已修改3个文件
1087 ■■■■ 文件已修改
src/api/equipmentManagement/upkeep.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/upkeep/fileList.vue 562 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/upkeep/index.vue 491 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/upkeep.js
@@ -70,3 +70,30 @@
    method: "delete",
  });
};
// æŸ¥è¯¢ä¿å…»ä»»åŠ¡é™„ä»¶åˆ—è¡¨
export function listMaintenanceTaskFiles(query) {
  return request({
    url: "/maintenanceTaskFile/listPage",
    method: "get",
    params: query,
  });
}
// æ–°å¢žä¿å…»ä»»åС附件
export function addMaintenanceTaskFile(data) {
  return request({
    url: "/maintenanceTaskFile/add",
    method: "post",
    data,
  });
}
// åˆ é™¤ä¿å…»ä»»åС附件
export function delMaintenanceTaskFile(id) {
  return request({
    url: "/maintenanceTaskFile/del",
    method: "delete",
    data: Array.isArray(id) ? id : [id],
  });
}
src/pages.json
@@ -541,6 +541,13 @@
      }
    },
    {
      "path": "pages/equipmentManagement/upkeep/fileList",
      "style": {
        "navigationBarTitleText": "保养文件管理",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/equipmentManagement/inspection/index",
      "style": {
        "navigationBarTitleText": "设备巡检",
src/pages/equipmentManagement/upkeep/fileList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,562 @@
<template>
  <view class="file-list-page">
    <!-- é¡µé¢å¤´éƒ¨ -->
    <PageHeader title="附件管理"
                @back="goBack" />
    <!-- é™„件列表 -->
    <view class="file-list-container">
      <view v-if="fileList.length > 0"
            class="file-list">
        <view v-for="(file, index) in fileList"
              :key="file.id || index"
              class="file-item">
          <!-- æ–‡ä»¶å›¾æ ‡ -->
          <!-- <view class="file-icon"
                :class="getFileIconClass(file.fileType)">
            <up-icon :name="getFileIcon(file.fileType)"
                     size="24"
                     color="#ffffff" />
          </view> -->
          <!-- æ–‡ä»¶ä¿¡æ¯ -->
          <view class="file-info">
            <text class="file-name">{{ file.name }}</text>
            <!-- <text class="file-meta">{{ formatFileSize(file.fileSize) }} Â· {{ file.uploadTime || file.createTime }}</text> -->
          </view>
          <!-- æ“ä½œæŒ‰é’® -->
          <view class="file-actions">
            <!-- <u-button size="small"
                      type="primary"
                      plain
                      @click="previewFile(file)">预览</u-button> -->
            <u-button size="small"
                      type="info"
                      plain
                      @click="downloadFile(file)">下载并预览</u-button>
            <u-button size="small"
                      type="error"
                      plain
                      @click="confirmDelete(file, index)">删除</u-button>
          </view>
        </view>
      </view>
      <!-- ç©ºçŠ¶æ€ -->
      <view v-else
            class="empty-state">
        <up-icon name="document"
                 size="64"
                 color="#c0c4cc" />
        <text class="empty-text">暂无附件</text>
      </view>
    </view>
    <!-- <a rel="nofollow"
       id="downloadLink"
       href="#"
       style="display:none;">下载文本文件</a> -->
    <!-- ä¸Šä¼ æŒ‰é’® -->
    <view class="upload-button"
          @click="chooseFile">
      <up-icon name="plus"
               size="24"
               color="#ffffff" />
      <text class="upload-text">上传附件</text>
    </view>
  </view>
</template>
<script setup>
  import { ref, onMounted } from "vue";
  import PageHeader from "@/components/PageHeader.vue";
  import config from "@/config";
  import { getToken } from "@/utils/auth";
  // import { saveAs } from "file-saver";
  import {
    listMaintenanceTaskFiles,
    addMaintenanceTaskFile,
    delMaintenanceTaskFile,
  } from "@/api/equipmentManagement/upkeep";
  import { blobValidate } from "@/utils/ruoyi";
  // é™„件列表
  const fileList = ref([]);
  // è¿”回上一页
  const goBack = () => {
    uni.navigateBack();
  };
  // const request = axios.create({
  //   baseURL: "URL.com",
  //   adapter: axiosAdapterUniapp,
  // });
  // èŽ·å–æ–‡ä»¶å›¾æ ‡
  const getFileIcon = fileType => {
    const iconMap = {
      doc: "document",
      docx: "document",
      xls: "grid",
      xlsx: "grid",
      pdf: "document",
      ppt: "copy",
      pptx: "copy",
      txt: "document",
      jpg: "image",
      jpeg: "image",
      png: "image",
      gif: "image",
      zip: "folder",
      rar: "folder",
    };
    return iconMap[fileType.toLowerCase()] || "document";
  };
  // èŽ·å–æ–‡ä»¶å›¾æ ‡æ ·å¼ç±»
  const getFileIconClass = fileType => {
    const colorMap = {
      doc: "blue",
      docx: "blue",
      xls: "green",
      xlsx: "green",
      pdf: "red",
      ppt: "orange",
      pptx: "orange",
      txt: "gray",
      jpg: "purple",
      jpeg: "purple",
      png: "purple",
      gif: "purple",
      zip: "yellow",
      rar: "yellow",
    };
    return colorMap[fileType.toLowerCase()] || "gray";
  };
  // æ ¼å¼åŒ–文件大小
  const formatFileSize = bytes => {
    if (bytes === 0) return "0 B";
    const k = 1024;
    const sizes = ["B", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  };
  // é€‰æ‹©æ–‡ä»¶
  const chooseFile = () => {
    uni.chooseImage({
      count: 9,
      sizeType: ["original", "compressed"],
      sourceType: ["album", "camera"],
      success: res => {
        console.log(res, "选择图片成功");
        uploadFiles(res.tempFiles);
      },
      fail: err => {
        console.error("选择图片失败:", err);
        showToast("选择文件失败");
      },
    });
    // uni.chooseFile({
    //   count: 9,
    //   extension: [
    //     ".doc",
    //     ".docx",
    //     ".xls",
    //     ".xlsx",
    //     ".pdf",
    //     ".ppt",
    //     ".pptx",
    //     ".txt",
    //     ".jpg",
    //     ".jpeg",
    //     ".png",
    //     ".gif",
    //     ".zip",
    //     ".rar",
    //   ],
    //   success: res => {
    //     console.log(res, "选择文件成功");
    //     uploadFiles(res.tempFiles);
    //   },
    //   fail: err => {
    //     showToast("选择文件失败");
    //   },
    // });
  };
  // ä¸Šä¼ æ–‡ä»¶
  const uploadFiles = tempFiles => {
    console.log(tempFiles, "上传文件1");
    tempFiles.forEach((tempFile, index) => {
      // æ˜¾ç¤ºä¸Šä¼ ä¸­æç¤º
      uni.showLoading({
        title: "上传中...",
        mask: true,
      });
      console.log(tempFile, "上传文件2");
      // 1. ç›´æŽ¥ä½¿ç”¨ uni.uploadFile ä¸Šä¼ æ–‡ä»¶
      uni.uploadFile({
        url: config.baseUrl + "/file/upload",
        filePath: tempFile.path,
        name: "file",
        header: {
          Authorization: "Bearer " + getToken(),
        },
        success: uploadRes => {
          uni.hideLoading();
          console.log(uploadRes, "上传文件3");
          try {
            const res = JSON.parse(uploadRes.data);
            console.log(res, "上传文件4");
            if (res.code === 200) {
              // 2. æå–文件信息
              const fileName = tempFile.name
                ? tempFile.name
                : tempFile.path.split("/").pop();
              // const fileType = fileName.split(".").pop();
              // 3. æž„造保存文件信息的参数
              const saveData = {
                name: fileName,
                deviceMaintenanceId: upkeepId.value,
                url: res.data.tempPath || "",
              };
              console.log(saveData, "保存文件信息参数");
              // 4. è°ƒç”¨ addRuleFile æŽ¥å£ä¿å­˜æ–‡ä»¶ä¿¡æ¯
              addMaintenanceTaskFile(saveData)
                .then(addRes => {
                  if (addRes.code === 200) {
                    // 5. æ·»åŠ åˆ°æ–‡ä»¶åˆ—è¡¨
                    const newFile = {
                      ...addRes.data,
                      uploadTime: new Date().toLocaleString(),
                    };
                    // fileList.value.push(newFile);
                    getFileList();
                    showToast("上传成功");
                  } else {
                    showToast("保存文件信息失败");
                  }
                })
                .catch(err => {
                  console.error("保存文件信息失败:", err);
                  showToast("保存文件信息失败");
                });
            } else {
              showToast("文件上传失败");
            }
          } catch (e) {
            console.error("解析上传结果失败:", e);
            showToast("上传失败");
          }
        },
        fail: err => {
          uni.hideLoading();
          console.error("上传失败:", err);
          showToast("上传失败");
        },
      });
    });
  };
  // ä¸‹è½½æ–‡ä»¶
  const downloadFile = file => {
    var url =
      config.baseUrl +
      "/common/download?fileName=" +
      encodeURIComponent(file.url) +
      "&delete=true";
    console.log(url, "url");
    uni
      .downloadFile({
        url: url,
        responseType: "blob",
        header: { Authorization: "Bearer " + getToken() },
      })
      .then(res => {
        let osType = uni.getStorageSync("deviceInfo").osName;
        let filePath = res.tempFilePath;
        if (osType === "ios") {
          uni.openDocument({
            filePath: filePath,
            showMenu: true,
            success: res => {},
            fail: err => {
              console.log("uni.openDocument--fail");
              reject(err);
            },
          });
        } else {
          uni.saveFile({
            tempFilePath: filePath,
            success: fileRes => {
              uni.showToast({
                icon: "none",
                mask: true,
                title:
                  "文件已保存:Android/data/uni.UNI720216F/apps/__UNI__720216F/" +
                  fileRes.savedFilePath, //保存路径
                duration: 3000,
              });
              setTimeout(() => {
                //打开文档查看
                uni.openDocument({
                  filePath: fileRes.savedFilePath,
                  success: function (res) {},
                });
              }, 1000);
            },
            fail: err => {
              console.log("uni.save--fail");
              reject(err);
            },
          });
        }
        // const isBlob = blobValidate(res.data);
        // if (isBlob) {
        //   const blob = new Blob([res.data], { type: "text/plain" });
        //   const url = URL.createObjectURL(blob);
        //   const downloadLink = document.getElementById("downloadLink");
        //   downloadLink.href = url;
        //   downloadLink.download = file.name;
        //   downloadLink.click();
        //   showToast("下载成功");
        // } else {
        //   showToast("下载失败");
        // }
      })
      .catch(err => {
        console.error("下载失败:", err);
        showToast("下载失败");
      });
  };
  // ç¡®è®¤åˆ é™¤
  const confirmDelete = (file, index) => {
    uni.showModal({
      title: "删除确认",
      content: `确定要删除附件 "${file.name}" å—?`,
      success: res => {
        if (res.confirm) {
          deleteFile(file.id, index);
        }
      },
    });
  };
  // åˆ é™¤æ–‡ä»¶
  const deleteFile = (fileId, index) => {
    uni.showLoading({
      title: "删除中...",
      mask: true,
    });
    delMaintenanceTaskFile([fileId])
      .then(res => {
        uni.hideLoading();
        if (res.code === 200) {
          // fileList.value.splice(index, 1);
          getFileList();
          showToast("删除成功");
        } else {
          showToast("删除失败");
        }
      })
      .catch(err => {
        uni.hideLoading();
        showToast("删除失败");
      });
  };
  // æ˜¾ç¤ºæç¤º
  const showToast = message => {
    uni.showToast({
      title: message,
      icon: "none",
    });
  };
  const rulesRegulationsManagementId = ref("");
  const upkeepId = ref("");
  // é¡µé¢åŠ è½½æ—¶
  onMounted(() => {
    // ä»Ž API èŽ·å–é™„ä»¶åˆ—è¡¨
    // ä»Žæœ¬åœ°å­˜å‚¨èŽ·å– rulesRegulationsManagementId
    rulesRegulationsManagementId.value = uni.getStorageSync(
      "rulesRegulationsManagement"
    );
    upkeepId.value = uni.getStorageSync("upkeepId");
    getFileList();
  });
  // èŽ·å–é™„ä»¶åˆ—è¡¨
  const getFileList = () => {
    uni.showLoading({
      title: "加载中...",
      mask: true,
    });
    listMaintenanceTaskFiles({
      current: 1,
      size: 100,
      deviceMaintenanceId: upkeepId.value,
      rulesRegulationsManagementId: upkeepId.value,
    })
      .then(res => {
        uni.hideLoading();
        if (res.code === 200) {
          fileList.value = res.data.records || [];
        } else {
          showToast("获取附件列表失败");
        }
      })
      .catch(err => {
        uni.hideLoading();
        showToast("获取附件列表失败");
      });
  };
</script>
<style scoped lang="scss">
  @import "../../../styles/sales-common.scss";
  .file-list-page {
    min-height: 100vh;
    background: #f8f9fa;
    padding-bottom: 100rpx;
  }
  .file-list-container {
    padding: 20rpx;
  }
  .file-list {
    background: #ffffff;
    border-radius: 8rpx;
    overflow: hidden;
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  }
  .file-item {
    display: flex;
    align-items: center;
    padding: 20rpx;
    border-bottom: 1rpx solid #f0f0f0;
    &:last-child {
      border-bottom: none;
    }
  }
  .file-icon {
    width: 56rpx;
    height: 56rpx;
    border-radius: 8rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 20rpx;
    &.blue {
      background: #409eff;
    }
    &.green {
      background: #67c23a;
    }
    &.red {
      background: #f56c6c;
    }
    &.orange {
      background: #e6a23c;
    }
    &.gray {
      background: #909399;
    }
    &.purple {
      background: #909399;
    }
    &.yellow {
      background: #e6a23c;
    }
  }
  .file-info {
    flex: 1;
    min-width: 0;
  }
  .file-name {
    display: block;
    font-size: 16px;
    color: #303133;
    margin-bottom: 8rpx;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .file-meta {
    display: block;
    font-size: 12px;
    color: #909399;
  }
  .file-actions {
    display: flex;
    gap: 12rpx;
  }
  .empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 100rpx 0;
    background: #ffffff;
    border-radius: 8rpx;
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  }
  .empty-text {
    font-size: 14px;
    color: #909399;
    margin-top: 20rpx;
  }
  .upload-button {
    position: fixed;
    bottom: 40rpx;
    right: 40rpx;
    width: 130rpx;
    height: 130rpx;
    border-radius: 50%;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.4);
    z-index: 1000;
  }
  .upload-text {
    font-size: 10px;
    color: #ffffff;
    margin-top: 4rpx;
  }
  .upload-progress {
    padding: 40rpx 0;
  }
  .upload-progress-text {
    display: block;
    text-align: center;
    margin-top: 20rpx;
    font-size: 14px;
    color: #606266;
  }
</style>
src/pages/equipmentManagement/upkeep/index.vue
@@ -1,44 +1,50 @@
<template>
  <view class="sales-account">
    <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
    <PageHeader title="设备保养" @back="goBack" />
    <PageHeader title="设备保养"
                @back="goBack" />
    <!-- æœç´¢åŒºåŸŸ -->
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <up-input
            class="search-text"
            placeholder="请输入设备名称搜索"
            v-model="searchKeyword"
            @change="getList"
            clearable
          />
          <up-input class="search-text"
                    placeholder="请输入设备名称搜索"
                    v-model="searchKeyword"
                    @change="getList"
                    clearable />
        </view>
        <view class="filter-button" @click="getList">
          <up-icon name="search" size="24" color="#999"></up-icon>
        <view class="filter-button"
              @click="getList">
          <up-icon name="search"
                   size="24"
                   color="#999"></up-icon>
        </view>
      </view>
    </view>
    <!-- è®¾å¤‡ä¿å…»åˆ—表 -->
    <view class="ledger-list" v-if="upkeepList.length > 0">
      <view v-for="(item, index) in upkeepList" :key="index">
        <view class="ledger-item" @click="toggleSelection(item)">
    <view class="ledger-list"
          v-if="upkeepList.length > 0">
      <view v-for="(item, index) in upkeepList"
            :key="index">
        <view class="ledger-item"
              @click="toggleSelection(item)">
          <view class="item-header">
            <view class="item-left">
              <view class="document-icon">
                <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
                <up-icon name="file-text"
                         size="16"
                         color="#ffffff"></up-icon>
              </view>
              <text class="item-id">设备名称:{{ item.deviceName }}</text>
            </view>
            <view class="status-tag">
              <u-tag v-if="item.status === 1" type="success">完结</u-tag>
              <u-tag v-if="item.status === 0" type="error">待保养</u-tag>
              <u-tag v-if="item.status === 1"
                     type="success">完结</u-tag>
              <u-tag v-if="item.status === 0"
                     type="error">待保养</u-tag>
            </view>
          </view>
          <up-divider></up-divider>
          <view class="item-details">
            <view class="detail-row">
              <text class="detail-label">规格型号</text>
@@ -67,267 +73,282 @@
            <view class="detail-row">
              <text class="detail-label">保养结果</text>
              <view class="detail-value">
              <u-tag v-if="item.maintenanceResult === 1" type="success" size="mini">
                å®Œå¥½
              </u-tag>
              <u-tag v-if="item.maintenanceResult === 0" type="error" size="mini">
                ç»´ä¿®
              </u-tag>
              <text v-if="item.maintenanceResult === undefined || item.maintenanceResult === null">-</text>
            </view>
                <u-tag v-if="item.maintenanceResult === 1"
                       type="success"
                       size="mini">
                  å®Œå¥½
                </u-tag>
                <u-tag v-if="item.maintenanceResult === 0"
                       type="error"
                       size="mini">
                  ç»´ä¿®
                </u-tag>
                <text v-if="item.maintenanceResult === undefined || item.maintenanceResult === null">-</text>
              </view>
            </view>
          </view>
          <!-- æŒ‰é’®åŒºåŸŸ -->
          <view class="action-buttons">
            <u-button
              type="primary"
              size="small"
              class="action-btn"
              :disabled="item.status === 1"
              @click.stop="edit(item.id)"
            >
            <u-button type="primary"
                      size="small"
                      class="action-btn"
                      :disabled="item.status === 1"
                      @click.stop="edit(item.id)">
              ç¼–辑
            </u-button>
            <u-button
              type="warning"
              size="small"
              class="action-btn"
              :disabled="item.status === 1"
              @click.stop="addMaintain(item.id)"
            >
            <u-button type="warning"
                      size="small"
                      class="action-btn"
                      :disabled="item.status === 1"
                      @click.stop="addMaintain(item.id)">
              ä¿å…»
            </u-button>
            <u-button
              type="error"
              size="small"
              plain
              class="action-btn"
              @click.stop="delUpkeepByIds(item.id)"
            >
            <u-button type="error"
                      size="small"
                      plain
                      class="action-btn"
                      @click.stop="delUpkeepByIds(item.id)">
              åˆ é™¤
            </u-button>
            <u-button type="warning"
                      size="small"
                      class="action-btn"
                      @click.stop="addFile(item.id)">
              é™„ä»¶
            </u-button>
          </view>
        </view>
      </view>
    </view>
    <view v-else class="no-data">
    <view v-else
          class="no-data">
      <text>暂无设备保养数据</text>
    </view>
    <!-- æµ®åŠ¨æ–°å¢žæŒ‰é’® -->
    <view class="fab-button" @click="addPlan">
      <up-icon name="plus" size="24" color="#ffffff"></up-icon>
    <view class="fab-button"
          @click="addPlan">
      <up-icon name="plus"
               size="24"
               color="#ffffff"></up-icon>
    </view>
  </view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import PageHeader from '@/components/PageHeader.vue'
import { getUpkeepPage, delUpkeep } from '@/api/equipmentManagement/upkeep'
import useUserStore from "@/store/modules/user"
// æ˜¾ç¤ºæç¤ºä¿¡æ¯
const showToast = (message) => {
  uni.showToast({
    title: message,
    icon: 'none'
  })
};
import dayjs from "dayjs"
  import { ref, onMounted } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import { getUpkeepPage, delUpkeep } from "@/api/equipmentManagement/upkeep";
  import useUserStore from "@/store/modules/user";
  // æ˜¾ç¤ºæç¤ºä¿¡æ¯
  const showToast = message => {
    uni.showToast({
      title: message,
      icon: "none",
    });
  };
  import dayjs from "dayjs";
const userStore = useUserStore()
  const userStore = useUserStore();
// æœç´¢å…³é”®è¯
const searchKeyword = ref('')
  // æœç´¢å…³é”®è¯
  const searchKeyword = ref("");
// è®¾å¤‡ä¿å…»æ•°æ®
const upkeepList = ref([])
  // è®¾å¤‡ä¿å…»æ•°æ®
  const upkeepList = ref([]);
// å¤šé€‰åˆ—表
const multipleList = ref([])
  // å¤šé€‰åˆ—表
  const multipleList = ref([]);
// è¿”回上一页
const goBack = () => {
  uni.navigateBack()
}
  // è¿”回上一页
  const goBack = () => {
    uni.navigateBack();
  };
// æ ¼å¼åŒ–日期
const formatDate = (dateStr) => {
  if (!dateStr) return ''
  return dayjs(dateStr).format("YYYY-MM-DD")
}
  // æ ¼å¼åŒ–日期
  const formatDate = dateStr => {
    if (!dateStr) return "";
    return dayjs(dateStr).format("YYYY-MM-DD");
  };
// æ ¼å¼åŒ–日期时间
const formatDateTime = (dateStr) => {
  if (!dateStr) return ''
  return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss")
}
  // æ ¼å¼åŒ–日期时间
  const formatDateTime = dateStr => {
    if (!dateStr) return "";
    return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss");
  };
// æŸ¥è¯¢åˆ—表
const getList = () => {
  showLoadingToast('加载中...')
  const params = {
    current: -1,
    size: -1,
    deviceName: searchKeyword.value || undefined
  }
  getUpkeepPage(params)
    .then((res) => {
      // å¦‚æžœres.data不是数组,设置为空数组
      upkeepList.value = res.records || res.data?.records || []
      closeToast()
    })
    .catch(() => {
      closeToast()
      showToast('获取数据失败')
    })
}
  // æŸ¥è¯¢åˆ—表
  const getList = () => {
    showLoadingToast("加载中...");
    const params = {
      current: -1,
      size: -1,
      deviceName: searchKeyword.value || undefined,
    };
    getUpkeepPage(params)
      .then(res => {
        // å¦‚æžœres.data不是数组,设置为空数组
        upkeepList.value = res.records || res.data?.records || [];
        closeToast();
      })
      .catch(() => {
        closeToast();
        showToast("获取数据失败");
      });
  };
  // æ–°å¢žé™„ä»¶ - è·³è½¬åˆ°é™„件页面
  const addFile = id => {
    // ä½¿ç”¨æœ¬åœ°å­˜å‚¨ä¼ é€’id
    uni.setStorageSync("upkeepId", id);
    uni.navigateTo({
      url: "/pages/equipmentManagement/upkeep/fileList",
    });
  };
// æ˜¾ç¤ºåŠ è½½æç¤º
const showLoadingToast = (message) => {
  uni.showLoading({
    title: message,
    mask: true
  });
};
  // æ˜¾ç¤ºåŠ è½½æç¤º
  const showLoadingToast = message => {
    uni.showLoading({
      title: message,
      mask: true,
    });
  };
// å…³é—­æç¤º
const closeToast = () => {
  uni.hideLoading();
};
  // å…³é—­æç¤º
  const closeToast = () => {
    uni.hideLoading();
  };
// åˆ‡æ¢é€‰æ‹©çŠ¶æ€
const toggleSelection = (item) => {
  const index = multipleList.value.findIndex(selected => selected.id === item.id)
  if (index > -1) {
    multipleList.value.splice(index, 1)
  } else {
    multipleList.value.push(item)
  }
}
// æ£€æŸ¥æ˜¯å¦å·²é€‰æ‹©
const isSelected = (item) => {
  return multipleList.value.some(selected => selected.id === item.id)
}
// æ–°å¢žä¿å…» - è·³è½¬åˆ°ä¿å…»é¡µé¢
const addMaintain = (id) => {
  if (!id && multipleList.value.length !== 1) {
    showToast('请选择一条记录')
    return
  }
  const targetId = id || multipleList.value[0].id
  // ä½¿ç”¨æœ¬åœ°å­˜å‚¨ä¼ é€’id
  uni.setStorageSync('repairId', targetId)
  uni.navigateTo({
    url: '/pages/equipmentManagement/upkeep/maintain'
  })
}
// æ–°å¢žè®¡åˆ’ - è·³è½¬åˆ°æ–°å¢žé¡µé¢
const addPlan = () => {
  uni.navigateTo({
    url: '/pages/equipmentManagement/upkeep/add'
  })
}
// ç¼–辑 - è·³è½¬åˆ°add页面,通过id区分新增还是编辑
const edit = (id) => {
  if (!id) return
  // ä½¿ç”¨æœ¬åœ°å­˜å‚¨ä¼ é€’id
  uni.setStorageSync('repairId', id)
  uni.navigateTo({
    url: '/pages/equipmentManagement/upkeep/add'
  })
}
// åˆ é™¤ä¿å…»æ•°æ®
const delUpkeepByIds = async (ids) => {
  const deleteIds = Array.isArray(ids) ? ids : [ids]
  if (deleteIds.length === 0) {
    showToast('请选择要删除的记录')
    return
  }
  uni.showModal({
    title: '警告',
    content: '确认删除保养数据, æ­¤æ“ä½œä¸å¯é€†?',
    confirmText: '确定',
    cancelText: '取消',
    success: async (res) => {
      if (!res.confirm) return
      try {
        // é€ä¸ªåˆ é™¤
        for (const id of deleteIds) {
          const response = await delUpkeep(id)
          if (response.code !== 200) {
            showToast('删除失败')
            return
          }
        }
        showToast('删除成功')
        multipleList.value = []
        getList()
      } catch (e) {
        showToast('删除失败')
      }
  // åˆ‡æ¢é€‰æ‹©çŠ¶æ€
  const toggleSelection = item => {
    const index = multipleList.value.findIndex(
      selected => selected.id === item.id
    );
    if (index > -1) {
      multipleList.value.splice(index, 1);
    } else {
      multipleList.value.push(item);
    }
  })
}
  };
onMounted(() => {
  getList()
})
  // æ£€æŸ¥æ˜¯å¦å·²é€‰æ‹©
  const isSelected = item => {
    return multipleList.value.some(selected => selected.id === item.id);
  };
onShow(() => {
  getList()
})
  // æ–°å¢žä¿å…» - è·³è½¬åˆ°ä¿å…»é¡µé¢
  const addMaintain = id => {
    if (!id && multipleList.value.length !== 1) {
      showToast("请选择一条记录");
      return;
    }
    const targetId = id || multipleList.value[0].id;
    // ä½¿ç”¨æœ¬åœ°å­˜å‚¨ä¼ é€’id
    uni.setStorageSync("repairId", targetId);
    uni.navigateTo({
      url: "/pages/equipmentManagement/upkeep/maintain",
    });
  };
  // æ–°å¢žè®¡åˆ’ - è·³è½¬åˆ°æ–°å¢žé¡µé¢
  const addPlan = () => {
    uni.navigateTo({
      url: "/pages/equipmentManagement/upkeep/add",
    });
  };
  // ç¼–辑 - è·³è½¬åˆ°add页面,通过id区分新增还是编辑
  const edit = id => {
    if (!id) return;
    // ä½¿ç”¨æœ¬åœ°å­˜å‚¨ä¼ é€’id
    uni.setStorageSync("repairId", id);
    uni.navigateTo({
      url: "/pages/equipmentManagement/upkeep/add",
    });
  };
  // åˆ é™¤ä¿å…»æ•°æ®
  const delUpkeepByIds = async ids => {
    const deleteIds = Array.isArray(ids) ? ids : [ids];
    if (deleteIds.length === 0) {
      showToast("请选择要删除的记录");
      return;
    }
    uni.showModal({
      title: "警告",
      content: "确认删除保养数据, æ­¤æ“ä½œä¸å¯é€†?",
      confirmText: "确定",
      cancelText: "取消",
      success: async res => {
        if (!res.confirm) return;
        try {
          // é€ä¸ªåˆ é™¤
          for (const id of deleteIds) {
            const response = await delUpkeep(id);
            if (response.code !== 200) {
              showToast("删除失败");
              return;
            }
          }
          showToast("删除成功");
          multipleList.value = [];
          getList();
        } catch (e) {
          showToast("删除失败");
        }
      },
    });
  };
  onMounted(() => {
    getList();
  });
  onShow(() => {
    getList();
  });
</script>
<style scoped lang="scss">
@import '@/styles/sales-common.scss';
  @import "@/styles/sales-common.scss";
// è®¾å¤‡ä¿å…»ç‰¹æœ‰æ ·å¼
.sales-account {
  padding-bottom: 80px; // ä¸ºæµ®åŠ¨æŒ‰é’®ç•™å‡ºç©ºé—´
}
  // è®¾å¤‡ä¿å…»ç‰¹æœ‰æ ·å¼
  .sales-account {
    padding-bottom: 80px; // ä¸ºæµ®åŠ¨æŒ‰é’®ç•™å‡ºç©ºé—´
  }
.action-section {
  padding: 10px 20px;
  background: #ffffff;
  border-bottom: 1px solid #f0f0f0;
}
  .action-section {
    padding: 10px 20px;
    background: #ffffff;
    border-bottom: 1px solid #f0f0f0;
  }
.action-section .action-buttons {
  gap: 8px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 12px ä¸åŒ
  justify-content: flex-start;
}
  .action-section .action-buttons {
    gap: 8px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 12px ä¸åŒ
    justify-content: flex-start;
  }
.checkbox-wrapper {
  display: flex;
  align-items: center;
}
  .checkbox-wrapper {
    display: flex;
    align-items: center;
  }
.status-tag {
  display: flex;
  align-items: center;
}
  .status-tag {
    display: flex;
    align-items: center;
  }
.detail-label {
  min-width: 80px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 60px ä¸åŒ
}
  .detail-label {
    min-width: 80px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 60px ä¸åŒ
  }
.detail-value {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
  .detail-value {
    display: flex;
    justify-content: flex-end;
    align-items: center;
  }
.ledger-item .action-buttons {
  gap: 8px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 12px ä¸åŒ
}
  .ledger-item .action-buttons {
    gap: 8px; // ä¸Žå…¬å…±æ ·å¼ä¸­çš„ 12px ä¸åŒ
  }
</style>