chenhj
5 天以前 2fc58fbb10745abd97168b8da21d4142e11d7f2e
新增设备维修保养过程描述,上传对应附件
已添加3个文件
已修改5个文件
272 ■■■■■ 文件已修改
src/api/basicData/common.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ImagePreview/ImagePreviewDialog.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ImageUpload/ImageUpload.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Form/RepairForm.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/index.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/Form/PlanForm.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/Modal/PlanModal.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/index.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/basicData/common.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
import request from '@/utils/request'
export function upload(data) {
    return request({
        url: '/common/minioUploads',
        method: 'post',
        data: data,
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    })
}
src/components/ImagePreview/ImagePreviewDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<template>
  <el-dialog
      v-model="visible"
      title="图片预览"
      width="800px"
      destroy-on-close
      align-center
  >
    <el-carousel
        v-if="images.length"
        height="450px"
        indicator-position="outside"
        arrow="always"
    >
      <el-carousel-item
          v-for="(img, index) in images"
          :key="index"
      >
        <el-image
            :src="img"
            fit="contain"
            style="width: 100%; height: 100%"
            :preview-src-list="images"
            :initial-index="index"
            preview-teleported
        />
      </el-carousel-item>
    </el-carousel>
    <div v-else class="empty">
      æš‚无图片
    </div>
  </el-dialog>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  images: {
    type: Array,
    default: () => []
  }
})
const emit = defineEmits(['update:modelValue'])
const visible = computed({
  get: () => props.modelValue,
  set: val => emit('update:modelValue', val)
})
</script>
<style scoped>
.empty {
  text-align: center;
  color: #999;
  padding: 80px 0;
}
</style>
src/components/ImageUpload/ImageUpload.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
<template>
  <el-upload
      class="image-upload"
      list-type="picture-card"
      :file-list="fileList"
      action="#"
      :http-request="customUpload"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-preview="handlePreview"
      :multiple="true"
  >
    <el-icon>
      <Plus/>
    </el-icon>
  </el-upload>
</template>
<script>
import {Plus} from '@element-plus/icons-vue'
import {upload} from "@/api/basicData/common.js";
export default {
  name: 'ImageUpload',
  emits: ['update:value'],
  components: {Plus},
  props: {
    value: {
      type: Array,
      default: () => []
    },
    type: {
      type: Number,
      required: true
    },
    bucketName: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      fileList: []
    }
  },
  watch: {
    /** ç¼–辑回显 */
    value: {
      immediate: true,
      handler(val) {
        this.fileList = (val || []).map((item, index) => ({
          id: item.id,
          name: item.originalFilename || `image_${index}`,
          url: item.url,
          status: 'success',
          response: item
        }))
      }
    }
  },
  methods: {
    beforeUpload(file) {
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        this.$message.error('只能上传图片')
      }
      return isImage
    },
    customUpload({file, onSuccess, onError}) {
      const formData = new FormData()
      formData.append('file', file)
      formData.append('bucketName', this.bucketName === '' ? undefined : this.bucketName)
      formData.append('type', this.type)
      upload(formData).then(res => {
        this.fileList.push({
          id: res.data[0].id,
          name: res.data[0].originalFilename,
          url: res.data[0].url,
          status: 'success',
          response: res.data[0]
        })
        onSuccess(res.data)
        this.emitChange()
      }).catch(err => {
        onError(err)
      })
    },
    handleRemove(file, fileList) {
      this.fileList = fileList
      this.emitChange()
    },
    handlePreview(file) {
      window.open(file.url)
    },
    emitChange() {
      this.$emit('update:value', this.fileList.map(item => item.response))   // v-model
    }
  }
}
</script>
<style scoped>
.image-upload ::v-deep(.el-upload--picture-card) {
  width: 120px;
  height: 120px;
}
</style>
src/views/equipmentManagement/repair/Form/RepairForm.vue
@@ -50,6 +50,21 @@
          />
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="过程描述">
          <el-input
              v-model="form.maintenanceProcessDesc"
              :rows="2"
              type="textarea"
              placeholder="请输入过程描述"
          />
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="附件">
          <image-upload v-model:value="form.files" :type="4"/>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
@@ -58,6 +73,7 @@
import useFormData from "@/hooks/useFormData";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import useUserStore from "@/store/modules/user";
import ImageUpload from "@/components/ImageUpload/ImageUpload.vue";
defineOptions({
  name: "设备报修表单",
@@ -78,6 +94,8 @@
  repairTime: undefined, // æŠ¥ä¿®æ—¥æœŸ
  repairName: userStore.nickName, // æŠ¥ä¿®äºº
  remark: undefined, // æ•…障现象
  maintenanceProcessDesc: undefined,
  files: []
});
const setDeviceModel = (id) => {
@@ -96,6 +114,8 @@
  form.repairTime = data.repairTime;
  form.repairName = data.repairName;
  form.remark = data.remark;
  form.maintenanceProcessDesc = data.maintenanceProcessDesc;
  form.files = data.files;
};
// onMounted(() => {
src/views/equipmentManagement/repair/index.vue
@@ -119,6 +119,14 @@
            ç¼–辑
          </el-button>
          <el-button
              type="primary"
              text
              icon="editPen"
              @click="showImage(row)"
          >
            é™„ä»¶
          </el-button>
          <el-button
            type="danger"
            text
            icon="delete"
@@ -131,17 +139,19 @@
    </div>
    <RepairModal ref="repairModalRef" @ok="getTableData" />
    <MaintainModal ref="maintainModalRef" @ok="getTableData" />
    <ImagePreviewDialog v-model:model-value="showImages" :images="imageUrls" />
  </div>
</template>
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
import {getRepairPage, delRepair, getRepairById} from "@/api/equipmentManagement/repair";
import { onMounted, getCurrentInstance } from "vue";
import RepairModal from "./Modal/RepairModal.vue";
import { ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
import MaintainModal from "./Modal/MaintainModal.vue";
import ImagePreviewDialog from "@/components/ImagePreview/ImagePreviewDialog.vue";
defineOptions({
  name: "设备报修",
@@ -152,6 +162,9 @@
// æ¨¡æ€æ¡†å®žä¾‹
const repairModalRef = ref();
const maintainModalRef = ref();
const showImages = ref(false)
const imageUrls = ref([])
// è¡¨æ ¼å¤šé€‰æ¡†é€‰ä¸­é¡¹
const multipleList = ref([]);
@@ -231,7 +244,7 @@
      dataType: "slot",
      slot: "operation",
      align: "center",
      width: "200px",
      width: "300px",
    },
  ]
);
@@ -309,6 +322,12 @@
    });
};
const showImage = async (row) => {
  const {data} = await getRepairById(row.id)
  imageUrls.value = data?.files.map((item) => item.url)
  showImages.value = true
}
onMounted(() => {
  getTableData();
});
src/views/equipmentManagement/upkeep/Form/PlanForm.vue
@@ -35,6 +35,17 @@
        clearable
      />
    </el-form-item>
    <el-form-item label="过程描述">
      <el-input
          v-model="form.maintenanceProcessDesc"
          :rows="2"
          type="textarea"
          placeholder="请输入过程描述"
      />
    </el-form-item>
    <el-form-item label="附件">
      <image-upload v-model:value="form.files" :type="5"/>
    </el-form-item>
  </el-form>
</template>
@@ -43,6 +54,7 @@
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import { onMounted } from "vue";
import dayjs from "dayjs";
import ImageUpload from "@/components/ImageUpload/ImageUpload.vue";
defineOptions({
  name: "计划表单",
@@ -59,6 +71,8 @@
  deviceName: undefined, // è®¾å¤‡åç§°
  deviceModel: undefined, // è§„格型号
  maintenancePlanTime: undefined, // è®¡åˆ’保养日期
  maintenanceProcessDesc: undefined,
  files: [],
});
const setDeviceModel = (id) => {
@@ -78,6 +92,8 @@
  form.deviceLedgerId = data.deviceLedgerId;
  form.deviceName = data.deviceName;
  form.deviceModel = data.deviceModel;
  form.maintenanceProcessDesc = data.maintenanceProcessDesc;
  form.files = data.files;
  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
    "YYYY-MM-DD HH:mm:ss"
  );
src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
@@ -2,7 +2,7 @@
  <el-dialog
    v-model="visible"
    :title="modalOptions.title"
    width="30%"
    width="50%"
    @close="close"
  >
    <PlanForm ref="planFormRef"></PlanForm>
src/views/equipmentManagement/upkeep/index.vue
@@ -107,6 +107,14 @@
            ç¼–辑
          </el-button>
          <el-button
              type="primary"
              text
              icon="editPen"
              @click="showImage(row)"
          >
            é™„ä»¶
          </el-button>
          <el-button
            type="danger"
            text
            icon="delete"
@@ -119,15 +127,17 @@
    </div>
    <PlanModal ref="planModalRef" @ok="getTableData" />
    <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
    <ImagePreviewDialog v-model:model-value="showImages" :images="imageUrls" />
  </div>
</template>
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
import { getUpkeepPage, delUpkeep } from "@/api/equipmentManagement/upkeep";
import {getUpkeepPage, delUpkeep, getUpkeepById} from "@/api/equipmentManagement/upkeep";
import { onMounted, getCurrentInstance } from "vue";
import PlanModal from "./Modal/PlanModal.vue";
import MaintenanceModal from "./Modal/MaintenanceModal.vue";
import ImagePreviewDialog from "@/components/ImagePreview/ImagePreviewDialog.vue";
import dayjs from "dayjs";
import { ElMessageBox, ElMessage } from "element-plus";
@@ -144,6 +154,9 @@
// è¡¨æ ¼å¤šé€‰æ¡†é€‰ä¸­é¡¹
const multipleList = ref([]);
const showImages = ref(false)
const imageUrls = ref([])
// å¤šé€‰åŽåšä»€ä¹ˆ
const handleSelectionChange = (selectionList) => {
@@ -225,7 +238,7 @@
    dataType: "slot",
    slot: "operation",
    align: "center",
    width: "200px",
    width: "300px",
  },
]);
// type == 1实际保养时间 2计划保养时间
@@ -296,6 +309,12 @@
    });
};
const showImage = async (row) => {
  const {data} = await getUpkeepById(row.id)
  imageUrls.value = data?.files.map((item) => item.url)
  showImages.value = true
}
onMounted(() => {
  getTableData();
});