businessLaunch.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <el-drawer
  3. :close-on-click-modal="false"
  4. class="local-launch_drawer-wrap"
  5. :title="record.processName"
  6. :model-value="modelValue"
  7. size="760px"
  8. @update:model-value="updateModelValue"
  9. >
  10. <div v-if="validateForm.loading" v-loading="true" class="local_loading"></div>
  11. <div class="info-wrap">
  12. <el-divider content-position="left">{{ record.processName }}表单</el-divider>
  13. <!-- 表单设计 -->
  14. <template v-if="record.formTemplate.type === 0">
  15. <div class="self-Everright-formEditor">
  16. <er-form-preview ref="EReditorRef" :is-show-complete-button="false" :file-upload-u-r-i="uploadFileApi" />
  17. </div>
  18. </template>
  19. <!-- vue自定义 -->
  20. <template v-if="record.formTemplate.type === 1">
  21. <component :is="dyVueComponent"></component>
  22. </template>
  23. <el-divider content-position="left">审批流程</el-divider>
  24. <flow-trend ref="flowTrendRef" v-model="modelContentConfig"></flow-trend>
  25. <el-divider></el-divider>
  26. </div>
  27. <template #footer>
  28. <el-button @click="updateModelValue(false)">{{ $t('le.btn.cancel') }}</el-button>
  29. <el-button :disabled="validateForm.loading" type="primary" style="margin-left: 8px" @click="onSubmit">{{ $t('le.btn.confirm') }}</el-button>
  30. </template>
  31. </el-drawer>
  32. </template>
  33. <script setup lang="ts">
  34. import model from '@/api/flow/process'
  35. import purchaseOrder from '@/api/test/purchaseOrder'
  36. import { nextTick, onMounted, ref, markRaw, defineAsyncComponent } from 'vue'
  37. import { ElMessage } from 'element-plus'
  38. import { erFormPreview } from '@ER/formEditor'
  39. import FlowTrend from '@/components/Flow/FlowTrend.vue'
  40. import type { ModelContentConfig } from '@/views/approve/components/config.ts'
  41. type Props = {
  42. modelValue: boolean
  43. record: { processId: string; processName: string; [key: string]: any }
  44. }
  45. type Assignee = {
  46. type: 1 | 3 // 1: 用户 3: 角色
  47. assignees: { [key: string]: any /*name, id*/ }
  48. disabled?: boolean
  49. selectOpts?: any
  50. // minSelected?: number
  51. // maxSelected?: number
  52. }
  53. // 当前form 表单数据字符串
  54. let cur_processForm_str = '{}'
  55. const updateModelValue = (bool: boolean) => emit('update:modelValue', bool)
  56. const props = defineProps<Props>()
  57. const emit = defineEmits<{
  58. 'update:modelValue': [bool: boolean] // 具名元组语法
  59. update: [value: string]
  60. }>()
  61. const validateForm = ref({ loading: false })
  62. const { VITE_APP_BASE_API } = import.meta.env
  63. const uploadFileApi = ref(`${VITE_APP_BASE_API}/v1/oss/upload`)
  64. const EReditorRef = ref()
  65. const modelContentConfig = ref<ModelContentConfig | any>({})
  66. const dyVueComponent = ref(undefined)
  67. const flowTrendRef = ref()
  68. const onSubmit = async () => {
  69. const processId = props.record.processId
  70. const form = EReditorRef.value.getSelfFormRef()
  71. form.validate((valid: any) => {
  72. if (valid) {
  73. // 表单验证通过 进行保存
  74. validateForm.value.loading = true
  75. const formData = EReditorRef.value.getData()
  76. let processForm = JSON.parse(cur_processForm_str)
  77. processForm = { ...processForm, formData }
  78. // 这里要从子节点获取流程图信息 进行保存
  79. const _assigneeMap = flowTrendRef.value.getAssigneeMap()
  80. const assigneeMap_ = Object.keys(_assigneeMap).reduce((obj, nodeKey: string) => {
  81. const _o = _assigneeMap[nodeKey]
  82. obj[nodeKey] = {
  83. assigneeList: _o.assignees,
  84. type: _o.type
  85. }
  86. return obj
  87. }, {} as { [nodeKey: string]: any })
  88. const params = {
  89. id: props.record.rowId,
  90. test: 'formTemplate',
  91. processStart: {
  92. processId, // 流程ID
  93. processForm: JSON.stringify(processForm), // 流程表单JSON内容 & local_value 保存
  94. assigneeMap: assigneeMap_
  95. }
  96. }
  97. purchaseOrder
  98. .postlaunchApi(params)
  99. .then(res => {
  100. ElMessage.success('提交成功')
  101. updateModelValue(false)
  102. })
  103. .finally(() => {
  104. validateForm.value.loading = false
  105. })
  106. }
  107. })
  108. }
  109. // 获取当前表单中的详情
  110. const getDetailInfo = () => {
  111. validateForm.value.loading = true
  112. let modelContent_config = {}
  113. const modelContent = JSON.parse(props.record.modelContent) // modelContent 这个是后台返回来的
  114. modelContent_config = modelContent.nodeConfig ?? modelContent.childNode
  115. modelContentConfig.value = modelContent_config
  116. const { content, type } = props.record.formTemplate
  117. if (!type) {
  118. // type: 0 表单设计 1 vue自定义表单
  119. cur_processForm_str = content || '{}' // processForm 这个是后台返回来的
  120. const formStructure = JSON.parse(cur_processForm_str)
  121. EReditorRef.value.setData(formStructure)
  122. } else {
  123. dyVueComponent.value = markRaw(defineAsyncComponent(() => import('./test1.vue')))
  124. }
  125. validateForm.value.loading = false
  126. }
  127. onMounted(() => {
  128. nextTick(() => {
  129. getDetailInfo()
  130. })
  131. })
  132. </script>
  133. <style lang="scss">
  134. // 和ItemDrawer一样可以公用,待提取
  135. .local-launch_drawer-wrap {
  136. .el-drawer__header {
  137. display: flex;
  138. padding: 16px 24px;
  139. align-items: center;
  140. justify-content: space-between;
  141. background-color: var(--el-color-info-light-9);
  142. text-align: left;
  143. /* margin-right: 0; */
  144. margin-bottom: 0;
  145. }
  146. .el-drawer__close-btn {
  147. padding: 0;
  148. margin-right: -12px;
  149. }
  150. .el-drawer__body {
  151. position: relative;
  152. display: flex;
  153. flex-direction: column;
  154. }
  155. .el-drawer__footer {
  156. border-top: 1px solid var(--el-border-color-lighter);
  157. padding: 12px 24px;
  158. }
  159. .local_loading {
  160. position: absolute;
  161. left: 0;
  162. display: flex;
  163. align-items: center;
  164. justify-content: center;
  165. width: 100%;
  166. height: 100%;
  167. z-index: 999;
  168. background: rgba(0, 0, 0, 0.05);
  169. }
  170. }
  171. </style>
  172. <style scoped lang="scss">
  173. .info-wrap {
  174. .form-wrap {
  175. flex: 1;
  176. }
  177. // 修改everright 表单的样式
  178. .self-Everright-formEditor {
  179. :deep(.Everright-formEditor-selectElement) {
  180. padding: 0px 16px;
  181. }
  182. }
  183. }
  184. </style>