ConstructionDailyReportDrawer.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 = { ...form.value } as Record<string, any>
  70. await FiveIotProjectDailyReportApi.updateIotProjectDailyReport(payload)
  71. message.success('保存成功')
  72. emits('update:visible', false)
  73. await props.loadList()
  74. } finally {
  75. submitLoading.value = false
  76. }
  77. }
  78. function handleModelChange(value: ConstructionDailyReportRow) {
  79. form.value = value
  80. }
  81. defineExpose({ handleOpenForm })
  82. </script>
  83. <template>
  84. <el-drawer
  85. :model-value="props.visible"
  86. size="80%"
  87. destroy-on-close
  88. header-class="mb-0!"
  89. @update:model-value="emits('update:visible', $event)">
  90. <template #header>
  91. <span class="text-xl font-bold text-[var(--el-text-color-primary)]">{{ drawerTitle }}</span>
  92. </template>
  93. <el-form ref="formRef" :model="form" label-position="top" v-loading="loading">
  94. <div class="flex flex-col gap-6">
  95. <ConstructionDailyReportFormSection
  96. v-for="section in formSections"
  97. :key="section.title"
  98. :model="form"
  99. :section="section"
  100. :disabled="disabled"
  101. @update:model="handleModelChange" />
  102. </div>
  103. </el-form>
  104. <template #footer>
  105. <el-button size="default" @click="emits('update:visible', false)">取消</el-button>
  106. <el-button
  107. size="default"
  108. v-if="!disabled"
  109. type="primary"
  110. :loading="submitLoading"
  111. @click="handleSubmit">
  112. 保存
  113. </el-button>
  114. </template>
  115. </el-drawer>
  116. </template>