yyb
8 小时以前 769fb543015f1a90d42882a0a9f0592efa45a10e
src/components/ProjectManagement/ProgressReportDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,242 @@
<template>
  <el-dialog v-model="visible" title="进度汇报" width="900px" top="8vh" append-to-body destroy-on-close @close="handleClose">
    <el-form ref="formRef" :model="form" :rules="rules" label-position="top" label-width="120px">
      <el-form-item label="项目阶段" prop="planNodeId">
        <el-select v-model="form.planNodeId" placeholder="请选择" clearable style="width: 100%">
          <el-option v-for="opt in stageOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
        </el-select>
      </el-form-item>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="计划开始时间" prop="planStartTime">
            <el-date-picker
              v-model="form.planStartTime"
              type="date"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              placeholder="请选择"
              style="width: 100%"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="计划完工时间" prop="planEndTime">
            <el-date-picker
              v-model="form.planEndTime"
              type="date"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              placeholder="请选择"
              style="width: 100%"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="实际开工日期" prop="actualStartTime">
            <el-date-picker
              v-model="form.actualStartTime"
              type="date"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              placeholder="请选择"
              style="width: 100%"
              clearable
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="本次进度日期" prop="reportDate">
            <el-date-picker
              v-model="form.reportDate"
              type="date"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              placeholder="请选择"
              style="width: 100%"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="上次进度(%)" prop="lastProgress">
            <el-input-number v-model="form.lastProgress" :min="0" :max="100" controls-position="right" style="width: 100%" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="完成进度(%)" prop="completionProgress">
            <div style="display: flex; gap: 8px; width: 100%;">
              <el-input-number v-model="form.completionProgress" :min="0" :max="100" controls-position="right" style="flex: 1" />
              <el-button type="danger" @click="markDone">完成</el-button>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="累计进度(%)" prop="totalProgress">
            <el-input-number v-model="form.totalProgress" :min="0" :max="100" controls-position="right" style="width: 100%" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="实际完工日期" prop="actualEndTime">
            <el-date-picker
              v-model="form.actualEndTime"
              type="date"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              placeholder="请选择"
              style="width: 100%"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="负责人" prop="managerName">
            <el-input v-model="form.managerName" placeholder="请输入" clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="部门" prop="departmentName">
            <el-input v-model="form.departmentName" placeholder="请输入" clearable />
          </el-form-item>
        </el-col>
        <el-col :span="16">
          <el-form-item label="备注" prop="remark">
            <el-input v-model="form.remark" placeholder="请输入" clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="附件" prop="attachmentIds">
        <FileUpload v-model:file-list="form.storageBlobDTOs" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="submit">确定</el-button>
        <el-button @click="visible = false">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup name="ProgressReportDialog">
import { computed, reactive, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/auth'
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
const props = defineProps({
  modelValue: { type: Boolean, default: false },
  projectId: { type: [Number, String], default: undefined },
  projectInfo: { type: Object, default: () => ({}) },
  planNodes: { type: Array, default: () => [] },
  defaultPlanNodeId: { type: [Number, String], default: undefined }
})
const emit = defineEmits(['update:modelValue', 'submitted'])
const visible = computed({
  get: () => props.modelValue,
  set: v => emit('update:modelValue', v)
})
const formRef = ref()
const form = ref({
  planNodeId: undefined,
  planStartTime: '',
  planEndTime: '',
  actualStartTime: '',
  actualEndTime: '',
  reportDate: '',
  lastProgress: 0,
  completionProgress: 0,
  totalProgress: 0,
  managerName: '',
  departmentName: '',
  remark: '',
  storageBlobDTOs: []
})
const rules = {
  planNodeId: [{ required: true, message: '请选择', trigger: 'change' }],
  planStartTime: [{ required: true, message: '请选择计划开始时间', trigger: 'change' }],
  planEndTime: [{ required: true, message: '请选择计划完工时间', trigger: 'change' }],
  reportDate: [{ required: true, message: '请选择', trigger: 'change' }],
  completionProgress: [{ required: true, message: '请输入', trigger: 'change' }]
}
const stageOptions = computed(() => {
  const list = Array.isArray(props.planNodes) ? props.planNodes : []
  const sorted = [...list].sort((a, b) => Number(a.sort ?? 0) - Number(b.sort ?? 0))
  return sorted
    .map(n => ({
      label: n.name || n.workContent || n.title || String(n.id ?? ''),
      value: n.id
    }))
    .filter(i => i.value !== undefined && i.value !== null && i.value !== '')
})
function resetFromProject() {
  const info = props.projectInfo || {}
  form.value = {
    planNodeId: props.defaultPlanNodeId ?? stageOptions.value[0]?.value,
    planStartTime: info.planStartTime || '',
    planEndTime: info.planEndTime || '',
    actualStartTime: info.actualStartTime || '',
    actualEndTime: info.actualEndTime || '',
    reportDate: '',
    lastProgress: Number(info.lastProgress ?? 0) || 0,
    completionProgress: 0,
    totalProgress: Number(info.totalProgress ?? info.progress ?? 0) || 0,
    managerName: info.managerName || '',
    departmentName: info.departmentName || '',
    remark: '',
    storageBlobDTOs: []
  }
}
watch(
  () => props.modelValue,
  v => {
    if (v) resetFromProject()
  }
)
function handleClose() {
  formRef.value?.resetFields?.()
}
function markDone() {
  form.value.completionProgress = 100
  form.value.totalProgress = 100
  if (!form.value.actualEndTime) form.value.actualEndTime = form.value.reportDate || ''
}
async function submit() {
  await formRef.value?.validate?.()
  emit('submitted', {
    projectId: props.projectId,
    ...form.value
  })
  visible.value = false
}
</script>
<style scoped lang="scss">
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>