edit.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <a-modal
  3. v-model:visible="visible"
  4. :title="`${project.projectId ? $t('sys.update') : $t('sys.add')} ${$t(
  5. 'project.name'
  6. )}`"
  7. width="660px"
  8. :after-close="onCancel"
  9. @ok="saveHandler"
  10. >
  11. <template #footer>
  12. <a-button class="action-bottom" size="middle" @click="visible = false">
  13. {{ $t('sys.cancel') }}
  14. </a-button>
  15. <a-button
  16. class="action-bottom"
  17. type="primary"
  18. size="middle"
  19. @click="saveHandler"
  20. >
  21. {{ project.projectId ? $t('sys.update') : $t('sys.add') }}
  22. </a-button>
  23. </template>
  24. <a-form
  25. ref="fromRef"
  26. :model="project"
  27. class="form"
  28. label-align="right"
  29. :label-col="{ span: 4 }"
  30. >
  31. <a-form-item
  32. name="projectName"
  33. :label="$t('project.projectNameLabel')"
  34. :rules="[rules.projectName]"
  35. >
  36. <a-input
  37. v-model:value.trim="project.projectName"
  38. :maxlength="rules.projectName.max"
  39. :placeholder="rules.projectName.message"
  40. />
  41. </a-form-item>
  42. <a-form-item
  43. name="projectMsg"
  44. :label="$t('project.projectMsgLabel')"
  45. :rules="[rules.projectMsg]"
  46. >
  47. <a-textarea
  48. v-model:value.trim="project.projectMsg"
  49. :maxlength="rules.projectMsg.max"
  50. :resize="false"
  51. style="height: 104px; resize: none"
  52. :placeholder="rules.projectMsg.message"
  53. />
  54. </a-form-item>
  55. <a-form-item name="projectImg" :label="$t('project.projectImgLabel')">
  56. <Upload
  57. v-model:file="project.projectImg"
  58. :max-size="10"
  59. :extnames="['png', 'jpg', 'gif']"
  60. :tips="[$t('project.projectImgTip')]"
  61. />
  62. </a-form-item>
  63. <a-form-item
  64. v-if="!project.projectId"
  65. name="projectImg"
  66. :label="$t('project.projectBimLabel')"
  67. >
  68. <Upload
  69. v-model:file="project.bimFile"
  70. :max-size="5 * 1024"
  71. :extnames="['ifc', 'fbx']"
  72. />
  73. </a-form-item>
  74. </a-form>
  75. </a-modal>
  76. </template>
  77. <script lang="ts" setup>
  78. import { ref, defineProps, toRaw } from 'vue'
  79. import Upload from '@/components/upload/index.vue'
  80. import type { InsertProjectData, Project } from '@/api'
  81. import type { FormInstance } from 'ant-design-vue'
  82. import { ui18n } from '@/lang'
  83. export type IProject = Omit<InsertProjectData, 'projectImg'> & {
  84. projectId?: Project['projectId']
  85. bimFile?: File
  86. projectImg?: string | File
  87. }
  88. defineOptions({ name: 'InsertProject' })
  89. const props = defineProps<{
  90. project?: IProject
  91. onSave: (data: IProject) => void
  92. onCancel: () => void
  93. }>()
  94. const project = ref<IProject>(
  95. props.project
  96. ? { ...props.project }
  97. : {
  98. projectName: '',
  99. projectMsg: '',
  100. bimFile: undefined,
  101. projectImg: undefined
  102. }
  103. )
  104. const rules = {
  105. projectName: {
  106. required: true,
  107. max: 40,
  108. min: 1,
  109. message: ui18n.t('project.projectNameRule', { max: 40 })
  110. },
  111. projectMsg: {
  112. required: true,
  113. max: 200,
  114. min: 1,
  115. message: ui18n.t('project.projectMsgRule', { max: 200 })
  116. }
  117. }
  118. const fromRef = ref<FormInstance>()
  119. const visible = ref(true)
  120. let enter = false
  121. const saveHandler = async () => {
  122. if (enter) return
  123. enter = true
  124. try {
  125. await fromRef.value?.validate()
  126. await props.onSave(toRaw(project.value))
  127. visible.value = false
  128. } catch (e) {
  129. throw e
  130. } finally {
  131. enter = false
  132. }
  133. }
  134. </script>
  135. <style lang="scss" scoped>
  136. .footer {
  137. display: flex;
  138. justify-content: space-between;
  139. align-items: center;
  140. p {
  141. margin-bottom: 0;
  142. color: #646566;
  143. font-size: 14px;
  144. }
  145. }
  146. </style>