From 771cd475a2aad9938f4e2085ca018ba31bdc1d7f Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Thu, 20 Nov 2025 14:11:03 +0800
Subject: [PATCH] feat:工单详情

---
 src/views/tickets/ticketComponent/TicketDetailDialog.vue | 1247 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 727 insertions(+), 520 deletions(-)

diff --git a/src/views/tickets/ticketComponent/TicketDetailDialog.vue b/src/views/tickets/ticketComponent/TicketDetailDialog.vue
index dc1acca..af8f87a 100644
--- a/src/views/tickets/ticketComponent/TicketDetailDialog.vue
+++ b/src/views/tickets/ticketComponent/TicketDetailDialog.vue
@@ -15,8 +15,7 @@
         </div>
         <div class="event-title-center">{{ currentDetail.orderName || '事件名称' }}</div>
       </div>
-      <div v-if="totalTime" class="event-total-time">总耗时:{{ totalTime }}</div>
-      
+      <div v-if="totalTime" class="event-total-time">总耗时:{{ totalTime }}</div>   
       <!-- 工单状态流程 -->
       <div class="custom-steps-container">
         <!-- 标题行 -->
@@ -380,392 +379,431 @@
   </el-dialog>
 </template>
 
-<script>
+<script setup>
+import { ref, computed, watch, nextTick } from 'vue';
 import { flowEvent, getStepInfo } from '@/api/tickets/ticket';
 import { getSmallImg, getShowImg } from '@/utils/util';
 import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue';
-
-export default {
-  name: 'TicketDetailDialog',
-  components: {
-    CreateQRcode
+import { ElMessage} from 'element-plus';
+// 定义props
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
   },
-  props: {
-    modelValue: {
-      type: Boolean,
-      default: false
+  currentDetail: {
+    type: Object,
+    default: () => ({})
+  },
+  currentIndex: {
+    type: Number,
+    default: 0
+  },
+  totalItems: {
+    type: Number,
+    default: 0
+  },
+  algorithms: {
+    type: Array,
+    default: () => []
+  },
+  types: {
+    type: Array,
+    default: () => []
+  },
+  permission: {
+    type: Object,
+    default: () => ({})
+  },
+  stepStatusList: {
+    type: Array,
+    default: () => []
+  },
+  workType: {
+    type: Number,
+    default: 0
+  }
+});
+
+// 定义emits
+const emit = defineEmits([
+  'update:modelValue',
+  'detail-success',
+  'detail-error',
+  'prev-item',
+  'next-item',
+  'update:currentDetail',
+  'approve-and-dispatch'
+]);
+
+// 响应式数据
+const stepInfos = ref([]);
+const totalTime = ref('');
+const approveLoading = ref(false);
+const rejectLoading = ref(false);
+const dispatchLoading = ref(false);
+const completeLoading = ref(false);
+const finalizeLoading = ref(false);
+const uploadRef = ref(null);
+const mapContainerRef = ref(null);
+
+// 计算属性
+const dialogVisible = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(value) {
+    emit('update:modelValue', value);
+  }
+});
+
+const isEditMode = computed(() => {
+  return props.currentDetail.status === -1;
+});
+
+const formattedDetailFields = computed(() => {
+  const fields = [
+    { label: '工单名称', value: props.currentDetail.orderName },
+    {
+      label: '工单类型',
+      value: props.types.find(t => t.value === props.currentDetail.type)?.label || props.currentDetail.type,
     },
-    currentDetail: {
-      type: Object,
-      default: () => ({})
+    { label: '关联任务', value: props.currentDetail.job_name || '/' },
+    { label: '工单创建人', value: props.currentDetail.creator },
+    { label: '当前状态', value: mapStatus(props.currentDetail.status) },
+    { label: '事件地址', value: props.currentDetail.address || props.currentDetail.latAndLon },
+    {
+      label: '关联算法',
+      value: props.algorithms.find(t => t.value === props.currentDetail.aiType)?.label || props.currentDetail.aiType,
     },
-    currentIndex: {
-      type: Number,
-      default: 0
-    },
-    totalItems: {
-      type: Number,
-      default: 0
-    },
-    algorithms: {
-      type: Array,
-      default: () => []
-    },
-    types: {
-      type: Array,
-      default: () => []
-    },
-    permission: {
-      type: Object,
-      default: () => ({})
-    },
-    stepStatusList: {
-      type: Array,
-      default: () => []
-    },
-    workType: {
-      type: Number,
-      default: 0
+    { label: '发起单位', value: props.currentDetail.department },
+    { label: '发起任务时间', value: props.currentDetail.startTime },
+    { label: '工单内容', value: props.currentDetail.content },
+  ];
+
+  const filteredFields = fields.filter(field => field.value !== '/');
+  const formattedFields = [];
+  for (let i = 0; i < filteredFields.length; i += 2) {
+    formattedFields.push({
+      label1: filteredFields[i]?.label || '',
+      value1: filteredFields[i]?.value || (filteredFields[i]?.label ? '暂无数据' : ''),
+      label2: filteredFields[i + 1]?.label || '',
+      value2: filteredFields[i + 1]?.value || (filteredFields[i + 1]?.label ? '暂无数据' : ''),
+    });
+  }
+
+  return formattedFields;
+});
+
+// 监听
+watch(
+  () => props.modelValue,
+  (newVal) => {
+    if (newVal) {
+      loadStepInfo();
+      initMap();
+    }
+  }
+);
+
+watch(
+  () => props.currentDetail,
+  (newVal) => {
+    if (newVal && dialogVisible.value) {
+      loadStepInfo();
+      initMap();
     }
   },
-  emits: [
-    'update:modelValue',
-    'detail-success',
-    'detail-error',
-    'prev-item',
-    'next-item',
-    'update:currentDetail'
-  ],
-  data() {
-    return {
-      stepInfos: [],
-      totalTime: '',
-      approveLoading: false,
-      rejectLoading: false,
-      dispatchLoading: false,
-      completeLoading: false,
-      finalizeLoading: false
+  { deep: true }
+);
+
+// 方法
+const handleClose = () => {
+  dialogVisible.value = false;
+};
+
+const handlePrev = () => {
+  if (props.currentIndex > 0) {
+    emit('prev-item');
+  }
+};
+
+const handleNext = () => {
+  if (props.currentIndex < props.totalItems - 1) {
+    emit('next-item');
+  }
+};
+
+const loadStepInfo = async () => {
+  try {
+    const stepResponse = await getStepInfo(props.currentDetail.orderNumber);
+    const steps = Array.isArray(stepResponse.data.data)
+      ? stepResponse.data.data
+      : stepResponse.data.data?.steps || [];
+    
+    const finishedStep = steps.find(s => String(s.status) === '4');
+    totalTime.value = finishedStep && finishedStep.total_time ? finishedStep.total_time : '';
+    
+    stepInfos.value = steps.map(step => ({
+      status: String(step.status),
+      name: step.name,
+      time: step.time,
+      create_time: step.create_time,
+    }));
+  } catch (error) {
+    stepInfos.value = [];
+  }
+};
+
+const initMap = () => {
+  nextTick(() => {
+    if (mapContainerRef.value && mapContainerRef.value.initAddEntity && props.currentDetail.location) {
+      mapContainerRef.value.initAddEntity('point', props.currentDetail.location);
+    }
+  });
+};
+
+const mapStatus = (status) => {
+  const statusTextMap = {
+    '-1': '草稿',
+    2: '待审核',
+    0: '待处理',
+    3: '处理中',
+    4: '已完成',
+  };
+  return statusTextMap[status] || '未知状态';
+};
+
+const getStepHandler = (status) => {
+  const step = stepInfos.value.find(step => step.status === status);
+  return step ? step.name : '';
+};
+
+const getStepTime = (status) => {
+  const step = stepInfos.value.find(step => step.status === status);
+  return step && step.time && step.time !== '0' ? step.time : false;
+};
+
+const getStepCreateTime = (status) => {
+  const step = stepInfos.value.find(step => step.status === status);
+  return step ? step.create_time : null;
+};
+
+const getActiveStep = () => {
+  const arr = props.stepStatusList;
+  const index = arr.indexOf(String(props.currentDetail.status));
+  return index !== -1 ? index + 2 : 1;
+};
+
+const handleQRCode = (val) => {
+  emit('update:currentDetail', {
+    ...props.currentDetail,
+    showQR: !val.showQR
+  });
+};
+
+const getThumbUrl = (url) => {
+  if (!url) return '';
+  return getSmallImg(url);
+};
+
+const getPreviewUrl = (url) => {
+  if (!url) return '';
+  return getShowImg(url);
+};
+
+const hasProcessingBtnPermission = () => {
+  return props.permission && props.permission.tickets_processing_btn === true;
+};
+
+const hasProcessedAndOverBtnPermission = () => {
+  return props.permission && props.permission.tickets_view_processedAndOver === true;
+};
+
+const hasReviewBtnPermission = () => {
+  return props.permission && props.permission.tickets_review_btn === true;
+};
+
+// 文件操作方法
+const handleFileChange = (file, fileList) => {
+  emit('update:currentDetail', {
+    ...props.currentDetail,
+    photos: fileList
+  });
+};
+
+const handleUploadRemove = (file, fileList) => {
+  emit('update:currentDetail', {
+    ...props.currentDetail,
+    photos: fileList
+  });
+};
+
+const beforeUpload = (file) => {
+  const isImage = file.type.includes('image');
+  const isLt5M = file.size / 1024 / 1024 < 5;
+
+  if (!isImage) {
+    ElMessage.error('只能上传图片文件!');
+    return false;
+  }
+  if (!isLt5M) {
+    ElMessage.error('图片大小不能超过5MB!');
+    return false;
+  }
+  return true;
+};
+
+// 工单操作方法
+const handleApprove = async () => {
+  if (approveLoading.value) return;
+  approveLoading.value = true;
+  
+  try {
+    const data = {
+      id: props.currentDetail.id,
+      status: props.currentDetail.status,
+      isPass: 0,
+      eventNum: props.currentDetail.orderNumber,
     };
-  },
-  computed: {
-    dialogVisible: {
-      get() {
-        return this.modelValue;
-      },
-      set(value) {
-        this.$emit('update:modelValue', value);
-      }
-    },
-    isEditMode() {
-      return this.currentDetail.status === -1;
-    },
-    formattedDetailFields() {
-      const fields = [
-        { label: '工单名称', value: this.currentDetail.orderName },
-        {
-          label: '工单类型',
-          value: this.types.find(t => t.value === this.currentDetail.type)?.label || this.currentDetail.type,
-        },
-        { label: '关联任务', value: this.currentDetail.job_name || '/' },
-        { label: '工单创建人', value: this.currentDetail.creator },
-        { label: '当前状态', value: this.mapStatus(this.currentDetail.status) },
-        { label: '事件地址', value: this.currentDetail.address || this.currentDetail.latAndLon },
-        {
-          label: '关联算法',
-          value: this.algorithms.find(t => t.value === this.currentDetail.aiType)?.label || this.currentDetail.aiType,
-        },
-        { label: '发起单位', value: this.currentDetail.department },
-        { label: '发起任务时间', value: this.currentDetail.startTime },
-        { label: '工单内容', value: this.currentDetail.content },
-      ];
 
-      const filteredFields = fields.filter(field => field.value !== '/');
-      const formattedFields = [];
-      for (let i = 0; i < filteredFields.length; i += 2) {
-        formattedFields.push({
-          label1: filteredFields[i]?.label || '',
-          value1: filteredFields[i]?.value || (filteredFields[i]?.label ? '暂无数据' : ''),
-          label2: filteredFields[i + 1]?.label || '',
-          value2: filteredFields[i + 1]?.value || (filteredFields[i + 1]?.label ? '暂无数据' : ''),
-        });
-      }
-
-      return formattedFields;
+    const response = await flowEvent(data);
+    if (response.data.code === 0) {
+      ElMessage.success('工单已通过');
+      emit('detail-success');
+      handleClose();
+    } else {
+      throw new Error(response.data.msg || '操作失败');
     }
-  },
-  watch: {
-    modelValue(newVal) {
-      if (newVal) {
-        this.loadStepInfo();
-        this.initMap();
-      }
-    },
-    currentDetail: {
-      handler(newVal) {
-        if (newVal && this.dialogVisible) {
-          this.loadStepInfo();
-          this.initMap();
-        }
-      },
-      deep: true
+  } catch (error) {
+    ElMessage.error(error.message || '操作失败,请稍后重试');
+    emit('detail-error', error);
+  } finally {
+    approveLoading.value = false;
+  }
+};
+
+const handleReject = async () => {
+  if (rejectLoading.value) return;
+  rejectLoading.value = true;
+  
+  try {
+    const data = {
+      id: props.currentDetail.id,
+      status: props.currentDetail.status,
+      isPass: 1,
+    };
+
+    const response = await flowEvent(data);
+    if (response.data.code === 0) {
+      ElMessage.success('工单未通过');
+      emit('detail-success');
+      handleClose();
+    } else {
+      throw new Error(response.data.msg || '操作失败');
     }
-  },
-  methods: {
-    handleClose() {
-      this.dialogVisible = false;
-    },
+  } catch (error) {
+    ElMessage.error(error.message || '操作失败,请稍后重试');
+    emit('detail-error', error);
+  } finally {
+    rejectLoading.value = false;
+  }
+};
 
-    handlePrev() {
-      if (this.currentIndex > 0) {
-        this.$emit('prev-item');
-      }
-    },
+const handleApproveAndDispatch = () => {
+  // 触发派发工单操作,由父组件处理
+  emit('approve-and-dispatch', props.currentDetail);
+};
 
-    handleNext() {
-      if (this.currentIndex < this.totalItems - 1) {
-        this.$emit('next-item');
-      }
-    },
-
-    async loadStepInfo() {
-      try {
-        const stepResponse = await getStepInfo(this.currentDetail.orderNumber);
-        const steps = Array.isArray(stepResponse.data.data)
-          ? stepResponse.data.data
-          : stepResponse.data.data?.steps || [];
-        
-        const finishedStep = steps.find(s => String(s.status) === '4');
-        this.totalTime = finishedStep && finishedStep.total_time ? finishedStep.total_time : '';
-        
-        this.stepInfos = steps.map(step => ({
-          status: String(step.status),
-          name: step.name,
-          time: step.time,
-          create_time: step.create_time,
-        }));
-      } catch (error) {
-        console.error('加载步骤信息失败:', error);
-        this.stepInfos = [];
-      }
-    },
-
-    initMap() {
-      this.$nextTick(() => {
-        if (this.$refs.mapContainerRef && this.$refs.mapContainerRef.initAddEntity && this.currentDetail.location) {
-          this.$refs.mapContainerRef.initAddEntity('point', this.currentDetail.location);
-        }
-      });
-    },
-
-    mapStatus(status) {
-      const statusTextMap = {
-        '-1': '草稿',
-        2: '待审核',
-        0: '待处理',
-        3: '处理中',
-        4: '已完成',
-      };
-      return statusTextMap[status] || '未知状态';
-    },
-
-    getStepHandler(status) {
-      const step = this.stepInfos.find(step => step.status === status);
-      return step ? step.name : '';
-    },
-
-    getStepTime(status) {
-      const step = this.stepInfos.find(step => step.status === status);
-      return step && step.time && step.time !== '0' ? step.time : false;
-    },
-
-    getStepCreateTime(status) {
-      const step = this.stepInfos.find(step => step.status === status);
-      return step ? step.create_time : null;
-    },
-
-    getActiveStep() {
-      const arr = this.stepStatusList;
-      console.log('stepStatusList',this.stepStatusList);
-      
-      const index = arr.indexOf(String(this.currentDetail.status));
-      return index !== -1 ? index + 2 : 1;
-    },
-
-    handleQRCode(val) {
-      this.$emit('update:currentDetail', {
-        ...this.currentDetail,
-        showQR: !val.showQR
-      });
-    },
-
-    getThumbUrl(url) {
-      if (!url) return '';
-      return getSmallImg(url);
-    },
-
-    getPreviewUrl(url) {
-      if (!url) return '';
-      return getShowImg(url);
-    },
-
-    hasProcessingBtnPermission() {
-      return this.permission && this.permission.tickets_processing_btn === true;
-    },
-
-    hasProcessedAndOverBtnPermission() {
-      return this.permission && this.permission.tickets_view_processedAndOver === true;
-    },
-
-    hasReviewBtnPermission() {
-      return this.permission && this.permission.tickets_review_btn === true;
-    },
-
-    // 文件操作方法
-    handleFileChange(file, fileList) {
-      this.$emit('update:currentDetail', {
-        ...this.currentDetail,
-        photos: fileList
-      });
-    },
-
-    handleUploadRemove(file, fileList) {
-      this.$emit('update:currentDetail', {
-        ...this.currentDetail,
-        photos: fileList
-      });
-    },
-
-    beforeUpload(file) {
-      const isImage = file.type.includes('image');
-      const isLt5M = file.size / 1024 / 1024 < 5;
-
-      if (!isImage) {
-        this.$message.error('只能上传图片文件!');
-        return false;
-      }
-      if (!isLt5M) {
-        this.$message.error('图片大小不能超过5MB!');
-        return false;
-      }
-      return true;
-    },
-
-    // 工单操作方法
-    async handleApprove() {
-      if (this.approveLoading) return;
-      this.approveLoading = true;
-      
-      try {
-        const data = {
-          id: this.currentDetail.id,
-          status: this.currentDetail.status,
-          isPass: 0,
-          eventNum: this.currentDetail.orderNumber,
-        };
-
-        const response = await flowEvent(data);
-        if (response.data.code === 0) {
-          this.$message.success('工单已通过');
-          this.$emit('detail-success');
-          this.handleClose();
-        } else {
-          throw new Error(response.data.msg || '操作失败');
-        }
-      } catch (error) {
-        this.$message.error(error.message || '操作失败,请稍后重试');
-        this.$emit('detail-error', error);
-      } finally {
-        this.approveLoading = false;
-      }
-    },
-
-    async handleReject() {
-      if (this.rejectLoading) return;
-      this.rejectLoading = true;
-      
-      try {
-        const data = {
-          id: this.currentDetail.id,
-          status: this.currentDetail.status,
-          isPass: 1,
-        };
-
-        const response = await flowEvent(data);
-        if (response.data.code === 0) {
-          this.$message.success('工单未通过');
-          this.$emit('detail-success');
-          this.handleClose();
-        } else {
-          throw new Error(response.data.msg || '操作失败');
-        }
-      } catch (error) {
-        this.$message.error(error.message || '操作失败,请稍后重试');
-        this.$emit('detail-error', error);
-      } finally {
-        this.rejectLoading = false;
-      }
-    },
-
-    handleApproveAndDispatch() {
-      // 触发派发工单操作,由父组件处理
-      this.$emit('approve-and-dispatch', this.currentDetail);
-    },
-
-    async handleComplete() {
-      if (this.completeLoading) return;
-      this.completeLoading = true;
-      
-      try {
-        if (!this.currentDetail.processingDetail) {
-          this.$message.warning('请先填写事件处理详情');
-          return;
-        }
-
-        if (!this.currentDetail.photos || this.currentDetail.photos.length === 0) {
-          this.$message.warning('请选择上传图片');
-          this.completeLoading = false;
-          return;
-        }
-
-        const data = {
-          id: this.currentDetail.id,
-          status: this.currentDetail.status,
-          processingDetails: this.currentDetail.processingDetail,
-          eventNum: this.currentDetail.orderNumber,
-        };
-
-        const file = this.currentDetail.photos?.[0]?.raw || null;
-
-        const response = await flowEvent(data, file);
-
-        if (response.data.code === 0) {
-          this.$message.success('工单已完成');
-          this.$emit('detail-success');
-          this.handleClose();
-        } else {
-          throw new Error(response.data.msg || '操作失败');
-        }
-      } catch (error) {
-        console.error('完成工单失败:', error);
-        this.$message.error(error.message || '操作失败,请稍后重试');
-        this.$emit('detail-error', error);
-      } finally {
-        this.completeLoading = false;
-      }
+const handleComplete = async () => {
+  if (completeLoading.value) return;
+  completeLoading.value = true;
+  
+  try {
+    if (!props.currentDetail.processingDetail) {
+      ElMessage.warning('请先填写事件处理详情');
+      return;
     }
+
+    if (!props.currentDetail.photos || props.currentDetail.photos.length === 0) {
+      ElMessage.warning('请选择上传图片');
+      completeLoading.value = false;
+      return;
+    }
+
+    const data = {
+      id: props.currentDetail.id,
+      status: props.currentDetail.status,
+      processingDetails: props.currentDetail.processingDetail,
+      eventNum: props.currentDetail.orderNumber,
+    };
+
+    const file = props.currentDetail.photos?.[0]?.raw || null;
+
+    const response = await flowEvent(data, file);
+
+    if (response.data.code === 0) {
+      ElMessage.success('工单已完成');
+      emit('detail-success');
+      handleClose();
+    } else {
+      throw new Error(response.data.msg || '操作失败');
+    }
+      handleClose();
+  } catch (error) {
+    console.error('完成工单失败:', error);
+    ElMessage.error(error.message || '操作失败,请稍后重试');
+    emit('detail-error', error);
+      handleClose();
+  } finally {
+    completeLoading.value = false;
+      handleClose();
   }
 };
 </script>
+
 <style lang="scss">
 .custom-dialog {
-  max-height: 95vh;
-
-  :deep(.el-dialog__body) {
+  max-height: 96vh;
+ transition: max-height 0.3s ease-out;
+  .el-dialog__body {
     border-top: 0.1rem solid #f0f0f0;
+  }
+}
+
+.custom-qrcode-popover {
+  min-width: 160px !important;
+  min-height: 140px !important;
+  position: relative;
+
+  .qrcode-content {
+    margin-top: 8px;
+
+    .close-btn {
+      position: absolute;
+      top: 2px;
+      right: 2px;
+      width: 16px;
+      height: 16px;
+      line-height: 16px;
+      text-align: center;
+      cursor: pointer;
+      color: #999;
+      font-size: 16px;
+      z-index: 10;
+    }
   }
 }
 </style>
 <style lang="scss" scoped>
+.uploadImg {
+  margin-bottom: 32px;
+}
+
+.tableCss {
+  width: 100%;
+  margin-bottom: 10px;
+}
 
 .step-timer {
   position: absolute;
@@ -777,6 +815,138 @@
   color: #666;
   font-size: 12px;
 }
+
+.event-total-time {
+  text-align: center;
+  color: #666;
+  font-size: 15px;
+  margin-bottom: 12px;
+}
+
+
+.el-dialog {
+  .el-form-item {
+    margin-bottom: 20px;
+  }
+}
+
+.el-upload {
+  width: 100%;
+  display: flex;
+  flex-wrap: wrap;
+
+  :deep(.el-upload-list__item) {
+    transition: all 0.3s ease;
+  }
+
+  :deep(.el-upload-list__item:hover) {
+    background-color: #f5f7fa;
+  }
+}
+
+.el-upload__tip {
+  font-size: 12px;
+  color: #909399;
+  margin-top: 12px;
+}
+
+:deep(.el-dialog__body) {
+  border-top: 0.1rem solid #f0f0f0;
+}
+
+
+.dialog-footer1-new {
+  position: sticky;
+  bottom: 28px;
+  left: 0;
+  right: 0;
+  background: white;
+  z-index: 10;
+  padding: 16px 20px;
+  border-top: 1px solid #ebeef5;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+
+  .el-button + .el-button {
+    margin-left: 12px;
+  }
+
+  .btngroups {
+    margin-left: 12px;
+  }
+
+  .el-button {
+    padding: 9px 20px;
+
+    &:last-child {
+      margin-left: 12px;
+      margin-right: 12px;
+    }
+  }
+}
+
+.map-container {
+  width: 100%;
+  height: 400px;
+  margin-bottom: 15px;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  overflow: hidden;
+
+  :deep(.el-input-map) {
+    height: 100%;
+  }
+}
+
+
+.map-select {
+  display: flex;
+  align-items: flex-start;
+  gap: 15px;
+
+  .selected-location {
+    flex: 1;
+    padding: 5px 10px;
+    background-color: #f5f7fa;
+    border-radius: 4px;
+
+    p {
+      margin: 5px 0;
+      color: #606266;
+      font-size: 14px;
+    }
+  }
+}
+
+.preview-image {
+  border-radius: 4px;
+  overflow: hidden;
+  background-color: #f5f7fa;
+}
+
+.image-placeholder,
+.image-error,
+.no-media {
+  height: 200px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  color: #909399;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+
+  i {
+    font-size: 32px;
+    margin-bottom: 8px;
+  }
+}
+
+.no-media {
+  border: 1px dashed #d9d9d9;
+}
+
 .detail-container {
   padding: 0 20px;
 
@@ -790,44 +960,7 @@
     }
   }
 }
-.event-title-center {
-  text-align: center;
-  font-size: 20px;
-  font-weight: bold;
-  margin-bottom: 5px;
-  color: #333;
-}
-.event-total-time {
-  text-align: center;
-  color: #666;
-  font-size: 15px;
-  margin-bottom: 12px;
-}
-.custom-steps-container {
-  width: 100%;
-  margin: 10px 0;
-}
 
-.steps-titles {
-  display: flex;
-  justify-content: space-between;
-  margin-bottom: 14px;
-  position: relative;
-}
-
-.step-title {
-  text-align: center;
-  flex: 1;
-  font-size: 14px;
-  color: #999;
-  position: relative;
-  padding-bottom: 5px;
-}
-
-.step-title.active {
-  color: #409eff;
-  font-weight: bold;
-}
 .status-flow {
   margin-bottom: 20px;
 
@@ -887,78 +1020,11 @@
     }
   }
 }
-.step-description {
-  font-size: 14px;
-  color: #666;
-  line-height: 1.5;
-  display: block;
-  text-align: center;
 
-  &:first-child {
-    font-weight: bold;
-    margin-bottom: 4px;
-  }
+.basic-info {
+  margin-bottom: 20px;
 }
-.PopUpTableScrolls {
-  max-height: 600px;
-  overflow-y: scroll;
-  overflow-x: hidden;
-}
-.tableCss {
-  width: 100%;
-  margin-bottom: 10px;
-}
-/* 必填项样式 */
-.required-label {
-  position: relative;
-  display: inline-block;
 
-  .required-star {
-    color: #f56c6c;
-    margin-right: 4px;
-  }
-}
-/* 必填输入框样式 */
-.required-input {
-  width: 100%;
-
-  :deep(.el-input__inner),
-  :deep(.el-textarea__inner) {
-    &:focus {
-      border-color: #409eff;
-    }
-  }
-}
-/* 新建工单和处理工单的上传组件样式 */
-.create-upload,
-.detail-upload {
-  :deep(.el-upload--picture-card) {
-    width: 120px;
-    height: 100px;
-    line-height: 100px;
-  }
-
-  /* 隐藏额外的上传按钮 */
-  :deep(.el-upload.el-upload--picture-card) {
-    display: none;
-  }
-
-  /* 当没有图片时显示上传按钮 */
-  :deep(.el-upload.el-upload--picture-card:first-child) {
-    display: flex;
-  }
-
-  /* 上传组件的预览图片样式 */
-  :deep(.el-upload-list--picture-card .el-upload-list__item) {
-    width: 120px;
-    height: 100px;
-  }
-}
-.el-upload__tip {
-  font-size: 12px;
-  color: #909399;
-  margin-top: 12px;
-}
 .media-section {
   // margin-bottom: 20px;
 
@@ -967,6 +1033,32 @@
     align-items: center;
   }
 }
+
+.leftBtn {
+  width: 70px;
+  height: 32px;
+  background-color: #999;
+  border-radius: 5px;
+  text-align: center;
+  line-height: 32px;
+  color: #fff;
+  cursor: pointer;
+  opacity: 0.8;
+}
+
+.disableds {
+  background: #999 !important;
+  cursor: not-allowed !important;
+  pointer-events: none;
+  opacity: 0.3 !important;
+}
+
+.PopUpTableScrolls {
+  max-height: 600px;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+
 .media-box {
   width: 100%;
   border: 1px solid #dcdfe6;
@@ -1006,75 +1098,50 @@
     }
   }
 }
+
 .image-placeholder,
 .image-error,
 .no-media {
-  height: 200px;
   display: flex;
-  flex-direction: column;
   align-items: center;
   justify-content: center;
+  height: 100%;
   color: #909399;
   background-color: #f5f7fa;
   border-radius: 4px;
+}
 
-  i {
-    font-size: 32px;
-    margin-bottom: 8px;
-  }
+.image-placeholder i,
+.image-error i {
+  font-size: 32px;
+  margin-bottom: 8px;
 }
 
 .no-media {
   border: 1px dashed #d9d9d9;
 }
-.dialog-footer1-new {
-  position: sticky;
-  bottom: 28px;
-  left: 0;
-  right: 0;
-  background: white;
-  z-index: 10;
-  padding: 16px 20px;
-  border-top: 1px solid #ebeef5;
+
+.info-table {
+  margin-bottom: 20px;
+}
+
+.info-item {
   display: flex;
-  justify-content: space-between;
-  align-items: center;
-
-  .el-button + .el-button {
-    margin-left: 12px;
-  }
-
-  .btngroups {
-    margin-left: 12px;
-  }
-
-  .el-button {
-    padding: 9px 20px;
-
-    &:last-child {
-      margin-left: 12px;
-      margin-right: 12px;
-    }
-  }
-}
-.leftBtn {
-  width: 70px;
-  height: 32px;
-  background-color: #999;
-  border-radius: 5px;
-  text-align: center;
-  line-height: 32px;
-  color: #fff;
-  cursor: pointer;
-  opacity: 0.8;
+  margin-bottom: 10px;
 }
 
-.disableds {
-  background: #999 !important;
-  cursor: not-allowed !important;
-  pointer-events: none;
-  opacity: 0.3 !important;
+.info-label {
+  font-weight: bold;
+  width: 120px;
+  color: #606266;
 }
+
+.info-value {
+  flex: 1;
+  color: #303133;
+  word-break: break-word;
+}
+
 .readonly-processing-detail {
   background-color: #f5f7fa;
   padding: 12px;
@@ -1091,4 +1158,144 @@
     margin-bottom: 4px;
   }
 }
-</style>
\ No newline at end of file
+
+// 添加删除按钮样式
+.danger-button {
+  color: #f56c6c;
+}
+
+.danger-button:hover {
+  color: #f78989;
+}
+
+.custom-steps-container {
+  width: 100%;
+  margin: 10px 0;
+}
+
+.steps-titles {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 14px;
+  position: relative;
+}
+
+.step-title {
+  text-align: center;
+  flex: 1;
+  font-size: 14px;
+  color: #999;
+  position: relative;
+  padding-bottom: 5px;
+}
+
+.step-title.active {
+  color: #409eff;
+  font-weight: bold;
+}
+
+.event-title-center {
+  text-align: center;
+  font-size: 20px;
+  font-weight: bold;
+  margin-bottom: 5px;
+  color: #333;
+}
+
+.custom-steps {
+  margin-top: -20px;
+
+  :deep(.el-step__description) {
+    margin-top: 8px;
+    padding: 0 20px;
+  }
+}
+
+.step-description {
+  font-size: 14px;
+  color: #666;
+  line-height: 1.5;
+  display: block;
+  text-align: center;
+
+  &:first-child {
+    font-weight: bold;
+    margin-bottom: 4px;
+  }
+}
+
+// 覆盖其他相关样式
+.status-flow {
+  .custom-steps {
+    .el-step__description {
+      position: relative;
+      margin: 0;
+      padding: 0;
+    }
+
+    // 移除之前的样式
+    .init-step-info,
+    .step-info {
+      display: block;
+      width: auto;
+      text-align: center;
+    }
+  }
+}
+
+/* 新建工单和处理工单的上传组件样式 */
+.create-upload,
+.detail-upload {
+  :deep(.el-upload--picture-card) {
+    width: 120px;
+    height: 100px;
+    line-height: 100px;
+  }
+
+  /* 隐藏额外的上传按钮 */
+  :deep(.el-upload.el-upload--picture-card) {
+    display: none;
+  }
+
+  /* 当没有图片时显示上传按钮 */
+  :deep(.el-upload.el-upload--picture-card:first-child) {
+    display: flex;
+  }
+
+  /* 上传组件的预览图片样式 */
+  :deep(.el-upload-list--picture-card .el-upload-list__item) {
+    width: 120px;
+    height: 100px;
+  }
+}
+
+/* 原有图片预览的样式 */
+.el-image-viewer__wrapper {
+  :deep(.el-image-viewer__img) {
+    max-width: 100%;
+    max-height: 100%;
+    object-fit: contain;
+  }
+}
+/* 必填项样式 */
+.required-label {
+  position: relative;
+  display: inline-block;
+
+  .required-star {
+    color: #f56c6c;
+    margin-right: 4px;
+  }
+}
+/* 必填输入框样式 */
+.required-input {
+  width: 100%;
+
+  :deep(.el-input__inner),
+  :deep(.el-textarea__inner) {
+    &:focus {
+      border-color: #409eff;
+    }
+  }
+}
+</style>

--
Gitblit v1.9.3