ConstructionDailyReportDrawer.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <script setup lang="ts">
  2. import { FiveIotProjectDailyReportApi } from '@/api/pms/fiveconstructiondailyreport'
  3. import dayjs from 'dayjs'
  4. import type { FormInstance } from 'element-plus'
  5. import ConstructionDailyReportFormSection from './ConstructionDailyReportFormSection.vue'
  6. import {
  7. createEmptyConstructionDailyReport,
  8. formSections,
  9. type ConstructionDailyReportRow
  10. } from './report-config'
  11. interface Props {
  12. visible: boolean
  13. loadList: () => void | Promise<void>
  14. }
  15. const props = defineProps<Props>()
  16. const emits = defineEmits(['update:visible'])
  17. const formRef = ref<FormInstance>()
  18. const loading = ref(false)
  19. const submitLoading = ref(false)
  20. const drawerMode = ref<'edit' | 'readonly'>('edit')
  21. const form = ref<ConstructionDailyReportRow>(createEmptyConstructionDailyReport())
  22. const message = useMessage()
  23. const drawerTitle = computed(() =>
  24. drawerMode.value === 'readonly' ? '查看施工日报' : '填报施工日报'
  25. )
  26. const disabled = computed(() => drawerMode.value === 'readonly')
  27. function normalizeDetail(detail: Record<string, any> = {}) {
  28. const createTime = detail.createTime
  29. const constructionEndDate = detail.constructionEndDate
  30. return {
  31. ...createEmptyConstructionDailyReport(),
  32. ...detail,
  33. createTime: createTime
  34. ? dayjs(createTime).isValid()
  35. ? dayjs(createTime).format('YYYY-MM-DD')
  36. : createTime
  37. : detail.createTime,
  38. constructionEndDate: constructionEndDate
  39. ? dayjs(constructionEndDate).isValid()
  40. ? dayjs(constructionEndDate).format('YYYY-MM-DD')
  41. : constructionEndDate
  42. : detail.constructionEndDate
  43. } as ConstructionDailyReportRow
  44. }
  45. async function loadDetail(id: number) {
  46. loading.value = true
  47. try {
  48. const detail = await FiveIotProjectDailyReportApi.getIotProjectDailyReport(id)
  49. form.value = normalizeDetail(detail)
  50. } finally {
  51. loading.value = false
  52. }
  53. }
  54. async function handleOpenForm(id: number, type: 'edit' | 'readonly') {
  55. drawerMode.value = type
  56. emits('update:visible', true)
  57. await loadDetail(id)
  58. nextTick(() => formRef.value?.clearValidate())
  59. }
  60. async function handleSubmit() {
  61. // console.log('handleSubmit', form.value)
  62. // return
  63. if (drawerMode.value === 'readonly') {
  64. emits('update:visible', false)
  65. return
  66. }
  67. submitLoading.value = true
  68. try {
  69. const payload = {
  70. ...form.value,
  71. taskId: form.value.taskId ?? null
  72. } as Record<string, any>
  73. await FiveIotProjectDailyReportApi.updateIotProjectDailyReport(payload)
  74. message.success('保存成功')
  75. emits('update:visible', false)
  76. await props.loadList()
  77. } finally {
  78. submitLoading.value = false
  79. }
  80. }
  81. function handleModelChange(value: ConstructionDailyReportRow) {
  82. form.value = value
  83. }
  84. defineExpose({ handleOpenForm })
  85. </script>
  86. <template>
  87. <el-drawer
  88. :model-value="props.visible"
  89. size="80%"
  90. destroy-on-close
  91. header-class="mb-0!"
  92. @update:model-value="emits('update:visible', $event)">
  93. <template #header>
  94. <span class="text-xl font-bold text-[var(--el-text-color-primary)]">{{ drawerTitle }}</span>
  95. </template>
  96. <el-form ref="formRef" :model="form" label-position="top" v-loading="loading">
  97. <div class="flex flex-col gap-6">
  98. <ConstructionDailyReportFormSection
  99. v-for="section in formSections"
  100. :key="section.title"
  101. :model="form"
  102. :section="section"
  103. :disabled="disabled"
  104. @update:model="handleModelChange" />
  105. </div>
  106. </el-form>
  107. <template #footer>
  108. <el-button size="default" @click="emits('update:visible', false)">取消</el-button>
  109. <el-button
  110. size="default"
  111. v-if="!disabled"
  112. type="primary"
  113. :loading="submitLoading"
  114. @click="handleSubmit">
  115. 保存
  116. </el-button>
  117. </template>
  118. </el-drawer>
  119. </template>