wlzboy
2025-11-08 99f528e235f11126fea44480c6e8888a9e463f2f
ruoyi-ui/src/views/task/general/detail.vue
@@ -203,11 +203,38 @@
      </div>
      
      <el-table :data="taskDetail.attachments" v-loading="attachmentLoading">
        <el-table-column label="文件名" align="center" prop="fileName" />
        <el-table-column label="文件类型" align="center" prop="fileType" />
        <el-table-column label="文件大小" align="center" prop="fileSize">
        <el-table-column label="缩略图" align="center" width="120">
          <template slot-scope="scope">
            <span>{{ formatFileSize(scope.row.fileSize) }}</span>
            <el-image
              v-if="isImage(scope.row.fileType)"
              :src="scope.row.fileUrl"
              :preview-src-list="[scope.row.fileUrl]"
              fit="cover"
              style="width: 80px; height: 80px; border-radius: 4px; cursor: pointer;"
            >
              <div slot="error" class="image-slot">
                <i class="el-icon-picture-outline" style="font-size: 40px; color: #C0C4CC;"></i>
              </div>
            </el-image>
            <div v-else style="text-align: center;">
              <i class="el-icon-document" style="font-size: 40px; color: #909399;"></i>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="业务分类" align="center" prop="attachmentCategory" width="150">
          <template slot-scope="scope">
            <dict-tag :options="dict.type.sys_attachment_category" :value="scope.row.attachmentCategory"/>
          </template>
        </el-table-column>
        <el-table-column label="同步状态" align="center" width="120">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.syncedToImageData === 0" type="info" size="small">
              <i class="el-icon-warning"></i> 未同步
            </el-tag>
            <el-tag v-else-if="scope.row.syncedToImageData === 1" type="success" size="small">
              <i class="el-icon-success"></i> 已同步
            </el-tag>
            <span v-else style="color: #C0C4CC;">--</span>
          </template>
        </el-table-column>
        <el-table-column label="上传时间" align="center" prop="uploadTime" width="180">
@@ -388,21 +415,42 @@
    </el-dialog>
    <!-- 上传附件对话框 -->
    <el-dialog title="上传附件" :visible.sync="uploadOpen" width="500px" append-to-body>
      <el-upload
        class="upload-demo"
        drag
        :action="uploadUrl"
        :headers="uploadHeaders"
        :data="uploadData"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        :before-upload="beforeUpload"
        multiple>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">只能上传jpg/png/pdf/doc/docx文件,且不超过10MB</div>
      </el-upload>
    <el-dialog title="上传附件" :visible.sync="uploadOpen" width="500px" append-to-body @close="cancelUpload">
      <el-form ref="uploadForm" :model="uploadForm" :rules="uploadRules" label-width="100px">
        <el-form-item label="业务分类" prop="category">
          <el-select v-model="uploadForm.category" placeholder="请选择业务分类" clearable style="width: 100%;">
            <el-option
              v-for="dict in dict.type.sys_attachment_category"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="附件" prop="files">
          <el-upload
            ref="upload"
            class="upload-demo"
            :action="uploadUrl"
            :headers="uploadHeaders"
            :data="uploadData"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            :before-upload="beforeUpload"
            :file-list="fileList"
            :auto-upload="false"
            multiple
            drag>
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
            <div class="el-upload__tip" slot="tip">只能上传jpg/png/pdf/doc/docx文件,且不超过100MB</div>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitUpload">确 定</el-button>
        <el-button @click="cancelUpload">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
@@ -414,7 +462,7 @@
export default {
  name: "TaskDetail",
  dicts: ['sys_task_type', 'sys_task_status', 'sys_vehicle_type', 'sys_task_vehicle_status', 'sys_user_sex', 'hospital_department'],
  dicts: ['sys_task_type', 'sys_task_status', 'sys_vehicle_type', 'sys_task_vehicle_status', 'sys_user_sex', 'hospital_department', 'sys_attachment_category'],
  data() {
    return {
      // 任务详情
@@ -433,6 +481,12 @@
      vehicleAssignOpen: false,
      // 是否显示上传对话框
      uploadOpen: false,
      // 上传表单
      uploadForm: {
        category: null
      },
      // 文件列表
      fileList: [],
      // 编辑表单
      editForm: {},
      // 分配表单
@@ -449,7 +503,7 @@
      vehicleLoading: false,
      attachmentLoading: false,
      // 上传相关
      uploadUrl: process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + this.$route.params.taskId,
      uploadUrl: process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + (new URLSearchParams(window.location.search).get('taskId') || ''),
      uploadHeaders: {
        Authorization: "Bearer " + getToken()
      },
@@ -480,12 +534,19 @@
        vehicleIds: [
          { required: true, message: "车辆不能为空", trigger: "change" }
        ]
      },
      uploadRules: {
        category: [
          { required: true, message: "业务分类不能为空", trigger: "change" }
        ]
      }
    };
  },
  created() {
    this.getTaskDetail();
    this.getUserList();
    // 初始化上传URL
    this.uploadUrl = process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + this.$route.params.taskId;
  },
  methods: {
    /** 获取任务详情 */
@@ -554,6 +615,10 @@
    },
    /** 上传附件 */
    handleUpload() {
      this.uploadForm = {
        category: null
      };
      this.fileList = [];
      this.uploadOpen = true;
    },
    /** 取消车辆分配 */
@@ -648,22 +713,67 @@
    },
    /** 上传前检查 */
    beforeUpload(file) {
      // 检查是否选择了业务分类
      if (!this.uploadForm.category) {
        this.$message.error('请先选择业务分类!');
        return false;
      }
      // 更新uploadData,确保每次上传都带有category参数
      this.uploadData = {
        category: this.uploadForm.category
      };
      const isValidType = ['image/jpeg', 'image/png', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'].includes(file.type);
      const isLt10M = file.size / 1024 / 1024 < 10;
      const isLt10M = file.size / 1024 / 1024 < 100;
      if (!isValidType) {
        this.$message.error('只能上传 JPG/PNG/PDF/DOC/DOCX 格式的文件!');
        return false;
      }
      if (!isLt10M) {
        this.$message.error('上传文件大小不能超过 10MB!');
        this.$message.error('上传文件大小不能超过 100MB!');
        return false;
      }
      return isValidType && isLt10M;
      return true;
    },
    /** 提交上传 */
    submitUpload() {
      this.$refs["uploadForm"].validate(valid => {
        if (valid) {
          // 检查是否选择了文件
          const fileList = this.$refs.upload.uploadFiles;
          if (!fileList || fileList.length === 0) {
            this.$message.warning('请选择要上传的文件');
            return;
          }
          // 触发上传
          this.$refs.upload.submit();
        }
      });
    },
    /** 取消上传 */
    cancelUpload() {
      this.uploadOpen = false;
      this.uploadForm = {
        category: null
      };
      this.fileList = [];
      if (this.$refs.upload) {
        this.$refs.upload.clearFiles();
      }
    },
    /** 上传成功 */
    handleUploadSuccess(response, file, fileList) {
      this.$modal.msgSuccess("上传成功");
      this.uploadOpen = false;
      this.getTaskDetail();
      // 检查是否所有文件都上传完成
      const allDone = fileList.every(f => f.status === 'success' || f.status === 'fail');
      if (allDone) {
        this.$modal.msgSuccess("上传成功");
        this.cancelUpload();
        this.getTaskDetail();
      }
    },
    /** 上传失败 */
    handleUploadError(err, file, fileList) {
@@ -687,6 +797,12 @@
        return typeItem ? typeItem.label : vehicleType;
      }
      return vehicleType;
    },
    /** 判断是否为图片类型 */
    isImage(fileType) {
      if (!fileType) return false;
      const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
      return imageTypes.includes(fileType.toLowerCase());
    }
  }
};